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

[Backport] pop: move pop constructor functions to datagen/ (#508) #510

Merged
merged 1 commit into from
Feb 12, 2025
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### Improvements

- [#508](https://github.com/babylonlabs-io/babylon/pull/508) Move PoP constructor functiosn to datagen/
- [#499](https://github.com/babylonlabs-io/babylon/pull/499) Add `params-by-version` CLI command

### Bug fixes
Expand Down
6 changes: 3 additions & 3 deletions test/e2e/btc_staking_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ func (s *BTCStakingTestSuite) Test6MultisigBTCDelegation() {

// NOTE: we use the multisig address for the BTC delegation
multisigStakerAddr := sdk.MustAccAddressFromBech32(multisigAddr)
pop, err := bstypes.NewPoPBTC(multisigStakerAddr, s.delBTCSK)
pop, err := datagen.NewPoPBTC(multisigStakerAddr, s.delBTCSK)
s.NoError(err)

// generate staking tx and slashing tx
Expand Down Expand Up @@ -480,7 +480,7 @@ func (s *BTCStakingTestSuite) Test7BTCDelegationFeeGrant() {
unbondingTime := btcStkParams.UnbondingTimeBlocks

// NOTE: we use the grantee staker address for the BTC delegation PoP
pop, err := bstypes.NewPoPBTC(granteeStakerAddr, s.delBTCSK)
pop, err := datagen.NewPoPBTC(granteeStakerAddr, s.delBTCSK)
s.NoError(err)

// generate staking tx and slashing tx
Expand Down Expand Up @@ -571,7 +571,7 @@ func (s *BTCStakingTestSuite) Test8BTCDelegationFeeGrantTyped() {
unbondingTime := btcStkParams.UnbondingTimeBlocks

// NOTE: we use the grantee staker address for the BTC delegation PoP
pop, err := bstypes.NewPoPBTC(granteeStakerAddr, s.delBTCSK)
pop, err := datagen.NewPoPBTC(granteeStakerAddr, s.delBTCSK)
s.NoError(err)

// generate staking tx and slashing tx
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/btc_staking_pre_approval_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (s *BTCStakingPreApprovalTestSuite) Test1CreateFinalityProviderAndDelegatio

// NOTE: we use the node's address for the BTC delegation
stakerAddr := sdk.MustAccAddressFromBech32(nonValidatorNode.PublicAddress)
pop, err := bstypes.NewPoPBTC(stakerAddr, s.delBTCSK)
pop, err := datagen.NewPoPBTC(stakerAddr, s.delBTCSK)
s.NoError(err)

// generate staking tx and slashing tx
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/configurer/chain/commands_btcstaking.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func (n *NodeConfig) CreateBTCDelegationAndCheck(

// NOTE: we use the node's address for the BTC delegation
del1Addr := sdk.MustAccAddressFromBech32(delAddr)
popDel1, err := bstypes.NewPoPBTC(del1Addr, btcStakerSK)
popDel1, err := datagen.NewPoPBTC(del1Addr, btcStakerSK)
require.NoError(t, err)

testStakingInfo, stakingTx, inclusionProof, testUnbondingInfo, delegatorSig := n.BTCStakingUnbondSlashInfo(r, t, btcNet, params, fp, btcStakerSK, stakingTimeBlocks, stakingSatAmt)
Expand Down
2 changes: 1 addition & 1 deletion testutil/btcstaking-helper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ func (h *Helper) CreateDelegationWithBtcBlockHeight(
staker := sdk.MustAccAddressFromBech32(datagen.GenRandomAccount().Address)

// PoP
pop, err := types.NewPoPBTC(staker, delSK)
pop, err := datagen.NewPoPBTC(staker, delSK)
h.NoError(err)
// generate staking tx info
prevBlock, _ := datagen.GenRandomBtcdBlock(r, 0, nil)
Expand Down
6 changes: 3 additions & 3 deletions testutil/datagen/btcstaking.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func GenRandomFinalityProviderWithBTCBabylonSKs(
btcPK := btcSK.PubKey()
bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK)
// pop
pop, err := bstypes.NewPoPBTC(fpAddr, btcSK)
pop, err := NewPoPBTC(fpAddr, btcSK)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -168,7 +168,7 @@ func GenRandomBTCDelegation(
require.NoError(t, err)
w := uint16(100) // TODO: parameterise w

pop, err := bstypes.NewPoPBTC(sdk.MustAccAddressFromBech32(staker.Address), delSK)
pop, err := NewPoPBTC(sdk.MustAccAddressFromBech32(staker.Address), delSK)
require.NoError(t, err)

del := &bstypes.BTCDelegation{
Expand Down Expand Up @@ -346,7 +346,7 @@ func GenRandomMsgCreateBtcDelegationAndMsgAddCovenantSignatures(
delSlashingTxSig, err := unbondingSlashingInfo.GenDelSlashingTxSig(delSK)
require.NoError(t, err)

pop, err := bstypes.NewPoPBTC(sdk.MustAccAddressFromBech32(stakerAddr.String()), delSK)
pop, err := NewPoPBTC(sdk.MustAccAddressFromBech32(stakerAddr.String()), delSK)
require.NoError(t, err)

msg := &bstypes.MsgCreateBTCDelegation{
Expand Down
120 changes: 120 additions & 0 deletions testutil/datagen/pop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package datagen

import (
"encoding/hex"

"github.com/babylonlabs-io/babylon/crypto/bip322"
"github.com/babylonlabs-io/babylon/crypto/ecdsa"
bbn "github.com/babylonlabs-io/babylon/types"
bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/cometbft/cometbft/crypto/tmhash"
sdk "github.com/cosmos/cosmos-sdk/types"
)

type bip322Sign[A btcutil.Address] func(sg []byte,
privKey *btcec.PrivateKey,
net *chaincfg.Params) (A, []byte, error)

// NewPoPBTC generates a new proof of possession that sk_BTC and the address are held by the same person
// a proof of possession contains only one signature
// - pop.BtcSig = schnorr_sign(sk_BTC, bbnAddress)
func NewPoPBTC(addr sdk.AccAddress, btcSK *btcec.PrivateKey) (*bstypes.ProofOfPossessionBTC, error) {
pop := bstypes.ProofOfPossessionBTC{
BtcSigType: bstypes.BTCSigType_BIP340, // by default, we use BIP-340 encoding for BTC signature
}

// generate pop.BtcSig = schnorr_sign(sk_BTC, hash(bbnAddress))
// NOTE: *schnorr.Sign has to take the hash of the message.
// So we have to hash the address before signing
hash := tmhash.Sum(addr.Bytes())
btcSig, err := schnorr.Sign(btcSK, hash)
if err != nil {
return nil, err
}
bip340Sig := bbn.NewBIP340SignatureFromBTCSig(btcSig)
pop.BtcSig = bip340Sig.MustMarshal()

return &pop, nil
}

// NewPoPWithECDSABTCSig generates a new proof of possession where Bitcoin signature is in ECDSA format
// a proof of possession contains two signatures:
// - pop.BtcSig = ecdsa_sign(sk_BTC, addr)
func NewPoPBTCWithECDSABTCSig(addr sdk.AccAddress, btcSK *btcec.PrivateKey) (*bstypes.ProofOfPossessionBTC, error) {
pop := bstypes.ProofOfPossessionBTC{
BtcSigType: bstypes.BTCSigType_ECDSA,
}

// generate pop.BtcSig = ecdsa_sign(sk_BTC, pop.BabylonSig)
// NOTE: ecdsa.Sign has to take the message as string.
// So we have to hex addr before signing
addrHex := hex.EncodeToString(addr.Bytes())
btcSig := ecdsa.Sign(btcSK, addrHex)
pop.BtcSig = btcSig

return &pop, nil
}

func newPoPBTCWithBIP322Sig[A btcutil.Address](
addressToSign sdk.AccAddress,
btcSK *btcec.PrivateKey,
net *chaincfg.Params,
bip322SignFn bip322Sign[A],
) (*bstypes.ProofOfPossessionBTC, error) {
pop := bstypes.ProofOfPossessionBTC{
BtcSigType: bstypes.BTCSigType_BIP322,
}

bip322SigEncoded, err := newBIP322Sig(tmhash.Sum(addressToSign.Bytes()), btcSK, net, bip322SignFn)
if err != nil {
return nil, err
}
pop.BtcSig = bip322SigEncoded

return &pop, nil
}

func newBIP322Sig[A btcutil.Address](
msgToSign []byte,
btcSK *btcec.PrivateKey,
net *chaincfg.Params,
bip322SignFn bip322Sign[A],
) ([]byte, error) {
address, witnessSignture, err := bip322SignFn(
msgToSign,
btcSK,
net,
)
if err != nil {
return nil, err
}

bip322Sig := bstypes.BIP322Sig{
Address: address.EncodeAddress(),
Sig: witnessSignture,
}

return bip322Sig.Marshal()
}

// NewPoPBTCWithBIP322P2WPKHSig creates a proof of possession of type BIP322
// that signs the address with the BTC secret key.
func NewPoPBTCWithBIP322P2WPKHSig(
addr sdk.AccAddress,
btcSK *btcec.PrivateKey,
net *chaincfg.Params,
) (*bstypes.ProofOfPossessionBTC, error) {
return newPoPBTCWithBIP322Sig(addr, btcSK, net, bip322.SignWithP2WPKHAddress)
}

func NewPoPBTCWithBIP322P2TRBIP86Sig(
addrToSign sdk.AccAddress,
btcSK *btcec.PrivateKey,
net *chaincfg.Params,
) (*bstypes.ProofOfPossessionBTC, error) {
return newPoPBTCWithBIP322Sig(addrToSign, btcSK, net, bip322.SignWithP2TrSpendAddress)
}
2 changes: 1 addition & 1 deletion x/btcstaking/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ func TestDoNotAllowDelegationWithoutFinalityProvider(t *testing.T) {
stakerAddr := sdk.MustAccAddressFromBech32(acc.Address)

// PoP
pop, err := types.NewPoPBTC(stakerAddr, delSK)
pop, err := datagen.NewPoPBTC(stakerAddr, delSK)
require.NoError(t, err)
// generate staking tx info
prevBlock, _ := datagen.GenRandomBtcdBlock(r, 0, nil)
Expand Down
104 changes: 0 additions & 104 deletions x/btcstaking/types/pop.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,102 +20,6 @@ import (

type checkStakerKey func(stakerKey *bbn.BIP340PubKey) error

type bip322Sign[A btcutil.Address] func(sg []byte,
privKey *btcec.PrivateKey,
net *chaincfg.Params) (A, []byte, error)

// NewPoPBTC generates a new proof of possession that sk_BTC and the address are held by the same person
// a proof of possession contains only one signature
// - pop.BtcSig = schnorr_sign(sk_BTC, bbnAddress)
func NewPoPBTC(addr sdk.AccAddress, btcSK *btcec.PrivateKey) (*ProofOfPossessionBTC, error) {
pop := ProofOfPossessionBTC{
BtcSigType: BTCSigType_BIP340, // by default, we use BIP-340 encoding for BTC signature
}

// generate pop.BtcSig = schnorr_sign(sk_BTC, hash(bbnAddress))
// NOTE: *schnorr.Sign has to take the hash of the message.
// So we have to hash the address before signing
hash := tmhash.Sum(addr.Bytes())
btcSig, err := schnorr.Sign(btcSK, hash)
if err != nil {
return nil, err
}
bip340Sig := bbn.NewBIP340SignatureFromBTCSig(btcSig)
pop.BtcSig = bip340Sig.MustMarshal()

return &pop, nil
}

// NewPoPWithECDSABTCSig generates a new proof of possession where Bitcoin signature is in ECDSA format
// a proof of possession contains two signatures:
// - pop.BtcSig = ecdsa_sign(sk_BTC, addr)
func NewPoPBTCWithECDSABTCSig(addr sdk.AccAddress, btcSK *btcec.PrivateKey) (*ProofOfPossessionBTC, error) {
pop := ProofOfPossessionBTC{
BtcSigType: BTCSigType_ECDSA,
}

// generate pop.BtcSig = ecdsa_sign(sk_BTC, pop.BabylonSig)
// NOTE: ecdsa.Sign has to take the message as string.
// So we have to hex addr before signing
addrHex := hex.EncodeToString(addr.Bytes())
btcSig := ecdsa.Sign(btcSK, addrHex)
pop.BtcSig = btcSig

return &pop, nil
}

func newPoPBTCWithBIP322Sig[A btcutil.Address](
addressToSign sdk.AccAddress,
btcSK *btcec.PrivateKey,
net *chaincfg.Params,
bip322SignFn bip322Sign[A],
) (*ProofOfPossessionBTC, error) {
pop := ProofOfPossessionBTC{
BtcSigType: BTCSigType_BIP322,
}

bip322SigEncoded, err := newBIP322Sig(tmhash.Sum(addressToSign.Bytes()), btcSK, net, bip322SignFn)
if err != nil {
return nil, err
}
pop.BtcSig = bip322SigEncoded

return &pop, nil
}

func newBIP322Sig[A btcutil.Address](
msgToSign []byte,
btcSK *btcec.PrivateKey,
net *chaincfg.Params,
bip322SignFn bip322Sign[A],
) ([]byte, error) {
address, witnessSignture, err := bip322SignFn(
msgToSign,
btcSK,
net,
)
if err != nil {
return nil, err
}

bip322Sig := BIP322Sig{
Address: address.EncodeAddress(),
Sig: witnessSignture,
}

return bip322Sig.Marshal()
}

// NewPoPBTCWithBIP322P2WPKHSig creates a proof of possession of type BIP322
// that signs the address with the BTC secret key.
func NewPoPBTCWithBIP322P2WPKHSig(
addr sdk.AccAddress,
btcSK *btcec.PrivateKey,
net *chaincfg.Params,
) (*ProofOfPossessionBTC, error) {
return newPoPBTCWithBIP322Sig(addr, btcSK, net, bip322.SignWithP2WPKHAddress)
}

func NewPoPBTCFromHex(popHex string) (*ProofOfPossessionBTC, error) {
popBytes, err := hex.DecodeString(popHex)
if err != nil {
Expand Down Expand Up @@ -185,14 +89,6 @@ func (pop *ProofOfPossessionBTC) VerifyBIP340(stakerAddr sdk.AccAddress, bip340P
return VerifyBIP340(pop.BtcSigType, pop.BtcSig, bip340PK, stakerAddr.Bytes())
}

func NewPoPBTCWithBIP322P2TRBIP86Sig(
addrToSign sdk.AccAddress,
btcSK *btcec.PrivateKey,
net *chaincfg.Params,
) (*ProofOfPossessionBTC, error) {
return newPoPBTCWithBIP322Sig(addrToSign, btcSK, net, bip322.SignWithP2TrSpendAddress)
}

// isSupportedAddressAndWitness checks whether provided address and witness are
// valid for proof of possession verification.
// Currently the only supported options are:
Expand Down
Loading