The course grained (hard-coded value) of something like 0.0001 BTC works great for standard transactions
    (one input, one output). However, it will cause a lag in more complex or large transactions. So we calculate the
    raw tx fee, then take the max of the default fee and the refined cost to ensure prompt processing.

    The transaction fee is:
        fee = satoshi_per_byte * tx_size
    :param tx_cost_constants:
    :param num_inputs:
    :param num_outputs:
    :return:

def calculate_tx_fee(tx_cost_constants, num_inputs, num_outputs):
    """
    The course grained (hard-coded value) of something like 0.0001 BTC works great for standard transactions
    (one input, one output). However, it will cause a lag in more complex or large transactions. So we calculate the
    raw tx fee, then take the max of the default fee and the refined cost to ensure prompt processing.

    The transaction fee is:
        fee = satoshi_per_byte * tx_size
    :param tx_cost_constants:
    :param num_inputs:
    :param num_outputs:
    :return:
    """
    tx_size = calculate_raw_tx_size_with_op_return(num_inputs, num_outputs)
    tx_fee = tx_cost_constants.satoshi_per_byte * tx_size
    return max(tx_fee, tx_cost_constants.get_recommended_fee_coin())