I was looking at the implementation of the send RPC method, specifically what happens when add_to_wallet is true and the transaction isn't eligible for the mempool.
As best I can tell, this sequence of events happens:
AcceptToMemoryPool also happens to be what queuerawtransaction() currently uses to test whether transaction are eligible, and chain().broadcastTransaction also happens to be what CWallet::EffectTransactionQueue currently uses to broadcast queued transactions, and SubmitTxMemoryPoolAndRelay also happens to be what MaybeResendWalletTxs uses for transactions that are in the wallet but aren't confirmed. So... it looks like we should be able to just use the send() method, without needing to maintain our own transaction queue?
Observations:
MaybeResendWalletTxs only tries to resubmit every 12-24 hours for privacy reasons. This seems OK for queued renewals. For queued registrations, we could work around it by adding an extra flag that makes it try every block only for name_firstupdate transactions. Alternatively, if we're worried about bunching together renewals in a way that reveals common ownership, we could make it try every block for all name transactions.
Using the wallet's built-in rebroadcasting should automatically avoid accidentally causing double-spends or address reuse.
Using the wallet's built-in rebroadcasting should result in the queued transactions automatically showing up in the GUI.
And of course, using the wallet's built-in rebroadcasting should yield a much smaller diff against Bitcoin Core.
Is my understanding of the code correct? Is there any reason we're not doing it this way?
I was looking at the implementation of the
send
RPC method, specifically what happens whenadd_to_wallet
is true and the transaction isn't eligible for the mempool.As best I can tell, this sequence of events happens:
send()
callsFinishTransaction()
. https://github.com/bitcoin/bitcoin/blob/a38603456e9a8448874106c56966f3defb41574a/src/wallet/rpc/spend.cpp#L1310FinishTransaction()
callspwallet->CommitTransaction()
: https://github.com/bitcoin/bitcoin/blob/a38603456e9a8448874106c56966f3defb41574a/src/wallet/rpc/spend.cpp#L131C13-L131C39CommitTransaction()
callsSubmitTxMemoryPoolAndRelay()
: https://github.com/bitcoin/bitcoin/blob/a38603456e9a8448874106c56966f3defb41574a/src/wallet/wallet.cpp#L2351C10-L2351C36SubmitTxMemoryPoolAndRelay
callschain().broadcastTransaction()
: https://github.com/bitcoin/bitcoin/blob/a38603456e9a8448874106c56966f3defb41574a/src/wallet/wallet.cpp#L2044C16-L2044C44broadcastTransaction()
callsBroadcastTransaction()
: https://github.com/bitcoin/bitcoin/blob/a38603456e9a8448874106c56966f3defb41574a/src/node/interfaces.cpp#L686BroadcastTransaction()
callsnode.chainman->ProcessTransaction()
: https://github.com/bitcoin/bitcoin/blob/a38603456e9a8448874106c56966f3defb41574a/src/node/transaction.cpp#L83C48-L83C81ProcessTransaction()
callsAcceptToMemoryPool()
: https://github.com/bitcoin/bitcoin/blob/a38603456e9a8448874106c56966f3defb41574a/src/validation.cpp#L4594C19-L4594C37AcceptToMemoryPool also happens to be what
queuerawtransaction()
currently uses to test whether transaction are eligible, andchain().broadcastTransaction
also happens to be whatCWallet::EffectTransactionQueue
currently uses to broadcast queued transactions, andSubmitTxMemoryPoolAndRelay
also happens to be whatMaybeResendWalletTxs
uses for transactions that are in the wallet but aren't confirmed. So... it looks like we should be able to just use thesend()
method, without needing to maintain our own transaction queue?Observations:
MaybeResendWalletTxs
only tries to resubmit every 12-24 hours for privacy reasons. This seems OK for queued renewals. For queued registrations, we could work around it by adding an extra flag that makes it try every block only for name_firstupdate transactions. Alternatively, if we're worried about bunching together renewals in a way that reveals common ownership, we could make it try every block for all name transactions.Is my understanding of the code correct? Is there any reason we're not doing it this way?