Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BTC Staker Improvements #107

Open
KonradStaniec opened this issue Dec 18, 2024 · 2 comments
Open

BTC Staker Improvements #107

KonradStaniec opened this issue Dec 18, 2024 · 2 comments
Labels
EPIC Big task or collections of task that must be split into smaller pieces

Comments

@KonradStaniec
Copy link
Collaborator

This epic describes possible improvements to BTC staker based on most recent developments.

Delete watch-staking endpoint

The exsiting endpoint watch-staking endpoint was only introduced as hack for the past testnet. It can be deleted. It should simplify database and logic in stakerapp as there are different code paths to handle this request (example: https://github.com/babylonlabs-io/btc-staker/blob/v0.13.0/staker/stakerapp.go#L1502)

Remove post-approval flow

In the past the only way to stake was:

  1. first send staking transaction to BTC and wait for it to be confirmed
  2. then send delegation to BTC

This flow is currently discouraged.

Currently staker supports both flows: pre-approval and post-approval, due to the fact that it was easier and quicker to add additional flow rather than do fully fledged refactoring. Difference in handling both flows can be tracked from handling staking cmd.

Removal of post-approval flow, should result in simplifications in btc-staker logic. It should also result in possibility of dropping most of the state from btc-staker database.

Reduce amount of state held in Database

Currently btc-staker, holds a lot of state in its database which leads to complex logic when restarting the program.

After removing post-approval flow and watch-staking endpoint it should be possible to remove most of the state from btc-staker database and relay mostly only Babylon blockchain as some sort of storage for all the data related to staking. In theory, the only thing that btc-staker could store in its local db are staking transactions hashes for initiated staked requests.

Track status of each sent staking transaction with each new BTC block

Currently btc-staker tracks the state changes of the sent staking transactions based on the operations initiated from btc-staker. i.e if user would unbond his staker from other place (lets say front end ui) the btc staker would be left with invalid db state. This is less than ideal.

The most comprehensive solution would be:

  • create descriptors of Babylon staking scripts
  • with each staking request import descriptor describing used staking/unbonding scripts through https://developer.bitcoin.org/reference/rpc/importdescriptors.html bitocoind endpoint
  • this way funds locked in staking scripts would be treated as internal to bitcoind wallet i.e they would treated similarity as native p2wpkh addresses.
@KonradStaniec KonradStaniec added the EPIC Big task or collections of task that must be split into smaller pieces label Dec 18, 2024
@wnjoon
Copy link

wnjoon commented Dec 24, 2024

Hi, I am an engineer at B-Harvest. Our team plans to work on this issue, and we are considering proceeding as follows. If there are any issues or alternative suggestions, I'd appreciate it if you could share them.

In reality, I didn't change anything, but I first organized the parts that I thought needed to be modified in the overall flow.

Delete watch-staking endpoint

  • Remove codes related to watch-staking
    • stakerservice/service.go
      • watchStaking() function
      • watch-staking endpoint in the GetRoutes() function
    • stakerservice/client/rpcclient.go
      • WatchStaking() function
    • staker/stakerapp.go
      • WatchStaking() function
    • staker/types.go
      • parseWatchStakingRequest() function
    • ittest/manager.go
  • Considerations
    • API Compatibility with existing clients using the watch-staking endpoint adapt

Remove post-approval flow

  • Remove codes related to post-approval
    • staker/stakerapp.go
      • Remove sendToBabylonFirst parameter from StakeFunds() function
    • stakerservice/service.go
      • Remove sendToBabylonFirst parameter from stake() function
      • Update API route definition in GetRoutes() function
    • ittest/manager.go
  • Considerations
    • Plan for migration for users who are currently using the Post-Approval flow
    • Testnet Compatibility

Reduce amount of state held in Database

Currently, btc-staker stores extensive transaction state information in stakerdb/trackedtranactionstore.go. After removing the Post-Approval flow and watch-staking endpoint, we can significantly simplify the transaction tracking logic

  • Code change plan

    • staker/stakerapp.go
      • It appears that most database transaction state values will be directly queried within the Babylon blockchain rather than being stored locally.

        switch tx.State {
        	case proto.TransactionState_SENT_TO_BTC:
        	case proto.TransactionState_CONFIRMED_ON_BTC:
        	case proto.TransactionState_SENT_TO_BABYLON:
        	case proto.TransactionState_VERIFIED:
        	case proto.TransactionState_DELEGATION_ACTIVE:
        	case proto.TransactionState_UNBONDING_CONFIRMED_ON_BTC:
        	case proto.TransactionState_SPENT_ON_BTC:
        }
      • The total transaction data currently stored locally is roughly as follows:

        • Staking transaction details
        • Staker address information
        • Unbonding transaction data
        • Etc
      • There appears to be less need to keep track of complex state recovery logic and unbonding transaction data locally, since it can be looked up through Babylon when needed.

  • Suggestion

    // Example
    type MinimalStakingState struct {
        StakingTxHash    chainhash.Hash
        InitiatedAt      time.Time
        LastCheckedBlock int64
    }
    • Minimize local state
      • Save only staking transaction hash and minimal metadata
      • Remove full transaction data
      • Remove state transitions that can be inferred from Babylon
    • Information to be managed in Babylon
      • Delegation state
      • Unbonding information
      • Transaction validation state
      • Finality Provider information

Track status of each sent staking transaction with each new BTC block

  • Key Implementation Points

    • Generate descriptors for Babylon staking scripts

    • Register descriptors through Bitcoin Core's importdescriptors endpoint for each staking request

    • Treat staked funds as internal to Bitcoin Core wallet, similar to P2WPKH addresses

    • Technical details (descriptor example)

      // Descriptor Example
      {
          "desc": "wsh(multi(2,<staking_key>,<finality_provider_key>))",
          "timestamp": "now",
          "internal": true
      }
  • Code plan (This is an expected part and may change during actual implementation)

    • Modify walletcontroller package

      • Added new interface for managing descriptors

        type DescriptorManager interface {
            ImportDescriptor(desc string) error
            ListDescriptors() ([]string, error)
            RemoveDescriptor(desc string) error
        }
      • Added descriptor-related methods that allow sending importdescriptors requests to Bitcoin clients

    • Modify staker package

      • Added a function to generate a staking script descriptor
      • Modified StakeFunds() function to allow the creation and registration of staking script descriptors
    • Modify stakedb package

      • Added method to save descriptor
    • Create a monitoring package

      • Monitoring to check the status of addresses registered as descriptors for each block
      • Check the UTXO status of all registered descriptors
      • Update database when changes are found

Discussions

  • In a situation where issues 1 and 2 have been resolved (removal of watch-staking and post-approval), is there a need for a response plan for users who are using the method before the change?
  • Are there any common elements that should be maintained between staker-db and babylon during the process of resolving issue 3?
  • Do you have any thoughts on how to configure descriptors? (e.g. wsh, wpkh) In example/global-params.json, It seems that Babylon staking system uses multi-sig.

@KonradStaniec
Copy link
Collaborator Author

Note about Remove post-approval flow point.

After removing support for post approval flow, the whole func (app *App) handleStakingEvents() function can be simplified. Though, how to simplify will be apparent only during implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
EPIC Big task or collections of task that must be split into smaller pieces
Projects
None yet
Development

No branches or pull requests

2 participants