Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheBlueMatt/3041216 to your computer and use it in GitHub Desktop.
Save TheBlueMatt/3041216 to your computer and use it in GitHub Desktop.
Transaction Fee rework proposal

Reworking Bitcoin Transaction Fees

Transaction fees as they are currently implemented in the original Bitcoin code suffer from a few problems:

  • The rules are somewhat complicated and are not at all transparent
  • Fees are hard-coded and do not reflect real costs
  • Adding fees to a transaction doesn't necessarily make it more likely the transaction will be confirmed more quickly.

The following is a summary of proposals and ideas put forth by others to provide for more discussion.

Proposals

Proposal: better priority algorithm

Transaction priority is currently calculated as: sum(input_value_in_base_units * input_age)/size_in_bytes. However, this does a relatively poor job addressing the total network cost of a transaction. A good priority algorithm will take into account the cost to the network as well as the "spammyness" of a given transaction. It should also be easy to calculate an intermediate value for a given txout may be, to make coin selection efficient.

Proposal: Client minimum fee/priority determination

For the last few thousand transactions, as they enter/exit the memory pool, remember (size, fees, time_in, time_out, priority_in, priority_out)

Estimate fee-per-kilobyte-to-get-into-the-next-block-or-two by: Something based on the transactions which have not been accepted to blocks for more than 6 blocks.

  • Straw man: average fee/kb among the highest N transactions (sorted by fee/kb) that have been in mempool unconfirmed for >6 blocks.

6 blocks is selected as, in the future, there may be several large miners who take few or no transactions from the peer-to-peer network in order to make room for the transactions of clients with whom they have mining contracts with and such block should be largely ignored by this algorithm.

Estimate minimum-priority-to-get-into-a-block as:

  • median priority_out for all transactions in blocks that had been in memory pool where fees are 0

Proposal: Transaction Spam Prevention

To address transaction spammers, nodes will not accept or relay any transactions that have a priority less than the X AND a fee*priority less than Y [AND a fee less than N/kb] This way high-priority transactions that are non-spammy will be accepted, but also semi-spammy transactions can be accepted if they pay a fee that is proportional to their estimated cost to the network.

One could also set a fee N that allows any transaction which pays a fee higher than N to be relayed. Such a N could be calculated based on a similar algorithm to the algorithm clients use to determine the fee-per-kb to pay.

Note that this policy needs to be as loose as possible, as it is one of the biggest PR issues with the current transaction fee policy.

TODO: figure out a reasonable X and Y.

Proposal: Mining

I propose that miners be given the following "knobs" to control their transaction acceptance policy:

  • Maximum size of blocks created (default: 200K, maximum: 1MB)
  • Maximum value of BTC fees to forgo per block to make room for high-priority, low/no-fee transactions (default: 0.01 BTC)

Miners are free to choose or change the parameters at any time for any reason.

I propose that the standard algorithm for deciding which transactions are included in a block be:

When creating a new block sort all transactions by fee-per-kb, and, starting with the highest-paying transactions, create a list of as many as will fit into the block.

Then replace transactions one at a time from the bottom of the list with the highest-priority transaction, until the amount of fees lost is just less than maximum-fees-to-forgo.

The result should be much better for both miners and users. Miners maximize their profits by taking the highest-paying transactions first, and if a user wants their transaction confirmed quickly then just need to pay a high enough fee to make it into the fee-paying head of the list.

If a user doesn't care how quickly their transactions are confirmed and miners are willing to forgo a modest amount of fees, then including low/no-fee, high-priority transactions will help keep Bitcoin's reputation as the "usually free payment solution."

Is a "dust spam" minimum transaction output value needed?

There is a special case in the current code that requires a minimum transaction fee if a transaction has any very-small outputs.

Sorting the "free" area by transaction priority eliminates the need for that special case. If you repeatedly "shave off" 0.0000001 bitcoin from a larger transaction then the first transaction may have a high priority, but subsequent transactions should have a low priority and will likely not be relayed or included in blocks.

Receiver-pays-fees model

When deciding what is a fee-paying transaction and what is not, it is a good idea to consider groups of related transactions together. For example, if a user sends a fee-less transaction to a merchant, the merchant might combine it with a few dozen other fee-less transactions and pay a fee to "sweep" them all into a savings address and get them confirmed. It would be fairly straightforward to consider the total size and fees of a set of related transactions together when deciding what to include in a block.

Also, when using a payment protocol to generate transactions which are going to merchants, the payment protocol should take into account the priority/anti-spam relayability. ie the merchant should be able to specify that the node can freely ignore the anti-spam and priority rules and simply submit the transaction to the merchant, allowing them to submit their transactions to miners with whom they have a mining contract.

Proposal: Bitcoin-Qt

Bitcoin-Qt should monitor transactions entering and exiting the memory pool, and infer miners' transaction inclusion policies from the behavior it sees (see "Client minimum fee/priority determination" proposal above). If it hasn't been up and running long enough to observe a few hundred transactions entering/exiting the memory pool, and the user hasn't explicitly set them, it will assume conservative, compiled-in defaults for minimum transaction fee-per-kilobyte and minimum free transaction priority.

A simple possible user-interface: Send dialog box has a checkbox that says something like "Automatically add fees for quick confirmation".

If checked: right level of fees automatically added. (and a confirmation before sending?)

If unchecked, and the transaction priority is high enough that the transaction will be relayed according to the loose anti-spam relay rules and is likely be confirmed within ~24 hours in blocks, add 0 fee.

If unchecked but the transaction priority is unlikely to be confirmed, but does meet the anti-spam relay rules, warn the user and explain the issue, giving them an option to add a fee.

If unchecked but the transactions does not meet the anti-spam relay rules, warn the user and explain the issue, suggesting that they wait roughly N blocks as their inputs age until they send to meet the anti-spam relay rules.

Proposal: Fetch "current fee policy" ?

In order to support filtering SPV nodes which do not see any transactions in mempool or blocks except their own, a current fee policy (calculated according to the "Client minimum fee/priority determination" proposal above) should be provided on bitcoin.org or other mirrors. Because the calculation depends on the memory pool of a given node, it may vary from other nodes' calculations. However, there is little reason the data shouldn't still be close to the data of other nodes (especially given a "Bitcoin backbone" that has public nodes which which other clients can peer), which should allow for loose verification of the data provided.

Proposal: Changes to RPC interface

New method(s) to get/set the 2 fee policy parameters; when set, they affect the next block created. These can also be set by command-line/bitcoin.conf parameters.

The "Client minimum fee/priority determination" proposal above will be used by the RPC send* commands. If generating a transaction with a priority less than the minimum, fees will automatically be added; otherwise, the transaction will be sent fee-free.

RPC users that want complete control over transaction fees can use the listunspent/createrawtx/signrawtx/sendrawtx API.

RPC commands will be provided to see the current "Client minimum fee/priority determination" data, which makes it easy for people to verify the bitcoin.org-provided data.

@luke-jr
Copy link

luke-jr commented Jul 3, 2012

  • Overriding fees shouldn't require dealing with raw transactions.
  • Fee policy publishing shouldn't be centralized

@TheBlueMatt
Copy link
Author

Fee policy publishing is deliberately non-centralized. Every full-node is able to get all the info it needs to publish fee policy info via RPC. By default, clients can pull from bitcoin.org, or wherever the client-creator wants to. Bitcoin-Qt may pull from bitcoin.org, but it only uses that info very briefly until it has seen enough transactions/blocks to make its own judgments.

@TheBlueMatt
Copy link
Author

In terms of how to override fees, meh...I have little opinion there. I dont see many people wanting to create their own transactions which want to use fees less than the minimum to relay them to pass the anti-spam rules, and Im not sure doing so should be made easy...but, that opinion is pretty weak, if others feel strongly there, its up to them.

@luke-jr
Copy link

luke-jr commented Jul 3, 2012

@TheBlueMatt
Copy link
Author

People who dont understand what they are doing, ignore the listed warnings and stupidly proceed anyway is the reason I kinda believe it shouldn't be made easy to do. If people who do understand what they are doing express interest, then Id say making it easy to do would be perfectly acceptable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment