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

tests: inject delegation using admin #13

Merged
merged 12 commits into from
Jun 13, 2024
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
20 changes: 11 additions & 9 deletions tests/e2e/main_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package e2e

import (
"encoding/json"
"math/rand"
"testing"
"time"
Expand All @@ -9,7 +10,6 @@ import (
"github.com/babylonchain/babylon-sdk/demo/app"
appparams "github.com/babylonchain/babylon-sdk/demo/app/params"
"github.com/babylonchain/babylon-sdk/tests/e2e/types"
zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types"
sdk "github.com/cosmos/cosmos-sdk/types"
ibctesting2 "github.com/cosmos/ibc-go/v8/testing"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -104,22 +104,24 @@ func (s *BabylonSDKTestSuite) Test1ContractDeployment() {
}

// TestExample is an example test case
func (s *BabylonSDKTestSuite) Test2MockFinalityProvider() {
t := s.T()

// mock message
msg := types.GenIBCPacket(t, r)
msgBytes, err := zctypes.ModuleCdc.MarshalJSON(msg)
func (s *BabylonSDKTestSuite) Test2MockConsumerFpDelegation() {
msg := types.GenExecMessage()
msgBytes, err := json.Marshal(msg)
s.NoError(err)

// send msg to BTC staking contract via admin account
_, err = s.ConsumerCli.Exec(s.ConsumerContract.BTCStaking, msgBytes)
s.NoError(err)

// ensure the finality provider is on consumer chain
resp, err := s.ConsumerCli.Query(s.ConsumerContract.BTCStaking, Query{"finality_providers": {}})
consumerFps, err := s.ConsumerCli.Query(s.ConsumerContract.BTCStaking, Query{"finality_providers": {}})
s.NoError(err)
s.NotEmpty(consumerFps)

// ensure delegations are on consumer chain
consumerDels, err := s.ConsumerCli.Query(s.ConsumerContract.BTCStaking, Query{"delegations": {}})
s.NoError(err)
s.NotEmpty(resp)
s.NotEmpty(consumerDels)
}

// TODO: trigger BeginBlock via s.ConsumerChain rather than ConsumerApp
Expand Down
265 changes: 238 additions & 27 deletions tests/e2e/types/datagen.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,258 @@
package types

import (
"encoding/base64"
"math/rand"
"testing"
"time"

sdkmath "cosmossdk.io/math"
"github.com/babylonchain/babylon/testutil/datagen"
bstypes "github.com/babylonchain/babylon/x/btcstaking/types"
zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types"
bbn "github.com/babylonchain/babylon/types"
"github.com/babylonchain/babylon/x/btcstaking/types"
"github.com/btcsuite/btcd/chaincfg"
"github.com/stretchr/testify/require"

bstypes "github.com/babylonchain/babylon/x/btcstaking/types"
)

func NewBTCStakingPacketData(packet *bstypes.BTCStakingIBCPacket) *zctypes.ZoneconciergePacketData {
return &zctypes.ZoneconciergePacketData{
Packet: &zctypes.ZoneconciergePacketData_BtcStaking{
BtcStaking: packet,
func GenExecMessage() ExecuteMessage {
_, newDel := genBTCDelegation()

newFp := NewFinalityProvider{
Description: &FinalityProviderDescription{
Moniker: "fp1",
Identity: "Finality Provider 1",
Website: "https://fp1.com",
SecurityContact: "security_contact",
Details: "details",
},
Commission: "0.05",
BabylonPK: &PubKey{
Key: base64.StdEncoding.EncodeToString([]byte("mock_pub_rand")),
},
BTCPKHex: newDel.FpBtcPkList[0],
Pop: &ProofOfPossession{
BTCSigType: 0,
BabylonSig: base64.StdEncoding.EncodeToString([]byte("mock_pub_rand")),
BTCSig: base64.StdEncoding.EncodeToString([]byte("mock_pub_rand")),
},
ConsumerID: "osmosis-1",
}

// Create the ExecuteMessage instance
executeMessage := ExecuteMessage{
BtcStaking: BtcStaking{
NewFP: []NewFinalityProvider{newFp},
ActiveDel: []ActiveBtcDelegation{newDel},
SlashedDel: []SlashedBtcDelegation{},
UnbondedDel: []UnbondedBtcDelegation{},
},
}

return executeMessage
}

func GenIBCPacket(t *testing.T, r *rand.Rand) *zctypes.ZoneconciergePacketData {
// generate a finality provider
fpBTCSK, _, err := datagen.GenRandomBTCKeyPair(r)
func genBTCDelegation() (*types.Params, ActiveBtcDelegation) {
var net = &chaincfg.RegressionNetParams
r := rand.New(rand.NewSource(time.Now().Unix()))
Dismissed Show dismissed Hide dismissed
t := &testing.T{}

delSK, _, err := datagen.GenRandomBTCKeyPair(r)
require.NoError(t, err)
fpBabylonSK, _, err := datagen.GenRandomSecp256k1KeyPair(r)

// restaked to a random number of finality providers
numRestakedFPs := int(datagen.RandomInt(r, 10) + 1)
_, fpPKs, err := datagen.GenRandomBTCKeyPairs(r, numRestakedFPs)
require.NoError(t, err)
fp, err := datagen.GenRandomCustomFinalityProvider(r, fpBTCSK, fpBabylonSK, "consumer-id")
fpBTCPKs := bbn.NewBIP340PKsFromBTCPKs(fpPKs)

// (3, 5) covenant committee
covenantSKs, covenantPKs, err := datagen.GenRandomBTCKeyPairs(r, 5)
require.NoError(t, err)
covenantQuorum := uint32(3)

packet := &bstypes.BTCStakingIBCPacket{
NewFp: []*bstypes.NewFinalityProvider{
// TODO: fill empty data
&bstypes.NewFinalityProvider{
// Description: fp.Description,
Commission: fp.Commission.String(),
// BabylonPk: fp.BabylonPk,
BtcPkHex: fp.BtcPk.MarshalHex(),
// Pop: fp.Pop,
ConsumerId: fp.ConsumerId,
},
},
ActiveDel: []*bstypes.ActiveBTCDelegation{},
SlashedDel: []*bstypes.SlashedBTCDelegation{},
UnbondedDel: []*bstypes.UnbondedBTCDelegation{},
stakingTimeBlocks := uint16(5)
stakingValue := int64(2 * 10e8)
Dismissed Show dismissed Hide dismissed
slashingAddress, err := datagen.GenRandomBTCAddress(r, net)
require.NoError(t, err)

slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2)
unbondingTime := uint16(100) + 1
slashingChangeLockTime := unbondingTime

bsParams := &types.Params{
CovenantPks: bbn.NewBIP340PKsFromBTCPKs(covenantPKs),
CovenantQuorum: covenantQuorum,
SlashingAddress: slashingAddress.EncodeAddress(),
}

// only the quorum of signers provided the signatures
covenantSigners := covenantSKs[:covenantQuorum]

// construct the BTC delegation with everything
btcDel, err := datagen.GenRandomBTCDelegation(
r,
t,
net,
fpBTCPKs,
delSK,
covenantSigners,
covenantPKs,
covenantQuorum,
slashingAddress.EncodeAddress(),
1000,
uint64(1000+stakingTimeBlocks),
uint64(stakingValue),
slashingRate,
slashingChangeLockTime,
)
require.NoError(t, err)

activeDel := convertBTCDelegationToActiveBtcDelegation(btcDel)
return bsParams, activeDel
}

func convertBTCDelegationToActiveBtcDelegation(mockDel *bstypes.BTCDelegation) ActiveBtcDelegation {
var fpBtcPkList []string
for _, pk := range mockDel.FpBtcPkList {
fpBtcPkList = append(fpBtcPkList, pk.MarshalHex())
}

var covenantSigs []CovenantAdaptorSignatures
for _, cs := range mockDel.CovenantSigs {
var adaptorSigs []string
for _, sig := range cs.AdaptorSigs {
adaptorSigs = append(adaptorSigs, base64.StdEncoding.EncodeToString(sig))
}
covenantSigs = append(covenantSigs, CovenantAdaptorSignatures{
CovPK: cs.CovPk.MarshalHex(),
AdaptorSigs: adaptorSigs,
})
}

var covenantUnbondingSigs []SignatureInfo
for _, sigInfo := range mockDel.BtcUndelegation.CovenantUnbondingSigList {
covenantUnbondingSigs = append(covenantUnbondingSigs, SignatureInfo{
PK: sigInfo.Pk.MarshalHex(),
Sig: base64.StdEncoding.EncodeToString(sigInfo.Sig.MustMarshal()),
})
}

var covenantSlashingSigs []CovenantAdaptorSignatures
for _, cs := range mockDel.BtcUndelegation.CovenantSlashingSigs {
var adaptorSigs []string
for _, sig := range cs.AdaptorSigs {
adaptorSigs = append(adaptorSigs, base64.StdEncoding.EncodeToString(sig))
}
covenantSlashingSigs = append(covenantSlashingSigs, CovenantAdaptorSignatures{
CovPK: cs.CovPk.MarshalHex(),
AdaptorSigs: adaptorSigs,
})
}

undelegationInfo := BtcUndelegationInfo{
UnbondingTx: base64.StdEncoding.EncodeToString(mockDel.BtcUndelegation.UnbondingTx),
SlashingTx: base64.StdEncoding.EncodeToString(mockDel.BtcUndelegation.SlashingTx.MustMarshal()),
DelegatorSlashingSig: base64.StdEncoding.EncodeToString(mockDel.BtcUndelegation.DelegatorSlashingSig.MustMarshal()),
CovenantUnbondingSigs: covenantUnbondingSigs,
CovenantSlashingSigs: covenantSlashingSigs,
}

return ActiveBtcDelegation{
BTCPkHex: mockDel.BtcPk.MarshalHex(),
FpBtcPkList: fpBtcPkList,
StartHeight: mockDel.StartHeight,
EndHeight: mockDel.EndHeight,
TotalSat: mockDel.TotalSat,
StakingTx: base64.StdEncoding.EncodeToString(mockDel.StakingTx),
SlashingTx: base64.StdEncoding.EncodeToString(mockDel.SlashingTx.MustMarshal()),
DelegatorSlashingSig: base64.StdEncoding.EncodeToString(mockDel.DelegatorSig.MustMarshal()),
CovenantSigs: covenantSigs,
StakingOutputIdx: mockDel.StakingOutputIdx,
UnbondingTime: mockDel.UnbondingTime,
UndelegationInfo: undelegationInfo,
ParamsVersion: mockDel.ParamsVersion,
}
return NewBTCStakingPacketData(packet)
}

type NewFinalityProvider struct {
Description *FinalityProviderDescription `json:"description,omitempty"`
Commission string `json:"commission"`
BabylonPK *PubKey `json:"babylon_pk,omitempty"`
BTCPKHex string `json:"btc_pk_hex"`
Pop *ProofOfPossession `json:"pop,omitempty"`
ConsumerID string `json:"consumer_id"`
}

type FinalityProviderDescription struct {
Moniker string `json:"moniker"`
Identity string `json:"identity"`
Website string `json:"website"`
SecurityContact string `json:"security_contact"`
Details string `json:"details"`
}

type PubKey struct {
Key string `json:"key"`
}

type ProofOfPossession struct {
BTCSigType int32 `json:"btc_sig_type"`
BabylonSig string `json:"babylon_sig"`
BTCSig string `json:"btc_sig"`
}

type CovenantAdaptorSignatures struct {
CovPK string `json:"cov_pk"`
AdaptorSigs []string `json:"adaptor_sigs"`
}

type SignatureInfo struct {
PK string `json:"pk"`
Sig string `json:"sig"`
}

type BtcUndelegationInfo struct {
UnbondingTx string `json:"unbonding_tx"`
DelegatorUnbondingSig string `json:"delegator_unbonding_sig"`
CovenantUnbondingSigs []SignatureInfo `json:"covenant_unbonding_sig_list"`
SlashingTx string `json:"slashing_tx"`
DelegatorSlashingSig string `json:"delegator_slashing_sig"`
CovenantSlashingSigs []CovenantAdaptorSignatures `json:"covenant_slashing_sigs"`
}

type ActiveBtcDelegation struct {
BTCPkHex string `json:"btc_pk_hex"`
FpBtcPkList []string `json:"fp_btc_pk_list"`
StartHeight uint64 `json:"start_height"`
EndHeight uint64 `json:"end_height"`
TotalSat uint64 `json:"total_sat"`
StakingTx string `json:"staking_tx"`
SlashingTx string `json:"slashing_tx"`
DelegatorSlashingSig string `json:"delegator_slashing_sig"`
CovenantSigs []CovenantAdaptorSignatures `json:"covenant_sigs"`
StakingOutputIdx uint32 `json:"staking_output_idx"`
UnbondingTime uint32 `json:"unbonding_time"`
UndelegationInfo BtcUndelegationInfo `json:"undelegation_info"`
ParamsVersion uint32 `json:"params_version"`
}

type SlashedBtcDelegation struct {
// Define fields as needed
}

type UnbondedBtcDelegation struct {
// Define fields as needed
}

type ExecuteMessage struct {
BtcStaking BtcStaking `json:"btc_staking"`
}

type BtcStaking struct {
NewFP []NewFinalityProvider `json:"new_fp"`
ActiveDel []ActiveBtcDelegation `json:"active_del"`
SlashedDel []SlashedBtcDelegation `json:"slashed_del"`
UnbondedDel []UnbondedBtcDelegation `json:"unbonded_del"`
}
Binary file modified tests/testdata/babylon_contract.wasm
Binary file not shown.
Binary file modified tests/testdata/btc_staking.wasm
Binary file not shown.
Loading