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

feat(adr-26): Separate inclusion proof from staking tx info #111

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/upgrades/signetlaunch/btcstaking_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ const BtcStakingParamStr = `
"min_unbonding_time_blocks": 0,
"unbonding_fee_sat": "1000",
"min_commission_rate": "0.03",
"max_active_finality_providers": 100
"max_active_finality_providers": 100,
"delegation_creation_base_gas_fee": 1000
}`
14 changes: 13 additions & 1 deletion proto/babylon/btcstaking/v1/btcstaking.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/staking/v1beta1/staking.proto";
import "babylon/btcstaking/v1/pop.proto";
import "babylon/btccheckpoint/v1/btccheckpoint.proto";

option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types";

Expand Down Expand Up @@ -195,4 +196,15 @@ message SelectiveSlashingEvidence {
// the covenant adaptor/Schnorr signature pair. It is the consequence
// of selective slashing.
bytes recovered_fp_btc_sk = 3;
}
}

// InclusionProof proves the existence of tx on BTC blockchain
// including
// - the position of the tx on BTC blockchain
// - the Merkle proof that this tx is on the above position
message InclusionProof {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Message needs doc comments as otherwise make proto-lint won't pass.

A bit tangent, I am not sure how make proto-lint got out of CI, most probably during migration to re-usable pipelines.

// key is the position (txIdx, blockHash) of this tx on BTC blockchain
babylon.btccheckpoint.v1.TransactionKey key = 1;
// proof is the Merkle proof that this tx is included in the position in `key`
bytes proof = 2;
}
2 changes: 2 additions & 0 deletions proto/babylon/btcstaking/v1/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ message Params {
];
// max_active_finality_providers is the maximum number of active finality providers in the BTC staking protocol
uint32 max_active_finality_providers = 13;
// base gas fee for delegation creation
uint64 delegation_creation_base_gas_fee = 14;
}

// StoredParams attach information about the version of stored parameters
Expand Down
22 changes: 12 additions & 10 deletions proto/babylon/btcstaking/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/msg/v1/msg.proto";
import "babylon/btcstaking/v1/params.proto";
import "babylon/btccheckpoint/v1/btccheckpoint.proto";
import "cosmos/staking/v1beta1/staking.proto";
import "babylon/btcstaking/v1/pop.proto";
import "babylon/btcstaking/v1/btcstaking.proto";

option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types";

Expand Down Expand Up @@ -90,34 +90,36 @@ message MsgCreateBTCDelegation {
uint32 staking_time = 5;
// staking_value is the amount of satoshis locked in staking output
int64 staking_value = 6;
// staking_tx is the staking tx along with the merkle proof of inclusion in btc block
babylon.btccheckpoint.v1.TransactionInfo staking_tx = 7;
// staking_tx is a bitcoin staking transaction i.e transaction that locks funds
bytes staking_tx = 7 ;
// staking_tx_inclusion_proof is the inclusion proof of the staking tx in BTC chain
InclusionProof staking_tx_inclusion_proof = 8;
// slashing_tx is the slashing tx
// Note that the tx itself does not contain signatures, which are off-chain.
bytes slashing_tx = 8 [ (gogoproto.customtype) = "BTCSlashingTx" ];
bytes slashing_tx = 9 [ (gogoproto.customtype) = "BTCSlashingTx" ];
// delegator_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk).
// It will be a part of the witness for the staking tx output.
// The staking tx output further needs signatures from covenant and finality provider in
// order to be spendable.
bytes delegator_slashing_sig = 9 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ];
bytes delegator_slashing_sig = 10 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ];
// unbonding_time is the time lock used when funds are being unbonded. It is be used in:
// - unbonding transaction, time lock spending path
// - staking slashing transaction, change output
// - unbonding slashing transaction, change output
// It must be smaller than math.MaxUInt16 and larger that max(MinUnbondingTime, CheckpointFinalizationTimeout)
uint32 unbonding_time = 10;
uint32 unbonding_time = 11;
// fields related to unbonding transaction
// unbonding_tx is a bitcoin unbonding transaction i.e transaction that spends
// staking output and sends it to the unbonding output
bytes unbonding_tx = 11;
bytes unbonding_tx = 12;
// unbonding_value is amount of satoshis locked in unbonding output.
// NOTE: staking_value and unbonding_value could be different because of the difference between the fee for staking tx and that for unbonding
int64 unbonding_value = 12;
int64 unbonding_value = 13;
// unbonding_slashing_tx is the slashing tx which slash unbonding contract
// Note that the tx itself does not contain signatures, which are off-chain.
bytes unbonding_slashing_tx = 13 [ (gogoproto.customtype) = "BTCSlashingTx" ];
bytes unbonding_slashing_tx = 14 [ (gogoproto.customtype) = "BTCSlashingTx" ];
// delegator_unbonding_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk).
bytes delegator_unbonding_slashing_sig = 14 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ];
bytes delegator_unbonding_slashing_sig = 15 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ];
}
// MsgCreateBTCDelegationResponse is the response for MsgCreateBTCDelegation
message MsgCreateBTCDelegationResponse {}
Expand Down
28 changes: 16 additions & 12 deletions test/e2e/btc_staking_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"github.com/babylonlabs-io/babylon/test/e2e/initialization"
"github.com/babylonlabs-io/babylon/testutil/datagen"
bbn "github.com/babylonlabs-io/babylon/types"
btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"
bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types"
ckpttypes "github.com/babylonlabs-io/babylon/x/checkpointing/types"
ftypes "github.com/babylonlabs-io/babylon/x/finality/types"
Expand Down Expand Up @@ -100,7 +99,7 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() {

// generate staking tx and slashing tx
stakingTimeBlocks := uint16(math.MaxUint16)
testStakingInfo, stakingTxInfo, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(nonValidatorNode, params, stakingTimeBlocks, cacheFP)
testStakingInfo, stakingTx, inclusionProof, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(nonValidatorNode, params, stakingTimeBlocks, cacheFP)

delUnbondingSlashingSig, err := testUnbondingInfo.GenDelSlashingTxSig(delBTCSK)
s.NoError(err)
Expand All @@ -109,7 +108,8 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() {
nonValidatorNode.CreateBTCDelegation(
bbn.NewBIP340PubKeyFromBTCPK(delBTCPK),
pop,
stakingTxInfo,
stakingTx,
inclusionProof,
cacheFP.BtcPk,
stakingTimeBlocks,
btcutil.Amount(stakingValue),
Expand Down Expand Up @@ -501,7 +501,7 @@ func (s *BTCStakingTestSuite) Test6MultisigBTCDelegation() {

// generate staking tx and slashing tx
stakingTimeBlocks := uint16(math.MaxUint16)
testStakingInfo, stakingTxInfo, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(nonValidatorNode, params, stakingTimeBlocks, cacheFP)
testStakingInfo, stakingTx, inclusionProof, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(nonValidatorNode, params, stakingTimeBlocks, cacheFP)

delUnbondingSlashingSig, err := testUnbondingInfo.GenDelSlashingTxSig(delBTCSK)
s.NoError(err)
Expand All @@ -510,7 +510,8 @@ func (s *BTCStakingTestSuite) Test6MultisigBTCDelegation() {
jsonTx := nonValidatorNode.CreateBTCDelegation(
bbn.NewBIP340PubKeyFromBTCPK(delBTCPK),
pop,
stakingTxInfo,
stakingTx,
inclusionProof,
cacheFP.BtcPk,
stakingTimeBlocks,
btcutil.Amount(stakingValue),
Expand Down Expand Up @@ -571,7 +572,7 @@ func (s *BTCStakingTestSuite) Test7BTCDelegationFeeGrant() {

// generate staking tx and slashing tx
stakingTimeBlocks := uint16(math.MaxUint16) - 5
testStakingInfo, stakingTxInfo, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(nonValidatorNode, btcStkParams, stakingTimeBlocks, cacheFP)
testStakingInfo, stakingTx, inclusionProof, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(nonValidatorNode, btcStkParams, stakingTimeBlocks, cacheFP)

delUnbondingSlashingSig, err := testUnbondingInfo.GenDelSlashingTxSig(delBTCSK)
s.NoError(err)
Expand All @@ -590,7 +591,8 @@ func (s *BTCStakingTestSuite) Test7BTCDelegationFeeGrant() {
nonValidatorNode.CreateBTCDelegation(
bbn.NewBIP340PubKeyFromBTCPK(delBTCPK),
pop,
stakingTxInfo,
stakingTx,
inclusionProof,
cacheFP.BtcPk,
stakingTimeBlocks,
btcutil.Amount(stakingValue),
Expand Down Expand Up @@ -662,7 +664,7 @@ func (s *BTCStakingTestSuite) Test8BTCDelegationFeeGrantTyped() {

// generate staking tx and slashing tx
stakingTimeBlocks := uint16(math.MaxUint16) - 2
testStakingInfo, stakingTxInfo, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(node, btcStkParams, stakingTimeBlocks, cacheFP)
testStakingInfo, stakingTx, inclusionProof, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(node, btcStkParams, stakingTimeBlocks, cacheFP)

delUnbondingSlashingSig, err := testUnbondingInfo.GenDelSlashingTxSig(delBTCSK)
s.NoError(err)
Expand Down Expand Up @@ -724,7 +726,8 @@ func (s *BTCStakingTestSuite) Test8BTCDelegationFeeGrantTyped() {
node.CreateBTCDelegation(
bbn.NewBIP340PubKeyFromBTCPK(delBTCPK),
pop,
stakingTxInfo,
stakingTx,
inclusionProof,
cacheFP.BtcPk,
stakingTimeBlocks,
btcutil.Amount(stakingValue),
Expand Down Expand Up @@ -898,7 +901,8 @@ func (s *BTCStakingTestSuite) BTCStakingUnbondSlashInfo(
fp *bstypes.FinalityProvider,
) (
testStakingInfo *datagen.TestStakingSlashingInfo,
stakingTxInfo *btcctypes.TransactionInfo,
stakingTx []byte,
txInclusionProof *bstypes.InclusionProof,
testUnbondingInfo *datagen.TestUnbondingSlashingInfo,
delegatorSig *bbn.BIP340Signature,
) {
Expand Down Expand Up @@ -935,7 +939,7 @@ func (s *BTCStakingTestSuite) BTCStakingUnbondSlashInfo(
for i := 0; i < initialization.BabylonBtcConfirmationPeriod; i++ {
node.InsertNewEmptyBtcHeader(r)
}
stakingTxInfo = btcctypes.NewTransactionInfoFromSpvProof(blockWithStakingTx.SpvProof)
inclusionProof := bstypes.NewInclusionProofFromSpvProof(blockWithStakingTx.SpvProof)

// generate BTC undelegation stuff
stkTxHash := testStakingInfo.StakingTx.TxHash()
Expand Down Expand Up @@ -967,5 +971,5 @@ func (s *BTCStakingTestSuite) BTCStakingUnbondSlashInfo(
)
s.NoError(err)

return testStakingInfo, stakingTxInfo, testUnbondingInfo, delegatorSig
return testStakingInfo, blockWithStakingTx.SpvProof.BtcTransaction, inclusionProof, testUnbondingInfo, delegatorSig
}
11 changes: 7 additions & 4 deletions test/e2e/configurer/chain/commands_btcstaking.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature"
"github.com/babylonlabs-io/babylon/test/e2e/containers"
bbn "github.com/babylonlabs-io/babylon/types"
btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"
bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types"
)

Expand All @@ -45,7 +44,8 @@ func (n *NodeConfig) CreateFinalityProvider(walletAddrOrName string, btcPK *bbn.
func (n *NodeConfig) CreateBTCDelegation(
btcPk *bbn.BIP340PubKey,
pop *bstypes.ProofOfPossessionBTC,
stakingTxInfo *btcctypes.TransactionInfo,
stakingTx []byte,
inclusionProof *bstypes.InclusionProof,
fpPK *bbn.BIP340PubKey,
stakingTimeBlocks uint16,
stakingValue btcutil.Amount,
Expand All @@ -69,7 +69,10 @@ func (n *NodeConfig) CreateBTCDelegation(
require.NoError(n.t, err)

// get staking tx info hex
stakingTxInfoHex, err := stakingTxInfo.ToHexStr()
stakingTxHex := hex.EncodeToString(stakingTx)

// get inclusion proof hex
inclusionProofHex, err := inclusionProof.MarshalHex()
require.NoError(n.t, err)

fpPKHex := fpPK.MarshalHex()
Expand All @@ -93,7 +96,7 @@ func (n *NodeConfig) CreateBTCDelegation(

cmd := []string{
"babylond", "tx", "btcstaking", "create-btc-delegation",
btcPkHex, popHex, stakingTxInfoHex, fpPKHex, stakingTimeString, stakingValueString, slashingTxHex, delegatorSigHex, unbondingTxHex, unbondingSlashingTxHex, unbondingTimeStr, unbondingValueStr, delUnbondingSlashingSigHex,
btcPkHex, popHex, stakingTxHex, inclusionProofHex, fpPKHex, stakingTimeString, stakingValueString, slashingTxHex, delegatorSigHex, unbondingTxHex, unbondingSlashingTxHex, unbondingTimeStr, unbondingValueStr, delUnbondingSlashingSigHex,
fmt.Sprintf("--from=%s", fromWalletName), containers.FlagHome, flagKeyringTest,
n.FlagChainID(), "--log_format=json",
}
Expand Down
5 changes: 3 additions & 2 deletions x/btccheckpoint/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import (
"fmt"
"math/big"

"github.com/babylonlabs-io/babylon/btctxformatter"
"github.com/babylonlabs-io/babylon/types"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/babylonlabs-io/babylon/btctxformatter"
"github.com/babylonlabs-io/babylon/types"
)

// RawCheckpointSubmission Semantically valid checkpoint submission with:
Expand Down
41 changes: 25 additions & 16 deletions x/btcstaking/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (

asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature"
bbn "github.com/babylonlabs-io/babylon/types"
btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"
"github.com/babylonlabs-io/babylon/x/btcstaking/types"
)

Expand Down Expand Up @@ -190,8 +189,8 @@ func NewEditFinalityProviderCmd() *cobra.Command {

func NewCreateBTCDelegationCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create-btc-delegation [btc_pk] [pop_hex] [staking_tx_info] [fp_pk] [staking_time] [staking_value] [slashing_tx] [delegator_slashing_sig] [unbonding_tx] [unbonding_slashing_tx] [unbonding_time] [unbonding_value] [delegator_unbonding_slashing_sig]",
Args: cobra.ExactArgs(13),
Use: "create-btc-delegation [btc_pk] [pop_hex] [staking_tx] [inclusion_proof] [fp_pk] [staking_time] [staking_value] [slashing_tx] [delegator_slashing_sig] [unbonding_tx] [unbonding_slashing_tx] [unbonding_time] [unbonding_value] [delegator_unbonding_slashing_sig]",
Args: cobra.ExactArgs(14),
Short: "Create a BTC delegation",
Long: strings.TrimSpace(
`Create a BTC delegation.`, // TODO: example
Expand All @@ -215,67 +214,76 @@ func NewCreateBTCDelegationCmd() *cobra.Command {
return err
}

// get staking tx info
stakingTxInfo, err := btcctypes.NewTransactionInfoFromHex(args[2])
// get staking tx bytes
stakingTx, err := hex.DecodeString(args[2])
if err != nil {
return err
}

var inclusionProof *types.InclusionProof
// inclusionProof can be nil if empty argument is provided
if len(args[3]) > 0 {
inclusionProof, err = types.NewInclusionProofFromHex(args[3])
if err != nil {
return err
}
}

// TODO: Support multiple finality providers
// get finality provider PK
fpPK, err := bbn.NewBIP340PubKeyFromHex(args[3])
fpPK, err := bbn.NewBIP340PubKeyFromHex(args[4])
if err != nil {
return err
}

// get staking time
stakingTime, err := parseLockTime(args[4])
stakingTime, err := parseLockTime(args[5])
if err != nil {
return err
}

stakingValue, err := parseBtcAmount(args[5])
stakingValue, err := parseBtcAmount(args[6])
if err != nil {
return err
}

// get slashing tx
slashingTx, err := types.NewBTCSlashingTxFromHex(args[6])
slashingTx, err := types.NewBTCSlashingTxFromHex(args[7])
if err != nil {
return err
}

// get delegator sig on slashing tx
delegatorSlashingSig, err := bbn.NewBIP340SignatureFromHex(args[7])
delegatorSlashingSig, err := bbn.NewBIP340SignatureFromHex(args[8])
if err != nil {
return err
}

// get unbonding tx
_, unbondingTxBytes, err := bbn.NewBTCTxFromHex(args[8])
_, unbondingTxBytes, err := bbn.NewBTCTxFromHex(args[9])
if err != nil {
return err
}

// get unbonding slashing tx
unbondingSlashingTx, err := types.NewBTCSlashingTxFromHex(args[9])
unbondingSlashingTx, err := types.NewBTCSlashingTxFromHex(args[10])
if err != nil {
return err
}

// get staking time
unbondingTime, err := parseLockTime(args[10])
unbondingTime, err := parseLockTime(args[11])
if err != nil {
return err
}

unbondingValue, err := parseBtcAmount(args[11])
unbondingValue, err := parseBtcAmount(args[12])
if err != nil {
return err
}

// get delegator sig on unbonding slashing tx
delegatorUnbondingSlashingSig, err := bbn.NewBIP340SignatureFromHex(args[12])
delegatorUnbondingSlashingSig, err := bbn.NewBIP340SignatureFromHex(args[13])
if err != nil {
return err
}
Expand All @@ -287,7 +295,8 @@ func NewCreateBTCDelegationCmd() *cobra.Command {
Pop: pop,
StakingTime: uint32(stakingTime),
StakingValue: int64(stakingValue),
StakingTx: stakingTxInfo,
StakingTx: stakingTx,
StakingTxInclusionProof: inclusionProof,
SlashingTx: slashingTx,
DelegatorSlashingSig: delegatorSlashingSig,
UnbondingTx: unbondingTxBytes,
Expand Down
Loading
Loading