Please describe the feature you’d like to see added.
This is a feature request for a broadcast pool. A broadcast pool is a cache local to the node which contains transactions which have been initially broadcast from that node, either from a local wallet or via an RPC like sendrawtransaction
. Broadcast transactions are retained in this cache until they are included in a block, or expire after the configured mempoolexpiry
period. The transactions in the broadcast pool are included in views on the mempool, ensuring that transactions broadcast from the node are not lost to the user due to fee rate environment changes. Transaction invalidation and replacement is handled in the same way as in the mempool. Transactions in broadcast pool that are not present in the mempool will occasionally be rebroadcasted, making this existing functionality available to all transactions broadcasted through the node and not just those created by a local wallet.
As an additional feature, a future-dated timestamp can be added in metadata associated with a broadcast pool transaction. Should such a timestamp exist, the transaction is only added to the local mempool and broadcast to the network after that date, allowing the user to mitigate timing analysis and obtain greater privacy. Future-dated transactions are also included in views on the mempool, but are marked as unbroadcast: true
in mempool RPC responses, and are similarly subject to removal via normal transaction invalidation and replacement rules.
Is your feature related to a problem, if so please describe it.
The necessary resource limitations on the mempool lead to an unfortunate consequence for wallet developers and users. Because the mempool does not distinguish between transactions broadcast by the user, and all other transactions, broadcasted transactions can be ’lost’ to the user due to external fee rate environment changes. These ’lost’ transactions are then not available in a wallet interface for view or replacement by fee - they simply (and often unexpectedly) disappear. Further, they may mysteriously reappear, having not been dropped from a larger mempool as typically configured by a miner. This is a poor user experience, and leads users to consider out-of-band solutions, or to increase the size of their local mempool which is resource inefficient and counterproductive to the network as a whole. It is reasonable to assume that a user’s broadcasted transactions carry much more economic value to them than most other transactions, and justify protection through some degree of additional resource allocation. This feature request seeks to realise that rationale, providing a better user experience consistent with the health of the network.
With respect to privacy, timing analysis is unfortunately a simple and convincing approach to link otherwise unconnected transactions. For example, a common use case is to transfer the funds in one wallet to another, perhaps for security reasons. In order to avoid linking the funds in disparate UTXOs, the user must not only send them one by one from the old wallet to the new, but do so with random (and lengthy) time intervals between each send. Failure to do so will result in a much higher chance of funds being linked onchain simply by the transactions being included in the same or adjacent blocks. Most bitcoin nodes are run as continuously online servers, and therefore are ideal candidates to handle this otherwise onerous task.
Describe the solution you’d like
The broadcast pool is a local cache of usually small but configurable maximum size. A default maximum value of 300 kB is proposed. Similarly to the mempool, the cache is persisted on shutdown and restored on startup. Transactions in the broadcast pool are subject to almost all of the same rules as those in the mempool, except that they are not removed due to mempool size limitations.
Transactions in the broadcast pool not present in the mempool are occasionally rebroadcast. Optionally, a future-dated timestamp can be specified when broadcasting a transaction. In this case, the transaction is added to the broadcast pool but not to the local mempool or broadcast to the network until after that date has passed. If the node is restarted after the timestamp on a future-dated transaction, the transaction will be immediately broadcast. All transactions in the broadcast pool are included in views on the mempool, and in that sense the broadcast pool can be viewed as an extension of the mempool where different eviction rules apply. Future-dated broadcast transactions are not included in block templates.
If the broadcast pool is full and the broadcast is not future-dated, the broadcast will proceed as it does currently but with a warning returned to the user. A future-dated broadcast to a full broadcast pool will fail.
Describe any alternatives you’ve considered
It is possible to try to solve the evicted transaction retention problem on the application layer within a wallet application. Practically however, this is far from ideal. Client wallets are generally opened and closed at indeterminate times, leading to a state conflict with the connected node that must be resolved. Light client protocols are generally not optimized for this use case, leading to significant complexity and performance degradation. Further, consensus logic such as that used for transaction replacement by fee must be replicated in each wallet application.
With respect to the timing analysis problem, setting a future-dated broadcast will encourage the user to leave their wallet application open, which is in conflict to the ideal of cold storage. Further, the environment for mobile wallets is not well suited to this long running task.
In summary, addressing these problems in a wallet application leads to poor separation of concerns.
Please leave any additional context
A short list of related issues from some popular Bitcoin wallets: