Minimal implementation for "Delayed Transaction Broadcast" new feature.
Goal: Allow a user to submit a transaction for delayed broadcasting, that will be broadcast only later, at a randomized time. The aim is increased privacy, by making time-correlation-based tracking more difficult. This fits together with private broadcast: private connection broadcast tries to hide the originator node; randomized delay tries to hide the creation time.
Goals in this PR: Extend the sendrawtransaction RPC with an optional delay_for parameter, and if set, postpone the initial broadcast to that later time, with some extra jitter.
Use case Details, with the limitations of the current changeset:
- What is a typical delay time? 30 - 90 minutes. (Too long times can get problematic: risk fee increase, node restart.)
- Delayed broadcast is only supported with private broadcast.
- Delay option and time is specified per submission (in
sendrawtransaction). Alternative: with node level config. - For now pending transactions are NOT persisted, so pending transactions will be lost during a node stop/restart/crash.
- Randomized delay is expressed as a percentage of the requested delay. A hard-coded value of 50% is used.
- Delay times are capped: requested delay between 0min to 12 hours, randomization range to minimum 5 minutes.
- Validation happens both at submission and broadcast time.
- No special handling for sudden fee increase situations.
- Pending (submitted but not yet broadcast) transactions can be inspected via existing
getprivatebroadcastinfoRPC. - The (pre-existing)
abortprivatebroadcastRPC can be used to cancel a pending transaction submission. - No special
nLockTimehandling, to be refined later. - No special support from the wallet subsystem. (A submitted but not broadcast transactions is not visible in the wallet.)
Solution Details:
- The solution is based on the Private Broadcast implementation.
- Transactions are stored in the already-existing
m_transactionscollection. - A scheduled periodic check is added to check for transactions that have became due. The implementation is very similar to the existing retry logic (
ReattemptPrivateBroadcast). - Queue is not persisted currently, to be added later.