Here we present the second part of the changes meant to implement RFC 12: Decentralized wallet coordination in the tBTC wallet client. This pull request focuses on the coordination procedure.
On the code level, this is about implementing the coordinationExecutor.coordinate function.
Coordination seed
Calculation of the coordination seed was implemented in the coordinationExecutor.getSeed function. This function computes the seed for the given coordination window according to the RFC 12 specification:
The computed value is used to initialize the RNG for random operations executed as part of the coordination procedure. Those operations are:
Leader selection
Heartbeat execution
Coordination leader
Leader selection was implemented in the coordinationExecutor.getLeader function. It uses the coordination seed to select the leader operator from all operators backing the coordinated wallet. The exact algorithm is:
Get the list of unique operators
Sort the list by address in the ascending order
Randomly shuffle the list using an RNG initialized with the coordination seed
Pick the first operator from the shuffled list
Actions checklist
The next step is determining which wallet actions should be checked and possibly proposed during the coordination window. A list of such actions is called actions checklist. Actions on the list are ordered by priority, in descending order.
For example, if the list is: [Redemption, DepositSweep, Heartbeat], the leader must start by checking if redemption can be proposed. If so, it should do it. Otherwise, it should check the deposit sweep. If neither redemption nor deposit sweep can be proposed, the leader should propose a heartbeat.
Actions checklist assembling was implemented in the coordinationExecutor.getActionsChecklist function. The exact checklist depends on the coordination window. The specific algorithm is:
Check the possibility of redemption on every window
Check the possibility of a deposit sweep, then moved funds sweep, then moving funds, every 16th window
Draw a decision regarding the heartbeat proposal, with a 12.5% chance of success
Leader's routine
If the given operator finds itself to be a leader for the given coordination window, it executes the leader's routine implemented in the coordinationExecutor.executeLeaderRoutine function. It uses the actions checklist to generate a proposal and broadcasts the proposal to the followers, using the underlying broadcast channel. It completes the coordination procedure returning the generated proposal as a result.
Proposal generator
The leader uses the proposal generator function to generate a proposal based on the actions checklist for the given window. The generator is expected to return a proposal for the first action from the checklist that is valid for the given wallet's state. If none of the actions are valid, the generator returns a no-op proposal.
Implementation of the proposal generator is beyond the scope of this pull request and will be handled in a follow-up PR. The plan is to use the code from pkg/maintainer/wallet that is currently used by the wallet maintainer bot.
Follower's routine
If the given operator is not the leader for the given coordination window, it executes the follower's routine implemented in the coordinationExecutor.executeFollowerRoutine function. It listens for incoming coordination messages and accepts the first message that:
Is of the proper type
Is not a self-message
Comes from a sender with a confirmed wallet membership
Refers to the currently processed coordination window
Refers to the coordinated wallet
Comes from the coordination leader designated for the given window
Holds a proposal referring to an action from the checklist or a no-op proposal
The operator-follower completes the coordination procedure returning the received proposal as a result.
Next steps
The next steps on the way towards RFC 12 implementation are:
Implement proposal generation
Finalize coordination result processing (i.e. implement the processCoordinationResult function and refactor node's handlers appropriately)
Remove the existing chain-based mechanism (i.e. detach WalletCoordinator's events handlers and remove unnecessary code from chain.go)
Modify the SPV maintainter to not rely on WalletCoordinator's events during unproven transactions lookup
Refs: https://github.com/keep-network/tbtc-v2/issues/737 Depends on: https://github.com/keep-network/keep-core/pull/3744
Here we present the second part of the changes meant to implement RFC 12: Decentralized wallet coordination in the tBTC wallet client. This pull request focuses on the coordination procedure.
On the code level, this is about implementing the
coordinationExecutor.coordinate
function.Coordination seed
Calculation of the coordination seed was implemented in the
coordinationExecutor.getSeed
function. This function computes the seed for the given coordination window according to the RFC 12 specification:The computed value is used to initialize the RNG for random operations executed as part of the coordination procedure. Those operations are:
Coordination leader
Leader selection was implemented in the
coordinationExecutor.getLeader
function. It uses the coordination seed to select the leader operator from all operators backing the coordinated wallet. The exact algorithm is:Actions checklist
The next step is determining which wallet actions should be checked and possibly proposed during the coordination window. A list of such actions is called actions checklist. Actions on the list are ordered by priority, in descending order.
For example, if the list is:
[Redemption, DepositSweep, Heartbeat]
, the leader must start by checking if redemption can be proposed. If so, it should do it. Otherwise, it should check the deposit sweep. If neither redemption nor deposit sweep can be proposed, the leader should propose a heartbeat.Actions checklist assembling was implemented in the
coordinationExecutor.getActionsChecklist
function. The exact checklist depends on the coordination window. The specific algorithm is:Leader's routine
If the given operator finds itself to be a leader for the given coordination window, it executes the leader's routine implemented in the
coordinationExecutor.executeLeaderRoutine
function. It uses the actions checklist to generate a proposal and broadcasts the proposal to the followers, using the underlying broadcast channel. It completes the coordination procedure returning the generated proposal as a result.Proposal generator
The leader uses the proposal generator function to generate a proposal based on the actions checklist for the given window. The generator is expected to return a proposal for the first action from the checklist that is valid for the given wallet's state. If none of the actions are valid, the generator returns a no-op proposal.
Implementation of the proposal generator is beyond the scope of this pull request and will be handled in a follow-up PR. The plan is to use the code from
pkg/maintainer/wallet
that is currently used by the wallet maintainer bot.Follower's routine
If the given operator is not the leader for the given coordination window, it executes the follower's routine implemented in the
coordinationExecutor.executeFollowerRoutine
function. It listens for incoming coordination messages and accepts the first message that:The operator-follower completes the coordination procedure returning the received proposal as a result.
Next steps
The next steps on the way towards RFC 12 implementation are:
processCoordinationResult
function and refactornode
's handlers appropriately)WalletCoordinator
's events handlers and remove unnecessary code fromchain.go
)WalletCoordinator
's events during unproven transactions lookup