Minimal implementation for "Scheduled Transaction Broadcast" new feature.
Goal: Allow a user to submit a transaction to be broadcast later, at a specified time (block height). This can be done for convenience, or to hide the exact time of the transaction creation (for increased privacy).
Goal in this PR: Extend the sendrawtransaction RPC with an option to schedule the broadcast at a later time, determined by the lock time of the transaction.
Use case details, with the limitations of the current changeset:
sendrawtransactionhas an optional parameter,delay_after_lock_time- If
delay_after_lock_timeis set to 0, thenLockTimeof the transaction determines the scheduled broadcast time (in the future). - If
delay_after_lock_timeis set to a positive number, the broadcast time will be the sum of the transactionnLockTimeand the parameter value. - Only height-based lock times are supported, time-based can be added later.
- Scheduled broadcast is only supported with private broadcast.
- What is a typical delay time? 3-12 blocks. (Too long times can get problematic: risk fee increase, node restart.)
- Pending transactions are NOT persisted, so pending transactions will be lost during a node stop/restart/crash (can be added later).
- Validation should happen at both submission time and broadcast time, but now this is not true, see below.
- If the goal is to conceal the real transaction creation time, the user should add a relatively short, random period to the current time (e.g between 3-12 blocks).
- 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 support from the wallet subsystem. (A submitted but not broadcast transactions is not visible in the wallet.)
- It is possible intentionally set the locktime of a TX in the past (e.g. as a measure against wallet fingerprinting), and still use a later schedule time --
delay_after_lock_timewith a positive value can be used to distance the submission time from the lock time.
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). Alternative: triggered by new blocks. - Queue is not persisted currently, to be added later.
- Submit-time validation is skipped, as it would fail, due to the future locktime. To be added later.
Further improvements:
- Add a cap on the time lock, on how far in the future it is acceptable, e.g. max 7 days / 1008 blocks.
- Support time-based locktime as well. Interpret
delay_after_lock_timein 10-minute units if time-based lock is used. - At submission time, perform validation but without timelock checks. This requires a small validation change (add bypass timelocks options to methods
ProcessTransactionandAcceptToMemoryPool). - Persist the queue with pending broadcasts, so scheduled broadcasts survive node restarts.
Related issue: #34118
EDIT (Nov-03): Reworked, see #36429 (comment)