Skip to content

Instantly share code, notes, and snippets.

@amitiuttarwar
Created July 17, 2019 19:06
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 amitiuttarwar/ac6c0e6981773ff62709e10bfe5e7b7f to your computer and use it in GitHub Desktop.
Save amitiuttarwar/ac6c0e6981773ff62709e10bfe5e7b7f to your computer and use it in GitHub Desktop.
I propose reworking the rebroadcast logic to
1. Significantly improve privacy
2. Create a cleaner divide between wallet & node responsibilities
#### Conceptual changes
* Instead of the wallet directly relaying transactions to peers , the wallet will submit unconfirmed txns to the node, and the node will apply logic to trigger txn rebroadcasts.
* The node will not keep track of “my” transactions but instead apply rebroadcast conditions to _all_ transactions.
* The wallet will attempt to resubmit unconfirmed transactions to the node on a scheduled timer. This is to ensure the txn is not dropped from the local mempool.
New rebroadcast conditions:
* relies on `BlockAssembler::addPackageTxs` to identify top block of transactions based on current mempool. I’ll call this “top transactions”.
* On some regular cadence find top transactions & only store the minimum package fee rate for inclusion.
* When it is time to rebroadcast, calculate top transactions, filter out transactions that are either recent or have a fee rate less than our calculated min. Queue the remaining up for rebroadcasting (and add timing delay logic).
#### Params & initially proposed values
* Frequency of resubmission attempt from wallet to node -> wallet resubmits once / day
* Frequency of finding min fee rate for txn to be included in block -> every 10 minutes
* Frequency of triggering rebroadcast -> after block comes in, initiate rebroadcast with delay between (1,30) mins (but have only one queued at a time)
* Defining highest priority transactions (top of mempool for potential txns to rebroadcast ) -> 3/4 block worth of txns based on package fee rate
* Define what “recent” transaction means -> only rebroadcast if txn is >10 minutes old.
#### Implementation (high level)
1. Update how the wallet submits transactions to the node
* Remove methods `CWalletTx::RelayWalletTransaction` & `ChainImpl#relayTransaction`
* Add logic to `LockImpl::submitToMemoryPool` to trigger transaction relay.
* Rework `CWallet::ResendWalletTransaction` to resubmit txns to the node instead of rebroadcasting them to peers.
2. Add rebroadcast logic to the mempool.
* Add a function `CTxMemPool::FeeRateForBlockInclusion` to calculate & store min txn fee rate to be included into block.
* Introduce new function `CTxMemPool::RebroadcastTransactions` to identify rebroadcast possibilities using `BlockAssembler::addPackageTxs`, apply filtering conditions as per logic above, and initiate relay to peers using `NetProcessing#RelayTransaction`. This would be kicked off towards the end of `ProcessNewBlock`, still identifying the exact place.
* Much of this new logic will be a slightly different version of `addPackageTxs`, so for a clean implementation I would want to pull out shared functionality into a separate method.
#### Considerations & Open questions
* Not introducing network-wide bandwidth spikes. Current proposed mechanisms to mitigate are 1. possion distribution of when rebroadcasts occur & 2. robust filtering logic. Some further possibilities are mentioned in this section.
* There is an inherent tradeoff between defining param [top of mempool] vs param [age of transactions filtered out]. The values I have proposed opt to reduce #1 allow for leniency for #2. Having more recent transactions enables txns evicted from the mempool during volatility to be rebroadcasted and thus confirmed sooner.
* We could do a simple fee rate traversal of the mempool instead of looking at transaction packages. One dependency for this to work is transaction package relay which is currently a WIP. However, mimic-ing the miner logic as closely as possible seems to reduce room for error.
* Possibility: use manual miner prioritization to boost the odds of my node rebroadcasting the transaction, without relaying that information to peers. This would increase assurance that originating wallet will rebroadcast txns, but decrease privacy.
* Possibility: node stores rebroadcast data, such as `last_rebroadcast_at` time or list of rebroadcasted txns per peer. Tradeoff between bandwidth vs memory. While not storing this data means two peers could rebroadcast the same txn to one another within a short time span, I believe the bandwidth usage of sending unnecessary INV messages is a lower cost than the memory usage and code complexity of effectively storing rebroadcasted txn per peer.
* Possibility: add an max of [# of rebroadcasts per duration] as a safety net. Under the current logic, the max would be 3/4 of a block of transactions ~1 time per block duration.
* Implementation: ensure we skip all rebroadcast calculations & relays unless we are at the main chain tip.
* Open question: instead of calculating & storing the min fee rate on an independent timer, could we calculate the set of top txns before removing block txns from mempool, store in memory and apply filter conditions?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment