keep-network / keep-core

The smart contracts and reference client behind the Keep network
https://keep.network
MIT License
118 stars 73 forks source link

RFC 12 Implementation: Coordination layer groundwork #3744

Closed lukasz-zimnoch closed 9 months ago

lukasz-zimnoch commented 9 months ago

Refs: https://github.com/keep-network/tbtc-v2/issues/737

Here we present the first part of the changes meant to implement RFC 12: Decentralized wallet coordination in the tBTC wallet client. This pull request focuses on the groundwork necessary to run the off-chain coordination layer.

Coordination layer orchestration

The node orchestrates the coordination layer upon startup. Specifically, it runs two separate goroutines:

Both goroutines are steered by the node's root context and communicate through a dedicated channel.

Coordination window watch

The coordination window watch goroutine is responsible for detecting coordination windows that occur every 900 blocks. Once a window is detected, it runs the window handler function and passes the window data as an argument. The window watch process guarantees that the window handler is called only once for the given coordination window. Moreover, it also guarantees that the window handler is called for all coordination windows. This is achieved by calling each handler in a separate goroutine so the watch loop does not block for long and the chance of missing a coordination window signal is negligible.

The window handler function triggers the window processing logic. Specific steps of that logic are:

  1. Determine the list of wallets controlled by the given node
  2. Take a coordination executor for each wallet
  3. Use the coordination executors to run the coordination procedure for each wallet (in parallel)
  4. Collect coordination results and push them to the processing channel

Coordination executor

The coordination executor is a component that is responsible for running the coordination procedure for the given wallet and coordination window. It is designed to encapsulate the logic of the procedure (coordination seed, communication, and so on). It also ensures that only one instance of the procedure is executed at a time. The executor is also responsible for assembling the coordination procedure's result and reporting all coordination faults detected during execution.

The design of the coordination executor is inspired by the existing signing and DKG executor. It attempts to fit the coordination procedure's logic into the existing codebase in an elegant way.

Coordination result processor

The coordination result processor goroutine listens for incoming coordination results and triggers the result handler function in a separate goroutine to ensure all results are processed independently.

The result handler function triggers the result processing logic. Specific steps of that logic are:

  1. Record coordination faults reported in the result
  2. Detect the type of the action proposal being part of the result
  3. Fire the appropriate proposal handler

The proposal handlers are part of the existing codebase. They are responsible for the orchestration and execution of the proposed wallet actions.

Intersection with the existing chain-based coordination mechanism

The presented groundwork was built alongside the existing chain-based coordination mechanism. Some initial integration steps around data types were done. The existing mechanism will be gradually removed and replaced in the follow-up pull requests.

Next steps

The next steps (coarse-grained) on the way towards RFC 12 implementation are:

pdyraga commented 9 months ago

Did a high-level review, looks good to me. Leaving it in the hands of @tomaszslabon.

lukasz-zimnoch commented 9 months ago

Did a high-level review, looks good to me. Leaving it in the hands of @tomaszslabon.

Thanks for reviewing @pdyraga !