Skip to content

Commit

Permalink
Implement pre-approval flow in btc-staker (#44)
Browse files Browse the repository at this point in the history
* Extend staker to support both flows

* Move inclusion proof generation to the caller

* Sending to Babylon in pre-approval flow

* Add new state and new loop

* Whole pre-approval flow closed
  • Loading branch information
KonradStaniec authored Oct 9, 2024
1 parent 171011d commit 4b64872
Show file tree
Hide file tree
Showing 17 changed files with 845 additions and 154 deletions.
69 changes: 52 additions & 17 deletions babylonclient/babyloncontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,20 +273,26 @@ func (bc *BabylonController) Sign(msg []byte) ([]byte, error) {
}
}

type DelegationData struct {
StakingTransaction *wire.MsgTx
type StakingTransactionInclusionInfo struct {
StakingTransactionIdx uint32
StakingTransactionInclusionProof []byte
StakingTransactionInclusionBlockHash *chainhash.Hash
StakingTime uint16
StakingValue btcutil.Amount
FinalityProvidersBtcPks []*btcec.PublicKey
SlashingTransaction *wire.MsgTx
SlashingTransactionSig *schnorr.Signature
BabylonStakerAddr sdk.AccAddress
StakerBtcPk *btcec.PublicKey
BabylonPop *stakerdb.ProofOfPossession
Ud *UndelegationData
}

type DelegationData struct {
StakingTransaction *wire.MsgTx
// Optional field, if not provided, delegation will be send to Babylon without
// the inclusion proof
StakingTransactionInclusionInfo *StakingTransactionInclusionInfo
StakingTime uint16
StakingValue btcutil.Amount
FinalityProvidersBtcPks []*btcec.PublicKey
SlashingTransaction *wire.MsgTx
SlashingTransactionSig *schnorr.Signature
BabylonStakerAddr sdk.AccAddress
StakerBtcPk *btcec.PublicKey
BabylonPop *stakerdb.ProofOfPossession
Ud *UndelegationData
}

type UndelegationData struct {
Expand Down Expand Up @@ -333,8 +339,6 @@ func delegationDataToMsg(dg *DelegationData) (*btcstypes.MsgCreateBTCDelegation,
return nil, err
}

inclusionBlockHash := bbntypes.NewBTCHeaderHashBytesFromChainhash(dg.StakingTransactionInclusionBlockHash)

slashingTx, err := btcstypes.NewBTCSlashingTxFromMsgTx(dg.SlashingTransaction)

if err != nil {
Expand Down Expand Up @@ -374,9 +378,20 @@ func delegationDataToMsg(dg *DelegationData) (*btcstypes.MsgCreateBTCDelegation,

slashUnbondingTxSig := bbntypes.NewBIP340SignatureFromBTCSig(dg.Ud.SlashUnbondingTransactionSig)

txKey := &bcctypes.TransactionKey{
Index: dg.StakingTransactionIdx,
Hash: &inclusionBlockHash,
var stakingTransactionInclusionProof *btcstypes.InclusionProof = nil

if dg.StakingTransactionInclusionInfo != nil {
inclusionBlockHash := bbntypes.NewBTCHeaderHashBytesFromChainhash(
dg.StakingTransactionInclusionInfo.StakingTransactionInclusionBlockHash,
)
txKey := &bcctypes.TransactionKey{
Index: dg.StakingTransactionInclusionInfo.StakingTransactionIdx,
Hash: &inclusionBlockHash,
}
stakingTransactionInclusionProof = btcstypes.NewInclusionProof(
txKey,
dg.StakingTransactionInclusionInfo.StakingTransactionInclusionProof,
)
}

return &btcstypes.MsgCreateBTCDelegation{
Expand All @@ -393,7 +408,7 @@ func delegationDataToMsg(dg *DelegationData) (*btcstypes.MsgCreateBTCDelegation,
// TODO: It is super bad that this thing (TransactionInfo) spread over whole babylon codebase, and it
// is used in all modules, rpc, database etc.
StakingTx: serizalizedStakingTransaction,
StakingTxInclusionProof: btcstypes.NewInclusionProof(txKey, dg.StakingTransactionInclusionProof),
StakingTxInclusionProof: stakingTransactionInclusionProof,
SlashingTx: slashingTx,
// Data related to unbonding
DelegatorSlashingSig: slashingTxSig,
Expand Down Expand Up @@ -893,3 +908,23 @@ func (bc *BabylonController) QueryBtcLightClientTip() (*btclctypes.BTCHeaderInfo

return res.Header, nil
}

func (bc *BabylonController) ActivateDelegation(
ctx context.Context,
stakingTxHash chainhash.Hash,
proof *btcctypes.BTCSpvProof) (*pv.RelayerTxResponse, error) {

msg := &btcstypes.MsgAddBTCDelegationInclusionProof{
Signer: bc.getTxSigner(),
StakingTxHash: stakingTxHash.String(),
StakingTxInclusionProof: btcstypes.NewInclusionProofFromSpvProof(proof),
}

res, err := bc.reliablySendMsgs([]sdk.Msg{msg})
if err != nil {
return nil, err
}

return res, nil

}
7 changes: 6 additions & 1 deletion babylonclient/msgsender.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ func (b *BabylonMsgSender) isBabylonBtcLcReady(
requiredInclusionBlockDepth uint64,
req *DelegationData,
) error {
depth, err := b.cl.QueryHeaderDepth(req.StakingTransactionInclusionBlockHash)
// no need to consult Babylon if we send delegation without inclusion proof
if req.StakingTransactionInclusionInfo == nil {
return nil
}

depth, err := b.cl.QueryHeaderDepth(req.StakingTransactionInclusionInfo.StakingTransactionInclusionBlockHash)

if err != nil {
// If header is not known to babylon, or it is on LCFork, then most probably
Expand Down
7 changes: 6 additions & 1 deletion cmd/stakercli/daemon/daemoncommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ var stakeCmd = cli.Command{
Usage: "Staking time in BTC blocks",
Required: true,
},
cli.BoolFlag{
Name: helpers.SendToBabylonFirstFlag,
Usage: "Whether staking transaction should be first to Babylon or BTC",
},
},
Action: stake,
}
Expand Down Expand Up @@ -324,8 +328,9 @@ func stake(ctx *cli.Context) error {
stakingAmount := ctx.Int64(helpers.StakingAmountFlag)
fpPks := ctx.StringSlice(fpPksFlag)
stakingTimeBlocks := ctx.Int64(helpers.StakingTimeBlocksFlag)
sendToBabylonFirst := ctx.Bool(helpers.SendToBabylonFirstFlag)

results, err := client.Stake(sctx, stakerAddress, stakingAmount, fpPks, stakingTimeBlocks)
results, err := client.Stake(sctx, stakerAddress, stakingAmount, fpPks, stakingTimeBlocks, sendToBabylonFirst)
if err != nil {
return err
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/stakercli/helpers/flags.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package helpers

const (
StakingAmountFlag = "staking-amount"
StakingTimeBlocksFlag = "staking-time"
StakingAmountFlag = "staking-amount"
StakingTimeBlocksFlag = "staking-time"
SendToBabylonFirstFlag = "send-to-babylon-first"
)
62 changes: 45 additions & 17 deletions example/global-params.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,53 @@
"versions": [
{
"version": 0,
"activation_height": 1,
"staking_cap": 50000000000,
"cap_height": 0,
"tag": "01020304",
"activation_height": 857910,
"staking_cap": 100000000000,
"tag": "62626e31",
"covenant_pks": [
"0205149a0c7a95320adf210e47bca8b363b7bd966be86be6392dd6cf4f96995869",
"02e8d503cb52715249f32f3ee79cee88dfd48c2565cb0c79cf9640d291f46fd518",
"02fe81b2409a32ddfd8ec1556557e8dd949b6e4fd37047523cb7f5fefca283d542",
"02bc4a1ff485d7b44faeec320b81ad31c3cad4d097813c21fcf382b4305e4cfc82",
"02001e50601a4a1c003716d7a1ee7fe25e26e55e24e909b3642edb60d30e3c40c1"
"03d45c70d28f169e1f0c7f4a78e2bc73497afe585b70aa897955989068f3350aaa",
"034b15848e495a3a62283daaadb3f458a00859fe48e321f0121ebabbdd6698f9fa",
"0223b29f89b45f4af41588dcaf0ca572ada32872a88224f311373917f1b37d08d1",
"02d3c79b99ac4d265c2f97ac11e3232c07a598b020cf56c6f055472c893c0967ae",
"038242640732773249312c47ca7bdb50ca79f15f2ecc32b9c83ceebba44fb74df7",
"03e36200aaa8dce9453567bba108bdc51f7f1174b97a65e4dc4402fc5de779d41c",
"03cbdd028cfe32c1c1f2d84bfec71e19f92df509bba7b8ad31ca6c1a134fe09204",
"03f178fcce82f95c524b53b077e6180bd2d779a9057fdff4255a0af95af918cee0",
"03de13fc96ea6899acbdc5db3afaa683f62fe35b60ff6eb723dad28a11d2b12f8c"
],
"covenant_quorum": 3,
"unbonding_time": 1000,
"unbonding_fee": 20000,
"max_staking_amount": 1000000000,
"min_staking_amount": 1000000,
"covenant_quorum": 6,
"unbonding_time": 1008,
"unbonding_fee": 64000,
"max_staking_amount": 5000000,
"min_staking_amount": 500000,
"max_staking_time": 64000,
"min_staking_time": 64000,
"confirmation_depth": 6
}
"confirmation_depth": 10
},
{
"version": 1,
"activation_height": 864790,
"cap_height": 864799,
"tag": "62626e31",
"covenant_pks": [
"03d45c70d28f169e1f0c7f4a78e2bc73497afe585b70aa897955989068f3350aaa",
"034b15848e495a3a62283daaadb3f458a00859fe48e321f0121ebabbdd6698f9fa",
"0223b29f89b45f4af41588dcaf0ca572ada32872a88224f311373917f1b37d08d1",
"02d3c79b99ac4d265c2f97ac11e3232c07a598b020cf56c6f055472c893c0967ae",
"038242640732773249312c47ca7bdb50ca79f15f2ecc32b9c83ceebba44fb74df7",
"03e36200aaa8dce9453567bba108bdc51f7f1174b97a65e4dc4402fc5de779d41c",
"03cbdd028cfe32c1c1f2d84bfec71e19f92df509bba7b8ad31ca6c1a134fe09204",
"03f178fcce82f95c524b53b077e6180bd2d779a9057fdff4255a0af95af918cee0",
"03de13fc96ea6899acbdc5db3afaa683f62fe35b60ff6eb723dad28a11d2b12f8c"
],
"covenant_quorum": 6,
"unbonding_time": 1008,
"unbonding_fee": 32000,
"max_staking_amount": 50000000000,
"min_staking_amount": 500000,
"max_staking_time": 64000,
"min_staking_time": 64000,
"confirmation_depth": 10
}
]
}
}
Loading

0 comments on commit 4b64872

Please sign in to comment.