Skip to content

Commit

Permalink
F/rewards distribution e2e (#76)
Browse files Browse the repository at this point in the history
Rewards distribution e2e tests
  • Loading branch information
maurolacy authored Jan 6, 2025
1 parent 88d4599 commit d3b4d27
Show file tree
Hide file tree
Showing 12 changed files with 207 additions and 42 deletions.
13 changes: 11 additions & 2 deletions contrib/images/ibcsim-bcd/setup-bcd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,16 @@
display_usage() {
echo "Missing parameters. Please check if all parameters were specified."
echo "Usage: setup-bcd.sh [CHAIN_ID] [CHAIN_DIR] [RPC_PORT] [P2P_PORT] [PROFILING_PORT] [GRPC_PORT] [BABYLON_CONTRACT_CODE_FILE] [BTCSTAKING_CONTRACT_CODE_FILE] [BTCFINALITY_CONTRACT_CODE_FILE] [INSTANTIATING_CFG]"
echo "Example: setup-bcd.sh test-chain-id ./data 26657 26656 6060 9090 ./babylon_contract.wasm '{"btc_confirmation_depth":1,"checkpoint_finalization_timeout":2,"network":"Regtest","babylon_tag":"bbn0", "notify_cosmos_zone":false, "btc_staking_code_id":2}'"
echo "Example: setup-bcd.sh test-chain-id ./data 26657 26656 6060 9090 ./babylon_contract.wasm ./btc_staking.wasm ./btc_finality.wasm '{
"btc_confirmation_depth": 1,
"checkpoint_finalization_timeout": 2,
"network": "Regtest",
"babylon_tag": "01020304",
"notify_cosmos_zone": false,
"btc_staking_code_id": 2,
"btc_finality_code_id": 3
}'
"
exit 1
}

Expand Down Expand Up @@ -105,7 +114,7 @@ sed -i 's/"btc_finality_contract_address": ""/"btc_finality_contract_address": "

# Start
echo "Starting $BINARY..."
$BINARY --home $CHAINDIR/$CHAINID start --pruning=nothing --grpc-web.enable=false --grpc.address="0.0.0.0:$GRPCPORT" --log_level trace --trace --log_format 'plain' 2>&1 | tee $CHAINDIR/$CHAINID.log &
$BINARY --home $CHAINDIR/$CHAINID start --pruning=nothing --grpc-web.enable=false --grpc.address="0.0.0.0:$GRPCPORT" --log_level trace --trace --log_format 'plain' --log_no_color 2>&1 | tee $CHAINDIR/$CHAINID.log &
sleep 20

# upload contract code
Expand Down
50 changes: 37 additions & 13 deletions contrib/images/ibcsim-bcd/wrapper.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env sh
# shellcheck disable=SC3037

# 0. Define configuration
BABYLON_KEY="babylon-key"
Expand All @@ -7,19 +8,41 @@ CONSUMER_KEY="bcd-key"
CONSUMER_CHAIN_ID="bcd-test"

# 1. Create a bcd testnet with Babylon contract
./setup-bcd.sh $CONSUMER_CHAIN_ID $CONSUMER_CONF 26657 26656 6060 9090 ./babylon_contract.wasm ./btc_staking.wasm ./btc_finality.wasm '{
"network": "regtest",
"babylon_tag": "01020304",
"btc_confirmation_depth": 1,
"checkpoint_finalization_timeout": 2,
"notify_cosmos_zone": false,
"btc_staking_code_id": 2,
"consumer_name": "Test Consumer",
"consumer_description": "Test Consumer Description",
"btc_finality_code_id": 3
FINALITY_MSG='{
"params": {
"max_active_finality_providers": 100,
"min_pub_rand": 1,
"finality_inflation_rate": "0.035",
"epoch_length": 10
}
}'
echo "btc-finality instantiation msg:"
echo -n "$FINALITY_MSG" | jq '.'
ENCODED_FINALITY_MSG=$(echo -n "$FINALITY_MSG" | base64 -w0)
BABYLON_MSG="{
\"network\": \"regtest\",
\"babylon_tag\": \"01020304\",
\"btc_confirmation_depth\": 1,
\"checkpoint_finalization_timeout\": 2,
\"notify_cosmos_zone\": false,
\"btc_staking_code_id\": 2,
\"consumer_name\": \"Test Consumer\",
\"consumer_description\": \"Test Consumer Description\",
\"btc_finality_code_id\": 3,
\"btc_finality_msg\": \"$ENCODED_FINALITY_MSG\",
\"transfer_info\": {
\"channel_id\": \"channel-1\",
\"recipient\": {
\"module_addr\": \"zoneconcierge\"
}
}
}"
echo "babylon-contract instantiation msg:"
echo -n "$BABYLON_MSG" | jq '.'

sleep 10
./setup-bcd.sh $CONSUMER_CHAIN_ID $CONSUMER_CONF 26657 26656 6060 9090 ./babylon_contract.wasm ./btc_staking.wasm ./btc_finality.wasm "$BABYLON_MSG"

sleep 5

CONTRACT_ADDRESS=$(bcd query wasm list-contract-by-code 1 | grep bbnc | cut -d' ' -f2)
CONTRACT_PORT="wasm.$CONTRACT_ADDRESS"
Expand Down Expand Up @@ -91,9 +114,10 @@ rly --home $RELAYER_CONF_DIR keys restore babylon $BABYLON_KEY "$BABYLON_MEMO"
sleep 10

# 3. Start relayer
echo "Creating an IBC light clients, connection, and channel between the two CZs"
echo "Creating IBC light clients, connection, and channels between the two CZs"
rly --home $RELAYER_CONF_DIR tx link bcd --src-port zoneconcierge --dst-port $CONTRACT_PORT --order ordered --version zoneconcierge-1
echo "Created IBC channel successfully!"
[ $? -eq 0 ] && echo "Created custom IBC channel successfully!" || echo "Error creating custom IBC channel"
rly --home $RELAYER_CONF_DIR tx link bcd --src-port transfer --dst-port transfer --order unordered --version ics20-1 &

sleep 10

Expand Down
1 change: 1 addition & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@ github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY=
github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0=
Expand Down
112 changes: 89 additions & 23 deletions tests/e2e/bcd_consumer_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
bsctypes "github.com/babylonlabs-io/babylon/x/btcstkconsumer/types"
ckpttypes "github.com/babylonlabs-io/babylon/x/checkpointing/types"
ftypes "github.com/babylonlabs-io/babylon/x/finality/types"
zctypes "github.com/babylonlabs-io/babylon/x/zoneconcierge/types"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/wire"
Expand Down Expand Up @@ -63,6 +64,19 @@ var (
czDelBtcSk, czDelBtcPk, _ = datagen.GenRandomBTCKeyPair(r)
)

func getFirstIBCDenom(balance sdk.Coins) string {
// Look up the ugly IBC denom
denoms := balance.Denoms()
var denomB string
for _, d := range denoms {
if strings.HasPrefix(d, "ibc/") {
denomB = d
break
}
}
return denomB
}

// TestBCDConsumerIntegrationTestSuite includes babylon<->bcd integration related tests
func TestBCDConsumerIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(BCDConsumerIntegrationTestSuite))
Expand Down Expand Up @@ -142,7 +156,7 @@ func (s *BCDConsumerIntegrationTestSuite) Test2RegisterAndIntegrateConsumer() {

// after the consumer is registered, wait till IBC connection/channel
// between babylon<->bcd is established
s.waitForIBCConnection()
s.waitForIBCConnections()
}

// Test3CreateConsumerFinalityProvider
Expand All @@ -152,6 +166,8 @@ func (s *BCDConsumerIntegrationTestSuite) Test2RegisterAndIntegrateConsumer() {
func (s *BCDConsumerIntegrationTestSuite) Test3CreateConsumerFinalityProvider() {
// generate a random number of finality providers from 1 to 5
numConsumerFPs := datagen.RandomInt(r, 5) + 1
fmt.Println("Number of consumer finality providers: ", numConsumerFPs)

var consumerFps []*bstypes.FinalityProvider
for i := 0; i < int(numConsumerFPs); i++ {
consumerFp, SK, PK := s.createVerifyConsumerFP()
Expand Down Expand Up @@ -257,7 +273,7 @@ func (s *BCDConsumerIntegrationTestSuite) Test5ActivateDelegation() {
s.Eventually(func() bool {
dataFromContract, err = s.cosmwasmController.QueryDelegations()
return err == nil && dataFromContract != nil && len(dataFromContract.Delegations) == 1
}, time.Second*30, time.Second)
}, time.Second*60, time.Second)

// Assert delegation details
s.Empty(dataFromContract.Delegations[0].UndelegationInfo.DelegatorUnbondingInfo)
Expand All @@ -283,7 +299,7 @@ func (s *BCDConsumerIntegrationTestSuite) Test5ActivateDelegation() {
}, time.Minute, time.Second*5)
}

func (s *BCDConsumerIntegrationTestSuite) Test6ConsumerFPRewardsGeneration() {
func (s *BCDConsumerIntegrationTestSuite) Test6ConsumerFPRewards() {
// Query consumer finality providers
consumerFp, err := s.babylonController.QueryConsumerFinalityProvider(consumerID, bbn.NewBIP340PubKeyFromBTCPK(czFpBTCPK).MarshalHex())
s.Require().NoError(err)
Expand All @@ -301,6 +317,11 @@ func (s *BCDConsumerIntegrationTestSuite) Test6ConsumerFPRewardsGeneration() {
s.NoError(err)
s.Empty(rewards)

// Check that there are no tokens in the module account
balance, err := s.babylonController.QueryModuleAccountBalances(zctypes.ModuleName)
s.NoError(err)
s.Empty(balance)

// Commit public randomness at the activated block height on the consumer chain
randListInfo, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, czFpBTCSK, uint64(czActivatedHeight), 100)
s.NoError(err)
Expand Down Expand Up @@ -342,18 +363,26 @@ func (s *BCDConsumerIntegrationTestSuite) Test6ConsumerFPRewardsGeneration() {
s.Equal(hex.EncodeToString(finalizedBlock.AppHash), hex.EncodeToString(czActivatedBlock.AppHash))
s.True(finalizedBlock.Finalized)

// Ensure consumer rewards are generated and sent to the staking contract
// Ensure consumer rewards are generated (initially sent to the finality contract,
// then sent to the Babylon contract, after Consumer-side distribution, and then sent to the Babylon zoneconcierge
// module account)
s.Eventually(func() bool {
rewards, err := s.cosmwasmController.QueryFinalityContractBalances()
balance, err := s.babylonController.QueryModuleAccountBalances(zctypes.ModuleName)
if err != nil {
s.T().Logf("failed to query rewards: %s", err.Error())
s.T().Logf("failed to query balance: %s", err.Error())
return false
}
if len(rewards) == 0 {
if len(balance) == 0 {
return false
}
fmt.Println("Consumer rewards: ", rewards)
return true
ibcDenom := getFirstIBCDenom(balance)
if ibcDenom == "" {
s.T().Logf("failed to get IBC denom")
return false
}
fmt.Printf("Balance of IBC denom '%s': %s\n", ibcDenom, balance.AmountOf(ibcDenom).String())
// Check that the balance of the IBC denom is greater than 0
return balance.AmountOf(ibcDenom).IsPositive()
}, 30*time.Second, time.Second*5)
}

Expand Down Expand Up @@ -482,7 +511,7 @@ func (s *BCDConsumerIntegrationTestSuite) Test8ConsumerFPCascadedSlashing() {
s.Eventually(func() bool {
dataFromContract, err = s.cosmwasmController.QueryDelegations()
return err == nil && dataFromContract != nil && len(dataFromContract.Delegations) == 2
}, time.Second*20, time.Second)
}, time.Second*30, time.Second)

// query and assert consumer finality provider's voting power is equal to the total stake
s.Eventually(func() bool {
Expand Down Expand Up @@ -718,7 +747,7 @@ func (s *BCDConsumerIntegrationTestSuite) submitCovenantSigs(consumerFp *bsctype
return false
}
return activatedHeight != nil && activatedHeight.Height > 0
}, time.Minute, time.Second*5)
}, 90*time.Second, time.Second*5)
}

// helper function: createBabylonDelegation creates a random BTC delegation restaking to Babylon and consumer finality providers
Expand Down Expand Up @@ -784,7 +813,7 @@ func (s *BCDConsumerIntegrationTestSuite) createBabylonDelegation(babylonFp *bst
}
headers := make([]bbn.BTCHeaderBytes, 0)
headers = append(headers, blockWithStakingTx.HeaderBytes)
for i := 0; i < int(params.ComfirmationTimeBlocks); i++ {
for i := 0; i < int(params.ConfirmationTimeBlocks); i++ {
headerInfo := datagen.GenRandomValidBTCHeaderInfoWithParent(r, *parentBlockHeaderInfo)
headers = append(headers, *headerInfo.Header)
parentBlockHeaderInfo = headerInfo
Expand Down Expand Up @@ -984,6 +1013,7 @@ func (s *BCDConsumerIntegrationTestSuite) initCosmwasmController() error {
s.T().Fatalf("Failed to get current working directory: %v", err)
}

cfg.BabylonContractAddress = "bbnc14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9syx25zf"
cfg.BtcStakingContractAddress = "bbnc1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrqgn0kq0"
cfg.BtcFinalityContractAddress = "bbnc17p9rzwnnfxcjp32un9ug7yhhzgtkhvl9jfksztgw5uh69wac2pgssg3nft"
cfg.ChainID = "bcd-test"
Expand All @@ -1010,9 +1040,11 @@ func (s *BCDConsumerIntegrationTestSuite) initCosmwasmController() error {
return nil
}

// helper function: waitForIBCConnection waits for the IBC connection to be established between Babylon and the consumer.
func (s *BCDConsumerIntegrationTestSuite) waitForIBCConnection() {
// helper function: waitForIBCConnections waits for the IBC connections to be established between Babylon and the
// Consumer.
func (s *BCDConsumerIntegrationTestSuite) waitForIBCConnections() {
var babylonChannel *channeltypes.IdentifiedChannel
// Wait for the custom channel
s.Eventually(func() bool {
babylonChannelsResp, err := s.babylonController.IBCChannels()
if err != nil {
Expand All @@ -1025,13 +1057,13 @@ func (s *BCDConsumerIntegrationTestSuite) waitForIBCConnection() {
}
babylonChannel = babylonChannelsResp.Channels[0]
if babylonChannel.State != channeltypes.OPEN {
s.T().Logf("Babylon channel state is not OPEN, got %s", babylonChannel.State)
s.T().Logf("Babylon custom channel state is not OPEN, got %s", babylonChannel.State)
return false
}
s.Equal(channeltypes.ORDERED, babylonChannel.Ordering)
s.Contains(babylonChannel.Counterparty.PortId, "wasm.")
return true
}, time.Minute*3, time.Second*10, "Failed to get expected Babylon IBC channel")
}, time.Minute*4, time.Second*10, "Failed to get expected Babylon custom IBC channel")

var consumerChannel *channeltypes.IdentifiedChannel
s.Eventually(func() bool {
Expand All @@ -1049,15 +1081,49 @@ func (s *BCDConsumerIntegrationTestSuite) waitForIBCConnection() {
}
s.Equal(channeltypes.ORDERED, consumerChannel.Ordering)
s.Equal(babylonChannel.PortId, consumerChannel.Counterparty.PortId)
s.T().Logf("IBC channel established successfully")
s.T().Logf("IBC custom channel established successfully")
return true
}, time.Minute, time.Second*2, "Failed to get expected Consumer IBC channel")
}, time.Minute, time.Second*2, "Failed to get expected Consumer custom IBC channel")

// Query the channel client state
//babylonChannelState, err := s.babylonController.QueryChannelClientState(babylonChannel.ChannelId, babylonChannel.PortId)
//s.Require().NoError(err, "Failed to query Babylon channel client state")
//
//return babylonChannelState.IdentifiedClientState.ClientId
// Wait for the transfer channel
s.Eventually(func() bool {
babylonChannelsResp, err := s.babylonController.IBCChannels()
if err != nil {
s.T().Logf("Error querying Babylon IBC channels: %v", err)
return false
}
if len(babylonChannelsResp.Channels) != 2 {
s.T().Logf("Expected 2 Babylon IBC channels, got %d", len(babylonChannelsResp.Channels))
return false
}
babylonChannel = babylonChannelsResp.Channels[0]
if babylonChannel.State != channeltypes.OPEN {
s.T().Logf("Babylon transfer channel state is not OPEN, got %s", babylonChannel.State)
return false
}
s.Equal(channeltypes.UNORDERED, babylonChannel.Ordering)
s.Contains(babylonChannel.Counterparty.PortId, "transfer")
return true
}, time.Minute*3, time.Second*10, "Failed to get expected Babylon transfer IBC channel")

s.Eventually(func() bool {
consumerChannelsResp, err := s.cosmwasmController.IBCChannels()
if err != nil {
s.T().Logf("Error querying Consumer IBC channels: %v", err)
return false
}
if len(consumerChannelsResp.Channels) != 2 {
return false
}
consumerChannel = consumerChannelsResp.Channels[0]
if consumerChannel.State != channeltypes.OPEN {
return false
}
s.Equal(channeltypes.UNORDERED, consumerChannel.Ordering)
s.Equal(babylonChannel.PortId, consumerChannel.Counterparty.PortId)
s.T().Logf("IBC transfer channel established successfully")
return true
}, time.Minute, time.Second*2, "Failed to get expected Consumer transfer IBC channel")
}

// helper function: verifyConsumerRegistration verifies the automatic registration of a consumer
Expand Down
Loading

0 comments on commit d3b4d27

Please sign in to comment.