diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..7336566f5 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,5 @@ +# CODEOWNERS: https://help.github.com/articles/about-codeowners/ + +# Primary repo maintainers +* @babylonlabs-io/core-dev + diff --git a/app/app.go b/app/app.go index 541bcd8d3..ab0c2123e 100644 --- a/app/app.go +++ b/app/app.go @@ -254,7 +254,6 @@ func NewBabylonApp( app.AppKeepers.InitKeepers( logger, - appCodec, &btcConfig, encCfg, bApp, diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 74174a608..17c9a5228 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -155,11 +155,12 @@ type AppKeepers struct { keys map[string]*storetypes.KVStoreKey tkeys map[string]*storetypes.TransientStoreKey memKeys map[string]*storetypes.MemoryStoreKey + + EncCfg *appparams.EncodingConfig } func (ak *AppKeepers) InitKeepers( logger log.Logger, - appCodec codec.Codec, btcConfig *bbn.BtcConfig, encodingConfig *appparams.EncodingConfig, bApp *baseapp.BaseApp, @@ -176,6 +177,9 @@ func (ak *AppKeepers) InitKeepers( powLimit := btcConfig.PowLimit() btcNetParams := btcConfig.NetParams() + ak.EncCfg = encodingConfig + appCodec := encodingConfig.Codec + // set persistent store keys keys := storetypes.NewKVStoreKeys( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, @@ -524,7 +528,9 @@ func (ak *AppKeepers) InitKeepers( runtime.NewKVStoreService(keys[btcstakingtypes.StoreKey]), &btclightclientKeeper, &btcCheckpointKeeper, - &checkpointingKeeper, + // setting the finality keeper as nil for now + // need to set it after finality keeper is initiated + nil, btcNetParams, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -535,10 +541,14 @@ func (ak *AppKeepers) InitKeepers( runtime.NewKVStoreService(keys[finalitytypes.StoreKey]), ak.BTCStakingKeeper, ak.IncentiveKeeper, + ak.CheckpointingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) ak.BTCStakingKeeper = *ak.BTCStakingKeeper.SetHooks(btcstakingtypes.NewMultiBtcStakingHooks(ak.FinalityKeeper.Hooks())) ak.FinalityKeeper = *ak.FinalityKeeper.SetHooks(finalitytypes.NewMultiFinalityHooks(ak.BTCStakingKeeper.Hooks())) + // TODO this introduces circular dependency between the finality module and + // the btcstaking modules, need refactoring + ak.BTCStakingKeeper.FinalityKeeper = ak.FinalityKeeper // create evidence keeper with router evidenceKeeper := evidencekeeper.NewKeeper( diff --git a/app/upgrades/signetlaunch/README.md b/app/upgrades/signetlaunch/README.md index 26c89a050..9ac84d3e6 100644 --- a/app/upgrades/signetlaunch/README.md +++ b/app/upgrades/signetlaunch/README.md @@ -2,3 +2,58 @@ This folder contains a software upgrade for testing purposes. DO NOT USE IN PRODUCTION! + +## Compile signet launch upgrade + +This upgrade loads 2 JSONs from strings in different files. +BTC Headers from `./data_btc_headers.go` and signed messages +to create finality providers `./data_signed_fps.go`. + +### BTC Headers + +This upgrade accepts insertion of multiple +[`btclighttypes.BTCHeaderInfo`](../../../x/btclightclient/types/btclightclient.pb.go#36) +due to Babylon Phase-1 and Phase-2 launch will be a few months appart, so +during Phase-1 Babylon accepts BTC delegations without Babylonchain running. +At the time of launching the Babylonchain it is needed all the BTC block +headers that has passed since babylon started to accept BTC staking messages, +and to avoid giving too much work for +[vigilante](https://github.com/babylonlabs-io/vigilante) +to submit all of those missing headers. + +To generate this BTC headers there is a specific command in +[staking-indexer](https://github.com/babylonlabs-io/staking-indexer) +that query BTC for all the BTC headers and outputs it as json file +`sid btc-headers [from-block-height] [to-block-height]` and then +it is needed to recreate the golang file `./data_btc_headers.go` +with some simple bash script: + +```shell +GO_BTC_HEADERS_PATH="signetlaunch/data_btc_headers.go" +EXPORT_TO="./btc-headers.json" +# export the btc headers to a file +$SID_BIN btc-headers 1 1000 --output $EXPORT_TO +btcHeadersJson=$(cat $EXPORT_TO) + +# writes the headers to babylon as go file +echo "package signetlaunch + +const NewBtcHeadersStr = \`$btcHeadersJson\`" > $GO_BTC_HEADERS_PATH +``` + +### Signed Create Finality Provider + +For BTC stakers to stake during Phase-1 it is needed to have finality +providers. Babylon created a repository to publicly store this information +inside [networks](https://github.com/babylonlabs-io/networks) repository. +Inside the bbn-1 mainnet all the finality providers that wanted to be available +for BTC staking since the beginning would need to +[register](https://github.com/babylonlabs-io/networks/blob/main/bbn-1/finality-providers/README.md) +theirselves in the registry. +For the transition from Phase-1 to Phase-2, registered finality providers in +Phase-1 will need to provider a signed +[MsgCreateFinalityProvider](../../../x/btcstaking/types/tx.pb.go#38) as a +json file message inside the networks repository registry. + + diff --git a/app/upgrades/signetlaunch/data_signed_fps.go b/app/upgrades/signetlaunch/data_signed_fps.go new file mode 100644 index 000000000..38c531aeb --- /dev/null +++ b/app/upgrades/signetlaunch/data_signed_fps.go @@ -0,0 +1,122 @@ +package signetlaunch + +const SignedFPsStr = `{ + "signed_txs_create_fp": [ + { + "body": { + "messages": [ + { + "@type": "/babylon.btcstaking.v1.MsgCreateFinalityProvider", + "addr": "bbn1gwecky0m842kvjg7mcvt9z330rz96948aplqlm", + "description": { + "moniker": "fp-1", + "identity": "", + "website": "fp1.com.br", + "security_contact": "fp.1@email.com", + "details": "best-fp-1" + }, + "commission": "0.050000000000000000", + "btc_pk": "a94eef36ea7c596ba01b2018d55c202ebd8a82a0baf1a435818bc524bfd4e10a", + "pop": { + "btc_sig_type": "BIP340", + "btc_sig": "q5aykrV4imao9kiIVvWhBf8hPbIQW7GbdnDDCAZQRyCm4ZBaUiAGO3oFbEgVeLKNAd0xGmcCAJSbXu0OrpcQkQ==" + } + } + ], + "memo": "", + "timeout_height": "0", + "extension_options": [], + "non_critical_extension_options": [] + }, + "auth_info": { + "signer_infos": [ + { + "public_key": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "A9XXtGMjEFgavPv7GHo5rbI/XulwA0Hn2xlzsdCRDCTl" + }, + "mode_info": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "0" + } + ], + "fee": { + "amount": [ + { + "denom": "ubbn", + "amount": "2000000" + } + ], + "gas_limit": "200000", + "payer": "", + "granter": "" + }, + "tip": null + }, + "signatures": [ + "8wQGbPM5Xc5PmrynGmxbslqSA6tFW/5Vgg9sVZZ1WWsRTR5m040t2wgR+BjUrLNnO+JtrDlb38Su4XFSR76b9Q==" + ] + }, + { + "body": { + "messages": [ + { + "@type": "/babylon.btcstaking.v1.MsgCreateFinalityProvider", + "addr": "bbn1mwwywrmynkf0n5maps6yrtvgx2qqh3mlccdg6g", + "description": { + "moniker": "fp-2", + "identity": "", + "website": "fp2.com.br", + "security_contact": "fp.2@email.com", + "details": "best-fp-2" + }, + "commission": "0.100000000000000000", + "btc_pk": "bae0f3bfedc4de9e776fcbbb4b1dbae2641193fc20527ffc0a728968ebcd2d95", + "pop": { + "btc_sig_type": "BIP340", + "btc_sig": "IFU+77I8e7VOGudJdN5kk/8Hs2Biqiiw+sejBbYrtPRSNhFRhFrxhOru5kYHPxZ2XwadlfZfZjmXB8Uvj/hb5w==" + } + } + ], + "memo": "", + "timeout_height": "0", + "extension_options": [], + "non_critical_extension_options": [] + }, + "auth_info": { + "signer_infos": [ + { + "public_key": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "A3XkUtvcp3DnAvDKN4zYkES3xc6wi83LQBeAAlNG3Ebl" + }, + "mode_info": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "0" + } + ], + "fee": { + "amount": [ + { + "denom": "ubbn", + "amount": "2000000" + } + ], + "gas_limit": "200000", + "payer": "", + "granter": "" + }, + "tip": null + }, + "signatures": [ + "QMpALwCa+mHtKRv9Jg9RyHg/lOnFNa5i09tHgHgSuwh8JbNalYy4v2bTZ2PGDUh0JZCPUMeO487WacZofVhl9g==" + ] + } + ] +}` diff --git a/app/upgrades/signetlaunch/data_signed_fps_test.go b/app/upgrades/signetlaunch/data_signed_fps_test.go new file mode 100644 index 000000000..338f863c8 --- /dev/null +++ b/app/upgrades/signetlaunch/data_signed_fps_test.go @@ -0,0 +1,113 @@ +package signetlaunch_test + +import ( + "bytes" + "encoding/json" + "testing" + "time" + + "github.com/babylonlabs-io/babylon/app" + v1 "github.com/babylonlabs-io/babylon/app/upgrades/signetlaunch" + btcstktypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/ante" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" + txmodule "github.com/cosmos/cosmos-sdk/x/auth/tx/config" + "github.com/stretchr/testify/require" +) + +func TestValidateSignatureSignedFPsFromData(t *testing.T) { + bbnApp := app.NewTmpBabylonApp() + cdc := bbnApp.AppCodec() + // the chain ID in context needs to match the one used when creating the tx signature. + chainID := "bbn-1" + + ctx := bbnApp.BaseApp.NewContextLegacy(true, tmproto.Header{Height: 1, ChainID: chainID, Time: time.Now().UTC()}) + buff := bytes.NewBufferString(v1.SignedFPsStr) + simulateTx := false + + var d v1.DataSignedFps + err := json.Unmarshal(buff.Bytes(), &d) + require.NoError(t, err) + + antehandlerSigVerifier := buildAnteHandlerSigVerifier(t, bbnApp) + + fpAddrs := make(map[string]interface{}, len(d.SignedTxsFP)) + for _, txAny := range d.SignedTxsFP { + txBytes, err := json.Marshal(txAny) + require.NoError(t, err) + + // decodes the transaction + tx, err := bbnApp.TxConfig().TxJSONDecoder()(txBytes) + require.NoError(t, err) + + msgs := tx.GetMsgs() + require.Len(t, msgs, 1) + + msg, ok := msgs[0].(*btcstktypes.MsgCreateFinalityProvider) + require.True(t, ok) + + _, exist := fpAddrs[msg.Addr] + require.False(t, exist) + fpAddrs[msg.Addr] = nil + + require.NoError(t, msg.ValidateBasic()) + + // loads messages from the tx, only one message per tx is allowed. + msgsV2, err := tx.GetMsgsV2() + require.NoError(t, err) + require.Len(t, msgsV2, 1) + + msgV2 := msgsV2[0] + signers, err := cdc.GetMsgV2Signers(msgV2) + require.NoError(t, err) + require.Len(t, signers, 1) + + // checks that the signer_infos corresponding address in the transaction + // matches the FP address defined. + signerAddrStr, err := cdc.InterfaceRegistry().SigningContext().AddressCodec().BytesToString(signers[0]) + require.NoError(t, err) + + signerBbnAddr, err := sdk.AccAddressFromBech32(signerAddrStr) + require.NoError(t, err) + + require.Equal(t, msg.Addr, signerAddrStr) + // Proof of Possession check only for type BIP340 as expected in the networks registry instructions + require.NoError(t, msg.Pop.VerifyBIP340(signerBbnAddr, msg.BtcPk)) + + // creates the account with the signer address and sets the + // sequence and acc number to zero every time, for this reason + // it needs to remove account right after, otherwise new accounts + // would have account number +1 and the signature verification would fail. + acc := bbnApp.AccountKeeper.NewAccountWithAddress(ctx, signerBbnAddr) + require.NoError(t, acc.SetSequence(0)) + require.NoError(t, acc.SetAccountNumber(0)) + bbnApp.AccountKeeper.SetAccount(ctx, acc) + + _, err = antehandlerSigVerifier(ctx, tx, simulateTx) + require.NoError(t, err) + + bbnApp.AccountKeeper.RemoveAccount(ctx, acc) + } +} + +func buildAnteHandlerSigVerifier(t *testing.T, bbnApp *app.BabylonApp) sdk.AnteHandler { + cdc := bbnApp.AppCodec() + + txConfigOpts := authtx.ConfigOptions{ + TextualCoinMetadataQueryFn: txmodule.NewBankKeeperCoinMetadataQueryFn(bbnApp.GetBankKeeper()), + EnabledSignModes: []signing.SignMode{signing.SignMode_SIGN_MODE_DIRECT}, + } + anteTxConfig, err := authtx.NewTxConfigWithOptions( + codec.NewProtoCodec(cdc.InterfaceRegistry()), + txConfigOpts, + ) + require.NoError(t, err) + + svd := ante.NewSigVerificationDecorator(bbnApp.AppKeepers.AccountKeeper, anteTxConfig.SignModeHandler()) + spkd := ante.NewSetPubKeyDecorator(bbnApp.AppKeepers.AccountKeeper) + return sdk.ChainAnteDecorators(spkd, svd) +} diff --git a/app/upgrades/signetlaunch/upgrades.go b/app/upgrades/signetlaunch/upgrades.go index 7460a7f2d..db37c5ff7 100644 --- a/app/upgrades/signetlaunch/upgrades.go +++ b/app/upgrades/signetlaunch/upgrades.go @@ -6,12 +6,15 @@ package signetlaunch import ( "bytes" "context" + "encoding/json" "errors" "fmt" + "sort" store "cosmossdk.io/store/types" upgradetypes "cosmossdk.io/x/upgrade/types" "github.com/btcsuite/btcd/chaincfg" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -21,6 +24,8 @@ import ( bbn "github.com/babylonlabs-io/babylon/types" btclightkeeper "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" btclighttypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + btcstkkeeper "github.com/babylonlabs-io/babylon/x/btcstaking/keeper" + btcstktypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) var Upgrade = upgrades.Upgrade{ @@ -29,6 +34,10 @@ var Upgrade = upgrades.Upgrade{ StoreUpgrades: store.StoreUpgrades{}, } +type DataSignedFps struct { + SignedTxsFP []any `json:"signed_txs_create_fp"` +} + // CreateUpgradeHandler upgrade handler for launch. func CreateUpgradeHandler( mm *module.Manager, @@ -44,7 +53,7 @@ func CreateUpgradeHandler( return nil, err } - if err := propLaunch(ctx, &keepers.BTCLightClientKeeper); err != nil { + if err := propLaunch(ctx, keepers.EncCfg, &keepers.BTCLightClientKeeper, &keepers.BTCStakingKeeper); err != nil { panic(err) } @@ -55,19 +64,31 @@ func CreateUpgradeHandler( // propLaunch runs the proposal of launch that is meant to insert new BTC Headers. func propLaunch( ctx sdk.Context, + encCfg *appparams.EncodingConfig, btcLigthK *btclightkeeper.Keeper, + btcStkK *btcstkkeeper.Keeper, ) error { - newHeaders, err := LoadBTCHeadersFromData() + cdc := encCfg.Codec + + newHeaders, err := LoadBTCHeadersFromData(cdc) + if err != nil { + return err + } + + if err := insertBtcHeaders(ctx, btcLigthK, newHeaders); err != nil { + return err + } + + fps, err := LoadSignedFPsFromData(cdc, encCfg.TxConfig.TxJSONDecoder()) if err != nil { return err } - return insertBtcHeaders(ctx, btcLigthK, newHeaders) + return insertFPs(ctx, btcStkK, fps) } // LoadBTCHeadersFromData returns the BTC headers load from the json string with the headers inside of it. -func LoadBTCHeadersFromData() ([]*btclighttypes.BTCHeaderInfo, error) { - cdc := appparams.DefaultEncodingConfig().Codec +func LoadBTCHeadersFromData(cdc codec.Codec) ([]*btclighttypes.BTCHeaderInfo, error) { buff := bytes.NewBufferString(NewBtcHeadersStr) var gs btclighttypes.GenesisState @@ -79,6 +100,72 @@ func LoadBTCHeadersFromData() ([]*btclighttypes.BTCHeaderInfo, error) { return gs.BtcHeaders, nil } +// LoadSignedFPsFromData returns the finality providers from the json string. +func LoadSignedFPsFromData(cdc codec.Codec, txJSONDecoder sdk.TxDecoder) ([]*btcstktypes.MsgCreateFinalityProvider, error) { + buff := bytes.NewBufferString(SignedFPsStr) + + var d DataSignedFps + err := json.Unmarshal(buff.Bytes(), &d) + if err != nil { + return nil, err + } + + fps := make([]*btcstktypes.MsgCreateFinalityProvider, len(d.SignedTxsFP)) + for i, txAny := range d.SignedTxsFP { + txBytes, err := json.Marshal(txAny) + if err != nil { + return nil, err + } + + tx, err := txJSONDecoder(txBytes) + if err != nil { + return nil, err + } + + fp, err := parseCreateFPFromSignedTx(cdc, tx) + if err != nil { + return nil, err + } + + fps[i] = fp + } + + // sorts all the FPs by their addresses + sort.Slice(fps, func(i, j int) bool { + return fps[i].Addr > fps[j].Addr + }) + + return fps, nil +} + +func parseCreateFPFromSignedTx(cdc codec.Codec, tx sdk.Tx) (*btcstktypes.MsgCreateFinalityProvider, error) { + msgs := tx.GetMsgs() + if len(msgs) != 1 { + return nil, fmt.Errorf("each tx should contain only one message, invalid tx %+v", tx) + } + + msg, ok := msgs[0].(*btcstktypes.MsgCreateFinalityProvider) + if !ok { + return nil, fmt.Errorf("unable to parse %+v to MsgCreateFinalityProvider", msg) + } + + return msg, nil +} + +func insertFPs( + ctx sdk.Context, + k *btcstkkeeper.Keeper, + fps []*btcstktypes.MsgCreateFinalityProvider, +) error { + for _, fp := range fps { + if err := k.AddFinalityProvider(ctx, fp); err != nil { + return err + } + } + + return nil +} + func insertBtcHeaders( ctx sdk.Context, k *btclightkeeper.Keeper, diff --git a/app/upgrades/signetlaunch/upgrades_test.go b/app/upgrades/signetlaunch/upgrades_test.go index caf1409a1..a3eba0782 100644 --- a/app/upgrades/signetlaunch/upgrades_test.go +++ b/app/upgrades/signetlaunch/upgrades_test.go @@ -13,6 +13,7 @@ import ( v1 "github.com/babylonlabs-io/babylon/app/upgrades/signetlaunch" "github.com/babylonlabs-io/babylon/x/btclightclient" btclighttypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" @@ -55,6 +56,7 @@ func TestKeeperTestSuite(t *testing.T) { func (s *UpgradeTestSuite) TestUpgrade() { oldHeadersLen := 0 + oldFPsLen := 0 testCases := []struct { msg string @@ -67,6 +69,10 @@ func (s *UpgradeTestSuite) TestUpgrade() { func() { allBtcHeaders := s.app.BTCLightClientKeeper.GetMainChainFrom(s.ctx, 0) oldHeadersLen = len(allBtcHeaders) + + resp, err := s.app.BTCStakingKeeper.FinalityProviders(s.ctx, &types.QueryFinalityProvidersRequest{}) + s.NoError(err) + oldFPsLen = len(resp.FinalityProviders) }, func() { // inject upgrade plan @@ -91,7 +97,7 @@ func (s *UpgradeTestSuite) TestUpgrade() { // ensure the btc headers were added allBtcHeaders := s.app.BTCLightClientKeeper.GetMainChainFrom(s.ctx, 0) - btcHeadersInserted, err := v1.LoadBTCHeadersFromData() + btcHeadersInserted, err := v1.LoadBTCHeadersFromData(s.app.AppCodec()) s.NoError(err) lenHeadersInserted := len(btcHeadersInserted) @@ -104,6 +110,24 @@ func (s *UpgradeTestSuite) TestUpgrade() { s.EqualValues(btcHeaderInserted.Header.MarshalHex(), btcHeaderInState.Header.MarshalHex()) } + + resp, err := s.app.BTCStakingKeeper.FinalityProviders(s.ctx, &types.QueryFinalityProvidersRequest{}) + s.NoError(err) + newFPsLen := len(resp.FinalityProviders) + + fpsInserted, err := v1.LoadSignedFPsFromData(s.app.AppCodec(), s.app.TxConfig().TxJSONDecoder()) + s.NoError(err) + + s.Equal(newFPsLen, oldFPsLen+len(fpsInserted)) + for _, fpInserted := range fpsInserted { + fpFromKeeper, err := s.app.BTCStakingKeeper.GetFinalityProvider(s.ctx, *fpInserted.BtcPk) + s.NoError(err) + + s.EqualValues(fpFromKeeper.Addr, fpInserted.Addr) + s.EqualValues(fpFromKeeper.Description, fpInserted.Description) + s.EqualValues(fpFromKeeper.Commission.String(), fpInserted.Commission.String()) + s.EqualValues(fpFromKeeper.Pop.String(), fpInserted.Pop.String()) + } }, }, } diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 00e83b140..a59dd6156 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -4738,7 +4738,7 @@ paths: type: boolean tags: - Query - /babylon/zoneconcierge/v1/chain_info/{chain_id}/header/{height}: + /babylon/zoneconcierge/v1/chain_info/{consumer_id}/header/{height}: get: summary: Header queries the CZ header and fork headers at a given height. operationId: Header @@ -4751,9 +4751,9 @@ paths: header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -4816,9 +4816,9 @@ paths: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -5108,7 +5108,7 @@ paths: "value": "1.212s" } parameters: - - name: chain_id + - name: consumer_id in: path required: true type: string @@ -5129,12 +5129,12 @@ paths: schema: type: object properties: - chain_ids: + consumer_ids: type: array items: type: string title: >- - chain_ids are IDs of the chains in ascending alphabetical + consumer_ids are IDs of the chains in ascending alphabetical order pagination: title: pagination defines the pagination in the response @@ -5438,15 +5438,15 @@ paths: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer latest_header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -5512,9 +5512,9 @@ paths: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -5820,7 +5820,7 @@ paths: "value": "1.212s" } parameters: - - name: chain_ids + - name: consumer_ids in: query required: false type: array @@ -5846,15 +5846,15 @@ paths: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer latest_header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -5920,9 +5920,9 @@ paths: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -6236,7 +6236,7 @@ paths: required: false type: string format: uint64 - - name: chain_ids + - name: consumer_ids in: query required: false type: array @@ -6245,7 +6245,7 @@ paths: collectionFormat: multi tags: - Query - /babylon/zoneconcierge/v1/finalized_chain_info/{chain_id}/height/{height}: + /babylon/zoneconcierge/v1/finalized_chain_info/{consumer_id}/height/{height}: get: summary: >- FinalizedChainInfoUntilHeight queries the BTC-finalised info no later @@ -6262,15 +6262,15 @@ paths: finalized_chain_info: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer latest_header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -6336,9 +6336,9 @@ paths: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -6953,8 +6953,8 @@ paths: "value": "1.212s" } parameters: - - name: chain_id - description: chain_id is the ID of the CZ + - name: consumer_id + description: consumer_id is the ID of the CZ in: path required: true type: string @@ -6996,21 +6996,21 @@ paths: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer finalized_chain_info: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer latest_header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -7077,9 +7077,11 @@ paths: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: >- + consumer_id is the unique ID of the + consumer hash: type: string format: byte @@ -7706,8 +7708,8 @@ paths: "value": "1.212s" } parameters: - - name: chain_ids - description: chain_ids is the list of ids of CZs. + - name: consumer_ids + description: consumer_ids is the list of ids of CZs. in: query required: false type: array @@ -7723,7 +7725,7 @@ paths: type: boolean tags: - Query - /babylon/zoneconcierge/v1/headers/{chain_id}: + /babylon/zoneconcierge/v1/headers/{consumer_id}: get: summary: |- ListHeaders queries the headers of a chain in Babylon's view, with @@ -7740,9 +7742,9 @@ paths: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -8029,7 +8031,7 @@ paths: "value": "1.212s" } parameters: - - name: chain_id + - name: consumer_id in: path required: true type: string @@ -8091,7 +8093,7 @@ paths: type: boolean tags: - Query - /babylon/zoneconcierge/v1/headers/{chain_id}/epochs/{epoch_num}: + /babylon/zoneconcierge/v1/headers/{consumer_id}/epochs/{epoch_num}: get: summary: |- ListEpochHeaders queries the headers of a chain timestamped in a given @@ -8108,9 +8110,9 @@ paths: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -8368,7 +8370,7 @@ paths: "value": "1.212s" } parameters: - - name: chain_id + - name: consumer_id in: path required: true type: string @@ -11391,15 +11393,15 @@ definitions: babylon.zoneconcierge.v1.ChainInfo: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer latest_header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -11458,9 +11460,9 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -11560,21 +11562,21 @@ definitions: babylon.zoneconcierge.v1.FinalizedChainInfo: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer finalized_chain_info: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer latest_header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -11637,9 +11639,9 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -12041,9 +12043,9 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -12124,9 +12126,9 @@ definitions: babylon.zoneconcierge.v1.IndexedHeader: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -12474,11 +12476,11 @@ definitions: babylon.zoneconcierge.v1.QueryChainListResponse: type: object properties: - chain_ids: + consumer_ids: type: array items: type: string - title: chain_ids are IDs of the chains in ascending alphabetical order + title: consumer_ids are IDs of the chains in ascending alphabetical order pagination: title: pagination defines the pagination in the response type: object @@ -12515,15 +12517,15 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer latest_header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -12586,9 +12588,9 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -12705,15 +12707,15 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer latest_header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -12776,9 +12778,9 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -12896,15 +12898,15 @@ definitions: finalized_chain_info: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer latest_header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -12967,9 +12969,9 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -13373,21 +13375,21 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer finalized_chain_info: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the ID of the chain + title: consumer_id is the ID of the consumer latest_header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -13452,9 +13454,9 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -13866,9 +13868,9 @@ definitions: header: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -13927,9 +13929,9 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -14023,9 +14025,9 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte @@ -14090,9 +14092,9 @@ definitions: items: type: object properties: - chain_id: + consumer_id: type: string - title: chain_id is the unique ID of the chain + title: consumer_id is the unique ID of the consumer hash: type: string format: byte diff --git a/client/query/zoneconcierge.go b/client/query/zoneconcierge.go index 6639d5207..bdc20c193 100644 --- a/client/query/zoneconcierge.go +++ b/client/query/zoneconcierge.go @@ -21,12 +21,12 @@ func (c *QueryClient) QueryZoneConcierge(f func(ctx context.Context, queryClient } // FinalizedConnectedChainsInfo queries the zoneconcierge module to get the finalization information for a connected chain -func (c *QueryClient) FinalizedConnectedChainsInfo(chainIds []string) (*zctypes.QueryFinalizedChainsInfoResponse, error) { +func (c *QueryClient) FinalizedConnectedChainsInfo(consumerIds []string) (*zctypes.QueryFinalizedChainsInfoResponse, error) { var resp *zctypes.QueryFinalizedChainsInfoResponse err := c.QueryZoneConcierge(func(ctx context.Context, queryClient zctypes.QueryClient) error { var err error req := &zctypes.QueryFinalizedChainsInfoRequest{ - ChainIds: chainIds, + ConsumerIds: consumerIds, } resp, err = queryClient.FinalizedChainsInfo(ctx, req) return err @@ -36,12 +36,12 @@ func (c *QueryClient) FinalizedConnectedChainsInfo(chainIds []string) (*zctypes. } // ConnectedChainsInfo queries the zoneconcierge module to get information for a connected chain -func (c *QueryClient) ConnectedChainsInfo(chainIds []string) (*zctypes.QueryChainsInfoResponse, error) { +func (c *QueryClient) ConnectedChainsInfo(consumerIds []string) (*zctypes.QueryChainsInfoResponse, error) { var resp *zctypes.QueryChainsInfoResponse err := c.QueryZoneConcierge(func(ctx context.Context, queryClient zctypes.QueryClient) error { var err error req := &zctypes.QueryChainsInfoRequest{ - ChainIds: chainIds, + ConsumerIds: consumerIds, } resp, err = queryClient.ChainsInfo(ctx, req) return err @@ -64,12 +64,12 @@ func (c *QueryClient) ConnectedChainList() (*zctypes.QueryChainListResponse, err } // ConnectedChainHeaders queries the zoneconcierge module for the headers of a connected chain -func (c *QueryClient) ConnectedChainHeaders(chainID string, pagination *sdkquerytypes.PageRequest) (*zctypes.QueryListHeadersResponse, error) { +func (c *QueryClient) ConnectedChainHeaders(consumerID string, pagination *sdkquerytypes.PageRequest) (*zctypes.QueryListHeadersResponse, error) { var resp *zctypes.QueryListHeadersResponse err := c.QueryZoneConcierge(func(ctx context.Context, queryClient zctypes.QueryClient) error { var err error req := &zctypes.QueryListHeadersRequest{ - ChainId: chainID, + ConsumerId: consumerID, Pagination: pagination, } resp, err = queryClient.ListHeaders(ctx, req) @@ -80,13 +80,13 @@ func (c *QueryClient) ConnectedChainHeaders(chainID string, pagination *sdkquery } // ConnectedChainsEpochInfo queries the zoneconcierge module for the chain information of a connected chain at a particular epoch -func (c *QueryClient) ConnectedChainsEpochInfo(chainIds []string, epochNum uint64) (*zctypes.QueryEpochChainsInfoResponse, error) { +func (c *QueryClient) ConnectedChainsEpochInfo(consumerIds []string, epochNum uint64) (*zctypes.QueryEpochChainsInfoResponse, error) { var resp *zctypes.QueryEpochChainsInfoResponse err := c.QueryZoneConcierge(func(ctx context.Context, queryClient zctypes.QueryClient) error { var err error req := &zctypes.QueryEpochChainsInfoRequest{ - ChainIds: chainIds, - EpochNum: epochNum, + ConsumerIds: consumerIds, + EpochNum: epochNum, } resp, err = queryClient.EpochChainsInfo(ctx, req) return err diff --git a/proto/babylon/btcstaking/v1/incentive.proto b/proto/babylon/btcstaking/v1/incentive.proto index 7dcde01f8..0a5561d00 100644 --- a/proto/babylon/btcstaking/v1/incentive.proto +++ b/proto/babylon/btcstaking/v1/incentive.proto @@ -9,9 +9,15 @@ option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types"; // VotingPowerDistCache is the cache for voting power distribution of finality providers // and their BTC delegations at a height message VotingPowerDistCache { + option (gogoproto.goproto_getters) = false; + // total_voting_power is the total voting power of all the finality providers + // in the cache uint64 total_voting_power = 1; // finality_providers is a list of finality providers' voting power information repeated FinalityProviderDistInfo finality_providers = 2; + // num_active_fps is the number of finality providers that have positive voting power + // as well as timestamped public randomness + uint32 num_active_fps = 3; } // FinalityProviderDistInfo is the reward distribution of a finality provider and its BTC delegations @@ -30,6 +36,9 @@ message FinalityProviderDistInfo { uint64 total_voting_power = 4; // btc_dels is a list of BTC delegations' voting power information under this finality provider repeated BTCDelDistInfo btc_dels = 5; + // is_timestamped indicates whether the finality provider + // has timestamped public randomness committed + bool is_timestamped = 6; } // BTCDelDistInfo contains the information related to reward distribution for a BTC delegation diff --git a/proto/babylon/finality/v1/finality.proto b/proto/babylon/finality/v1/finality.proto index f6f56f6d9..1167e774a 100644 --- a/proto/babylon/finality/v1/finality.proto +++ b/proto/babylon/finality/v1/finality.proto @@ -27,6 +27,8 @@ message PubRandCommit { // commitment is the value of the commitment // currently, it is the root of the merkle tree constructed by the public randomness bytes commitment = 3; + // epoch_num defines the epoch number that the commit falls into + uint64 epoch_num = 4; } // Evidence is the evidence that a finality provider has signed finality diff --git a/proto/babylon/finality/v1/query.proto b/proto/babylon/finality/v1/query.proto index 7b6c9fb0b..159995a69 100644 --- a/proto/babylon/finality/v1/query.proto +++ b/proto/babylon/finality/v1/query.proto @@ -102,6 +102,8 @@ message PubRandCommitResponse { uint64 num_pub_rand = 1; // commitment is the value of the commitment bytes commitment = 2; + // epoch_num defines the epoch number that the commit falls into + uint64 epoch_num = 3; } // QueryListPubRandCommitRequest is the request type for the diff --git a/proto/babylon/zoneconcierge/v1/query.proto b/proto/babylon/zoneconcierge/v1/query.proto index 690ab0182..67f3b4503 100644 --- a/proto/babylon/zoneconcierge/v1/query.proto +++ b/proto/babylon/zoneconcierge/v1/query.proto @@ -21,7 +21,7 @@ service Query { // Header queries the CZ header and fork headers at a given height. rpc Header(QueryHeaderRequest) returns (QueryHeaderResponse) { option (google.api.http).get = - "/babylon/zoneconcierge/v1/chain_info/{chain_id}/header/{height}"; + "/babylon/zoneconcierge/v1/chain_info/{consumer_id}/header/{height}"; } // ChainList queries the list of chains that checkpoint to Babylon rpc ChainList(QueryChainListRequest) returns (QueryChainListResponse) { @@ -43,14 +43,14 @@ service Query { // pagination support rpc ListHeaders(QueryListHeadersRequest) returns (QueryListHeadersResponse) { option (google.api.http).get = - "/babylon/zoneconcierge/v1/headers/{chain_id}"; + "/babylon/zoneconcierge/v1/headers/{consumer_id}"; } // ListEpochHeaders queries the headers of a chain timestamped in a given // epoch of Babylon, with pagination support rpc ListEpochHeaders(QueryListEpochHeadersRequest) returns (QueryListEpochHeadersResponse) { option (google.api.http).get = - "/babylon/zoneconcierge/v1/headers/{chain_id}/epochs/{epoch_num}"; + "/babylon/zoneconcierge/v1/headers/{consumer_id}/epochs/{epoch_num}"; } // FinalizedChainsInfo queries the BTC-finalised info of chains with given IDs, with proofs rpc FinalizedChainsInfo(QueryFinalizedChainsInfoRequest) @@ -63,7 +63,7 @@ service Query { rpc FinalizedChainInfoUntilHeight(QueryFinalizedChainInfoUntilHeightRequest) returns (QueryFinalizedChainInfoUntilHeightResponse) { option (google.api.http).get = - "/babylon/zoneconcierge/v1/finalized_chain_info/{chain_id}/height/" + "/babylon/zoneconcierge/v1/finalized_chain_info/{consumer_id}/height/" "{height}"; } } @@ -79,7 +79,7 @@ message QueryParamsResponse { // QueryHeaderRequest is request type for the Query/Header RPC method. message QueryHeaderRequest { - string chain_id = 1; + string consumer_id = 1; uint64 height = 2; } @@ -97,14 +97,14 @@ message QueryChainListRequest { // QueryChainListResponse is response type for the Query/ChainList RPC method message QueryChainListResponse { - // chain_ids are IDs of the chains in ascending alphabetical order - repeated string chain_ids = 1; + // consumer_ids are IDs of the chains in ascending alphabetical order + repeated string consumer_ids = 1; // pagination defines the pagination in the response cosmos.base.query.v1beta1.PageResponse pagination = 2; } // QueryChainsInfoRequest is request type for the Query/ChainsInfo RPC method. -message QueryChainsInfoRequest { repeated string chain_ids = 1; } +message QueryChainsInfoRequest { repeated string consumer_ids = 1; } // QueryChainsInfoResponse is response type for the Query/ChainsInfo RPC method. message QueryChainsInfoResponse { @@ -115,7 +115,7 @@ message QueryChainsInfoResponse { // method. message QueryEpochChainsInfoRequest { uint64 epoch_num = 1; - repeated string chain_ids = 2; + repeated string consumer_ids = 2; } // QueryEpochChainsInfoResponse is response type for the Query/EpochChainsInfo RPC @@ -127,7 +127,7 @@ message QueryEpochChainsInfoResponse { // QueryListHeadersRequest is request type for the Query/ListHeaders RPC method. message QueryListHeadersRequest { - string chain_id = 1; + string consumer_id = 1; // pagination defines whether to have the pagination in the request cosmos.base.query.v1beta1.PageRequest pagination = 2; } @@ -145,7 +145,7 @@ message QueryListHeadersResponse { // RPC method. message QueryListEpochHeadersRequest { uint64 epoch_num = 1; - string chain_id = 2; + string consumer_id = 2; } // QueryListEpochHeadersResponse is response type for the Query/ListEpochHeaders @@ -158,8 +158,8 @@ message QueryListEpochHeadersResponse { // QueryFinalizedChainsInfoRequest is request type for the // Query/FinalizedChainsInfo RPC method. message QueryFinalizedChainsInfoRequest { - // chain_ids is the list of ids of CZs - repeated string chain_ids = 1; + // consumer_ids is the list of ids of CZs + repeated string consumer_ids = 1; // prove indicates whether the querier wants to get proofs of this timestamp bool prove = 2; } @@ -173,8 +173,8 @@ message QueryFinalizedChainsInfoResponse { // QueryFinalizedChainInfoUntilHeightRequest is request type for the // Query/FinalizedChainInfoUntilHeight RPC method. message QueryFinalizedChainInfoUntilHeightRequest { - // chain_id is the ID of the CZ - string chain_id = 1; + // consumer_id is the ID of the CZ + string consumer_id = 1; // height is the height of the CZ chain // such that the returned finalised chain info will be no later than this // height diff --git a/proto/babylon/zoneconcierge/v1/zoneconcierge.proto b/proto/babylon/zoneconcierge/v1/zoneconcierge.proto index b6c1dde8c..44eeefdb1 100644 --- a/proto/babylon/zoneconcierge/v1/zoneconcierge.proto +++ b/proto/babylon/zoneconcierge/v1/zoneconcierge.proto @@ -14,8 +14,8 @@ option go_package = "github.com/babylonlabs-io/babylon/x/zoneconcierge/types"; // IndexedHeader is the metadata of a CZ header message IndexedHeader { - // chain_id is the unique ID of the chain - string chain_id = 1; + // consumer_id is the unique ID of the consumer + string consumer_id = 1; // hash is the hash of this header bytes hash = 2; // height is the height of this header on CZ ledger @@ -60,8 +60,8 @@ message Forks { // ChainInfo is the information of a CZ message ChainInfo { - // chain_id is the ID of the chain - string chain_id = 1; + // consumer_id is the ID of the consumer + string consumer_id = 1; // latest_header is the latest header in CZ's canonical chain IndexedHeader latest_header = 2; // latest_forks is the latest forks, formed as a series of IndexedHeader (from @@ -84,8 +84,8 @@ message ChainInfoWithProof { // FinalizedChainInfo is the information of a CZ that is BTC-finalised message FinalizedChainInfo { - // chain_id is the ID of the chain - string chain_id = 1; + // consumer_id is the ID of the consumer + string consumer_id = 1; // finalized_chain_info is the info of the CZ babylon.zoneconcierge.v1.ChainInfo finalized_chain_info = 2; diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index f4f67a203..58c28f562 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -26,6 +26,7 @@ import ( 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" itypes "github.com/babylonlabs-io/babylon/x/incentive/types" ) @@ -243,21 +244,6 @@ func (s *BTCStakingTestSuite) Test2SubmitCovenantSignature() { activeDel := activeDels.Dels[0] s.True(activeDel.HasCovenantQuorums(covenantQuorum)) - - // wait for a block so that above txs take effect and the voting power table - // is updated in the next block's BeginBlock - nonValidatorNode.WaitForNextBlock() - - // ensure BTC staking is activated - activatedHeight := nonValidatorNode.QueryActivatedHeight() - s.Positive(activatedHeight) - // ensure finality provider has voting power at activated height - currentBtcTip, err := nonValidatorNode.QueryTip() - s.NoError(err) - activeFps := nonValidatorNode.QueryActiveFinalityProvidersAtHeight(activatedHeight) - s.Len(activeFps, 1) - s.Equal(activeFps[0].VotingPower, activeDels.VotingPower(currentBtcTip.Height, initialization.BabylonBtcFinalizationPeriod, params.CovenantQuorum)) - s.Equal(activeFps[0].VotingPower, activeDel.VotingPower(currentBtcTip.Height, initialization.BabylonBtcFinalizationPeriod, params.CovenantQuorum)) } // Test2CommitPublicRandomnessAndSubmitFinalitySignature is an end-to-end @@ -270,15 +256,19 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat s.NoError(err) // get activated height - activatedHeight := nonValidatorNode.QueryActivatedHeight() - s.Positive(activatedHeight) + _, err = nonValidatorNode.QueryActivatedHeight() + s.ErrorContains(err, bstypes.ErrBTCStakingNotActivated.Error()) + fps := nonValidatorNode.QueryFinalityProviders() + s.Len(fps, 1) + s.Zero(fps[0].VotingPower) /* commit a number of public randomness since activatedHeight */ // commit public randomness list numPubRand := uint64(100) - randListInfo, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, fpBTCSK, activatedHeight, numPubRand) + commitStartHeight := uint64(1) + randListInfo, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, fpBTCSK, commitStartHeight, numPubRand) s.NoError(err) nonValidatorNode.CommitPubRandList( msgCommitPubRandList.FpBtcPk, @@ -288,16 +278,6 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat msgCommitPubRandList.Sig, ) - // ensure public randomness list is eventually committed - nonValidatorNode.WaitForNextBlock() - var prCommitMap map[uint64]*ftypes.PubRandCommitResponse - s.Eventually(func() bool { - prCommitMap = nonValidatorNode.QueryListPubRandCommit(cacheFP.BtcPk) - return len(prCommitMap) > 0 - }, time.Minute, time.Second*5) - s.Equal(prCommitMap[activatedHeight].NumPubRand, msgCommitPubRandList.NumPubRand) - s.Equal(prCommitMap[activatedHeight].Commitment, msgCommitPubRandList.Commitment) - // no reward gauge for finality provider and delegation yet fpBabylonAddr, err := sdk.AccAddressFromBech32(cacheFP.Addr) s.NoError(err) @@ -306,6 +286,41 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat s.ErrorContains(err, itypes.ErrRewardGaugeNotFound.Error()) delBabylonAddr := fpBabylonAddr + // finalize epochs from 1 to the current epoch + currentEpoch, err := nonValidatorNode.QueryCurrentEpoch() + s.NoError(err) + + // wait until the end epoch is sealed + s.Eventually(func() bool { + resp, err := nonValidatorNode.QueryRawCheckpoint(currentEpoch) + if err != nil { + return false + } + return resp.Status == ckpttypes.Sealed + }, time.Minute, time.Millisecond*50) + nonValidatorNode.FinalizeSealedEpochs(1, currentEpoch) + + // ensure the committed epoch is finalized + lastFinalizedEpoch := uint64(0) + s.Eventually(func() bool { + lastFinalizedEpoch, err = nonValidatorNode.QueryLastFinalizedEpoch() + if err != nil { + return false + } + return lastFinalizedEpoch >= currentEpoch + }, time.Minute, time.Millisecond*50) + + // ensure btc staking is activated + var activatedHeight uint64 + s.Eventually(func() bool { + activatedHeight, err = nonValidatorNode.QueryActivatedHeight() + if err != nil { + return false + } + return activatedHeight > 0 + }, time.Minute, time.Millisecond*50) + s.T().Logf("the activated height is %d", activatedHeight) + /* submit finality signature */ @@ -314,7 +329,7 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat s.NoError(err) appHash := blockToVote.AppHash - idx := 0 + idx := activatedHeight - commitStartHeight msgToSign := append(sdk.Uint64ToBigEndian(activatedHeight), appHash...) // generate EOTS signature sig, err := eots.Sign(fpBTCSK, randListInfo.SRList[idx], msgToSign) @@ -324,21 +339,14 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat nonValidatorNode.AddFinalitySig(cacheFP.BtcPk, activatedHeight, &randListInfo.PRList[idx], *randListInfo.ProofList[idx].ToProto(), appHash, eotsSig) // ensure vote is eventually cast - nonValidatorNode.WaitForNextBlock() - var votes []bbn.BIP340PubKey + var finalizedBlocks []*ftypes.IndexedBlock s.Eventually(func() bool { - votes = nonValidatorNode.QueryVotesAtHeight(activatedHeight) - return len(votes) > 0 - }, time.Minute, time.Second*5) - s.Equal(1, len(votes)) - s.Equal(votes[0].MarshalHex(), cacheFP.BtcPk.MarshalHex()) - // once the vote is cast, ensure block is finalised - finalizedBlock := nonValidatorNode.QueryIndexedBlock(activatedHeight) - s.NotEmpty(finalizedBlock) - s.Equal(appHash.Bytes(), finalizedBlock.AppHash) - finalizedBlocks := nonValidatorNode.QueryListBlocks(ftypes.QueriedBlockStatus_FINALIZED) - s.NotEmpty(finalizedBlocks) + finalizedBlocks = nonValidatorNode.QueryListBlocks(ftypes.QueriedBlockStatus_FINALIZED) + return len(finalizedBlocks) > 0 + }, time.Minute, time.Millisecond*50) + s.Equal(activatedHeight, finalizedBlocks[0].Height) s.Equal(appHash.Bytes(), finalizedBlocks[0].AppHash) + s.T().Logf("the block %d is finalized", activatedHeight) // ensure finality provider has received rewards after the block is finalised fpRewardGauges, err := nonValidatorNode.QueryRewardGauge(fpBabylonAddr) @@ -352,6 +360,7 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat btcDelRewardGauge, ok := btcDelRewardGauges[itypes.BTCDelegationType.String()] s.True(ok) s.True(btcDelRewardGauge.Coins.IsAllPositive()) + s.T().Logf("the finality provider received rewards for providing finality") } func (s *BTCStakingTestSuite) Test4WithdrawReward() { diff --git a/test/e2e/btc_timestamping_e2e_test.go b/test/e2e/btc_timestamping_e2e_test.go index 8e985113d..c344e6e17 100644 --- a/test/e2e/btc_timestamping_e2e_test.go +++ b/test/e2e/btc_timestamping_e2e_test.go @@ -112,10 +112,19 @@ func (s *BTCTimestampingTestSuite) Test4IbcCheckpointing() { nonValidatorNode, err := chainA.GetNodeAtIndex(2) s.NoError(err) + // Query open IBC channels and assert there is only one + channels, err := nonValidatorNode.QueryIBCChannels() + s.NoError(err) + s.Equal(1, len(channels.Channels), "Expected only one open IBC channel") + // Get the client ID under this IBC channel + channelClientState, err := nonValidatorNode.QueryChannelClientState(channels.Channels[0].ChannelId, channels.Channels[0].PortId) + s.NoError(err) + clientID := channelClientState.IdentifiedClientState.ClientId + // Query checkpoint chain info for opposing chain - chainsInfo, err := nonValidatorNode.QueryChainsInfo([]string{initialization.ChainBID}) + chainsInfo, err := nonValidatorNode.QueryChainsInfo([]string{clientID}) s.NoError(err) - s.Equal(chainsInfo[0].ChainId, initialization.ChainBID) + s.Equal(chainsInfo[0].ConsumerId, clientID) // Finalize epoch 1, 2, 3, as first headers of opposing chain are in epoch 3 var ( @@ -140,17 +149,17 @@ func (s *BTCTimestampingTestSuite) Test4IbcCheckpointing() { nonValidatorNode.WaitForNextBlock() // Check we have epoch info for opposing chain and some basic assertions - epochChainsInfo, err := nonValidatorNode.QueryEpochChainsInfo(endEpochNum, []string{initialization.ChainBID}) + epochChainsInfo, err := nonValidatorNode.QueryEpochChainsInfo(endEpochNum, []string{clientID}) s.NoError(err) - s.Equal(epochChainsInfo[0].ChainId, initialization.ChainBID) + s.Equal(epochChainsInfo[0].ConsumerId, clientID) s.Equal(epochChainsInfo[0].LatestHeader.BabylonEpoch, endEpochNum) // Check we have finalized epoch info for opposing chain and some basic assertions - finalizedChainsInfo, err := nonValidatorNode.QueryFinalizedChainsInfo([]string{initialization.ChainBID}) + finalizedChainsInfo, err := nonValidatorNode.QueryFinalizedChainsInfo([]string{clientID}) s.NoError(err) // TODO Add more assertion here. Maybe check proofs ? - s.Equal(finalizedChainsInfo[0].FinalizedChainInfo.ChainId, initialization.ChainBID) + s.Equal(finalizedChainsInfo[0].FinalizedChainInfo.ConsumerId, clientID) s.Equal(finalizedChainsInfo[0].EpochInfo.EpochNumber, endEpochNum) currEpoch, err := nonValidatorNode.QueryCurrentEpoch() diff --git a/test/e2e/btc_timestamping_phase2_hermes_test.go b/test/e2e/btc_timestamping_phase2_hermes_test.go index b8eb6a1e8..4f656e068 100644 --- a/test/e2e/btc_timestamping_phase2_hermes_test.go +++ b/test/e2e/btc_timestamping_phase2_hermes_test.go @@ -4,7 +4,6 @@ import ( "time" "github.com/babylonlabs-io/babylon/test/e2e/configurer" - "github.com/babylonlabs-io/babylon/test/e2e/initialization" ct "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/types/query" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" @@ -51,6 +50,8 @@ func (s *BTCTimestampingPhase2HermesTestSuite) TearDownSuite() { func (s *BTCTimestampingPhase2HermesTestSuite) Test1IbcCheckpointingPhase2Hermes() { chainA := s.configurer.GetChainConfig(0) + nonValidatorNode, err := chainA.GetNodeAtIndex(2) + s.NoError(err) babylonNode, err := chainA.GetNodeAtIndex(2) s.NoError(err) @@ -98,9 +99,15 @@ func (s *BTCTimestampingPhase2HermesTestSuite) Test1IbcCheckpointingPhase2Hermes return true }, time.Minute, time.Second*2) + // Get the client ID under this IBC channel + channelClientState, err := nonValidatorNode.QueryChannelClientState(babylonChannel.ChannelId, babylonChannel.PortId) + s.NoError(err) + clientID := channelClientState.IdentifiedClientState.ClientId + // Query checkpoint chain info for the consumer chain - listHeaderResp, err := babylonNode.QueryListHeaders(initialization.ChainBID, &query.PageRequest{Limit: 1}) + listHeaderResp, err := babylonNode.QueryListHeaders(clientID, &query.PageRequest{Limit: 1}) s.NoError(err) + s.GreaterOrEqual(len(listHeaderResp.Headers), 1) startEpochNum := listHeaderResp.Headers[0].BabylonEpoch endEpochNum := startEpochNum + 2 diff --git a/test/e2e/btc_timestamping_phase2_rly_test.go b/test/e2e/btc_timestamping_phase2_rly_test.go index 7dc31959e..744fc7d06 100644 --- a/test/e2e/btc_timestamping_phase2_rly_test.go +++ b/test/e2e/btc_timestamping_phase2_rly_test.go @@ -4,7 +4,6 @@ import ( "time" "github.com/babylonlabs-io/babylon/test/e2e/configurer" - "github.com/babylonlabs-io/babylon/test/e2e/initialization" ct "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/types/query" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" @@ -51,6 +50,8 @@ func (s *BTCTimestampingPhase2RlyTestSuite) TearDownSuite() { func (s *BTCTimestampingPhase2RlyTestSuite) Test1IbcCheckpointingPhase2Rly() { chainA := s.configurer.GetChainConfig(0) + nonValidatorNode, err := chainA.GetNodeAtIndex(2) + s.NoError(err) babylonNode, err := chainA.GetNodeAtIndex(2) s.NoError(err) @@ -98,9 +99,15 @@ func (s *BTCTimestampingPhase2RlyTestSuite) Test1IbcCheckpointingPhase2Rly() { return true }, time.Minute, time.Second*2) + // Get the client ID under this IBC channel + channelClientState, err := nonValidatorNode.QueryChannelClientState(babylonChannel.ChannelId, babylonChannel.PortId) + s.NoError(err) + clientID := channelClientState.IdentifiedClientState.ClientId + // Query checkpoint chain info for the consumer chain - listHeaderResp, err := babylonNode.QueryListHeaders(initialization.ChainBID, &query.PageRequest{Limit: 1}) + listHeaderResp, err := babylonNode.QueryListHeaders(clientID, &query.PageRequest{Limit: 1}) s.NoError(err) + s.GreaterOrEqual(len(listHeaderResp.Headers), 1) startEpochNum := listHeaderResp.Headers[0].BabylonEpoch endEpochNum := startEpochNum + 2 diff --git a/test/e2e/configurer/chain/queries.go b/test/e2e/configurer/chain/queries.go index 178349bbf..c0ce271ca 100644 --- a/test/e2e/configurer/chain/queries.go +++ b/test/e2e/configurer/chain/queries.go @@ -180,7 +180,9 @@ func (n *NodeConfig) QueryListSnapshots() ([]*cmtabcitypes.Snapshot, error) { func (n *NodeConfig) QueryRawCheckpoint(epoch uint64) (*ct.RawCheckpointWithMetaResponse, error) { path := fmt.Sprintf("babylon/checkpointing/v1/raw_checkpoint/%d", epoch) bz, err := n.QueryGRPCGateway(path, url.Values{}) - require.NoError(n.t, err) + if err != nil { + return nil, err + } var checkpointingResponse ct.QueryRawCheckpointResponse if err := util.Cdc.UnmarshalJSON(bz, &checkpointingResponse); err != nil { @@ -208,6 +210,19 @@ func (n *NodeConfig) QueryRawCheckpoints(pagination *query.PageRequest) (*ct.Que return &checkpointingResponse, nil } +func (n *NodeConfig) QueryLastFinalizedEpoch() (uint64, error) { + queryParams := url.Values{} + queryParams.Add("status", fmt.Sprintf("%d", ct.Finalized)) + + bz, err := n.QueryGRPCGateway(fmt.Sprintf("/babylon/checkpointing/v1/last_raw_checkpoint/%d", ct.Finalized), queryParams) + require.NoError(n.t, err) + var res ct.QueryLastCheckpointWithStatusResponse + if err := util.Cdc.UnmarshalJSON(bz, &res); err != nil { + return 0, err + } + return res.RawCheckpoint.EpochNum, nil +} + func (n *NodeConfig) QueryBtcBaseHeader() (*blc.BTCHeaderInfoResponse, error) { bz, err := n.QueryGRPCGateway("babylon/btclightclient/v1/baseheader", url.Values{}) require.NoError(n.t, err) @@ -245,14 +260,14 @@ func (n *NodeConfig) QueryHeaderDepth(hash string) (uint64, error) { return blcResponse.Depth, nil } -func (n *NodeConfig) QueryListHeaders(chainID string, pagination *query.PageRequest) (*zctypes.QueryListHeadersResponse, error) { +func (n *NodeConfig) QueryListHeaders(consumerID string, pagination *query.PageRequest) (*zctypes.QueryListHeadersResponse, error) { queryParams := url.Values{} if pagination != nil { queryParams.Set("pagination.key", base64.URLEncoding.EncodeToString(pagination.Key)) queryParams.Set("pagination.limit", strconv.Itoa(int(pagination.Limit))) } - path := fmt.Sprintf("babylon/zoneconcierge/v1/headers/%s", chainID) + path := fmt.Sprintf("babylon/zoneconcierge/v1/headers/%s", consumerID) bz, err := n.QueryGRPCGateway(path, queryParams) require.NoError(n.t, err) @@ -264,10 +279,10 @@ func (n *NodeConfig) QueryListHeaders(chainID string, pagination *query.PageRequ return &resp, nil } -func (n *NodeConfig) QueryFinalizedChainsInfo(chainIDs []string) ([]*zctypes.FinalizedChainInfo, error) { +func (n *NodeConfig) QueryFinalizedChainsInfo(consumerIDs []string) ([]*zctypes.FinalizedChainInfo, error) { queryParams := url.Values{} - for _, chainId := range chainIDs { - queryParams.Add("chain_ids", chainId) + for _, consumerID := range consumerIDs { + queryParams.Add("consumer_ids", consumerID) } bz, err := n.QueryGRPCGateway("babylon/zoneconcierge/v1/finalized_chains_info", queryParams) @@ -281,11 +296,11 @@ func (n *NodeConfig) QueryFinalizedChainsInfo(chainIDs []string) ([]*zctypes.Fin return resp.FinalizedChainsInfo, nil } -func (n *NodeConfig) QueryEpochChainsInfo(epochNum uint64, chainIDs []string) ([]*zctypes.ChainInfo, error) { +func (n *NodeConfig) QueryEpochChainsInfo(epochNum uint64, consumerIDs []string) ([]*zctypes.ChainInfo, error) { queryParams := url.Values{} - for _, chainId := range chainIDs { + for _, consumerID := range consumerIDs { queryParams.Add("epoch_num", fmt.Sprintf("%d", epochNum)) - queryParams.Add("chain_ids", chainId) + queryParams.Add("consumer_ids", consumerID) } bz, err := n.QueryGRPCGateway("babylon/zoneconcierge/v1/epoch_chains_info", queryParams) @@ -306,13 +321,13 @@ func (n *NodeConfig) QueryChains() (*[]string, error) { if err := util.Cdc.UnmarshalJSON(bz, &chainsResponse); err != nil { return nil, err } - return &chainsResponse.ChainIds, nil + return &chainsResponse.ConsumerIds, nil } -func (n *NodeConfig) QueryChainsInfo(chainIDs []string) ([]*zctypes.ChainInfo, error) { +func (n *NodeConfig) QueryChainsInfo(consumerIDs []string) ([]*zctypes.ChainInfo, error) { queryParams := url.Values{} - for _, chainId := range chainIDs { - queryParams.Add("chain_ids", chainId) + for _, consumerId := range consumerIDs { + queryParams.Add("consumer_ids", consumerId) } bz, err := n.QueryGRPCGateway("/babylon/zoneconcierge/v1/chains_info", queryParams) diff --git a/test/e2e/configurer/chain/queries_btcstaking.go b/test/e2e/configurer/chain/queries_btcstaking.go index f7a735c8f..861ac6a69 100644 --- a/test/e2e/configurer/chain/queries_btcstaking.go +++ b/test/e2e/configurer/chain/queries_btcstaking.go @@ -94,15 +94,19 @@ func (n *NodeConfig) QueryUnbondedDelegations() []*bstypes.BTCDelegationResponse return resp.BtcDelegations } -func (n *NodeConfig) QueryActivatedHeight() uint64 { +func (n *NodeConfig) QueryActivatedHeight() (uint64, error) { bz, err := n.QueryGRPCGateway("/babylon/btcstaking/v1/activated_height", url.Values{}) - require.NoError(n.t, err) + if err != nil { + return 0, err + } var resp bstypes.QueryActivatedHeightResponse err = util.Cdc.UnmarshalJSON(bz, &resp) - require.NoError(n.t, err) + if err != nil { + return 0, err + } - return resp.Height + return resp.Height, nil } // TODO: pagination support diff --git a/test/e2e/configurer/chain/queries_ibc.go b/test/e2e/configurer/chain/queries_ibc.go index f5889b229..39c5cc3e7 100644 --- a/test/e2e/configurer/chain/queries_ibc.go +++ b/test/e2e/configurer/chain/queries_ibc.go @@ -23,6 +23,21 @@ func (n *NodeConfig) QueryIBCChannels() (*channeltypes.QueryChannelsResponse, er return &resp, nil } +func (n *NodeConfig) QueryChannelClientState(channelID, portID string) (*channeltypes.QueryChannelClientStateResponse, error) { + path := fmt.Sprintf("/ibc/core/channel/v1/channels/%s/ports/%s/client_state", channelID, portID) + bz, err := n.QueryGRPCGateway(path, url.Values{}) + if err != nil { + return nil, err + } + + var resp channeltypes.QueryChannelClientStateResponse + if err := util.Cdc.UnmarshalJSON(bz, &resp); err != nil { + return nil, err + } + + return &resp, nil +} + func (n *NodeConfig) QueryNextSequenceReceive(channelID, portID string) (*channeltypes.QueryNextSequenceReceiveResponse, error) { path := fmt.Sprintf("/ibc/core/channel/v1/channels/%s/ports/%s/next_sequence", channelID, portID) bz, err := n.QueryGRPCGateway(path, url.Values{}) diff --git a/test/e2e/software_upgrade_e2e_signet_launch_test.go b/test/e2e/software_upgrade_e2e_signet_launch_test.go index b750ce5d7..1288d7053 100644 --- a/test/e2e/software_upgrade_e2e_signet_launch_test.go +++ b/test/e2e/software_upgrade_e2e_signet_launch_test.go @@ -1,6 +1,8 @@ package e2e import ( + "sort" + "github.com/stretchr/testify/suite" "github.com/babylonlabs-io/babylon/app" @@ -53,12 +55,14 @@ func (s *SoftwareUpgradeSignetLaunchTestSuite) TestUpgradeSignetLaunch() { govProp, err := s.configurer.ParseGovPropFromFile() s.NoError(err) + bbnApp := app.NewTmpBabylonApp() + // makes sure that the upgrade was actually executed expectedUpgradeHeight := govProp.Plan.Height resp := n.QueryAppliedPlan(v1.Upgrade.UpgradeName) s.EqualValues(expectedUpgradeHeight, resp.Height, "the plan should be applied at the height %d", expectedUpgradeHeight) - btcHeadersInserted, err := v1.LoadBTCHeadersFromData() + btcHeadersInserted, err := v1.LoadBTCHeadersFromData(bbnApp.AppCodec()) s.NoError(err) lenHeadersInserted := len(btcHeadersInserted) @@ -76,4 +80,24 @@ func (s *SoftwareUpgradeSignetLaunchTestSuite) TestUpgradeSignetLaunch() { s.EqualValues(headerInserted.Header.MarshalHex(), headerStoredResp.HeaderHex) } + + oldFPsLen := 0 // it should not have any FP + fpsFromNode := n.QueryFinalityProviders() + + fpsInserted, err := v1.LoadSignedFPsFromData(bbnApp.AppCodec(), bbnApp.TxConfig().TxJSONDecoder()) + s.NoError(err) + s.Equal(len(fpsInserted), len(fpsFromNode)+oldFPsLen) + + // sorts all the FPs from node to match the ones from loaded string json + sort.Slice(fpsFromNode, func(i, j int) bool { + return fpsFromNode[i].Addr > fpsFromNode[j].Addr + }) + + for i, fpInserted := range fpsInserted { + fpFromKeeper := fpsFromNode[i] + s.EqualValues(fpFromKeeper.Addr, fpInserted.Addr) + s.EqualValues(fpFromKeeper.Description, fpInserted.Description) + s.EqualValues(fpFromKeeper.Commission.String(), fpInserted.Commission.String()) + s.EqualValues(fpFromKeeper.Pop.String(), fpInserted.Pop.String()) + } } diff --git a/test/e2e/upgrades/signet-launch.json b/test/e2e/upgrades/signet-launch.json index f1be8ba79..2bd5a9f31 100644 --- a/test/e2e/upgrades/signet-launch.json +++ b/test/e2e/upgrades/signet-launch.json @@ -6,7 +6,7 @@ "plan": { "name": "signet-launch", "time": "0001-01-01T00:00:00Z", - "height": "23", + "height": "21", "info": "Msg info", "upgraded_client_state": null } @@ -17,4 +17,4 @@ "title": "any title", "summary": "any summary", "expedited": false -} \ No newline at end of file +} diff --git a/testutil/datagen/incentive.go b/testutil/datagen/incentive.go index 2cd0e10b6..d379e82ba 100644 --- a/testutil/datagen/incentive.go +++ b/testutil/datagen/incentive.go @@ -4,10 +4,11 @@ import ( "math/rand" sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" itypes "github.com/babylonlabs-io/babylon/x/incentive/types" - sdk "github.com/cosmos/cosmos-sdk/types" ) const ( @@ -105,6 +106,7 @@ func GenRandomFinalityProviderDistInfo(r *rand.Rand) (*bstypes.FinalityProviderD } fpDistInfo.BtcDels = append(fpDistInfo.BtcDels, btcDelDistInfo) fpDistInfo.TotalVotingPower += btcDelDistInfo.VotingPower + fpDistInfo.IsTimestamped = true } return fpDistInfo, nil } diff --git a/testutil/datagen/tendermint.go b/testutil/datagen/tendermint.go index c09368739..8a40fc275 100644 --- a/testutil/datagen/tendermint.go +++ b/testutil/datagen/tendermint.go @@ -21,11 +21,11 @@ func GenRandomTMHeader(r *rand.Rand, chainID string, height uint64) *cmtproto.He } } -func GenRandomIBCTMHeader(r *rand.Rand, chainID string, height uint64) *ibctmtypes.Header { +func GenRandomIBCTMHeader(r *rand.Rand, height uint64) *ibctmtypes.Header { return &ibctmtypes.Header{ SignedHeader: &cmtproto.SignedHeader{ Header: &cmtproto.Header{ - ChainID: chainID, + ChainID: GenRandomHexStr(r, 10), Height: int64(height), AppHash: GenRandomByteArray(r, 32), }, @@ -34,22 +34,20 @@ func GenRandomIBCTMHeader(r *rand.Rand, chainID string, height uint64) *ibctmtyp } func GenRandomTMHeaderInfo(r *rand.Rand, chainID string, height uint64) *header.Info { - tmHeader := GenRandomIBCTMHeader(r, chainID, height) return &header.Info{ - Height: tmHeader.Header.Height, - Hash: tmHeader.Header.DataHash, - Time: tmHeader.Header.Time, - ChainID: tmHeader.Header.ChainID, - AppHash: tmHeader.Header.AppHash, + Height: int64(height), + ChainID: chainID, + AppHash: GenRandomByteArray(r, 32), } } -func HeaderToHeaderInfo(header *ibctmtypes.Header) *zctypes.HeaderInfo { +func NewZCHeaderInfo(header *ibctmtypes.Header, clientID string) *zctypes.HeaderInfo { return &zctypes.HeaderInfo{ - AppHash: header.Header.AppHash, - ChainId: header.Header.ChainID, - Time: header.Header.Time, - Height: uint64(header.Header.Height), + ClientId: clientID, + AppHash: header.Header.AppHash, + ChainId: header.Header.ChainID, + Time: header.Header.Time, + Height: uint64(header.Header.Height), } } diff --git a/testutil/helper/helper.go b/testutil/helper/helper.go index 6ae1de0d9..fc34f024a 100644 --- a/testutil/helper/helper.go +++ b/testutil/helper/helper.go @@ -313,5 +313,12 @@ func (h *Helper) AddDelegation(del *btcstakingtypes.BTCDelegation) { } func (h *Helper) AddFinalityProvider(fp *btcstakingtypes.FinalityProvider) { - h.App.BTCStakingKeeper.SetFinalityProvider(h.Ctx, fp) + err := h.App.BTCStakingKeeper.AddFinalityProvider(h.Ctx, &btcstakingtypes.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: fp.Description, + Commission: fp.Commission, + BtcPk: fp.BtcPk, + Pop: fp.Pop, + }) + h.NoError(err) } diff --git a/testutil/keeper/btcstaking.go b/testutil/keeper/btcstaking.go index fd00fbf7f..a3bcad46a 100644 --- a/testutil/keeper/btcstaking.go +++ b/testutil/keeper/btcstaking.go @@ -27,7 +27,7 @@ func BTCStakingKeeper( t testing.TB, btclcKeeper types.BTCLightClientKeeper, btccKeeper types.BtcCheckpointKeeper, - ckptKeeper types.CheckpointingKeeper, + finalityKeeper types.FinalityKeeper, ) (*keeper.Keeper, sdk.Context) { storeKey := storetypes.NewKVStoreKey(types.StoreKey) @@ -44,7 +44,7 @@ func BTCStakingKeeper( runtime.NewKVStoreService(storeKey), btclcKeeper, btccKeeper, - ckptKeeper, + finalityKeeper, &chaincfg.SimNetParams, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) diff --git a/testutil/keeper/finality.go b/testutil/keeper/finality.go index fc15a866e..1b8a2adee 100644 --- a/testutil/keeper/finality.go +++ b/testutil/keeper/finality.go @@ -22,7 +22,7 @@ import ( "github.com/babylonlabs-io/babylon/x/finality/types" ) -func FinalityKeeper(t testing.TB, bsKeeper types.BTCStakingKeeper, iKeeper types.IncentiveKeeper) (*keeper.Keeper, sdk.Context) { +func FinalityKeeper(t testing.TB, bsKeeper types.BTCStakingKeeper, iKeeper types.IncentiveKeeper, cKeeper types.CheckpointingKeeper) (*keeper.Keeper, sdk.Context) { storeKey := storetypes.NewKVStoreKey(types.StoreKey) db := dbm.NewMemDB() @@ -38,6 +38,7 @@ func FinalityKeeper(t testing.TB, bsKeeper types.BTCStakingKeeper, iKeeper types runtime.NewKVStoreService(storeKey), bsKeeper, iKeeper, + cKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) diff --git a/x/btccheckpoint/types/btcutils.go b/x/btccheckpoint/types/btcutils.go index b03d476ae..f3b969028 100644 --- a/x/btccheckpoint/types/btcutils.go +++ b/x/btccheckpoint/types/btcutils.go @@ -192,6 +192,14 @@ func verify(tx *btcutil.Tx, merkleRoot *chainhash.Hash, intermediateNodes []byte return bytes.Equal(current[:], root) } +func VerifyInclusionProof( + tx *btcutil.Tx, + merkleRoot *chainhash.Hash, + intermediateNodes []byte, + index uint32) bool { + return verify(tx, merkleRoot, intermediateNodes, index) +} + // ExtractStandardOpReturnData extract OP_RETURN data from transaction OP_RETURN // output. // If OP_RETURN output is not standard it will be ignored. If there is more than diff --git a/x/btcstaking/README.md b/x/btcstaking/README.md index b07b297d5..a54c93953 100644 --- a/x/btcstaking/README.md +++ b/x/btcstaking/README.md @@ -72,7 +72,7 @@ follows: unbonding transaction, and unbonding slashing transaction to Babylon. 3. The covenant committee verifies spending conditions of the staking transaction, and submits its signatures on the BTC staker's transactions. At - this point, the finality provider receives bitcoins and thus voting power + this point, the finality provider receives voting power from the BTC delegation. 4. Upon each new block, the BTC Staking module will record the voting power table of finality providers. @@ -297,6 +297,9 @@ voting power table of all finality providers at each height of the Babylon chain. The key is the block height concatenated with the finality provider's Bitcoin secp256k1 public key in BIP-340 format, and the value is the finality provider's voting power quantified in Satoshis. +Voting power is assigned to top `N` (defined in parameters) finality providers +that have BTC-timestamped public randomness for the height, ranked by the total +delegated value. ### Params @@ -406,9 +409,7 @@ Upon `MsgCreateFinalityProvider`, a Babylon node will execute as follows: parameters and at most 100%. 3. Ensure the finality provider does not exist already. 4. Ensure the finality provider is not slashed. -5. Ensure the finality provider is registered at an epoch that has been BTC-timestamped. -6. Ensure the committed master public randomness is in the correct format. -7. Create a `FinalityProvider` object and save it to finality provider storage. +5. Create a `FinalityProvider` object and save it to finality provider storage. ### MsgEditFinalityProvider @@ -703,6 +704,9 @@ Upon `BeginBlock`, the BTC Staking module will execute the following: voting power table at the last height with all events that affect voting power distribution (including newly active BTC delegations, newly unbonded BTC delegations, and slashed finality providers). + Note that the voting power is assigned to a finality provider if it (1) has + BTC-timestamped public randomness, and (2) it is ranked at top `N` by the + total delegated value. 3. If the BTC Staking protocol is activated, i.e., there exists at least 1 active BTC delegation, then record the reward distribution w.r.t. the active finality providers and active BTC delegations. diff --git a/x/btcstaking/genesis_test.go b/x/btcstaking/genesis_test.go index dc034bdf3..2ab7d793c 100644 --- a/x/btcstaking/genesis_test.go +++ b/x/btcstaking/genesis_test.go @@ -3,11 +3,12 @@ package btcstaking_test import ( "testing" + "github.com/stretchr/testify/require" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" "github.com/babylonlabs-io/babylon/testutil/nullify" "github.com/babylonlabs-io/babylon/x/btcstaking" "github.com/babylonlabs-io/babylon/x/btcstaking/types" - "github.com/stretchr/testify/require" ) func TestGenesis(t *testing.T) { diff --git a/x/btcstaking/keeper/bench_test.go b/x/btcstaking/keeper/bench_test.go index 27fe36b65..3a41a8e1c 100644 --- a/x/btcstaking/keeper/bench_test.go +++ b/x/btcstaking/keeper/bench_test.go @@ -8,11 +8,12 @@ import ( "testing" "time" + "github.com/golang/mock/gomock" + "github.com/babylonlabs-io/babylon/testutil/datagen" btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" bsmodule "github.com/babylonlabs-io/babylon/x/btcstaking" "github.com/babylonlabs-io/babylon/x/btcstaking/types" - "github.com/golang/mock/gomock" ) func benchBeginBlock(b *testing.B, numFPs int, numDelsUnderFP int) { @@ -23,8 +24,8 @@ func benchBeginBlock(b *testing.B, numFPs int, numDelsUnderFP int) { defer ctrl.Finish() btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(b, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(b, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) diff --git a/x/btcstaking/keeper/btc_height_index_test.go b/x/btcstaking/keeper/btc_height_index_test.go index a40b5d4d3..a099df268 100644 --- a/x/btcstaking/keeper/btc_height_index_test.go +++ b/x/btcstaking/keeper/btc_height_index_test.go @@ -4,12 +4,13 @@ import ( "math/rand" "testing" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/babylonlabs-io/babylon/testutil/datagen" keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/babylonlabs-io/babylon/x/btcstaking/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) func FuzzBTCHeightIndex(f *testing.F) { diff --git a/x/btcstaking/keeper/finality_providers.go b/x/btcstaking/keeper/finality_providers.go index f590ffc94..24a158c71 100644 --- a/x/btcstaking/keeper/finality_providers.go +++ b/x/btcstaking/keeper/finality_providers.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + sdkmath "cosmossdk.io/math" "cosmossdk.io/store/prefix" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" @@ -11,8 +12,42 @@ import ( "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) -// SetFinalityProvider adds the given finality provider to KVStore -func (k Keeper) SetFinalityProvider(ctx context.Context, fp *types.FinalityProvider) { +// AddFinalityProvider adds the given finality provider to KVStore if it has valid +// commission and it was not inserted before +func (k Keeper) AddFinalityProvider(goCtx context.Context, msg *types.MsgCreateFinalityProvider) error { + ctx := sdk.UnwrapSDKContext(goCtx) + params := k.GetParams(ctx) + // ensure commission rate is + // - at least the minimum commission rate in parameters, and + // - at most 1 + if msg.Commission.LT(params.MinCommissionRate) { + return types.ErrCommissionLTMinRate.Wrapf("cannot set finality provider commission to less than minimum rate of %s", params.MinCommissionRate.String()) + } + if msg.Commission.GT(sdkmath.LegacyOneDec()) { + return types.ErrCommissionGTMaxRate + } + + // ensure finality provider does not already exist + if k.HasFinalityProvider(ctx, *msg.BtcPk) { + return types.ErrFpRegistered + } + + // all good, add this finality provider + fp := types.FinalityProvider{ + Description: msg.Description, + Commission: msg.Commission, + Addr: msg.Addr, + BtcPk: msg.BtcPk, + Pop: msg.Pop, + } + k.setFinalityProvider(ctx, &fp) + + // notify subscriber + return ctx.EventManager().EmitTypedEvent(&types.EventNewFinalityProvider{Fp: &fp}) +} + +// setFinalityProvider adds the given finality provider to KVStore +func (k Keeper) setFinalityProvider(ctx context.Context, fp *types.FinalityProvider) { store := k.finalityProviderStore(ctx) fpBytes := k.cdc.MustMarshal(fp) store.Set(fp.BtcPk.MustMarshal(), fpBytes) @@ -57,7 +92,7 @@ func (k Keeper) SlashFinalityProvider(ctx context.Context, fpBTCPK []byte) error return fmt.Errorf("failed to get current BTC tip") } fp.SlashedBtcHeight = btcTip.Height - k.SetFinalityProvider(ctx, fp) + k.setFinalityProvider(ctx, fp) // record slashed event. The next `BeginBlock` will consume this // event for updating the finality provider set @@ -83,7 +118,7 @@ func (k Keeper) RevertSluggishFinalityProvider(ctx context.Context, fpBTCPK []by } fp.Sluggish = false - k.SetFinalityProvider(ctx, fp) + k.setFinalityProvider(ctx, fp) return nil } diff --git a/x/btcstaking/keeper/genesis.go b/x/btcstaking/keeper/genesis.go index 1e4a59a58..dc787b62a 100644 --- a/x/btcstaking/keeper/genesis.go +++ b/x/btcstaking/keeper/genesis.go @@ -21,7 +21,7 @@ func (k Keeper) InitGenesis(ctx context.Context, gs types.GenesisState) error { } for _, fp := range gs.FinalityProviders { - k.SetFinalityProvider(ctx, fp) + k.setFinalityProvider(ctx, fp) } for _, btcDel := range gs.BtcDelegations { diff --git a/x/btcstaking/keeper/grpc_query_test.go b/x/btcstaking/keeper/grpc_query_test.go index af2b03d47..4b841edc2 100644 --- a/x/btcstaking/keeper/grpc_query_test.go +++ b/x/btcstaking/keeper/grpc_query_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "context" "errors" "math/rand" "testing" @@ -17,6 +18,7 @@ import ( bbn "github.com/babylonlabs-io/babylon/types" btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + btcstakingkeeper "github.com/babylonlabs-io/babylon/x/btcstaking/keeper" "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) @@ -60,7 +62,7 @@ func FuzzFinalityProviders(f *testing.F) { fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) - keeper.SetFinalityProvider(ctx, fp) + AddFinalityProvider(t, ctx, *keeper, fp) fpsMap[fp.BtcPk.MarshalHex()] = fp } numOfFpsInStore := len(fpsMap) @@ -125,7 +127,7 @@ func FuzzFinalityProvider(f *testing.F) { fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) - keeper.SetFinalityProvider(ctx, fp) + AddFinalityProvider(t, ctx, *keeper, fp) fpsMap[fp.BtcPk.MarshalHex()] = fp } @@ -172,8 +174,7 @@ func FuzzPendingBTCDelegations(f *testing.F) { btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) + keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, nil) // covenant and slashing addr covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) @@ -194,7 +195,7 @@ func FuzzPendingBTCDelegations(f *testing.F) { for i := uint64(0); i < numFps; i++ { fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) - keeper.SetFinalityProvider(ctx, fp) + AddFinalityProvider(t, ctx, *keeper, fp) fps = append(fps, fp) } @@ -281,7 +282,7 @@ func FuzzFinalityProviderPowerAtHeight(f *testing.F) { fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) // add this finality provider - keeper.SetFinalityProvider(ctx, fp) + AddFinalityProvider(t, ctx, *keeper, fp) // set random voting power at random height randomHeight := datagen.RandomInt(r, 100) + 1 randomPower := datagen.RandomInt(r, 100) + 1 @@ -330,7 +331,7 @@ func FuzzFinalityProviderCurrentVotingPower(f *testing.F) { fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) // add this finality provider - keeper.SetFinalityProvider(ctx, fp) + AddFinalityProvider(t, ctx, *keeper, fp) // set random voting power at random height randomHeight := datagen.RandomInt(r, 100) + 1 ctx = datagen.WithCtxHeight(ctx, randomHeight) @@ -376,8 +377,7 @@ func FuzzActiveFinalityProvidersAtHeight(f *testing.F) { btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 10}).AnyTimes() btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) + keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, nil) // covenant and slashing addr covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) @@ -400,7 +400,7 @@ func FuzzActiveFinalityProvidersAtHeight(f *testing.F) { for i := uint64(0); i < numFps; i++ { fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) - keeper.SetFinalityProvider(ctx, fp) + AddFinalityProvider(t, ctx, *keeper, fp) fps = append(fps, fp) } @@ -496,8 +496,7 @@ func FuzzFinalityProviderDelegations(f *testing.F) { btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) + keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, nil) // covenant and slashing addr covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) @@ -515,7 +514,7 @@ func FuzzFinalityProviderDelegations(f *testing.F) { // Generate a finality provider fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) - keeper.SetFinalityProvider(ctx, fp) + AddFinalityProvider(t, ctx, *keeper, fp) startHeight := datagen.RandomInt(r, 100) + 1 endHeight := datagen.RandomInt(r, 1000) + startHeight + btcctypes.DefaultParams().CheckpointFinalizationTimeout + 1 @@ -617,3 +616,14 @@ func constructRequestWithKeyAndLimit(r *rand.Rand, key []byte, limit uint64) *qu func constructRequestWithLimit(r *rand.Rand, limit uint64) *query.PageRequest { return constructRequestWithKeyAndLimit(r, nil, limit) } + +func AddFinalityProvider(t *testing.T, goCtx context.Context, k btcstakingkeeper.Keeper, fp *types.FinalityProvider) { + err := k.AddFinalityProvider(goCtx, &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: fp.Description, + Commission: fp.Commission, + BtcPk: fp.BtcPk, + Pop: fp.Pop, + }) + require.NoError(t, err) +} diff --git a/x/btcstaking/keeper/hooks.go b/x/btcstaking/keeper/hooks.go index c7283e95a..d17f71f5c 100644 --- a/x/btcstaking/keeper/hooks.go +++ b/x/btcstaking/keeper/hooks.go @@ -33,7 +33,7 @@ func (h Hooks) AfterSluggishFinalityProviderDetected(ctx context.Context, fpPk * fp.Sluggish = true - h.k.SetFinalityProvider(ctx, fp) + h.k.setFinalityProvider(ctx, fp) return nil } diff --git a/x/btcstaking/keeper/incentive_test.go b/x/btcstaking/keeper/incentive_test.go index ea7d699d5..3ebfa9aff 100644 --- a/x/btcstaking/keeper/incentive_test.go +++ b/x/btcstaking/keeper/incentive_test.go @@ -23,8 +23,9 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + finalityKeeper.EXPECT().HasTimestampedPubRand(gomock.Any(), gomock.Any(), gomock.Any()).Return(true).AnyTimes() + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -43,7 +44,8 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) { } } - // for the first numFpsWithVotingPower finality providers, generate a random number of BTC delegations and add covenant signatures to activate them + // for the first numFpsWithVotingPower finality providers, generate a random number of BTC + // delegations and add covenant signatures to activate them numBTCDels := datagen.RandomInt(r, 10) + 1 stakingValue := datagen.RandomInt(r, 100000) + 100000 for _, fp := range fpsWithVotingPowerMap { @@ -71,8 +73,7 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) { require.NoError(t, err) require.NotNil(t, dc) require.Equal(t, dc.TotalVotingPower, numFpsWithVotingPower*numBTCDels*stakingValue) - maxNumFps := h.BTCStakingKeeper.GetParams(h.Ctx).MaxActiveFinalityProviders - activeFPs := dc.GetActiveFinalityProviderSet(maxNumFps) + activeFPs := dc.GetActiveFinalityProviderSet() for _, fpDistInfo := range activeFPs { require.Equal(t, fpDistInfo.TotalVotingPower, numBTCDels*stakingValue) fp, ok := fpsWithVotingPowerMap[fpDistInfo.Addr] diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index 5a992423a..e1d38689d 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -19,9 +19,9 @@ type ( cdc codec.BinaryCodec storeService corestoretypes.KVStoreService - btclcKeeper types.BTCLightClientKeeper - btccKeeper types.BtcCheckpointKeeper - ckptKeeper types.CheckpointingKeeper + btclcKeeper types.BTCLightClientKeeper + btccKeeper types.BtcCheckpointKeeper + FinalityKeeper types.FinalityKeeper hooks types.BtcStakingHooks @@ -38,7 +38,7 @@ func NewKeeper( btclcKeeper types.BTCLightClientKeeper, btccKeeper types.BtcCheckpointKeeper, - ckptKeeper types.CheckpointingKeeper, + finalityKeeper types.FinalityKeeper, btcNet *chaincfg.Params, authority string, @@ -47,9 +47,9 @@ func NewKeeper( cdc: cdc, storeService: storeService, - btclcKeeper: btclcKeeper, - btccKeeper: btccKeeper, - ckptKeeper: ckptKeeper, + btclcKeeper: btclcKeeper, + btccKeeper: btccKeeper, + FinalityKeeper: finalityKeeper, hooks: nil, @@ -86,7 +86,3 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { return nil } - -func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { - return k.ckptKeeper.GetLastFinalizedEpoch(ctx) -} diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index 1ce64721e..ef00fc59c 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -33,14 +33,19 @@ type Helper struct { BTCStakingKeeper *keeper.Keeper BTCLightClientKeeper *types.MockBTCLightClientKeeper BTCCheckpointKeeper *types.MockBtcCheckpointKeeper - CheckpointingKeeper *types.MockCheckpointingKeeper + FinalityKeeper *types.MockFinalityKeeper BTCStakingHooks *types.MockBtcStakingHooks MsgServer types.MsgServer Net *chaincfg.Params } -func NewHelper(t testing.TB, btclcKeeper *types.MockBTCLightClientKeeper, btccKeeper *types.MockBtcCheckpointKeeper, ckptKeeper *types.MockCheckpointingKeeper) *Helper { - k, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) +func NewHelper( + t testing.TB, + btclcKeeper *types.MockBTCLightClientKeeper, + btccKeeper *types.MockBtcCheckpointKeeper, + finalityKeeper *types.MockFinalityKeeper, +) *Helper { + k, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, btccKeeper, finalityKeeper) ctx = ctx.WithHeaderInfo(header.Info{Height: 1}) msgSrvr := keeper.NewMsgServerImpl(*k) @@ -55,7 +60,6 @@ func NewHelper(t testing.TB, btclcKeeper *types.MockBTCLightClientKeeper, btccKe BTCStakingKeeper: k, BTCLightClientKeeper: btclcKeeper, BTCCheckpointKeeper: btccKeeper, - CheckpointingKeeper: ckptKeeper, MsgServer: msgSrvr, Net: &chaincfg.SimNetParams, } @@ -86,9 +90,6 @@ func (h *Helper) GenAndApplyCustomParams( baseHeader := btclctypes.SimnetGenesisBlock() h.BTCLightClientKeeper.EXPECT().GetBaseBTCHeader(gomock.Any()).Return(&baseHeader).AnyTimes() - // mocking stuff for BTC checkpoint keeper - h.BTCCheckpointKeeper.EXPECT().GetPowLimit().Return(h.Net.PowLimit).AnyTimes() - params := btcctypes.DefaultParams() params.CheckpointFinalizationTimeout = finalizationTimeout @@ -281,8 +282,8 @@ func (h *Helper) CreateDelegation( bcParams := h.BTCCheckpointKeeper.GetParams(h.Ctx) minUnbondingTime := types.MinimumUnbondingTime( - bsParams, - bcParams, + &bsParams, + &bcParams, ) stakingTxHash, delSK, delPK, msgCreateBTCDel, err := h.CreateDelegationCustom( diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index a1617d9ed..b94ff8bd9 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -6,19 +6,21 @@ import ( "strings" "time" + btcckpttypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" - "github.com/babylonlabs-io/babylon/btcstaking" - bbn "github.com/babylonlabs-io/babylon/types" - "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" - "github.com/btcsuite/btcd/wire" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + + "github.com/babylonlabs-io/babylon/btcstaking" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) type msgServer struct { @@ -71,36 +73,9 @@ func (ms msgServer) CreateFinalityProvider(goCtx context.Context, req *types.Msg return nil, status.Errorf(codes.InvalidArgument, "invalid proof of possession: %v", err) } - // ensure commission rate is - // - at least the minimum commission rate in parameters, and - // - at most 1 - if req.Commission.LT(ms.MinCommissionRate(ctx)) { - return nil, types.ErrCommissionLTMinRate.Wrapf("cannot set finality provider commission to less than minimum rate of %s", ms.MinCommissionRate(ctx)) - } - if req.Commission.GT(sdkmath.LegacyOneDec()) { - return nil, types.ErrCommissionGTMaxRate - } - - // ensure finality provider does not already exist - if ms.HasFinalityProvider(ctx, *req.BtcPk) { - return nil, types.ErrFpRegistered - } - - // all good, add this finality provider - fp := types.FinalityProvider{ - Description: req.Description, - Commission: req.Commission, - Addr: fpAddr.String(), - BtcPk: req.BtcPk, - Pop: req.Pop, - } - ms.SetFinalityProvider(ctx, &fp) - - // notify subscriber - if err := ctx.EventManager().EmitTypedEvent(&types.EventNewFinalityProvider{Fp: &fp}); err != nil { + if err := ms.AddFinalityProvider(ctx, req); err != nil { return nil, err } - return &types.MsgCreateFinalityProviderResponse{}, nil } @@ -142,67 +117,40 @@ func (ms msgServer) EditFinalityProvider(ctx context.Context, req *types.MsgEdit // all good, update the finality provider and set back fp.Description = req.Description fp.Commission = req.Commission - ms.SetFinalityProvider(ctx, fp) + ms.setFinalityProvider(ctx, fp) return &types.MsgEditFinalityProviderResponse{}, nil } -// caluculateMinimumUnbondingValue calculates minimum unbonding value basend on current staking output value -// and params.MinUnbondingRate -func caluculateMinimumUnbondingValue( - stakingOutput *wire.TxOut, - params *types.Params, -) btcutil.Amount { - // this conversions must always succeed, as it is part of our params - minUnbondingRate := params.MinUnbondingRate.MustFloat64() - // Caluclate min unbonding output value based on staking output, use btc native multiplication - minUnbondingOutputValue := btcutil.Amount(stakingOutput.Value).MulF64(minUnbondingRate) - return minUnbondingOutputValue -} - // CreateBTCDelegation creates a BTC delegation -// TODO: refactor this handler. It's now too convoluted func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCreateBTCDelegation) (*types.MsgCreateBTCDelegationResponse, error) { defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeyCreateBTCDelegation) ctx := sdk.UnwrapSDKContext(goCtx) - // basic stateless checks - if err := req.ValidateBasic(); err != nil { - return nil, status.Errorf(codes.InvalidArgument, "%v", err) - } - vp := ms.GetParamsWithVersion(ctx) - btccParams := ms.btccKeeper.GetParams(ctx) - kValue, wValue := btccParams.BtcConfirmationDepth, btccParams.CheckpointFinalizationTimeout + // 1. Parse the message into better domain format + parsedMsg, err := types.ParseCreateDelegationMessage(req) - minUnbondingTime := types.MinimumUnbondingTime(vp.Params, btccParams) - - // Check unbonding time (staking time from unbonding tx) is larger than min unbonding time - // which is larger value from: - // - MinUnbondingTime - // - CheckpointFinalizationTimeout - if uint64(req.UnbondingTime) <= minUnbondingTime { - return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding time %d must be larger than %d", req.UnbondingTime, minUnbondingTime) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "%v", err) } - // At this point we know that unbonding time in request: - // - is larger than min unbonding time - // - is smaller than math.MaxUint16 (due to check in req.ValidateBasic()) - validatedUnbondingTime := uint16(req.UnbondingTime) - - stakerAddr, err := sdk.AccAddressFromBech32(req.StakerAddr) - if err != nil { - return nil, types.ErrInvalidStakingTx.Wrapf("invalid staker addr %s: %v", req.StakerAddr, err) + // 2. Basic stateless checks + // - verify proof of possession + if err := parsedMsg.ParsedPop.Verify(parsedMsg.StakerAddress, parsedMsg.StakerPK.BIP340PubKey, ms.btcNet); err != nil { + return nil, types.ErrInvalidProofOfPossession.Wrap(err.Error()) } - // verify proof of possession - if err := req.Pop.Verify(stakerAddr, req.BtcPk, ms.btcNet); err != nil { - return nil, types.ErrInvalidProofOfPossession.Wrapf("error while validating proof of posession: %v", err) + // 3. Check if it is not duplicated staking tx + stakingTxHash := parsedMsg.StakingTx.Transaction.TxHash() + delgation := ms.getBTCDelegation(ctx, stakingTxHash) + if delgation != nil { + return nil, types.ErrReusedStakingTx.Wrapf("duplicated tx hash: %s", stakingTxHash.String()) } - // Ensure all finality providers are known to Babylon, are not slashed, - // and their registered epochs are finalised - for _, fpBTCPK := range req.FpBtcPkList { + // 4. Check finality providers to which message delegate + // Ensure all finality providers are known to Babylon, are not slashed + for _, fpBTCPK := range parsedMsg.FinalityProviderKeys.PublicKeysBbnFormat { // get this finality provider fp, err := ms.GetFinalityProvider(ctx, fpBTCPK) if err != nil { @@ -210,246 +158,86 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre } // ensure the finality provider is not slashed if fp.IsSlashed() { - return nil, types.ErrFpAlreadySlashed + return nil, types.ErrFpAlreadySlashed.Wrapf("finality key: %s", fpBTCPK.MarshalHex()) } } - // Parse staking tx - stakingMsgTx, err := bbn.NewBTCTxFromBytes(req.StakingTx.Transaction) - if err != nil { - return nil, types.ErrInvalidStakingTx.Wrapf("cannot be parsed: %v", err) - } + // 5. Validate parsed message against parameters + vp := ms.GetParamsWithVersion(ctx) - // Check staking tx is not duplicated - stakingTxHash := stakingMsgTx.TxHash() - delgation := ms.getBTCDelegation(ctx, stakingTxHash) - if delgation != nil { - return nil, types.ErrReusedStakingTx.Wrapf("duplicated tx hash: %s", stakingTxHash.String()) - } + btccParams := ms.btccKeeper.GetParams(ctx) - // Check if data provided in request, matches data to which staking tx is committed - fpPKs, err := bbn.NewBTCPKsFromBIP340PKs(req.FpBtcPkList) - if err != nil { - return nil, types.ErrInvalidStakingTx.Wrapf("cannot parse finality provider PK list: %v", err) - } - covenantPKs, err := bbn.NewBTCPKsFromBIP340PKs(vp.Params.CovenantPks) - if err != nil { - // programming error - panic("failed to parse covenant PKs in KVStore") - } - stakerPk := req.BtcPk.MustToBTCPK() - - stakingInfo, err := btcstaking.BuildStakingInfo( - stakerPk, - fpPKs, - covenantPKs, - vp.Params.CovenantQuorum, - uint16(req.StakingTime), - btcutil.Amount(req.StakingValue), - ms.btcNet, - ) - if err != nil { - return nil, types.ErrInvalidStakingTx.Wrapf("err: %v", err) - } + paramsValidationResult, err := types.ValidateParams(parsedMsg, &vp.Params, &btccParams, ms.btcNet) - stakingOutputIdx, err := bbn.GetOutputIdxInBTCTx(stakingMsgTx, stakingInfo.StakingOutput) if err != nil { - return nil, types.ErrInvalidStakingTx.Wrap("staking tx does not contain expected staking output") + return nil, err } - // Check staking tx timelock has correct values - // get startheight and endheight of the timelock - stakingTxHeader := ms.btclcKeeper.GetHeaderByHash(ctx, req.StakingTx.Key.Hash) + // 6. Check: + // - timelock of staking tx + // - staking tx is k-deep + // - staking tx inclusion proof + stakingTxHeader := ms.btclcKeeper.GetHeaderByHash(ctx, parsedMsg.StakingTxProofOfInclusion.HeaderHash) + if stakingTxHeader == nil { return nil, fmt.Errorf("header that includes the staking tx is not found") } - startHeight := stakingTxHeader.Height - endHeight := stakingTxHeader.Height + uint64(req.StakingTime) - // ensure staking tx is k-deep - btcTip := ms.btclcKeeper.GetTipInfo(ctx) - stakingTxDepth := btcTip.Height - stakingTxHeader.Height - if stakingTxDepth < kValue { - return nil, types.ErrInvalidStakingTx.Wrapf("not k-deep: k=%d; depth=%d", kValue, stakingTxDepth) - } - // ensure staking tx's timelock has more than w BTC blocks left - if btcTip.Height+wValue >= endHeight { - return nil, types.ErrInvalidStakingTx.Wrapf("staking tx's timelock has no more than w(=%d) blocks left", wValue) - } + // no need to do more validations to the btc header as it was already + // validated by the btclightclient module + btcHeader := stakingTxHeader.Header.ToBlockHeader() - // verify staking tx info, i.e., inclusion proof - if err := req.StakingTx.VerifyInclusion(stakingTxHeader.Header, ms.btccKeeper.GetPowLimit()); err != nil { - return nil, types.ErrInvalidStakingTx.Wrapf("not included in the Bitcoin chain: %v", err) - } + proofValid := btcckpttypes.VerifyInclusionProof( + btcutil.NewTx(parsedMsg.StakingTx.Transaction), + &btcHeader.MerkleRoot, + parsedMsg.StakingTxProofOfInclusion.Proof, + parsedMsg.StakingTxProofOfInclusion.Index, + ) - // check slashing tx and its consistency with staking tx - slashingMsgTx, err := req.SlashingTx.ToMsgTx() - if err != nil { - return nil, types.ErrInvalidSlashingTx.Wrapf("cannot be converted to wire.MsgTx: %v", err) + if !proofValid { + return nil, types.ErrInvalidStakingTx.Wrapf("not included in the Bitcoin chain") } - // decode slashing address - // TODO: Decode slashing address only once, as it is the same for all BTC delegations - slashingAddr, err := btcutil.DecodeAddress(vp.Params.SlashingAddress, ms.btcNet) - if err != nil { - panic(fmt.Errorf("failed to decode slashing address in genesis: %w", err)) - } - - // Check slashing tx and staking tx are valid and consistent - if err := btcstaking.CheckTransactions( - slashingMsgTx, - stakingMsgTx, - stakingOutputIdx, - vp.Params.MinSlashingTxFeeSat, - vp.Params.SlashingRate, - slashingAddr, - stakerPk, - validatedUnbondingTime, - ms.btcNet, - ); err != nil { - return nil, types.ErrInvalidStakingTx.Wrap(err.Error()) - } + startHeight := stakingTxHeader.Height - // verify delegator sig against slashing path of the staking tx's script - slashingSpendInfo, err := stakingInfo.SlashingPathSpendInfo() - if err != nil { - panic(fmt.Errorf("failed to construct slashing path from the staking tx: %w", err)) - } + endHeight := stakingTxHeader.Height + uint64(parsedMsg.StakingTime) - err = req.SlashingTx.VerifySignature( - stakingInfo.StakingOutput, - slashingSpendInfo.GetPkScriptPath(), - stakerPk, - req.DelegatorSlashingSig, - ) - if err != nil { - return nil, types.ErrInvalidSlashingTx.Wrapf("invalid delegator signature: %v", err) + btcTip := ms.btclcKeeper.GetTipInfo(ctx) + stakingTxDepth := btcTip.Height - stakingTxHeader.Height + if stakingTxDepth < btccParams.BtcConfirmationDepth { + return nil, types.ErrInvalidStakingTx.Wrapf("not k-deep: k=%d; depth=%d", btccParams.BtcConfirmationDepth, stakingTxDepth) + } + // ensure staking tx's timelock has more than w BTC blocks left + if btcTip.Height+btccParams.CheckpointFinalizationTimeout >= endHeight { + return nil, types.ErrInvalidStakingTx.Wrapf("staking tx's timelock has no more than w(=%d) blocks left", btccParams.CheckpointFinalizationTimeout) } - // all good, construct BTCDelegation and insert BTC delegation + // 7.all good, construct BTCDelegation and insert BTC delegation // NOTE: the BTC delegation does not have voting power yet. It will - // have voting power only when 1) its corresponding staking tx is k-deep, - // and 2) it receives a covenant signature + // have voting power only when it receives a covenant signatures newBTCDel := &types.BTCDelegation{ - StakerAddr: stakerAddr.String(), - BtcPk: req.BtcPk, - Pop: req.Pop, - FpBtcPkList: req.FpBtcPkList, + StakerAddr: parsedMsg.StakerAddress.String(), + BtcPk: parsedMsg.StakerPK.BIP340PubKey, + Pop: parsedMsg.ParsedPop, + FpBtcPkList: parsedMsg.FinalityProviderKeys.PublicKeysBbnFormat, StartHeight: startHeight, EndHeight: endHeight, - TotalSat: uint64(stakingInfo.StakingOutput.Value), - StakingTx: req.StakingTx.Transaction, - StakingOutputIdx: stakingOutputIdx, - SlashingTx: req.SlashingTx, - DelegatorSig: req.DelegatorSlashingSig, - UnbondingTime: uint32(validatedUnbondingTime), - CovenantSigs: nil, // NOTE: covenant signature will be submitted in a separate msg by covenant - BtcUndelegation: nil, // this will be constructed in below code - ParamsVersion: vp.Version, // version of the params against delegations was validated - } - - /* - logics about early unbonding - */ - - // deserialize provided transactions - unbondingSlashingMsgTx, err := req.UnbondingSlashingTx.ToMsgTx() - if err != nil { - return nil, types.ErrInvalidSlashingTx.Wrapf("cannot convert unbonding slashing tx to wire.MsgTx: %v", err) - } - unbondingMsgTx, err := bbn.NewBTCTxFromBytes(req.UnbondingTx) - if err != nil { - return nil, types.ErrInvalidUnbondingTx.Wrapf("cannot be converted to wire.MsgTx: %v", err) - } - - // Check that unbonding tx input is pointing to staking tx - if !unbondingMsgTx.TxIn[0].PreviousOutPoint.Hash.IsEqual(&stakingTxHash) { - return nil, types.ErrInvalidUnbondingTx.Wrapf("slashing transaction must spend staking output") - } - // Check that staking tx output index matches unbonding tx output index - if unbondingMsgTx.TxIn[0].PreviousOutPoint.Index != stakingOutputIdx { - return nil, types.ErrInvalidUnbondingTx.Wrapf("slashing transaction input must spend staking output") - } - - // building unbonding info - unbondingInfo, err := btcstaking.BuildUnbondingInfo( - newBTCDel.BtcPk.MustToBTCPK(), - fpPKs, - covenantPKs, - vp.Params.CovenantQuorum, - validatedUnbondingTime, - btcutil.Amount(req.UnbondingValue), - ms.btcNet, - ) - if err != nil { - return nil, types.ErrInvalidUnbondingTx.Wrapf("err: %v", err) - } - - // get unbonding output index - unbondingOutputIdx, err := bbn.GetOutputIdxInBTCTx(unbondingMsgTx, unbondingInfo.UnbondingOutput) - if err != nil { - return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding tx does not contain expected unbonding output") - } - - // Check that slashing tx and unbonding tx are valid and consistent - err = btcstaking.CheckTransactions( - unbondingSlashingMsgTx, - unbondingMsgTx, - unbondingOutputIdx, - vp.Params.MinSlashingTxFeeSat, - vp.Params.SlashingRate, - vp.Params.MustGetSlashingAddress(ms.btcNet), - stakerPk, - validatedUnbondingTime, - ms.btcNet, - ) - if err != nil { - return nil, types.ErrInvalidUnbondingTx.Wrapf("err: %v", err) - } - - // Check staker signature against slashing path of the unbonding tx - unbondingSlashingSpendInfo, err := unbondingInfo.SlashingPathSpendInfo() - if err != nil { - // our staking info was constructed by using BuildStakingInfo constructor, so if - // this fails, it is a programming error - panic(err) - } - - err = req.UnbondingSlashingTx.VerifySignature( - unbondingInfo.UnbondingOutput, - unbondingSlashingSpendInfo.GetPkScriptPath(), - newBTCDel.BtcPk.MustToBTCPK(), - req.DelegatorUnbondingSlashingSig, - ) - if err != nil { - return nil, types.ErrInvalidSlashingTx.Wrapf("invalid delegator signature: %v", err) - } - - // Check unbonding tx fees against staking tx. - // - fee is larger than 0 - // - ubonding output value is is at leat `MinUnbondingValue` percent of staking output value - if unbondingMsgTx.TxOut[0].Value >= stakingMsgTx.TxOut[newBTCDel.StakingOutputIdx].Value { - // Note: we do not enfore any minimum fee for unbonding tx, we only require that it is larger than 0 - // Given that unbonding tx must not be replacable and we do not allow sending it second time, it places - // burden on staker to choose right fee. - // Unbonding tx should not be replaceable at babylon level (and by extension on btc level), as this would - // allow staker to spam the network with unbonding txs, which would force covenant and finality provider to send signatures. - return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding tx fee must be larger that 0") - } - - minUnbondingValue := caluculateMinimumUnbondingValue(stakingMsgTx.TxOut[stakingOutputIdx], &vp.Params) - if btcutil.Amount(unbondingMsgTx.TxOut[0].Value) < minUnbondingValue { - return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding output value must be at least %s, based on staking output", minUnbondingValue) - } - - // all good, add BTC undelegation - newBTCDel.BtcUndelegation = &types.BTCUndelegation{ - UnbondingTx: req.UnbondingTx, - SlashingTx: req.UnbondingSlashingTx, - DelegatorSlashingSig: req.DelegatorUnbondingSlashingSig, - DelegatorUnbondingSig: nil, - CovenantSlashingSigs: nil, - CovenantUnbondingSigList: nil, + TotalSat: uint64(parsedMsg.StakingValue), + StakingTx: parsedMsg.StakingTx.TransactionBytes, + StakingOutputIdx: paramsValidationResult.StakingOutputIdx, + SlashingTx: types.NewBtcSlashingTxFromBytes(parsedMsg.StakingSlashingTx.TransactionBytes), + DelegatorSig: parsedMsg.StakerStakingSlashingTxSig.BIP340Signature, + UnbondingTime: uint32(parsedMsg.UnbondingTime), + CovenantSigs: nil, // NOTE: covenant signature will be submitted in a separate msg by covenant + BtcUndelegation: &types.BTCUndelegation{ + UnbondingTx: parsedMsg.UnbondingTx.TransactionBytes, + SlashingTx: types.NewBtcSlashingTxFromBytes(parsedMsg.UnbondingSlashingTx.TransactionBytes), + DelegatorSlashingSig: parsedMsg.StakerUnbondingSlashingSig.BIP340Signature, + DelegatorUnbondingSig: nil, + CovenantSlashingSigs: nil, // NOTE: covenant signature will be submitted in a separate msg by covenant + CovenantUnbondingSigList: nil, // NOTE: covenant signature will be submitted in a separate msg by covenant + }, + ParamsVersion: vp.Version, // version of the params against delegations was validated } // add this BTC delegation, and emit corresponding events diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index 24d2b2cec..ec2e537a5 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -37,8 +37,8 @@ func FuzzMsgCreateFinalityProvider(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters h.GenAndApplyParams(r) @@ -144,8 +144,8 @@ func FuzzCreateBTCDelegation(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters h.GenAndApplyParams(r) @@ -189,8 +189,8 @@ func TestProperVersionInDelegation(t *testing.T) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters h.GenAndApplyParams(r) @@ -257,8 +257,8 @@ func FuzzAddCovenantSigs(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -322,8 +322,8 @@ func FuzzBTCUndelegate(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -395,8 +395,8 @@ func FuzzSelectiveSlashing(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -462,8 +462,8 @@ func FuzzSelectiveSlashing_StakingTx(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -539,8 +539,8 @@ func TestDoNotAllowDelegationWithoutFinalityProvider(t *testing.T) { btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set covenant PK to params _, covenantPKs := h.GenAndApplyParams(r) @@ -548,8 +548,8 @@ func TestDoNotAllowDelegationWithoutFinalityProvider(t *testing.T) { bcParams := h.BTCCheckpointKeeper.GetParams(h.Ctx) minUnbondingTime := types.MinimumUnbondingTime( - bsParams, - bcParams, + &bsParams, + &bcParams, ) slashingChangeLockTime := uint16(minUnbondingTime) + 1 @@ -707,8 +707,8 @@ func TestCorrectUnbondingTimeInDelegation(t *testing.T) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters _, _ = h.GenAndApplyCustomParams(r, tt.finalizationTimeout, tt.minUnbondingTime) @@ -780,8 +780,8 @@ func TestMinimalUnbondingRate(t *testing.T) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters, by default minimal unbonding value is 80% of staking value _, _ = h.GenAndApplyParams(r) diff --git a/x/btcstaking/keeper/params_test.go b/x/btcstaking/keeper/params_test.go index 58f8500f4..fcd589bd0 100644 --- a/x/btcstaking/keeper/params_test.go +++ b/x/btcstaking/keeper/params_test.go @@ -5,10 +5,11 @@ import ( "math/rand" "testing" + "github.com/stretchr/testify/require" + "github.com/babylonlabs-io/babylon/testutil/datagen" testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" "github.com/babylonlabs-io/babylon/x/btcstaking/types" - "github.com/stretchr/testify/require" ) func TestGetParams(t *testing.T) { diff --git a/x/btcstaking/keeper/power_dist_change.go b/x/btcstaking/keeper/power_dist_change.go index bde774ce7..d924dd5e4 100644 --- a/x/btcstaking/keeper/power_dist_change.go +++ b/x/btcstaking/keeper/power_dist_change.go @@ -35,8 +35,23 @@ func (k Keeper) UpdatePowerDist(ctx context.Context) { if len(events) == 0 { if dc != nil { // map everything in prev height to this height - k.recordVotingPowerAndCache(ctx, dc, maxActiveFps) + // NOTE: deep copy the previous dist cache because the + // cache for the new height shares the same distribution + // info due to no new events but timestamping status + // might be changed in the new dist cache after calling + // k.recordVotingPowerAndCache() + newDc := types.NewVotingPowerDistCache() + newDc.TotalVotingPower = dc.TotalVotingPower + newDc.NumActiveFps = dc.NumActiveFps + newFps := make([]*types.FinalityProviderDistInfo, len(dc.FinalityProviders)) + for i, prevFp := range dc.FinalityProviders { + newFp := *prevFp + newFps[i] = &newFp + } + newDc.FinalityProviders = newFps + k.recordVotingPowerAndCache(ctx, dc, newDc, maxActiveFps) } + return } @@ -56,37 +71,61 @@ func (k Keeper) UpdatePowerDist(ctx context.Context) { // to construct the new distribution newDc := k.ProcessAllPowerDistUpdateEvents(ctx, dc, events, maxActiveFps) - // find newly bonded finality providers and execute the hooks - newBondedFinalityProviders := newDc.FindNewActiveFinalityProviders(dc, maxActiveFps) - for _, fp := range newBondedFinalityProviders { - if err := k.hooks.AfterFinalityProviderActivated(ctx, fp.BtcPk); err != nil { - panic(fmt.Errorf("failed to execute after finality provider %s bonded", fp.BtcPk.MarshalHex())) - } - } - // record voting power and cache for this height - k.recordVotingPowerAndCache(ctx, newDc, maxActiveFps) + k.recordVotingPowerAndCache(ctx, dc, newDc, maxActiveFps) // record metrics - k.recordMetrics(newDc, maxActiveFps) + k.recordMetrics(newDc) } -func (k Keeper) recordVotingPowerAndCache(ctx context.Context, dc *types.VotingPowerDistCache, maxActiveFps uint32) { +// recordVotingPowerAndCache assigns voting power to each active finality provider +// with the following consideration: +// 1. the fp must have timestamped pub rand +// 2. the fp must in the top x ranked by the voting power (x is given by maxActiveFps) +// NOTE: the previous and the new dist cache cannot be nil +func (k Keeper) recordVotingPowerAndCache(ctx context.Context, prevDc, newDc *types.VotingPowerDistCache, maxActiveFps uint32) { + if prevDc == nil || newDc == nil { + panic("the voting power distribution cache cannot be nil") + } + babylonTipHeight := uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) - // set voting power table for this height - for i := uint32(0); i < dc.GetNumActiveFPs(maxActiveFps); i++ { - fp := dc.FinalityProviders[i] + // label fps with whether it has timestamped pub rand so that these fps + // will not be assigned voting power + for _, fp := range newDc.FinalityProviders { + // TODO calling HasTimestampedPubRand potentially iterates + // all the pub rand committed by the fp, which might slow down + // the process, need optimization + fp.IsTimestamped = k.FinalityKeeper.HasTimestampedPubRand(ctx, fp.BtcPk, babylonTipHeight) + } + + // apply the finality provider voting power dist info to the new cache + // after which the cache would have active fps that are top N fps ranked + // by voting power with timestamped pub rand + newDc.ApplyActiveFinalityProviders(maxActiveFps) + + // set voting power table for each active finality providers at this height + for i := uint32(0); i < newDc.NumActiveFps; i++ { + fp := newDc.FinalityProviders[i] k.SetVotingPower(ctx, fp.BtcPk.MustMarshal(), babylonTipHeight, fp.TotalVotingPower) + } + // find newly activated finality providers and execute the hooks by comparing + // the previous dist cache + newActivatedFinalityProviders := newDc.FindNewActiveFinalityProviders(prevDc) + for _, fp := range newActivatedFinalityProviders { + if err := k.hooks.AfterFinalityProviderActivated(ctx, fp.BtcPk); err != nil { + panic(fmt.Errorf("failed to execute after finality provider %s activated", fp.BtcPk.MarshalHex())) + } + k.Logger(sdk.UnwrapSDKContext(ctx)).Info("a new finality provider is activated", "pk", fp.BtcPk.MarshalHex()) } // set the voting power distribution cache of the current height - k.setVotingPowerDistCache(ctx, babylonTipHeight, dc) + k.setVotingPowerDistCache(ctx, babylonTipHeight, newDc) } -func (k Keeper) recordMetrics(dc *types.VotingPowerDistCache, maxActiveFps uint32) { +func (k Keeper) recordMetrics(dc *types.VotingPowerDistCache) { // number of active FPs - numActiveFPs := int(dc.GetNumActiveFPs(maxActiveFps)) + numActiveFPs := int(dc.NumActiveFps) types.RecordActiveFinalityProviders(numActiveFPs) // number of inactive FPs numInactiveFPs := len(dc.FinalityProviders) - numActiveFPs @@ -236,10 +275,6 @@ func (k Keeper) ProcessAllPowerDistUpdateEvents( } } - // filter out the top N finality providers and their total voting power, and - // record them in the new cache - newDc.ApplyActiveFinalityProviders(maxActiveFps) - return newDc } diff --git a/x/btcstaking/keeper/power_dist_change_test.go b/x/btcstaking/keeper/power_dist_change_test.go index 65320c5df..0277ad28c 100644 --- a/x/btcstaking/keeper/power_dist_change_test.go +++ b/x/btcstaking/keeper/power_dist_change_test.go @@ -4,12 +4,13 @@ import ( "math/rand" "testing" - "github.com/babylonlabs-io/babylon/testutil/datagen" - btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" - "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + + "github.com/babylonlabs-io/babylon/testutil/datagen" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) func FuzzProcessAllPowerDistUpdateEvents_Determinism(f *testing.F) { @@ -23,8 +24,9 @@ func FuzzProcessAllPowerDistUpdateEvents_Determinism(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + finalityKeeper.EXPECT().HasTimestampedPubRand(gomock.Any(), gomock.Any(), gomock.Any()).Return(true).AnyTimes() + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters h.GenAndApplyParams(r) @@ -75,8 +77,9 @@ func FuzzFinalityProviderEvents(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + finalityKeeper.EXPECT().HasTimestampedPubRand(gomock.Any(), gomock.Any(), gomock.Any()).Return(true).AnyTimes() + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -153,8 +156,8 @@ func FuzzBTCDelegationEvents(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -217,10 +220,21 @@ func FuzzBTCDelegationEvents(f *testing.F) { require.Equal(t, expectedStakingTxHash, btcDelStateUpdate.StakingTxHash) require.Equal(t, types.BTCDelegationStatus_ACTIVE, btcDelStateUpdate.NewState) - // ensure this finality provider has voting power at the current height + // ensure this finality provider does not have voting power at the current height + // due to no timestamped randomness + babylonHeight += 1 + h.SetCtxHeight(babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(btcTip).AnyTimes() + finalityKeeper.EXPECT().HasTimestampedPubRand(gomock.Any(), gomock.Any(), gomock.Eq(babylonHeight)).Return(false).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) + h.NoError(err) + require.Zero(t, h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fp.BtcPk, babylonHeight)) + + // ensure this finality provider has voting power at the current height after having timestamped pub rand babylonHeight += 1 h.SetCtxHeight(babylonHeight) h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(btcTip).AnyTimes() + finalityKeeper.EXPECT().HasTimestampedPubRand(gomock.Any(), gomock.Any(), gomock.Eq(babylonHeight)).Return(true).AnyTimes() err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) h.NoError(err) require.Equal(t, uint64(stakingValue), h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fp.BtcPk, babylonHeight)) diff --git a/x/btcstaking/keeper/query_params_test.go b/x/btcstaking/keeper/query_params_test.go index 6d0239d0b..1e4624c4a 100644 --- a/x/btcstaking/keeper/query_params_test.go +++ b/x/btcstaking/keeper/query_params_test.go @@ -3,9 +3,10 @@ package keeper_test import ( "testing" + "github.com/stretchr/testify/require" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" "github.com/babylonlabs-io/babylon/x/btcstaking/types" - "github.com/stretchr/testify/require" ) func TestParamsQuery(t *testing.T) { diff --git a/x/btcstaking/keeper/voting_power_table_test.go b/x/btcstaking/keeper/voting_power_table_test.go index a8c743afe..a76ee2e82 100644 --- a/x/btcstaking/keeper/voting_power_table_test.go +++ b/x/btcstaking/keeper/voting_power_table_test.go @@ -5,11 +5,12 @@ import ( "sort" "testing" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/babylonlabs-io/babylon/testutil/datagen" btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/babylonlabs-io/babylon/x/btcstaking/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) func FuzzVotingPowerTable(f *testing.F) { @@ -23,8 +24,9 @@ func FuzzVotingPowerTable(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + finalityKeeper.EXPECT().HasTimestampedPubRand(gomock.Any(), gomock.Any(), gomock.Any()).Return(true).AnyTimes() + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -162,8 +164,8 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -173,6 +175,7 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { // generate a random batch of finality providers, each with a BTC delegation with random power fpsWithMeta := []*types.FinalityProviderDistInfo{} numFps := datagen.RandomInt(r, 300) + 1 + noTimestampedFps := map[string]bool{} for i := uint64(0); i < numFps; i++ { // generate finality provider _, _, fp := h.CreateFinalityProvider(r) @@ -188,17 +191,26 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { ) h.CreateCovenantSigs(r, covenantSKs, delMsg, del) + // 30 percent not have timestamped randomness, which causes + // zero voting power in the table + fpDistInfo := &types.FinalityProviderDistInfo{BtcPk: fp.BtcPk, TotalVotingPower: stakingValue} + if r.Intn(10) <= 2 { + finalityKeeper.EXPECT().HasTimestampedPubRand(gomock.Any(), fp.BtcPk, gomock.Any()).Return(false).AnyTimes() + noTimestampedFps[fp.BtcPk.MarshalHex()] = true + fpDistInfo.IsTimestamped = false + } else { + finalityKeeper.EXPECT().HasTimestampedPubRand(gomock.Any(), fp.BtcPk, gomock.Any()).Return(true).AnyTimes() + fpDistInfo.IsTimestamped = true + } + // record voting power - fpsWithMeta = append(fpsWithMeta, &types.FinalityProviderDistInfo{ - BtcPk: fp.BtcPk, - TotalVotingPower: stakingValue, - }) + fpsWithMeta = append(fpsWithMeta, fpDistInfo) } maxActiveFpsParam := h.BTCStakingKeeper.GetParams(h.Ctx).MaxActiveFinalityProviders // get a map of expected active finality providers - types.SortFinalityProviders(fpsWithMeta) - expectedActiveFps := fpsWithMeta[:min(uint32(len(fpsWithMeta)), maxActiveFpsParam)] + types.SortFinalityProvidersWithTimestamping(fpsWithMeta) + expectedActiveFps := fpsWithMeta[:min(uint32(len(fpsWithMeta)-len(noTimestampedFps)), maxActiveFpsParam)] expectedActiveFpsMap := map[string]uint64{} for _, fp := range expectedActiveFps { expectedActiveFpsMap[fp.BtcPk.MarshalHex()] = fp.TotalVotingPower @@ -211,7 +223,7 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) require.NoError(t, err) - // only finality providers in expectedActiveFpsMap have voting power + // only finality providers in expectedActiveFpsMap have voting power for _, fp := range fpsWithMeta { power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, fp.BtcPk.MustMarshal(), babylonHeight) if expectedPower, ok := expectedActiveFpsMap[fp.BtcPk.MarshalHex()]; ok { @@ -247,8 +259,9 @@ func FuzzVotingPowerTable_ActiveFinalityProviderRotation(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + finalityKeeper := types.NewMockFinalityKeeper(ctrl) + finalityKeeper.EXPECT().HasTimestampedPubRand(gomock.Any(), gomock.Any(), gomock.Any()).Return(true).AnyTimes() + h := NewHelper(t, btclcKeeper, btccKeeper, finalityKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) diff --git a/x/btcstaking/types/btc_slashing_tx.go b/x/btcstaking/types/btc_slashing_tx.go index 2bd135905..613caec3d 100644 --- a/x/btcstaking/types/btc_slashing_tx.go +++ b/x/btcstaking/types/btc_slashing_tx.go @@ -40,6 +40,11 @@ func NewBTCSlashingTxFromHex(txHex string) (*BTCSlashingTx, error) { return &tx, nil } +func NewBtcSlashingTxFromBytes(txBytes []byte) *BTCSlashingTx { + tx := BTCSlashingTx(txBytes) + return &tx +} + func (tx BTCSlashingTx) Marshal() ([]byte, error) { return tx, nil } diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index f907537f2..1bd3bb7b9 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -42,10 +42,18 @@ func (fp *FinalityProvider) ValidateBasic() error { return nil } -// SortFinalityProviders sorts the finality providers slice, +// SortFinalityProvidersWithTimestamping sorts the finality providers slice, // from higher to lower voting power -func SortFinalityProviders(fps []*FinalityProviderDistInfo) { +// finality providers that are timestamped come higher than +// those are not +func SortFinalityProvidersWithTimestamping(fps []*FinalityProviderDistInfo) { sort.SliceStable(fps, func(i, j int) bool { + if fps[i].IsTimestamped && !fps[j].IsTimestamped { + return true + } + if !fps[i].IsTimestamped && fps[j].IsTimestamped { + return false + } return fps[i].TotalVotingPower > fps[j].TotalVotingPower }) } @@ -119,8 +127,8 @@ func GetOrderedCovenantSignatures(fpIdx int, covSigsList []*CovenantAdaptorSigna // - MinUnbondingTime // - CheckpointFinalizationTimeout func MinimumUnbondingTime( - stakingParams Params, - checkpointingParams btcctypes.Params) uint64 { + stakingParams *Params, + checkpointingParams *btcctypes.Params) uint64 { return math.Max[uint64]( uint64(stakingParams.MinUnbondingTime), checkpointingParams.CheckpointFinalizationTimeout, diff --git a/x/btcstaking/types/create_delegation_parser.go b/x/btcstaking/types/create_delegation_parser.go new file mode 100644 index 000000000..44b645e03 --- /dev/null +++ b/x/btcstaking/types/create_delegation_parser.go @@ -0,0 +1,268 @@ +package types + +import ( + "fmt" + math "math" + + "github.com/babylonlabs-io/babylon/btcstaking" + bbn "github.com/babylonlabs-io/babylon/types" + btcckpttypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/wire" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type ParsedPublicKey struct { + *btcec.PublicKey + *bbn.BIP340PubKey +} + +func NewParsedPublicKey(key *bbn.BIP340PubKey) (*ParsedPublicKey, error) { + if key == nil { + return nil, fmt.Errorf("cannont parse nil *bbn.BIP340PubKey") + } + pk, err := key.ToBTCPK() + + if err != nil { + return nil, fmt.Errorf("failed to parse *bbn.BIP340PubKey: %w", err) + } + + return &ParsedPublicKey{ + PublicKey: pk, + BIP340PubKey: key, + }, nil +} + +type ParsedBIP340Signature struct { + *schnorr.Signature + *bbn.BIP340Signature +} + +func NewParsedBIP340Signature(sig *bbn.BIP340Signature) (*ParsedBIP340Signature, error) { + if sig == nil { + return nil, fmt.Errorf("cannot parse nil *bbn.BIP340Signature") + } + + signature, err := sig.ToBTCSig() + + if err != nil { + return nil, fmt.Errorf("failed to parse *bbn.BIP340Signature: %w", err) + } + + return &ParsedBIP340Signature{ + Signature: signature, + BIP340Signature: sig, + }, nil +} + +type ParsedBtcTransaction struct { + Transaction *wire.MsgTx + TransactionBytes []byte +} + +func NewBtcTransaction(transactionBytes []byte) (*ParsedBtcTransaction, error) { + tx, err := bbn.NewBTCTxFromBytes(transactionBytes) + + if err != nil { + return nil, err + } + + return &ParsedBtcTransaction{ + Transaction: tx, + TransactionBytes: transactionBytes, + }, nil +} + +type ParsedPublicKeyList struct { + PublicKeys []*btcec.PublicKey + PublicKeysBbnFormat []bbn.BIP340PubKey +} + +func NewParsedPublicKeyList(pks []bbn.BIP340PubKey) (*ParsedPublicKeyList, error) { + if len(pks) == 0 { + return nil, fmt.Errorf("cannot parse empty list of *bbn.BIP340PubKey") + } + + parsedKeys, err := bbn.NewBTCPKsFromBIP340PKs(pks) + + if err != nil { + return nil, fmt.Errorf("failed to parse list of *bbn.BIP340PubKey: %w", err) + } + + return &ParsedPublicKeyList{ + PublicKeys: parsedKeys, + PublicKeysBbnFormat: pks, + }, nil +} + +type ParsedProofOfInclusion struct { + HeaderHash *bbn.BTCHeaderHashBytes + Proof []byte + Index uint32 +} + +func NewParsedProofOfInclusion( + info *btcckpttypes.TransactionInfo, +) (*ParsedProofOfInclusion, error) { + if info == nil { + return nil, fmt.Errorf("cannot parse nil *btcckpttypes.TransactionInfo") + } + + if err := info.ValidateBasic(); err != nil { + return nil, err + } + + return &ParsedProofOfInclusion{ + HeaderHash: info.Key.Hash, + Proof: info.Proof, + Index: info.Key.Index, + }, nil +} + +type ParsedCreateDelegationMessage struct { + StakerAddress sdk.AccAddress + StakingTx *ParsedBtcTransaction + StakingTxProofOfInclusion *ParsedProofOfInclusion + StakingTime uint16 + StakingValue btcutil.Amount + StakingSlashingTx *ParsedBtcTransaction + StakerPK *ParsedPublicKey + StakerStakingSlashingTxSig *ParsedBIP340Signature + UnbondingTx *ParsedBtcTransaction + UnbondingTime uint16 + UnbondingValue btcutil.Amount + UnbondingSlashingTx *ParsedBtcTransaction + StakerUnbondingSlashingSig *ParsedBIP340Signature + FinalityProviderKeys *ParsedPublicKeyList + ParsedPop *ProofOfPossessionBTC +} + +// ParseCreateDelegationMessage parses a MsgCreateBTCDelegation message and performs some basic +// stateless checks: +// - unbonding transaction is a simple transfer +// - there is no duplicated keys in the finality provider key list +func ParseCreateDelegationMessage(msg *MsgCreateBTCDelegation) (*ParsedCreateDelegationMessage, error) { + if msg == nil { + return nil, fmt.Errorf("cannot parse nil MsgCreateBTCDelegation") + } + + stakingTxProofOfInclusion, err := NewParsedProofOfInclusion(msg.StakingTx) + + if err != nil { + return nil, fmt.Errorf("failed to parse staking tx proof of inclusion: %v", err) + } + + // 1. Parse all transactions + stakingTx, err := NewBtcTransaction(msg.StakingTx.Transaction) + + if err != nil { + return nil, fmt.Errorf("failed to deserialize staking tx: %v", err) + } + + stakingSlashingTx, err := NewBtcTransaction(msg.SlashingTx.MustMarshal()) + + if err != nil { + return nil, fmt.Errorf("failed to deserialize staking slashing tx: %v", err) + } + + unbondingTx, err := NewBtcTransaction(msg.UnbondingTx) + + if err != nil { + return nil, fmt.Errorf("failed to deserialize unbonding tx: %v", err) + } + + if err := btcstaking.IsSimpleTransfer(unbondingTx.Transaction); err != nil { + return nil, fmt.Errorf("unbonding tx is not a simple transfer: %v", err) + } + + unbondingSlashingTx, err := NewBtcTransaction(msg.UnbondingSlashingTx.MustMarshal()) + + if err != nil { + return nil, fmt.Errorf("failed to deserialize unbonding slashing tx: %v", err) + } + + // 2. Check all timelocks + if msg.UnbondingTime > math.MaxUint16 { + return nil, fmt.Errorf("unbonding time %d must be lower than %d", msg.UnbondingTime, math.MaxUint16) + } + + if msg.StakingTime > math.MaxUint16 { + return nil, fmt.Errorf("staking time %d must be lower than %d", msg.StakingTime, math.MaxUint16) + } + + // 3. Parse staker address + stakerAddr, err := sdk.AccAddressFromBech32(msg.StakerAddr) + + if err != nil { + return nil, fmt.Errorf("invalid staker address %s: %v", msg.StakerAddr, err) + } + + // 4. Parse proof of possession + if msg.Pop == nil { + return nil, fmt.Errorf("empty proof of possession") + } + + if err := msg.Pop.ValidateBasic(); err != nil { + return nil, err + } + + // 5. Parse signatures for slashing transaction + stakerStakingSlashingTxSig, err := NewParsedBIP340Signature(msg.DelegatorSlashingSig) + + if err != nil { + return nil, fmt.Errorf("failed to parse staker staking slashing signature: %v", err) + } + + stakerUnbondingSlashingSig, err := NewParsedBIP340Signature(msg.DelegatorUnbondingSlashingSig) + + if err != nil { + return nil, fmt.Errorf("failed to parse staker unbonding slashing signature: %v", err) + } + + // 6. Parse finality provider public keys and check for duplicates + fpPKs, err := NewParsedPublicKeyList(msg.FpBtcPkList) + + if err != nil { + return nil, fmt.Errorf("failed to parse finality provider public keys: %v", err) + } + + if ExistsDup(fpPKs.PublicKeysBbnFormat) { + return nil, ErrDuplicatedFp + } + + // 7. Parse staker public key + stakerPK, err := NewParsedPublicKey(msg.BtcPk) + + if err != nil { + return nil, fmt.Errorf("failed to parse staker public key: %v", err) + } + + // 8. Parse staking and unbonding value + if msg.StakingValue < 0 { + return nil, fmt.Errorf("staking value must be positive") + } + + if msg.UnbondingValue < 0 { + return nil, fmt.Errorf("unbonding value must be positive") + } + + return &ParsedCreateDelegationMessage{ + StakerAddress: stakerAddr, + StakingTx: stakingTx, + StakingTxProofOfInclusion: stakingTxProofOfInclusion, + StakingTime: uint16(msg.StakingTime), + StakingValue: btcutil.Amount(msg.StakingValue), + StakingSlashingTx: stakingSlashingTx, + StakerPK: stakerPK, + StakerStakingSlashingTxSig: stakerStakingSlashingTxSig, + UnbondingTx: unbondingTx, + UnbondingTime: uint16(msg.UnbondingTime), + UnbondingValue: btcutil.Amount(msg.UnbondingValue), + UnbondingSlashingTx: unbondingSlashingTx, + StakerUnbondingSlashingSig: stakerUnbondingSlashingSig, + FinalityProviderKeys: fpPKs, + ParsedPop: msg.Pop, + }, nil +} diff --git a/x/btcstaking/types/errors.go b/x/btcstaking/types/errors.go index 5de1421d5..ffca7d9ab 100644 --- a/x/btcstaking/types/errors.go +++ b/x/btcstaking/types/errors.go @@ -11,7 +11,6 @@ var ( ErrBTCDelegationNotFound = errorsmod.Register(ModuleName, 1102, "the BTC delegation is not found") ErrFpRegistered = errorsmod.Register(ModuleName, 1103, "the finality provider has already been registered") ErrFpAlreadySlashed = errorsmod.Register(ModuleName, 1104, "the finality provider has already been slashed") - ErrFpNotBTCTimestamped = errorsmod.Register(ModuleName, 1105, "the finality provider is not BTC timestamped yet") ErrBTCStakingNotActivated = errorsmod.Register(ModuleName, 1106, "the BTC staking protocol is not activated yet") ErrBTCHeightNotFound = errorsmod.Register(ModuleName, 1107, "the BTC height is not found") ErrReusedStakingTx = errorsmod.Register(ModuleName, 1108, "the BTC staking tx is already used") diff --git a/x/btcstaking/types/expected_keepers.go b/x/btcstaking/types/expected_keepers.go index 237879011..3f4a12625 100644 --- a/x/btcstaking/types/expected_keepers.go +++ b/x/btcstaking/types/expected_keepers.go @@ -2,12 +2,10 @@ package types import ( "context" - "math/big" bbn "github.com/babylonlabs-io/babylon/types" btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" - etypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) type BTCLightClientKeeper interface { @@ -17,13 +15,11 @@ type BTCLightClientKeeper interface { } type BtcCheckpointKeeper interface { - GetPowLimit() *big.Int GetParams(ctx context.Context) (p btcctypes.Params) } -type CheckpointingKeeper interface { - GetEpoch(ctx context.Context) *etypes.Epoch - GetLastFinalizedEpoch(ctx context.Context) uint64 +type FinalityKeeper interface { + HasTimestampedPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64) bool } type BtcStakingHooks interface { diff --git a/x/btcstaking/types/incentive.go b/x/btcstaking/types/incentive.go index 7dd020896..e6955ee2f 100644 --- a/x/btcstaking/types/incentive.go +++ b/x/btcstaking/types/incentive.go @@ -20,9 +20,9 @@ func (dc *VotingPowerDistCache) AddFinalityProviderDistInfo(v *FinalityProviderD dc.FinalityProviders = append(dc.FinalityProviders, v) } -func (dc *VotingPowerDistCache) FindNewActiveFinalityProviders(prevDc *VotingPowerDistCache, maxActiveFPs uint32) []*FinalityProviderDistInfo { - activeFps := dc.GetActiveFinalityProviderSet(maxActiveFPs) - prevActiveFps := prevDc.GetActiveFinalityProviderSet(maxActiveFPs) +func (dc *VotingPowerDistCache) FindNewActiveFinalityProviders(prevDc *VotingPowerDistCache) []*FinalityProviderDistInfo { + activeFps := dc.GetActiveFinalityProviderSet() + prevActiveFps := prevDc.GetActiveFinalityProviderSet() newActiveFps := make([]*FinalityProviderDistInfo, 0) for pk, fp := range activeFps { @@ -36,28 +36,44 @@ func (dc *VotingPowerDistCache) FindNewActiveFinalityProviders(prevDc *VotingPow } // ApplyActiveFinalityProviders sorts all finality providers, counts the total voting -// power of top N finality providers, and records them in cache +// power of top N finality providers, excluding those who don't have timestamped pub rand +// and records them in cache func (dc *VotingPowerDistCache) ApplyActiveFinalityProviders(maxActiveFPs uint32) { - // reset total voting power - dc.TotalVotingPower = 0 - // sort finality providers - SortFinalityProviders(dc.FinalityProviders) - // calculate voting power of top N finality providers - numActiveFPs := dc.GetNumActiveFPs(maxActiveFPs) + // sort finality providers with timestamping considered + SortFinalityProvidersWithTimestamping(dc.FinalityProviders) + + numActiveFPs := uint32(0) + + // finality providers are in the descending order of voting power + // and timestamped ones come in the last + for _, fp := range dc.FinalityProviders { + if numActiveFPs == maxActiveFPs { + break + } + if fp.TotalVotingPower == 0 { + break + } + if !fp.IsTimestamped { + break + } + numActiveFPs++ + } + + totalVotingPower := uint64(0) + for i := uint32(0); i < numActiveFPs; i++ { - dc.TotalVotingPower += dc.FinalityProviders[i].TotalVotingPower + totalVotingPower += dc.FinalityProviders[i].TotalVotingPower } -} -func (dc *VotingPowerDistCache) GetNumActiveFPs(maxActiveFPs uint32) uint32 { - return min(maxActiveFPs, uint32(len(dc.FinalityProviders))) + dc.TotalVotingPower = totalVotingPower + dc.NumActiveFps = numActiveFPs } // GetActiveFinalityProviderSet returns a set of active finality providers // keyed by the hex string of the finality provider's BTC public key // i.e., top N of them in terms of voting power -func (dc *VotingPowerDistCache) GetActiveFinalityProviderSet(maxActiveFPs uint32) map[string]*FinalityProviderDistInfo { - numActiveFPs := dc.GetNumActiveFPs(maxActiveFPs) +func (dc *VotingPowerDistCache) GetActiveFinalityProviderSet() map[string]*FinalityProviderDistInfo { + numActiveFPs := dc.NumActiveFps activeFps := make(map[string]*FinalityProviderDistInfo) @@ -71,8 +87,8 @@ func (dc *VotingPowerDistCache) GetActiveFinalityProviderSet(maxActiveFPs uint32 // FilterVotedDistCache filters out a voting power distribution cache // with finality providers that have voted according to a map of given // voters, and their total voted power. -func (dc *VotingPowerDistCache) FilterVotedDistCache(maxActiveFPs uint32, voterBTCPKs map[string]struct{}) *VotingPowerDistCache { - activeFPs := dc.GetActiveFinalityProviderSet(maxActiveFPs) +func (dc *VotingPowerDistCache) FilterVotedDistCache(voterBTCPKs map[string]struct{}) *VotingPowerDistCache { + activeFPs := dc.GetActiveFinalityProviderSet() var filteredFps []*FinalityProviderDistInfo totalVotingPower := uint64(0) for k, v := range activeFPs { diff --git a/x/btcstaking/types/incentive.pb.go b/x/btcstaking/types/incentive.pb.go index e1234e074..098ad0cb1 100644 --- a/x/btcstaking/types/incentive.pb.go +++ b/x/btcstaking/types/incentive.pb.go @@ -29,9 +29,14 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // VotingPowerDistCache is the cache for voting power distribution of finality providers // and their BTC delegations at a height type VotingPowerDistCache struct { + // total_voting_power is the total voting power of all the finality providers + // in the cache TotalVotingPower uint64 `protobuf:"varint,1,opt,name=total_voting_power,json=totalVotingPower,proto3" json:"total_voting_power,omitempty"` // finality_providers is a list of finality providers' voting power information FinalityProviders []*FinalityProviderDistInfo `protobuf:"bytes,2,rep,name=finality_providers,json=finalityProviders,proto3" json:"finality_providers,omitempty"` + // num_active_fps is the number of finality providers that have positive voting power + // as well as timestamped public randomness + NumActiveFps uint32 `protobuf:"varint,3,opt,name=num_active_fps,json=numActiveFps,proto3" json:"num_active_fps,omitempty"` } func (m *VotingPowerDistCache) Reset() { *m = VotingPowerDistCache{} } @@ -67,20 +72,6 @@ func (m *VotingPowerDistCache) XXX_DiscardUnknown() { var xxx_messageInfo_VotingPowerDistCache proto.InternalMessageInfo -func (m *VotingPowerDistCache) GetTotalVotingPower() uint64 { - if m != nil { - return m.TotalVotingPower - } - return 0 -} - -func (m *VotingPowerDistCache) GetFinalityProviders() []*FinalityProviderDistInfo { - if m != nil { - return m.FinalityProviders - } - return nil -} - // FinalityProviderDistInfo is the reward distribution of a finality provider and its BTC delegations type FinalityProviderDistInfo struct { // btc_pk is the Bitcoin secp256k1 PK of this finality provider @@ -94,6 +85,9 @@ type FinalityProviderDistInfo struct { TotalVotingPower uint64 `protobuf:"varint,4,opt,name=total_voting_power,json=totalVotingPower,proto3" json:"total_voting_power,omitempty"` // btc_dels is a list of BTC delegations' voting power information under this finality provider BtcDels []*BTCDelDistInfo `protobuf:"bytes,5,rep,name=btc_dels,json=btcDels,proto3" json:"btc_dels,omitempty"` + // is_timestamped indicates whether the finality provider + // has timestamped public randomness committed + IsTimestamped bool `protobuf:"varint,6,opt,name=is_timestamped,json=isTimestamped,proto3" json:"is_timestamped,omitempty"` } func (m *FinalityProviderDistInfo) Reset() { *m = FinalityProviderDistInfo{} } @@ -150,6 +144,13 @@ func (m *FinalityProviderDistInfo) GetBtcDels() []*BTCDelDistInfo { return nil } +func (m *FinalityProviderDistInfo) GetIsTimestamped() bool { + if m != nil { + return m.IsTimestamped + } + return false +} + // BTCDelDistInfo contains the information related to reward distribution for a BTC delegation type BTCDelDistInfo struct { // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation @@ -228,39 +229,43 @@ func init() { } var fileDescriptor_ac354c3bd6d7a66b = []byte{ - // 504 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x4f, 0x6f, 0xd3, 0x30, - 0x18, 0xc6, 0x9b, 0xae, 0x1b, 0xe0, 0x8e, 0x7f, 0x56, 0x91, 0xc2, 0x90, 0xb2, 0x52, 0x69, 0xa8, - 0x87, 0x35, 0x61, 0x6c, 0x07, 0xb8, 0x41, 0x16, 0x21, 0x26, 0xfe, 0x45, 0x61, 0xe2, 0xc0, 0x81, - 0xc8, 0x76, 0xdc, 0xc4, 0x6a, 0x12, 0x57, 0xb1, 0x17, 0x9a, 0x6f, 0xc1, 0x87, 0xe0, 0x23, 0xec, - 0x43, 0x70, 0x9c, 0x76, 0x9a, 0x76, 0x98, 0x50, 0x7b, 0xe0, 0x6b, 0xa0, 0x38, 0x81, 0x15, 0xb4, - 0x4a, 0x3d, 0x70, 0xb3, 0xfd, 0x3c, 0xaf, 0xdf, 0xf7, 0xf9, 0x49, 0x2f, 0xd8, 0xc2, 0x08, 0x17, - 0x31, 0x4f, 0x2d, 0x2c, 0x89, 0x90, 0x68, 0xc4, 0xd2, 0xd0, 0xca, 0x77, 0x2c, 0x96, 0x12, 0x9a, - 0x4a, 0x96, 0x53, 0x73, 0x9c, 0x71, 0xc9, 0xe1, 0xbd, 0xda, 0x66, 0x5e, 0xda, 0xcc, 0x7c, 0x67, - 0xa3, 0x13, 0xf2, 0x90, 0x2b, 0x87, 0x55, 0x9e, 0x2a, 0xf3, 0xc6, 0x7d, 0xc2, 0x45, 0xc2, 0x85, - 0x5f, 0x09, 0xd5, 0xa5, 0x92, 0x7a, 0xdf, 0x34, 0xd0, 0xf9, 0xc8, 0x25, 0x4b, 0x43, 0x97, 0x7f, - 0xa1, 0x99, 0xc3, 0x84, 0xdc, 0x47, 0x24, 0xa2, 0x70, 0x1b, 0x40, 0xc9, 0x25, 0x8a, 0xfd, 0x5c, - 0xa9, 0xfe, 0xb8, 0x94, 0x75, 0xad, 0xab, 0xf5, 0x5b, 0xde, 0x1d, 0xa5, 0xcc, 0x95, 0xc1, 0xcf, - 0x00, 0x0e, 0x59, 0x8a, 0x62, 0x26, 0x8b, 0xb2, 0x4b, 0xce, 0x02, 0x9a, 0x09, 0xbd, 0xd9, 0x5d, - 0xe9, 0xb7, 0x9f, 0x58, 0xe6, 0x95, 0xb3, 0x9a, 0x2f, 0xeb, 0x02, 0xb7, 0xf6, 0x97, 0xbd, 0x0f, - 0xd2, 0x21, 0xf7, 0xee, 0x0e, 0xff, 0x51, 0x44, 0xef, 0xac, 0x09, 0xf4, 0x45, 0x7e, 0xf8, 0x1e, - 0xac, 0x61, 0x49, 0xfc, 0xf1, 0x48, 0x8d, 0xb7, 0x6e, 0x3f, 0x3d, 0xbf, 0xd8, 0xdc, 0x0b, 0x99, - 0x8c, 0x8e, 0xb0, 0x49, 0x78, 0x62, 0xd5, 0xed, 0x63, 0x84, 0xc5, 0x80, 0xf1, 0xdf, 0x57, 0x4b, - 0x16, 0x63, 0x2a, 0x4c, 0xfb, 0xc0, 0xdd, 0xdd, 0x7b, 0xec, 0x1e, 0xe1, 0xd7, 0xb4, 0xf0, 0x56, - 0xb1, 0x24, 0xee, 0x08, 0x6e, 0x83, 0x16, 0x0a, 0x82, 0x4c, 0x6f, 0x76, 0xb5, 0xfe, 0x0d, 0x5b, - 0x3f, 0x3d, 0x1e, 0x74, 0x6a, 0x68, 0x2f, 0x82, 0x20, 0xa3, 0x42, 0x7c, 0x90, 0x19, 0x4b, 0x43, - 0x4f, 0xb9, 0xe0, 0x5b, 0x00, 0x08, 0x4f, 0x12, 0x26, 0x04, 0xe3, 0xa9, 0xbe, 0xa2, 0x6a, 0x06, - 0xe7, 0x17, 0x9b, 0x0f, 0xaa, 0x1a, 0x11, 0x8c, 0x4c, 0xc6, 0xad, 0x04, 0xc9, 0xc8, 0x7c, 0x43, - 0x43, 0x44, 0x0a, 0x87, 0x92, 0xd3, 0xe3, 0x01, 0xa8, 0xbf, 0x74, 0x28, 0xf1, 0xe6, 0x3e, 0x58, - 0x00, 0xbe, 0xb5, 0x00, 0xfc, 0x73, 0x70, 0xbd, 0xcc, 0x1e, 0xd0, 0x58, 0xe8, 0xab, 0x0a, 0xf7, - 0xd6, 0x02, 0xdc, 0xf6, 0xe1, 0xbe, 0x43, 0xe3, 0x3f, 0x90, 0xaf, 0x61, 0x49, 0x1c, 0x1a, 0x8b, - 0xde, 0x4f, 0x0d, 0xdc, 0xfa, 0x5b, 0xfb, 0xff, 0x40, 0x9f, 0x81, 0x76, 0x39, 0x09, 0xcd, 0xfc, - 0xa5, 0xb8, 0x82, 0xca, 0x5c, 0x3e, 0xc2, 0x47, 0xe0, 0x76, 0x1d, 0xc2, 0x97, 0x13, 0x3f, 0x42, - 0x22, 0xaa, 0x10, 0x7b, 0x37, 0xeb, 0xe7, 0xc3, 0xc9, 0x2b, 0x24, 0x22, 0xf8, 0x10, 0xac, 0x5f, - 0x01, 0xac, 0x9d, 0x5f, 0xb2, 0xb2, 0xdf, 0x7d, 0x9f, 0x1a, 0xda, 0xc9, 0xd4, 0xd0, 0x7e, 0x4c, - 0x0d, 0xed, 0xeb, 0xcc, 0x68, 0x9c, 0xcc, 0x8c, 0xc6, 0xd9, 0xcc, 0x68, 0x7c, 0x5a, 0x22, 0xdc, - 0x64, 0x7e, 0x21, 0x55, 0x52, 0xbc, 0xa6, 0x56, 0x68, 0xf7, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x84, 0x61, 0x20, 0xde, 0xb3, 0x03, 0x00, 0x00, + // 565 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x53, 0xcd, 0x6e, 0xd3, 0x4c, + 0x14, 0x8d, 0xdb, 0x34, 0x5f, 0x3b, 0xf9, 0xf9, 0x60, 0x14, 0x24, 0x53, 0x24, 0x27, 0x44, 0x04, + 0x65, 0xd1, 0xd8, 0x94, 0x76, 0x01, 0xac, 0xa8, 0x1b, 0x55, 0x54, 0xfc, 0x45, 0x26, 0x62, 0xc1, + 0x02, 0x6b, 0x3c, 0x9e, 0xd8, 0xa3, 0xd8, 0x1e, 0xcb, 0x33, 0x31, 0xc9, 0x1b, 0xb0, 0xe4, 0x11, + 0x78, 0x88, 0x3e, 0x04, 0xcb, 0xa8, 0x2b, 0xd4, 0x45, 0x85, 0x92, 0x05, 0x8f, 0x01, 0xf2, 0x0f, + 0x24, 0xa0, 0x46, 0xea, 0x82, 0xdd, 0xcc, 0x3d, 0xe7, 0xde, 0xb9, 0xe7, 0x1c, 0x0d, 0x68, 0x5b, + 0xc8, 0x9a, 0x7a, 0x2c, 0xd0, 0x2c, 0x81, 0xb9, 0x40, 0x23, 0x1a, 0x38, 0x5a, 0xbc, 0xaf, 0xd1, + 0x00, 0x93, 0x40, 0xd0, 0x98, 0xa8, 0x61, 0xc4, 0x04, 0x83, 0xb7, 0x72, 0x9a, 0xba, 0xa4, 0xa9, + 0xf1, 0xfe, 0x6e, 0xdd, 0x61, 0x0e, 0x4b, 0x19, 0x5a, 0x72, 0xca, 0xc8, 0xbb, 0xb7, 0x31, 0xe3, + 0x3e, 0xe3, 0x66, 0x06, 0x64, 0x97, 0x0c, 0x6a, 0xcd, 0x24, 0x50, 0x7f, 0xcb, 0x04, 0x0d, 0x9c, + 0x3e, 0xfb, 0x40, 0xa2, 0x1e, 0xe5, 0xe2, 0x18, 0x61, 0x97, 0xc0, 0x3d, 0x00, 0x05, 0x13, 0xc8, + 0x33, 0xe3, 0x14, 0x35, 0xc3, 0x04, 0x96, 0xa5, 0xa6, 0xd4, 0x29, 0x1a, 0x37, 0x52, 0x64, 0xa5, + 0x0d, 0xbe, 0x07, 0x70, 0x48, 0x03, 0xe4, 0x51, 0x31, 0x4d, 0x5e, 0x89, 0xa9, 0x4d, 0x22, 0x2e, + 0x6f, 0x34, 0x37, 0x3b, 0xe5, 0x87, 0x9a, 0x7a, 0xe5, 0xae, 0xea, 0x49, 0xde, 0xd0, 0xcf, 0xf9, + 0xc9, 0xdb, 0xa7, 0xc1, 0x90, 0x19, 0x37, 0x87, 0x7f, 0x21, 0x1c, 0xde, 0x03, 0xb5, 0x60, 0xec, + 0x9b, 0x08, 0x27, 0x16, 0x98, 0xc3, 0x90, 0xcb, 0x9b, 0x4d, 0xa9, 0x53, 0x35, 0x2a, 0xc1, 0xd8, + 0x3f, 0x4a, 0x8b, 0x27, 0x21, 0x7f, 0x52, 0xfc, 0xf8, 0xb9, 0x51, 0x68, 0xfd, 0xd8, 0x00, 0xf2, + 0xba, 0xd9, 0xf0, 0x35, 0x28, 0x59, 0x02, 0x9b, 0xe1, 0x28, 0x95, 0x52, 0xd1, 0x1f, 0x5d, 0x5c, + 0x36, 0x0e, 0x1d, 0x2a, 0xdc, 0xb1, 0xa5, 0x62, 0xe6, 0x6b, 0xf9, 0xaa, 0x1e, 0xb2, 0x78, 0x97, + 0xb2, 0x5f, 0x57, 0x4d, 0x4c, 0x43, 0xc2, 0x55, 0xfd, 0xb4, 0x7f, 0x70, 0xf8, 0xa0, 0x3f, 0xb6, + 0x9e, 0x93, 0xa9, 0xb1, 0x65, 0x09, 0xdc, 0x1f, 0xc1, 0x3d, 0x50, 0x44, 0xb6, 0x1d, 0xc9, 0x1b, + 0x4d, 0xa9, 0xb3, 0xa3, 0xcb, 0xe7, 0x67, 0xdd, 0x7a, 0x6e, 0xf0, 0x91, 0x6d, 0x47, 0x84, 0xf3, + 0x37, 0x22, 0xa2, 0x81, 0x63, 0xa4, 0x2c, 0xf8, 0x12, 0x00, 0xcc, 0x7c, 0x9f, 0x72, 0x4e, 0x59, + 0x90, 0x6a, 0xd8, 0xd1, 0xbb, 0x17, 0x97, 0x8d, 0x3b, 0x59, 0x0f, 0xb7, 0x47, 0x2a, 0x65, 0x9a, + 0x8f, 0x84, 0xab, 0xbe, 0x20, 0x0e, 0xc2, 0xd3, 0x1e, 0xc1, 0xe7, 0x67, 0x5d, 0x90, 0x8f, 0xec, + 0x11, 0x6c, 0xac, 0x0c, 0x58, 0x13, 0x52, 0x71, 0x4d, 0x48, 0x4f, 0xc1, 0x76, 0xa2, 0xdd, 0x26, + 0x1e, 0x97, 0xb7, 0xd2, 0x68, 0xda, 0x6b, 0xa2, 0xd1, 0x07, 0xc7, 0x3d, 0xe2, 0xfd, 0x0e, 0xe4, + 0x3f, 0x4b, 0xe0, 0x1e, 0xf1, 0x38, 0x6c, 0x83, 0x1a, 0xe5, 0xa6, 0xa0, 0x3e, 0xe1, 0x02, 0xf9, + 0x21, 0xb1, 0xe5, 0x52, 0x53, 0xea, 0x6c, 0x1b, 0x55, 0xca, 0x07, 0xcb, 0x62, 0xeb, 0xbb, 0x04, + 0x6a, 0x7f, 0x8e, 0xf8, 0xf7, 0xbe, 0x3f, 0x06, 0xe5, 0x64, 0x61, 0x12, 0x99, 0xd7, 0xb2, 0x1f, + 0x64, 0xe4, 0xa4, 0x08, 0xef, 0x83, 0xff, 0x73, 0xad, 0xa6, 0x98, 0x98, 0x2e, 0xe2, 0x6e, 0x96, + 0x84, 0x51, 0xcd, 0xcb, 0x83, 0xc9, 0x33, 0xc4, 0x5d, 0x78, 0x17, 0x54, 0xae, 0xf0, 0xb5, 0x1c, + 0x2f, 0x2d, 0xd5, 0x5f, 0x7d, 0x99, 0x2b, 0xd2, 0x6c, 0xae, 0x48, 0xdf, 0xe6, 0x8a, 0xf4, 0x69, + 0xa1, 0x14, 0x66, 0x0b, 0xa5, 0xf0, 0x75, 0xa1, 0x14, 0xde, 0x5d, 0x43, 0xdc, 0x64, 0xf5, 0x8f, + 0xa7, 0x4a, 0xad, 0x52, 0xfa, 0x2b, 0x0f, 0x7e, 0x06, 0x00, 0x00, 0xff, 0xff, 0x8d, 0x88, 0x9d, + 0x74, 0x06, 0x04, 0x00, 0x00, } func (m *VotingPowerDistCache) Marshal() (dAtA []byte, err error) { @@ -283,6 +288,11 @@ func (m *VotingPowerDistCache) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NumActiveFps != 0 { + i = encodeVarintIncentive(dAtA, i, uint64(m.NumActiveFps)) + i-- + dAtA[i] = 0x18 + } if len(m.FinalityProviders) > 0 { for iNdEx := len(m.FinalityProviders) - 1; iNdEx >= 0; iNdEx-- { { @@ -325,6 +335,16 @@ func (m *FinalityProviderDistInfo) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if m.IsTimestamped { + i-- + if m.IsTimestamped { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } if len(m.BtcDels) > 0 { for iNdEx := len(m.BtcDels) - 1; iNdEx >= 0; iNdEx-- { { @@ -458,6 +478,9 @@ func (m *VotingPowerDistCache) Size() (n int) { n += 1 + l + sovIncentive(uint64(l)) } } + if m.NumActiveFps != 0 { + n += 1 + sovIncentive(uint64(m.NumActiveFps)) + } return n } @@ -488,6 +511,9 @@ func (m *FinalityProviderDistInfo) Size() (n int) { n += 1 + l + sovIncentive(uint64(l)) } } + if m.IsTimestamped { + n += 2 + } return n } @@ -603,6 +629,25 @@ func (m *VotingPowerDistCache) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumActiveFps", wireType) + } + m.NumActiveFps = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIncentive + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumActiveFps |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipIncentive(dAtA[iNdEx:]) @@ -809,6 +854,26 @@ func (m *FinalityProviderDistInfo) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsTimestamped", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIncentive + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsTimestamped = bool(v != 0) default: iNdEx = preIndex skippy, err := skipIncentive(dAtA[iNdEx:]) diff --git a/x/btcstaking/types/incentive_test.go b/x/btcstaking/types/incentive_test.go new file mode 100644 index 000000000..fe844fe21 --- /dev/null +++ b/x/btcstaking/types/incentive_test.go @@ -0,0 +1,119 @@ +package types + +import ( + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/stretchr/testify/require" + + "github.com/babylonlabs-io/babylon/types" +) + +var ( + fpPrivKey1, _ = btcec.NewPrivateKey() + fpPrivKey2, _ = btcec.NewPrivateKey() + fpPubKey1 = types.NewBIP340PubKeyFromBTCPK(fpPrivKey1.PubKey()) + fpPubKey2 = types.NewBIP340PubKeyFromBTCPK(fpPrivKey2.PubKey()) +) + +func TestVotingPowerDistCache(t *testing.T) { + tests := []struct { + desc string + maxActiveFPs uint32 + numActiveFps uint32 + totalVotingPower uint64 + prevDistCache *VotingPowerDistCache + fps []*FinalityProviderDistInfo + }{ + { + desc: "all not timestamped", + maxActiveFPs: 80, + numActiveFps: 0, + totalVotingPower: 0, + prevDistCache: NewVotingPowerDistCache(), + fps: []*FinalityProviderDistInfo{ + { + BtcPk: fpPubKey1, + TotalVotingPower: 1000, + IsTimestamped: false, + }, + { + BtcPk: fpPubKey2, + TotalVotingPower: 2000, + IsTimestamped: false, + }, + }, + }, + { + desc: "all timestamped", + maxActiveFPs: 80, + numActiveFps: 2, + totalVotingPower: 3000, + prevDistCache: NewVotingPowerDistCache(), + fps: []*FinalityProviderDistInfo{ + { + BtcPk: fpPubKey1, + TotalVotingPower: 1000, + IsTimestamped: true, + }, + { + BtcPk: fpPubKey2, + TotalVotingPower: 2000, + IsTimestamped: true, + }, + }, + }, + { + desc: "partly timestamped", + maxActiveFPs: 80, + numActiveFps: 1, + totalVotingPower: 1000, + prevDistCache: NewVotingPowerDistCache(), + fps: []*FinalityProviderDistInfo{ + { + BtcPk: fpPubKey1, + TotalVotingPower: 1000, + IsTimestamped: true, + }, + { + BtcPk: fpPubKey2, + TotalVotingPower: 2000, + IsTimestamped: false, + }, + }, + }, + { + desc: "small max active fps", + maxActiveFPs: 1, + numActiveFps: 1, + totalVotingPower: 2000, + prevDistCache: NewVotingPowerDistCache(), + fps: []*FinalityProviderDistInfo{ + { + BtcPk: fpPubKey1, + TotalVotingPower: 1000, + IsTimestamped: true, + }, + { + BtcPk: fpPubKey2, + TotalVotingPower: 2000, + IsTimestamped: true, + }, + }, + }, + } + for _, tc := range tests { + t.Run(tc.desc, func(t *testing.T) { + dc := NewVotingPowerDistCache() + for _, fp := range tc.fps { + dc.AddFinalityProviderDistInfo(fp) + } + dc.ApplyActiveFinalityProviders(tc.maxActiveFPs) + require.Equal(t, tc.totalVotingPower, dc.TotalVotingPower) + require.Equal(t, tc.numActiveFps, dc.NumActiveFps) + + newBondedFps := dc.FindNewActiveFinalityProviders(tc.prevDistCache) + require.Equal(t, tc.numActiveFps, uint32(len(newBondedFps))) + }) + } +} diff --git a/x/btcstaking/types/mocked_keepers.go b/x/btcstaking/types/mocked_keepers.go index d68d89080..2b7cfc3ec 100644 --- a/x/btcstaking/types/mocked_keepers.go +++ b/x/btcstaking/types/mocked_keepers.go @@ -6,13 +6,11 @@ package types import ( context "context" - big "math/big" reflect "reflect" types "github.com/babylonlabs-io/babylon/types" types0 "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" types1 "github.com/babylonlabs-io/babylon/x/btclightclient/types" - types2 "github.com/babylonlabs-io/babylon/x/epoching/types" gomock "github.com/golang/mock/gomock" ) @@ -118,69 +116,41 @@ func (mr *MockBtcCheckpointKeeperMockRecorder) GetParams(ctx interface{}) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParams", reflect.TypeOf((*MockBtcCheckpointKeeper)(nil).GetParams), ctx) } -// GetPowLimit mocks base method. -func (m *MockBtcCheckpointKeeper) GetPowLimit() *big.Int { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPowLimit") - ret0, _ := ret[0].(*big.Int) - return ret0 -} - -// GetPowLimit indicates an expected call of GetPowLimit. -func (mr *MockBtcCheckpointKeeperMockRecorder) GetPowLimit() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPowLimit", reflect.TypeOf((*MockBtcCheckpointKeeper)(nil).GetPowLimit)) -} - -// MockCheckpointingKeeper is a mock of CheckpointingKeeper interface. -type MockCheckpointingKeeper struct { +// MockFinalityKeeper is a mock of FinalityKeeper interface. +type MockFinalityKeeper struct { ctrl *gomock.Controller - recorder *MockCheckpointingKeeperMockRecorder + recorder *MockFinalityKeeperMockRecorder } -// MockCheckpointingKeeperMockRecorder is the mock recorder for MockCheckpointingKeeper. -type MockCheckpointingKeeperMockRecorder struct { - mock *MockCheckpointingKeeper +// MockFinalityKeeperMockRecorder is the mock recorder for MockFinalityKeeper. +type MockFinalityKeeperMockRecorder struct { + mock *MockFinalityKeeper } -// NewMockCheckpointingKeeper creates a new mock instance. -func NewMockCheckpointingKeeper(ctrl *gomock.Controller) *MockCheckpointingKeeper { - mock := &MockCheckpointingKeeper{ctrl: ctrl} - mock.recorder = &MockCheckpointingKeeperMockRecorder{mock} +// NewMockFinalityKeeper creates a new mock instance. +func NewMockFinalityKeeper(ctrl *gomock.Controller) *MockFinalityKeeper { + mock := &MockFinalityKeeper{ctrl: ctrl} + mock.recorder = &MockFinalityKeeperMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockCheckpointingKeeper) EXPECT() *MockCheckpointingKeeperMockRecorder { +func (m *MockFinalityKeeper) EXPECT() *MockFinalityKeeperMockRecorder { return m.recorder } -// GetEpoch mocks base method. -func (m *MockCheckpointingKeeper) GetEpoch(ctx context.Context) *types2.Epoch { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetEpoch", ctx) - ret0, _ := ret[0].(*types2.Epoch) - return ret0 -} - -// GetEpoch indicates an expected call of GetEpoch. -func (mr *MockCheckpointingKeeperMockRecorder) GetEpoch(ctx interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEpoch", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetEpoch), ctx) -} - -// GetLastFinalizedEpoch mocks base method. -func (m *MockCheckpointingKeeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { +// HasTimestampedPubRand mocks base method. +func (m *MockFinalityKeeper) HasTimestampedPubRand(ctx context.Context, fpBtcPK *types.BIP340PubKey, height uint64) bool { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLastFinalizedEpoch", ctx) - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "HasTimestampedPubRand", ctx, fpBtcPK, height) + ret0, _ := ret[0].(bool) return ret0 } -// GetLastFinalizedEpoch indicates an expected call of GetLastFinalizedEpoch. -func (mr *MockCheckpointingKeeperMockRecorder) GetLastFinalizedEpoch(ctx interface{}) *gomock.Call { +// HasTimestampedPubRand indicates an expected call of HasTimestampedPubRand. +func (mr *MockFinalityKeeperMockRecorder) HasTimestampedPubRand(ctx, fpBtcPK, height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastFinalizedEpoch", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetLastFinalizedEpoch), ctx) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasTimestampedPubRand", reflect.TypeOf((*MockFinalityKeeper)(nil).HasTimestampedPubRand), ctx, fpBtcPK, height) } // MockBtcStakingHooks is a mock of BtcStakingHooks interface. diff --git a/x/btcstaking/types/msg.go b/x/btcstaking/types/msg.go index e7e3efe46..9d4e29708 100644 --- a/x/btcstaking/types/msg.go +++ b/x/btcstaking/types/msg.go @@ -2,9 +2,7 @@ package types import ( "fmt" - math "math" - "github.com/babylonlabs-io/babylon/btcstaking" bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/chaincfg/chainhash" sdk "github.com/cosmos/cosmos-sdk/types" @@ -72,90 +70,10 @@ func (m *MsgEditFinalityProvider) ValidateBasic() error { } func (m *MsgCreateBTCDelegation) ValidateBasic() error { - if _, err := sdk.AccAddressFromBech32(m.StakerAddr); err != nil { - return fmt.Errorf("invalid staker addr %s: %w", m.StakerAddr, err) - } - if m.Pop == nil { - return fmt.Errorf("empty proof of possession") - } - if m.BtcPk == nil { - return fmt.Errorf("empty delegator BTC public key") - } - if _, err := m.BtcPk.ToBTCPK(); err != nil { - return fmt.Errorf("invalid BTC public key: %v", err) - } - if m.StakingTx == nil { - return fmt.Errorf("empty staking tx info") - } - if m.SlashingTx == nil { - return fmt.Errorf("empty slashing tx") - } - - if _, err := m.SlashingTx.ToMsgTx(); err != nil { - return fmt.Errorf("invalid slashing tx: %w", err) - } - - if m.DelegatorSlashingSig == nil { - return fmt.Errorf("empty delegator signature") - } - - if _, err := m.DelegatorSlashingSig.ToBTCSig(); err != nil { - return fmt.Errorf("invalid delegator slashing signature: %w", err) - } - - // Check staking time is at most uint16 - if m.StakingTime > math.MaxUint16 { - return ErrInvalidStakingTx.Wrapf("invalid lock time: %d, max: %d", m.StakingTime, math.MaxUint16) - } - // Ensure list of finality provider BTC PKs is not empty - if len(m.FpBtcPkList) == 0 { - return ErrEmptyFpList - } - // Ensure list of finality provider BTC PKs is not duplicated - if ExistsDup(m.FpBtcPkList) { - return ErrDuplicatedFp - } - - // staking tx should be correctly formatted - if err := m.StakingTx.ValidateBasic(); err != nil { - return err - } - if err := m.Pop.ValidateBasic(); err != nil { - return err - } - - // verifications about on-demand unbonding - if m.UnbondingTx == nil { - return fmt.Errorf("empty unbonding tx") - } - if m.UnbondingSlashingTx == nil { - return fmt.Errorf("empty slashing tx") - } - if m.DelegatorUnbondingSlashingSig == nil { - return fmt.Errorf("empty delegator signature") - } - - if _, err := m.UnbondingSlashingTx.ToMsgTx(); err != nil { - return fmt.Errorf("invalid unbonding slashing tx: %w", err) - } - - if _, err := m.DelegatorUnbondingSlashingSig.ToBTCSig(); err != nil { - return fmt.Errorf("invalid delegator unbonding slashing signature: %w", err) - } - - unbondingTxMsg, err := bbn.NewBTCTxFromBytes(m.UnbondingTx) - if err != nil { - return err - } - if err := btcstaking.IsSimpleTransfer(unbondingTxMsg); err != nil { + if _, err := ParseCreateDelegationMessage(m); err != nil { return err } - // Check unbonding time is lower than max uint16 - if m.UnbondingTime > math.MaxUint16 { - return ErrInvalidUnbondingTx.Wrapf("unbonding time %d must be lower than %d", m.UnbondingTime, math.MaxUint16) - } - return nil } diff --git a/x/btcstaking/types/params.go b/x/btcstaking/types/params.go index f3fc1fd92..d599cdd2c 100644 --- a/x/btcstaking/types/params.go +++ b/x/btcstaking/types/params.go @@ -189,3 +189,13 @@ func (p Params) CovenantPksHex() []string { } return covPksHex } + +func (p Params) MustGetCovenantPks() []*btcec.PublicKey { + covenantKeys, err := bbn.NewBTCPKsFromBIP340PKs(p.CovenantPks) + + if err != nil { + panic(fmt.Errorf("failed to get covenant keys: %w", err)) + } + + return covenantKeys +} diff --git a/x/btcstaking/types/parsed_message_validator.go b/x/btcstaking/types/parsed_message_validator.go new file mode 100644 index 000000000..81be55108 --- /dev/null +++ b/x/btcstaking/types/parsed_message_validator.go @@ -0,0 +1,186 @@ +package types + +import ( + "fmt" + + "github.com/babylonlabs-io/babylon/btcstaking" + bbn "github.com/babylonlabs-io/babylon/types" + btcckpttypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/wire" +) + +type ParamsValidationResult struct { + StakingOutputIdx uint32 + UnbondingOutputIdx uint32 +} + +// caluculateMinimumUnbondingValue calculates minimum unbonding value basend on current staking output value +// and params.MinUnbondingRate +func caluculateMinimumUnbondingValue( + stakingOutput *wire.TxOut, + params *Params, +) btcutil.Amount { + // this conversions must always succeed, as it is part of our params + minUnbondingRate := params.MinUnbondingRate.MustFloat64() + // Caluclate min unbonding output value based on staking output, use btc native multiplication + minUnbondingOutputValue := btcutil.Amount(stakingOutput.Value).MulF64(minUnbondingRate) + return minUnbondingOutputValue +} + +// ValidateParams validates parsed message against parameters +func ValidateParams( + pm *ParsedCreateDelegationMessage, + parameters *Params, + btcheckpointParamseters *btcckpttypes.Params, + net *chaincfg.Params, +) (*ParamsValidationResult, error) { + // 1. Validate unbonding time first as it will be used in other checks + minUnbondingTime := MinimumUnbondingTime(parameters, btcheckpointParamseters) + // Check unbonding time (staking time from unbonding tx) is larger than min unbonding time + // which is larger value from: + // - MinUnbondingTime + // - CheckpointFinalizationTimeout + if uint64(pm.UnbondingTime) <= minUnbondingTime { + return nil, ErrInvalidUnbondingTx.Wrapf("unbonding time %d must be larger than %d", pm.UnbondingTime, minUnbondingTime) + } + + stakingTxHash := pm.StakingTx.Transaction.TxHash() + covenantPks := parameters.MustGetCovenantPks() + slashingAddr := parameters.MustGetSlashingAddress(net) + + // 2. Validate all data related to staking tx: + // - it has valid staking output + // - slashing tx is relevent to staking tx + // - slashing tx signature is valid + stakingInfo, err := btcstaking.BuildStakingInfo( + pm.StakerPK.PublicKey, + pm.FinalityProviderKeys.PublicKeys, + covenantPks, + parameters.CovenantQuorum, + pm.StakingTime, + pm.StakingValue, + net, + ) + if err != nil { + return nil, ErrInvalidStakingTx.Wrapf("err: %v", err) + } + + stakingOutputIdx, err := bbn.GetOutputIdxInBTCTx(pm.StakingTx.Transaction, stakingInfo.StakingOutput) + + if err != nil { + return nil, ErrInvalidStakingTx.Wrap("staking tx does not contain expected staking output") + } + + if err := btcstaking.CheckTransactions( + pm.StakingSlashingTx.Transaction, + pm.StakingTx.Transaction, + stakingOutputIdx, + parameters.MinSlashingTxFeeSat, + parameters.SlashingRate, + slashingAddr, + pm.StakerPK.PublicKey, + pm.UnbondingTime, + net, + ); err != nil { + return nil, ErrInvalidStakingTx.Wrap(err.Error()) + } + + slashingSpendInfo, err := stakingInfo.SlashingPathSpendInfo() + if err != nil { + panic(fmt.Errorf("failed to construct slashing path from the staking tx: %w", err)) + } + + if err := btcstaking.VerifyTransactionSigWithOutput( + pm.StakingSlashingTx.Transaction, + pm.StakingTx.Transaction.TxOut[stakingOutputIdx], + slashingSpendInfo.RevealedLeaf.Script, + pm.StakerPK.PublicKey, + pm.StakerStakingSlashingTxSig.BIP340Signature.MustMarshal(), + ); err != nil { + return nil, ErrInvalidSlashingTx.Wrapf("invalid delegator signature: %v", err) + } + + // 3. Validate all data related to unbonding tx: + // - it has valid unbonding output + // - slashing tx is relevent to unbonding tx + // - slashing tx signature is valid + unbondingInfo, err := btcstaking.BuildUnbondingInfo( + pm.StakerPK.PublicKey, + pm.FinalityProviderKeys.PublicKeys, + covenantPks, + parameters.CovenantQuorum, + pm.UnbondingTime, + pm.UnbondingValue, + net, + ) + if err != nil { + return nil, ErrInvalidUnbondingTx.Wrapf("err: %v", err) + } + + unbondingOutputIdx, err := bbn.GetOutputIdxInBTCTx(pm.UnbondingTx.Transaction, unbondingInfo.UnbondingOutput) + if err != nil { + return nil, ErrInvalidUnbondingTx.Wrapf("unbonding tx does not contain expected unbonding output") + } + + err = btcstaking.CheckTransactions( + pm.UnbondingSlashingTx.Transaction, + pm.UnbondingTx.Transaction, + unbondingOutputIdx, + parameters.MinSlashingTxFeeSat, + parameters.SlashingRate, + slashingAddr, + pm.StakerPK.PublicKey, + pm.UnbondingTime, + net, + ) + if err != nil { + return nil, ErrInvalidUnbondingTx.Wrapf("err: %v", err) + } + + unbondingSlashingSpendInfo, err := unbondingInfo.SlashingPathSpendInfo() + if err != nil { + panic(fmt.Errorf("failed to construct slashing path from the unbonding tx: %w", err)) + } + + if err := btcstaking.VerifyTransactionSigWithOutput( + pm.UnbondingSlashingTx.Transaction, + pm.UnbondingTx.Transaction.TxOut[unbondingOutputIdx], + unbondingSlashingSpendInfo.RevealedLeaf.Script, + pm.StakerPK.PublicKey, + pm.StakerUnbondingSlashingSig.BIP340Signature.MustMarshal(), + ); err != nil { + return nil, ErrInvalidSlashingTx.Wrapf("invalid delegator signature: %v", err) + } + + // 4. Check that unbonding tx input is pointing to staking tx + if !pm.UnbondingTx.Transaction.TxIn[0].PreviousOutPoint.Hash.IsEqual(&stakingTxHash) { + return nil, ErrInvalidUnbondingTx.Wrapf("unbonding transaction must spend staking output") + } + + if pm.UnbondingTx.Transaction.TxIn[0].PreviousOutPoint.Index != stakingOutputIdx { + return nil, ErrInvalidUnbondingTx.Wrapf("unbonding transaction input must spend staking output") + } + // 5. Check unbonding tx fees against staking tx. + // - fee is larger than 0 + // - ubonding output value is is at leat `MinUnbondingValue` percent of staking output value + if pm.UnbondingTx.Transaction.TxOut[0].Value >= pm.StakingTx.Transaction.TxOut[stakingOutputIdx].Value { + // Note: we do not enfore any minimum fee for unbonding tx, we only require that it is larger than 0 + // Given that unbonding tx must not be replacable and we do not allow sending it second time, it places + // burden on staker to choose right fee. + // Unbonding tx should not be replaceable at babylon level (and by extension on btc level), as this would + // allow staker to spam the network with unbonding txs, which would force covenant and finality provider to send signatures. + return nil, ErrInvalidUnbondingTx.Wrapf("unbonding tx fee must be larger that 0") + } + + minUnbondingValue := caluculateMinimumUnbondingValue(pm.StakingTx.Transaction.TxOut[stakingOutputIdx], parameters) + if btcutil.Amount(pm.UnbondingTx.Transaction.TxOut[0].Value) < minUnbondingValue { + return nil, ErrInvalidUnbondingTx.Wrapf("unbonding output value must be at least %s, based on staking output", minUnbondingValue) + } + + return &ParamsValidationResult{ + StakingOutputIdx: stakingOutputIdx, + UnbondingOutputIdx: unbondingOutputIdx, + }, nil +} diff --git a/x/finality/README.md b/x/finality/README.md index a6aa17399..11c35a766 100644 --- a/x/finality/README.md +++ b/x/finality/README.md @@ -9,6 +9,8 @@ The Finality module is responsible for handling finality votes, maintaining the finalization status of blocks, and identifying equivocating finality providers in the finalization rounds. This includes: +- handling requests for committing EOTS public randomness from finality +providers; - handling requests for submitting finality votes from finality providers; - maintaining the finalization status of blocks; - identifying sluggish finality providers; and @@ -19,10 +21,13 @@ in the finalization rounds. This includes: - [Table of contents](#table-of-contents) - [Concepts](#concepts) - [States](#states) + - [Parameters](#parameters) + - [Public randomness](#public-randomness) - [Finality votes](#finality-votes) - [Indexed blocks with finalization status](#indexed-blocks-with-finalization-status) - [Equivocation evidences](#equivocation-evidences) - [Messages](#messages) + - [MsgCommitPubRandList](#msgcommitpubrandlist) - [MsgAddFinalitySig](#msgaddfinalitysig) - [MsgUpdateParams](#msgupdateparams) - [EndBlocker](#endblocker) @@ -77,17 +82,14 @@ participate in the finality voting round, an active finality provider with BTC delegations (as specified in the [BTC Staking module](../btcstaking/README.md)) needs to interact with Babylon as follows: -- **Committing EOTS master public randomness.** The finality provider needs to - generate a pair of EOTS master secret/public randomness, and commit the master - public randomness when registering itself to Babylon. The EOTS master - secret/public randomness allows to derive a EOTS secret/public randomness - deterministically for each given height, respectively. Babylon further - requires the epoch of the finality provider registration to be finalized by - BTC timestamping before the registered finality provider can submit finality - signatures. This ensures that each finality provider has a unique public - randomness for each height, and that if the finality provider submits two - finality signatures over two conflicting blocks, anyone can extract the - finality provider's secret key using EOTS. +- **Committing EOTS public randomness.** The finality provider proactively + sends a merkle-tree-based commit of a list of *EOTS public randomness* + for future heights to the Finality module. EOTS ensures that given an EOTS + public randomness, a signer can only sign a single message. + Otherwise, anyone can extract the signer's secret key + by using two EOTS signatures on different messages, the corresponding EOTS + public randomness, and the signer's public key. + A public randomness commit takes effect only after it is BTC-timestamped. - **Submitting EOTS signatures.** Upon a new block, the finality provider submits an EOTS signature w.r.t. the derived public randomness at that height. The Finality module will verify the EOTS signature, and check if there are @@ -106,6 +108,61 @@ transactions to the Bitcoin network. The Finality module maintains the following KV stores. +### Parameters + +The [parameter storage](./keeper/params.go) maintains the Finality module's +parameters. The Finality module's parameters are represented as a `Params` +[object](../../proto/babylon/finality/v1/params.proto) defined as follows: + +```protobuf +// Params defines the parameters for the module. +message Params { + option (gogoproto.goproto_stringer) = false; + // signed_blocks_window defines the size of the sliding window for tracking finality provider liveness + int64 signed_blocks_window = 1; + // finality_sig_timeout defines how much time (in terms of blocks) finality providers have to cast a finality + // vote before being judged as missing their voting turn on the given block + int64 finality_sig_timeout = 2; + // min_signed_per_window defines the minimum number of blocks that a finality provider is required to sign + // within the sliding window to avoid being detected as sluggish + bytes min_signed_per_window = 3 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false, + (amino.dont_omitempty) = true + ]; + // min_pub_rand is the minimum number of public randomness each + // message should commit + uint64 min_pub_rand = 4; +} +``` + +### Public randomness + +The [public randomness storage](./keeper/public_randomness.go) maintains the +EOTS public randomness commit that each finality provider commits to Babylon. +The key is the finality provider's Bitcoin secp256k1 public key concatenated +with the block height, and the value is a merkle tree constructed by the list +of public randomness with starting height, and the number of public randomness. +It also stores the epoch number at which Babylon receives the commit. + +```protobuf +// PubRandCommit is a commitment to a series of public randomness +// currently, the commitment is a root of a Merkle tree that includes +// a series of public randomness +message PubRandCommit { + // start_height is the height of the first commitment + uint64 start_height = 1; + // num_pub_rand is the number of committed public randomness + uint64 num_pub_rand = 2; + // commitment is the value of the commitment + // currently, it is the root of the merkle tree constructed by the public randomness + bytes commitment = 3; + // epoch_num defines the epoch number that the commit falls into + uint64 epoch_num = 4; +} +``` + ### Finality votes The [finality vote storage](./keeper/votes.go) maintains the finality votes of @@ -240,6 +297,46 @@ message formats are defined at The message handlers are defined at [x/finality/keeper/msg_server.go](./keeper/msg_server.go). +### MsgCommitPubRandList + +The `MsgCommitPubRandList` message is used for committing a merkle tree +constructed by a list of EOTS public randomness that will be used by a +finality provider in the future. It is typically submitted by a finality +provider via the [finality provider](https://github.com/babylonchain/finality-provider) program. + +```protobuf +// MsgCommitPubRandList defines a message for committing a list of public randomness for EOTS +message MsgCommitPubRandList { + option (cosmos.msg.v1.signer) = "signer"; + string signer = 1; + // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; + // start_height is the start block height of the list of public randomness + uint64 start_height = 3; + // num_pub_rand is the number of public randomness committed + uint64 num_pub_rand = 4; + // commitment is the commitment of these public randomness + // currently it's the root of the Merkle tree that includes these public randomness + bytes commitment = 5; + // sig is the signature on (start_height || num_pub_rand || commitment) signed by + // SK corresponding to fp_btc_pk. This prevents others to commit public + // randomness on behalf of fp_btc_pk + bytes sig = 6 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; +} +``` + +Upon `MsgCommitPubRandList`, a Babylon node will execute as follows: + +1. Ensure the message contains at least `MinPubRand` number of EOTS public + randomness, where `MinPubRand` is defined in the module parameters. +2. Ensure the finality provider has been registered in Babylon. +3. Ensure the list of EOTS public randomness does not overlap with existing EOTS + public randomness that this finality provider previously committed before. +4. Verify the Schnorr signature over the list of public randomness signed by the + finality provider. +5. Store the list of EOTS public randomness along with the current epoch number + to the public randomness storage. + ### MsgAddFinalitySig The `MsgAddFinalitySig` message is used for submitting a finality vote, i.e., an diff --git a/x/finality/genesis_test.go b/x/finality/genesis_test.go index f66eb3555..3e7b821f7 100644 --- a/x/finality/genesis_test.go +++ b/x/finality/genesis_test.go @@ -3,11 +3,12 @@ package finality_test import ( "testing" + "github.com/stretchr/testify/require" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" "github.com/babylonlabs-io/babylon/testutil/nullify" "github.com/babylonlabs-io/babylon/x/finality" "github.com/babylonlabs-io/babylon/x/finality/types" - "github.com/stretchr/testify/require" ) func TestGenesis(t *testing.T) { @@ -15,7 +16,7 @@ func TestGenesis(t *testing.T) { Params: types.DefaultParams(), } - k, ctx := keepertest.FinalityKeeper(t, nil, nil) + k, ctx := keepertest.FinalityKeeper(t, nil, nil, nil) finality.InitGenesis(ctx, *k, genesisState) got := finality.ExportGenesis(ctx, *k) require.NotNil(t, got) diff --git a/x/finality/keeper/genesis_test.go b/x/finality/keeper/genesis_test.go index cdad29119..695b504d5 100644 --- a/x/finality/keeper/genesis_test.go +++ b/x/finality/keeper/genesis_test.go @@ -16,7 +16,7 @@ func FuzzTestExportGenesis(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - k, ctx := keepertest.FinalityKeeper(t, nil, nil) + k, ctx := keepertest.FinalityKeeper(t, nil, nil, nil) btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) diff --git a/x/finality/keeper/grpc_query_test.go b/x/finality/keeper/grpc_query_test.go index d8d878696..8f15e20a0 100644 --- a/x/finality/keeper/grpc_query_test.go +++ b/x/finality/keeper/grpc_query_test.go @@ -14,6 +14,7 @@ import ( "github.com/babylonlabs-io/babylon/testutil/datagen" testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" bbn "github.com/babylonlabs-io/babylon/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/babylonlabs-io/babylon/x/finality/keeper" "github.com/babylonlabs-io/babylon/x/finality/types" ) @@ -24,7 +25,7 @@ func FuzzBlock(f *testing.F) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil) + keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil, nil) ctx = sdk.UnwrapSDKContext(ctx) height := datagen.RandomInt(r, 100) @@ -55,7 +56,7 @@ func FuzzListBlocks(f *testing.F) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil) + keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil, nil) ctx = sdk.UnwrapSDKContext(ctx) // index a random list of finalised blocks @@ -146,7 +147,7 @@ func FuzzVotesAtHeight(f *testing.F) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil) + keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil, nil) ctx = sdk.UnwrapSDKContext(ctx) // Add random number of voted finality providers to the store @@ -191,7 +192,8 @@ func FuzzListPubRandCommit(f *testing.F) { // Setup keeper and context bsKeeper := types.NewMockBTCStakingKeeper(ctrl) - fKeeper, ctx := testkeeper.FinalityKeeper(t, bsKeeper, nil) + cKeeper := types.NewMockCheckpointingKeeper(ctrl) + fKeeper, ctx := testkeeper.FinalityKeeper(t, bsKeeper, nil, cKeeper) ctx = sdk.UnwrapSDKContext(ctx) ms := keeper.NewMsgServerImpl(*fKeeper) @@ -205,6 +207,7 @@ func FuzzListPubRandCommit(f *testing.F) { require.NoError(t, err) bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(bip340PK.MustMarshal())).Return(fp, nil).AnyTimes() bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(bip340PK.MustMarshal())).Return(true).AnyTimes() + cKeeper.EXPECT().GetEpoch(gomock.Any()).Return(&epochingtypes.Epoch{EpochNumber: 1}).AnyTimes() numPrCommitList := datagen.RandomInt(r, 10) + 1 prCommitList := []*types.PubRandCommit{} @@ -260,7 +263,7 @@ func FuzzQueryEvidence(f *testing.F) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil) + keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil, nil) ctx = sdk.UnwrapSDKContext(ctx) // set random BTC SK PK @@ -307,7 +310,7 @@ func FuzzListEvidences(f *testing.F) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil) + keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil, nil) ctx = sdk.UnwrapSDKContext(ctx) // generate a random list of evidences since startHeight @@ -371,7 +374,7 @@ func FuzzSigningInfo(f *testing.F) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - fKeeper, ctx := testkeeper.FinalityKeeper(t, nil, nil) + fKeeper, ctx := testkeeper.FinalityKeeper(t, nil, nil, nil) ctx = sdk.UnwrapSDKContext(ctx) // generate a random list of signing info diff --git a/x/finality/keeper/keeper.go b/x/finality/keeper/keeper.go index fe185a569..d569896f9 100644 --- a/x/finality/keeper/keeper.go +++ b/x/finality/keeper/keeper.go @@ -18,8 +18,9 @@ type ( cdc codec.BinaryCodec storeService corestoretypes.KVStoreService - BTCStakingKeeper types.BTCStakingKeeper - IncentiveKeeper types.IncentiveKeeper + BTCStakingKeeper types.BTCStakingKeeper + IncentiveKeeper types.IncentiveKeeper + CheckpointingKeeper types.CheckpointingKeeper // the address capable of executing a MsgUpdateParams message. Typically, this // should be the x/gov module account. authority string @@ -38,6 +39,7 @@ func NewKeeper( storeService corestoretypes.KVStoreService, btcstakingKeeper types.BTCStakingKeeper, incentiveKeeper types.IncentiveKeeper, + checkpointingKeeper types.CheckpointingKeeper, authority string, ) Keeper { sb := collections.NewSchemaBuilder(storeService) @@ -45,9 +47,10 @@ func NewKeeper( cdc: cdc, storeService: storeService, - BTCStakingKeeper: btcstakingKeeper, - IncentiveKeeper: incentiveKeeper, - authority: authority, + BTCStakingKeeper: btcstakingKeeper, + IncentiveKeeper: incentiveKeeper, + CheckpointingKeeper: checkpointingKeeper, + authority: authority, FinalityProviderSigningTracker: collections.NewMap( sb, types.FinalityProviderSigningInfoKeyPrefix, @@ -81,5 +84,14 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { } func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { - return k.BTCStakingKeeper.GetLastFinalizedEpoch(ctx) + return k.CheckpointingKeeper.GetLastFinalizedEpoch(ctx) +} + +func (k Keeper) GetCurrentEpoch(ctx context.Context) uint64 { + currentEpoch := k.CheckpointingKeeper.GetEpoch(ctx) + if currentEpoch == nil { + panic("cannot get the current epoch") + } + + return currentEpoch.EpochNumber } diff --git a/x/finality/keeper/liveness.go b/x/finality/keeper/liveness.go index 59cf453cc..f46e52b37 100644 --- a/x/finality/keeper/liveness.go +++ b/x/finality/keeper/liveness.go @@ -142,7 +142,7 @@ func (k Keeper) updateSigningInfo( // fetch signing info signInfo, err := k.FinalityProviderSigningTracker.Get(ctx, fpPk.MustMarshal()) if err != nil { - return false, nil, err + return false, nil, fmt.Errorf("the signing info is not created") } signedBlocksWindow := params.SignedBlocksWindow diff --git a/x/finality/keeper/liveness_test.go b/x/finality/keeper/liveness_test.go index da92702e5..74f25f2d6 100644 --- a/x/finality/keeper/liveness_test.go +++ b/x/finality/keeper/liveness_test.go @@ -24,7 +24,8 @@ func FuzzHandleLiveness(f *testing.F) { bsKeeper := types.NewMockBTCStakingKeeper(ctrl) bsKeeper.EXPECT().GetParams(gomock.Any()).Return(bstypes.Params{MaxActiveFinalityProviders: 100}).AnyTimes() iKeeper := types.NewMockIncentiveKeeper(ctrl) - fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper) + cKeeper := types.NewMockCheckpointingKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper, cKeeper) mockedHooks := types.NewMockFinalityHooks(ctrl) mockedHooks.EXPECT().AfterSluggishFinalityProviderDetected(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() diff --git a/x/finality/keeper/msg_server.go b/x/finality/keeper/msg_server.go index 3576f7cd1..7fdb6172e 100644 --- a/x/finality/keeper/msg_server.go +++ b/x/finality/keeper/msg_server.go @@ -7,12 +7,13 @@ import ( "time" errorsmod "cosmossdk.io/errors" - bbn "github.com/babylonlabs-io/babylon/types" - bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" - "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + bbn "github.com/babylonlabs-io/babylon/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) type msgServer struct { @@ -82,7 +83,7 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal } fpPK := req.FpBtcPk if ms.BTCStakingKeeper.GetVotingPower(ctx, fpPK.MustMarshal(), req.BlockHeight) == 0 { - return nil, types.ErrInvalidFinalitySig.Wrapf("the finality provider %v does not have voting power at height %d", fpPK.MustMarshal(), req.BlockHeight) + return nil, types.ErrInvalidFinalitySig.Wrapf("the finality provider %s does not have voting power at height %d", fpPK.MarshalHex(), req.BlockHeight) } // ensure the finality provider has not cast the same vote yet @@ -96,8 +97,8 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal return &types.MsgAddFinalitySigResponse{}, nil } - // find the public randomness commitment for this height from this finality provider - prCommit, err := ms.GetPubRandCommitForHeight(ctx, req.FpBtcPk, req.BlockHeight) + // find the timestamped public randomness commitment for this height from this finality provider + prCommit, err := ms.GetTimestampedPubRandCommitForHeight(ctx, req.FpBtcPk, req.BlockHeight) if err != nil { return nil, err } @@ -132,7 +133,7 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal // if this finality provider has also signed canonical block, slash it canonicalSig, err := ms.GetSig(ctx, req.BlockHeight, fpPK) if err == nil { - //set canonial sig + // set canonial sig evidence.CanonicalFinalitySig = canonicalSig // slash this finality provider, including setting its voting power to // zero, extracting its BTC SK, and emit an event @@ -206,6 +207,7 @@ func (ms msgServer) CommitPubRandList(goCtx context.Context, req *types.MsgCommi StartHeight: req.StartHeight, NumPubRand: req.NumPubRand, Commitment: req.Commitment, + EpochNum: ms.GetCurrentEpoch(ctx), } // get last public randomness commitment diff --git a/x/finality/keeper/msg_server_test.go b/x/finality/keeper/msg_server_test.go index 231ef895e..7bb39d9c9 100644 --- a/x/finality/keeper/msg_server_test.go +++ b/x/finality/keeper/msg_server_test.go @@ -7,18 +7,20 @@ import ( "time" "cosmossdk.io/core/header" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/babylonlabs-io/babylon/testutil/datagen" keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" bbn "github.com/babylonlabs-io/babylon/types" bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/babylonlabs-io/babylon/x/finality/keeper" "github.com/babylonlabs-io/babylon/x/finality/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) func setupMsgServer(t testing.TB) (*keeper.Keeper, types.MsgServer, context.Context) { - fKeeper, ctx := keepertest.FinalityKeeper(t, nil, nil) + fKeeper, ctx := keepertest.FinalityKeeper(t, nil, nil, nil) return fKeeper, keeper.NewMsgServerImpl(*fKeeper), ctx } @@ -29,7 +31,7 @@ func TestMsgServer(t *testing.T) { } func FuzzCommitPubRandList(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) + datagen.AddRandomSeedsToFuzzer(f, 100) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) @@ -37,8 +39,11 @@ func FuzzCommitPubRandList(f *testing.F) { defer ctrl.Finish() bsKeeper := types.NewMockBTCStakingKeeper(ctrl) - fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil) + cKeeper := types.NewMockCheckpointingKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil, cKeeper) ms := keeper.NewMsgServerImpl(*fKeeper) + committedEpochNum := datagen.GenRandomEpochNum(r) + cKeeper.EXPECT().GetEpoch(gomock.Any()).Return(&epochingtypes.Epoch{EpochNumber: committedEpochNum}).AnyTimes() // create a random finality provider btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) @@ -75,6 +80,11 @@ func FuzzCommitPubRandList(f *testing.F) { // query last public randomness and assert lastPrCommit := fKeeper.GetLastPubRandCommit(ctx, fpBTCPK) require.NotNil(t, lastPrCommit) + require.Equal(t, committedEpochNum, lastPrCommit.EpochNum) + committedHeight := datagen.RandomInt(r, int(numPubRand)) + startHeight + commitByHeight, err := fKeeper.GetPubRandCommitForHeight(ctx, fpBTCPK, committedHeight) + require.NoError(t, err) + require.Equal(t, committedEpochNum, commitByHeight.EpochNum) // Case 4: commit a pubrand list with overlap of the existing pubrand in KVStore and it should fail overlappedStartHeight := startHeight + numPubRand - 1 - datagen.RandomInt(r, 5) @@ -93,7 +103,7 @@ func FuzzCommitPubRandList(f *testing.F) { } func FuzzAddFinalitySig(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) + datagen.AddRandomSeedsToFuzzer(f, 100) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) @@ -101,7 +111,8 @@ func FuzzAddFinalitySig(f *testing.F) { defer ctrl.Finish() bsKeeper := types.NewMockBTCStakingKeeper(ctrl) - fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil) + cKeeper := types.NewMockCheckpointingKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil, cKeeper) ms := keeper.NewMsgServerImpl(*fKeeper) // create and register a random finality provider @@ -113,6 +124,11 @@ func FuzzAddFinalitySig(f *testing.F) { fpBTCPKBytes := fpBTCPK.MustMarshal() require.NoError(t, err) bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(true).AnyTimes() + + // set committed epoch num + committedEpochNum := datagen.GenRandomEpochNum(r) + 1 + cKeeper.EXPECT().GetEpoch(gomock.Any()).Return(&epochingtypes.Epoch{EpochNumber: committedEpochNum}).AnyTimes() + // commit some public randomness startHeight := uint64(0) numPubRand := uint64(200) @@ -128,6 +144,18 @@ func FuzzAddFinalitySig(f *testing.F) { msg, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blockHeight, randListInfo, blockAppHash) require.NoError(t, err) + // Case 0: fail if the committed epoch is not finalized + lastFinalizedEpoch := datagen.RandomInt(r, int(committedEpochNum)) + o1 := cKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(lastFinalizedEpoch).Times(1) + bsKeeper.EXPECT().GetVotingPower(gomock.Any(), gomock.Eq(fpBTCPKBytes), gomock.Eq(blockHeight)).Return(uint64(1)).Times(1) + bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) + _, err = ms.AddFinalitySig(ctx, msg) + require.ErrorIs(t, err, types.ErrPubRandCommitNotBTCTimestamped) + + // set the committed epoch finalized for the rest of the cases + lastFinalizedEpoch = datagen.GenRandomEpochNum(r) + committedEpochNum + cKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(lastFinalizedEpoch).After(o1).AnyTimes() + // Case 1: fail if the finality provider does not have voting power bsKeeper.EXPECT().GetVotingPower(gomock.Any(), gomock.Eq(fpBTCPKBytes), gomock.Eq(blockHeight)).Return(uint64(0)).Times(1) bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) @@ -208,7 +236,8 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() bsKeeper := types.NewMockBTCStakingKeeper(ctrl) - fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil) + cKeeper := types.NewMockCheckpointingKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil, cKeeper) ms := keeper.NewMsgServerImpl(*fKeeper) // create and register a random finality provider btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) @@ -220,6 +249,8 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { require.NoError(t, err) bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(true).AnyTimes() + cKeeper.EXPECT().GetEpoch(gomock.Any()).Return(&epochingtypes.Epoch{EpochNumber: 1}).AnyTimes() + cKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(1)).AnyTimes() // commit some public randomness startHeight := uint64(0) numPubRand := uint64(200) @@ -245,7 +276,6 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { // some "evidence" ctx = ctx.WithHeaderInfo(header.Info{Height: int64(blockHeight), AppHash: forkHash}) msg1, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blockHeight, randListInfo, forkHash) - require.NoError(t, err) bsKeeper.EXPECT().GetVotingPower(gomock.Any(), gomock.Eq(fpBTCPKBytes), diff --git a/x/finality/keeper/params_test.go b/x/finality/keeper/params_test.go index 649fd3eda..b4621546d 100644 --- a/x/finality/keeper/params_test.go +++ b/x/finality/keeper/params_test.go @@ -3,13 +3,14 @@ package keeper_test import ( "testing" + "github.com/stretchr/testify/require" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" "github.com/babylonlabs-io/babylon/x/finality/types" - "github.com/stretchr/testify/require" ) func TestGetParams(t *testing.T) { - k, ctx := testkeeper.FinalityKeeper(t, nil, nil) + k, ctx := testkeeper.FinalityKeeper(t, nil, nil, nil) params := types.DefaultParams() err := k.SetParams(ctx, params) diff --git a/x/finality/keeper/public_randomness.go b/x/finality/keeper/public_randomness.go index 68cb87e84..d68dc6f48 100644 --- a/x/finality/keeper/public_randomness.go +++ b/x/finality/keeper/public_randomness.go @@ -7,9 +7,10 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" "cosmossdk.io/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/babylonlabs-io/babylon/x/finality/types" - sdk "github.com/cosmos/cosmos-sdk/types" ) /* @@ -33,6 +34,33 @@ func (k Keeper) GetPubRandCommitForHeight(ctx context.Context, fpBtcPK *bbn.BIP3 return nil, types.ErrPubRandNotFound } +// GetTimestampedPubRandCommitForHeight finds the public randomness commitment that includes the given +// height for the given finality provider +func (k Keeper) GetTimestampedPubRandCommitForHeight(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64) (*types.PubRandCommit, error) { + prCommit, err := k.GetPubRandCommitForHeight(ctx, fpBtcPK, height) + if err != nil { + return nil, err + } + + // ensure the finality provider's last randomness commit is already finalised by BTC timestamping + finalizedEpoch := k.GetLastFinalizedEpoch(ctx) + if finalizedEpoch == 0 { + return nil, types.ErrPubRandCommitNotBTCTimestamped.Wrapf("no finalized epoch yet") + } + if finalizedEpoch < prCommit.EpochNum { + return nil, types.ErrPubRandCommitNotBTCTimestamped. + Wrapf("the finality provider %s last committed epoch number: %d, last finalized epoch number: %d", + fpBtcPK.MarshalHex(), prCommit.EpochNum, finalizedEpoch) + } + + return prCommit, nil +} + +func (k Keeper) HasTimestampedPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64) bool { + _, err := k.GetTimestampedPubRandCommitForHeight(ctx, fpBtcPK, height) + return err == nil +} + // SetPubRandCommit adds the given public randomness commitment for the given public key func (k Keeper) SetPubRandCommit(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, prCommit *types.PubRandCommit) { store := k.pubRandCommitFpStore(ctx, fpBtcPK) diff --git a/x/finality/keeper/query_params_test.go b/x/finality/keeper/query_params_test.go index 2bdbfcc07..bc670b3e0 100644 --- a/x/finality/keeper/query_params_test.go +++ b/x/finality/keeper/query_params_test.go @@ -3,13 +3,14 @@ package keeper_test import ( "testing" + "github.com/stretchr/testify/require" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" "github.com/babylonlabs-io/babylon/x/finality/types" - "github.com/stretchr/testify/require" ) func TestParamsQuery(t *testing.T) { - keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil) + keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil, nil) params := types.DefaultParams() err := keeper.SetParams(ctx, params) require.NoError(t, err) diff --git a/x/finality/keeper/tallying.go b/x/finality/keeper/tallying.go index 9af4c6fec..efc2ef4e1 100644 --- a/x/finality/keeper/tallying.go +++ b/x/finality/keeper/tallying.go @@ -4,8 +4,9 @@ import ( "context" "fmt" - "github.com/babylonlabs-io/babylon/x/finality/types" sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/babylonlabs-io/babylon/x/finality/types" ) // TallyBlocks tries to finalise all blocks that are non-finalised AND have a non-nil @@ -89,8 +90,7 @@ func (k Keeper) finalizeBlock(ctx context.Context, block *types.IndexedBlock, vo panic(err) } // filter out voted finality providers - maxActiveFPs := k.BTCStakingKeeper.GetParams(ctx).MaxActiveFinalityProviders - filteredDc := dc.FilterVotedDistCache(maxActiveFPs, voterBTCPKs) + filteredDc := dc.FilterVotedDistCache(voterBTCPKs) // reward voted finality providers k.IncentiveKeeper.RewardBTCStaking(ctx, block.Height, filteredDc) // remove reward distribution cache afterwards diff --git a/x/finality/keeper/tallying_bench_test.go b/x/finality/keeper/tallying_bench_test.go index abe4c38ca..52b1532d7 100644 --- a/x/finality/keeper/tallying_bench_test.go +++ b/x/finality/keeper/tallying_bench_test.go @@ -8,13 +8,14 @@ import ( "testing" "time" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/babylonlabs-io/babylon/testutil/datagen" keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" bbn "github.com/babylonlabs-io/babylon/types" bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/babylonlabs-io/babylon/x/finality/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) func benchmarkTallyBlocks(b *testing.B, numFPs int) { @@ -24,7 +25,8 @@ func benchmarkTallyBlocks(b *testing.B, numFPs int) { bsKeeper := types.NewMockBTCStakingKeeper(ctrl) iKeeper := types.NewMockIncentiveKeeper(ctrl) - fKeeper, ctx := keepertest.FinalityKeeper(b, bsKeeper, iKeeper) + cKeeper := types.NewMockCheckpointingKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(b, bsKeeper, iKeeper, cKeeper) // activate BTC staking protocol at a random height activatedHeight := uint64(1) diff --git a/x/finality/keeper/tallying_test.go b/x/finality/keeper/tallying_test.go index 881985136..9a69988d2 100644 --- a/x/finality/keeper/tallying_test.go +++ b/x/finality/keeper/tallying_test.go @@ -5,15 +5,16 @@ import ( "math/rand" "testing" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/babylonlabs-io/babylon/testutil/datagen" keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" bbn "github.com/babylonlabs-io/babylon/types" bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/babylonlabs-io/babylon/x/finality/keeper" "github.com/babylonlabs-io/babylon/x/finality/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) func FuzzTallying_PanicCases(f *testing.F) { @@ -26,7 +27,8 @@ func FuzzTallying_PanicCases(f *testing.F) { bsKeeper := types.NewMockBTCStakingKeeper(ctrl) iKeeper := types.NewMockIncentiveKeeper(ctrl) - fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper) + cKeeper := types.NewMockCheckpointingKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper, cKeeper) // Case 1: expect to panic if tallying upon BTC staking protocol is not activated bsKeeper.EXPECT().GetBTCStakingActivatedHeight(gomock.Any()).Return(uint64(0), bstypes.ErrBTCStakingNotActivated).Times(1) @@ -56,7 +58,8 @@ func FuzzTallying_FinalizingNoBlock(f *testing.F) { bsKeeper := types.NewMockBTCStakingKeeper(ctrl) iKeeper := types.NewMockIncentiveKeeper(ctrl) - fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper) + cKeeper := types.NewMockCheckpointingKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper, cKeeper) // activate BTC staking protocol at a random height activatedHeight := datagen.RandomInt(r, 10) + 1 @@ -99,7 +102,8 @@ func FuzzTallying_FinalizingSomeBlocks(f *testing.F) { bsKeeper := types.NewMockBTCStakingKeeper(ctrl) bsKeeper.EXPECT().GetParams(gomock.Any()).Return(bstypes.Params{MaxActiveFinalityProviders: 100}).AnyTimes() iKeeper := types.NewMockIncentiveKeeper(ctrl) - fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper) + cKeeper := types.NewMockCheckpointingKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper, cKeeper) // activate BTC staking protocol at a random height activatedHeight := datagen.RandomInt(r, 10) + 1 diff --git a/x/finality/keeper/votes_bench_test.go b/x/finality/keeper/votes_bench_test.go index 2f78a75c4..3a0f97faa 100644 --- a/x/finality/keeper/votes_bench_test.go +++ b/x/finality/keeper/votes_bench_test.go @@ -8,13 +8,14 @@ import ( "time" "cosmossdk.io/core/header" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/babylonlabs-io/babylon/testutil/datagen" keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" bbn "github.com/babylonlabs-io/babylon/types" "github.com/babylonlabs-io/babylon/x/finality/keeper" "github.com/babylonlabs-io/babylon/x/finality/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) func benchmarkAddFinalitySig(b *testing.B) { @@ -23,7 +24,8 @@ func benchmarkAddFinalitySig(b *testing.B) { defer ctrl.Finish() bsKeeper := types.NewMockBTCStakingKeeper(ctrl) - fKeeper, ctx := keepertest.FinalityKeeper(b, bsKeeper, nil) + cKeeper := types.NewMockCheckpointingKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(b, bsKeeper, nil, cKeeper) ms := keeper.NewMsgServerImpl(*fKeeper) // create a random finality provider diff --git a/x/finality/types/errors.go b/x/finality/types/errors.go index ee10b27fb..12a2966d8 100644 --- a/x/finality/types/errors.go +++ b/x/finality/types/errors.go @@ -6,15 +6,15 @@ import ( // x/finality module sentinel errors var ( - ErrBlockNotFound = errorsmod.Register(ModuleName, 1100, "Block is not found") - ErrVoteNotFound = errorsmod.Register(ModuleName, 1101, "vote is not found") - ErrHeightTooHigh = errorsmod.Register(ModuleName, 1102, "the chain has not reached the given height yet") - ErrPubRandNotFound = errorsmod.Register(ModuleName, 1103, "public randomness is not found") - ErrPubRandCommitNotFound = errorsmod.Register(ModuleName, 1104, "public randomness commitment is not found") - ErrNoPubRandYet = errorsmod.Register(ModuleName, 1105, "the finality provider has not committed any public randomness yet") - ErrTooFewPubRand = errorsmod.Register(ModuleName, 1106, "the request contains too few public randomness") - ErrInvalidPubRand = errorsmod.Register(ModuleName, 1107, "the public randomness list is invalid") - ErrEvidenceNotFound = errorsmod.Register(ModuleName, 1108, "evidence is not found") - ErrInvalidFinalitySig = errorsmod.Register(ModuleName, 1109, "finality signature is not valid") - ErrNoSlashableEvidence = errorsmod.Register(ModuleName, 1110, "there is no slashable evidence") + ErrBlockNotFound = errorsmod.Register(ModuleName, 1100, "Block is not found") + ErrVoteNotFound = errorsmod.Register(ModuleName, 1101, "vote is not found") + ErrHeightTooHigh = errorsmod.Register(ModuleName, 1102, "the chain has not reached the given height yet") + ErrPubRandNotFound = errorsmod.Register(ModuleName, 1103, "public randomness is not found") + ErrNoPubRandYet = errorsmod.Register(ModuleName, 1104, "the finality provider has not committed any public randomness yet") + ErrTooFewPubRand = errorsmod.Register(ModuleName, 1105, "the request contains too few public randomness") + ErrInvalidPubRand = errorsmod.Register(ModuleName, 1106, "the public randomness list is invalid") + ErrEvidenceNotFound = errorsmod.Register(ModuleName, 1107, "evidence is not found") + ErrInvalidFinalitySig = errorsmod.Register(ModuleName, 1108, "finality signature is not valid") + ErrNoSlashableEvidence = errorsmod.Register(ModuleName, 1109, "there is no slashable evidence") + ErrPubRandCommitNotBTCTimestamped = errorsmod.Register(ModuleName, 1110, "the public randomness commit is not BTC timestamped yet") ) diff --git a/x/finality/types/expected_keepers.go b/x/finality/types/expected_keepers.go index f4d6e58d9..f3e47d3ff 100644 --- a/x/finality/types/expected_keepers.go +++ b/x/finality/types/expected_keepers.go @@ -5,6 +5,7 @@ import ( bbn "github.com/babylonlabs-io/babylon/types" bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + etypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) type BTCStakingKeeper interface { @@ -17,10 +18,14 @@ type BTCStakingKeeper interface { GetBTCStakingActivatedHeight(ctx context.Context) (uint64, error) GetVotingPowerDistCache(ctx context.Context, height uint64) (*bstypes.VotingPowerDistCache, error) RemoveVotingPowerDistCache(ctx context.Context, height uint64) - GetLastFinalizedEpoch(ctx context.Context) uint64 RevertSluggishFinalityProvider(ctx context.Context, fpBTCPK []byte) error } +type CheckpointingKeeper interface { + GetEpoch(ctx context.Context) *etypes.Epoch + GetLastFinalizedEpoch(ctx context.Context) uint64 +} + // IncentiveKeeper defines the expected interface needed to distribute rewards. type IncentiveKeeper interface { RewardBTCStaking(ctx context.Context, height uint64, filteredDc *bstypes.VotingPowerDistCache) diff --git a/x/finality/types/finality.pb.go b/x/finality/types/finality.pb.go index 8d2eb5f4b..0b1804fbf 100644 --- a/x/finality/types/finality.pb.go +++ b/x/finality/types/finality.pb.go @@ -100,6 +100,8 @@ type PubRandCommit struct { // commitment is the value of the commitment // currently, it is the root of the merkle tree constructed by the public randomness Commitment []byte `protobuf:"bytes,3,opt,name=commitment,proto3" json:"commitment,omitempty"` + // epoch_num defines the epoch number that the commit falls into + EpochNum uint64 `protobuf:"varint,4,opt,name=epoch_num,json=epochNum,proto3" json:"epoch_num,omitempty"` } func (m *PubRandCommit) Reset() { *m = PubRandCommit{} } @@ -156,6 +158,13 @@ func (m *PubRandCommit) GetCommitment() []byte { return nil } +func (m *PubRandCommit) GetEpochNum() uint64 { + if m != nil { + return m.EpochNum + } + return 0 +} + // Evidence is the evidence that a finality provider has signed finality // signatures with correct public randomness on two conflicting Babylon headers type Evidence struct { @@ -304,41 +313,43 @@ func init() { } var fileDescriptor_ca5b87e52e3e6d02 = []byte{ - // 539 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x4d, 0x6f, 0xd3, 0x30, - 0x18, 0x6e, 0x68, 0x69, 0x3b, 0x37, 0x13, 0x90, 0x8d, 0xa9, 0x7c, 0x28, 0x2b, 0x39, 0xf5, 0x00, - 0x2d, 0xfb, 0x10, 0x42, 0xdc, 0xc8, 0x34, 0xb4, 0x0a, 0x24, 0xaa, 0x74, 0x5c, 0xb8, 0x58, 0x4e, - 0xe2, 0x24, 0x56, 0x1b, 0xdb, 0x8a, 0x9d, 0x6a, 0xe5, 0x07, 0x70, 0xe6, 0x67, 0x21, 0x4e, 0x3b, - 0xa2, 0x1d, 0x26, 0xd4, 0xfe, 0x11, 0x14, 0xe7, 0xa3, 0xeb, 0x09, 0x04, 0xda, 0x2d, 0x7e, 0xdf, - 0x57, 0xcf, 0xc7, 0xeb, 0x27, 0x06, 0x96, 0x8b, 0xdc, 0xc5, 0x8c, 0xd1, 0x61, 0x40, 0x28, 0x9a, - 0x11, 0xb9, 0x18, 0xce, 0x0f, 0xaa, 0xef, 0x01, 0x4f, 0x98, 0x64, 0xc6, 0x4e, 0x31, 0x33, 0xa8, - 0xea, 0xf3, 0x83, 0xc7, 0xbb, 0x21, 0x0b, 0x99, 0xea, 0x0f, 0xb3, 0xaf, 0x7c, 0xd4, 0x82, 0x40, - 0x1f, 0x51, 0x1f, 0x5f, 0x60, 0xdf, 0x9e, 0x31, 0x6f, 0x6a, 0xec, 0x81, 0x66, 0x84, 0x49, 0x18, - 0xc9, 0xae, 0xd6, 0xd3, 0xfa, 0x0d, 0xa7, 0x38, 0x19, 0x8f, 0x40, 0x1b, 0x71, 0x0e, 0x23, 0x24, - 0xa2, 0xee, 0x9d, 0x9e, 0xd6, 0xd7, 0x9d, 0x16, 0xe2, 0xfc, 0x0c, 0x89, 0xc8, 0x78, 0x0a, 0xb6, - 0x72, 0x9e, 0x2f, 0xd8, 0xef, 0xd6, 0x7b, 0x5a, 0xbf, 0xed, 0xac, 0x0b, 0x96, 0x04, 0xdb, 0xe3, - 0xd4, 0x75, 0x10, 0xf5, 0x4f, 0x58, 0x1c, 0x13, 0x69, 0x3c, 0x03, 0xba, 0x90, 0x28, 0x91, 0x70, - 0x83, 0xa7, 0xa3, 0x6a, 0x67, 0x39, 0x59, 0x0f, 0xe8, 0x34, 0x8d, 0x21, 0x4f, 0x5d, 0x98, 0x20, - 0xea, 0x2b, 0xc2, 0x86, 0x03, 0x68, 0x1a, 0x17, 0x50, 0x86, 0x09, 0x80, 0xa7, 0xe0, 0x62, 0x4c, - 0xa5, 0x22, 0xd5, 0x9d, 0x1b, 0x15, 0xeb, 0x6b, 0x03, 0xb4, 0x4f, 0xe7, 0xc4, 0xc7, 0xd4, 0xc3, - 0xc6, 0x39, 0xd8, 0x0a, 0x38, 0x74, 0xa5, 0x07, 0xf9, 0x54, 0xd1, 0xe9, 0xf6, 0xeb, 0xab, 0xeb, - 0xfd, 0xe3, 0x90, 0xc8, 0x28, 0x75, 0x07, 0x1e, 0x8b, 0x87, 0xc5, 0xc2, 0x66, 0xc8, 0x15, 0x2f, - 0x08, 0x2b, 0x8f, 0x43, 0xb9, 0xe0, 0x58, 0x0c, 0xec, 0xd1, 0xf8, 0xe8, 0xf8, 0xe5, 0x38, 0x75, - 0xdf, 0xe3, 0x85, 0xd3, 0x0a, 0xb8, 0x2d, 0xbd, 0xf1, 0x34, 0xf3, 0xe1, 0x66, 0x2b, 0x2b, 0x7d, - 0xe4, 0x22, 0x3b, 0xaa, 0x56, 0xf8, 0xf8, 0x04, 0xda, 0x95, 0x07, 0xa5, 0xd1, 0x7e, 0x73, 0x75, - 0xbd, 0xff, 0xea, 0x6f, 0x79, 0x27, 0x5e, 0x44, 0x59, 0x92, 0x14, 0x9e, 0x9d, 0x16, 0x2f, 0xcc, - 0x3f, 0x07, 0x86, 0x87, 0x28, 0xa3, 0xc4, 0x43, 0x33, 0x58, 0xdd, 0x4a, 0x43, 0x2d, 0xe1, 0x7e, - 0xd5, 0x79, 0x5b, 0x5c, 0x8f, 0x05, 0xb6, 0x03, 0x96, 0x4c, 0xd7, 0x83, 0x77, 0xd5, 0x60, 0x27, - 0x2b, 0x96, 0x33, 0x1c, 0xec, 0xad, 0x11, 0xcb, 0xd0, 0x40, 0x41, 0xc2, 0x6e, 0xf3, 0x9f, 0x65, - 0x9f, 0x7e, 0x3c, 0x9f, 0x4c, 0x48, 0xe8, 0xec, 0x56, 0xc8, 0xef, 0x0a, 0xe0, 0x09, 0x09, 0x8d, - 0x00, 0x3c, 0x50, 0xaa, 0x36, 0xc8, 0x5a, 0xff, 0x4d, 0x76, 0x2f, 0x03, 0xbd, 0xc1, 0x63, 0xfd, - 0xd0, 0xc0, 0x93, 0xf2, 0x3c, 0x4e, 0x58, 0x16, 0x89, 0x64, 0x42, 0x42, 0x4a, 0x68, 0x38, 0xa2, - 0x01, 0xbb, 0xbd, 0x6c, 0x6c, 0x64, 0x3c, 0xcb, 0x46, 0x7d, 0x33, 0xe3, 0x87, 0xe0, 0x61, 0x4c, - 0x84, 0xc0, 0x3e, 0x54, 0x89, 0x11, 0xd0, 0x63, 0x29, 0x95, 0x38, 0x51, 0x41, 0xa9, 0x3b, 0x3b, - 0x79, 0x53, 0xfd, 0x94, 0xe2, 0x24, 0x6f, 0xd9, 0x1f, 0xbe, 0x2f, 0x4d, 0xed, 0x72, 0x69, 0x6a, - 0xbf, 0x96, 0xa6, 0xf6, 0x6d, 0x65, 0xd6, 0x2e, 0x57, 0x66, 0xed, 0xe7, 0xca, 0xac, 0x7d, 0x3e, - 0xfc, 0xb3, 0xde, 0x8b, 0xf5, 0x8b, 0xa1, 0xa4, 0xbb, 0x4d, 0xf5, 0x02, 0x1c, 0xfd, 0x0e, 0x00, - 0x00, 0xff, 0xff, 0xb1, 0x31, 0x31, 0x81, 0x52, 0x04, 0x00, 0x00, + // 561 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x4d, 0x6f, 0xd3, 0x40, + 0x10, 0x8d, 0x49, 0xc8, 0xc7, 0xc6, 0x15, 0xe0, 0x96, 0x2a, 0x50, 0xe4, 0x06, 0x9f, 0x72, 0x80, + 0x84, 0x7e, 0x08, 0x21, 0x6e, 0xb8, 0x2a, 0x6a, 0x04, 0x82, 0xc8, 0x29, 0x17, 0x2e, 0xab, 0xf5, + 0x7a, 0x6d, 0xaf, 0x12, 0xef, 0xae, 0xec, 0x75, 0xd4, 0xf0, 0x03, 0x38, 0xc3, 0xbf, 0x42, 0x9c, + 0x7a, 0x44, 0x3d, 0x54, 0x28, 0xf9, 0x23, 0xc8, 0x6b, 0xc7, 0x69, 0x4e, 0x20, 0x10, 0x37, 0xef, + 0x9b, 0xf1, 0xbc, 0x79, 0xb3, 0x6f, 0x16, 0x58, 0x2e, 0x72, 0xe7, 0x53, 0xce, 0x06, 0x3e, 0x65, + 0x68, 0x4a, 0xe5, 0x7c, 0x30, 0x3b, 0x28, 0xbf, 0xfb, 0x22, 0xe6, 0x92, 0x1b, 0xdb, 0x45, 0x4e, + 0xbf, 0xc4, 0x67, 0x07, 0x0f, 0x77, 0x02, 0x1e, 0x70, 0x15, 0x1f, 0x64, 0x5f, 0x79, 0xaa, 0x05, + 0x81, 0x3e, 0x64, 0x1e, 0xb9, 0x20, 0x9e, 0x3d, 0xe5, 0x78, 0x62, 0xec, 0x82, 0x7a, 0x48, 0x68, + 0x10, 0xca, 0x8e, 0xd6, 0xd5, 0x7a, 0x35, 0xa7, 0x38, 0x19, 0x0f, 0x40, 0x13, 0x09, 0x01, 0x43, + 0x94, 0x84, 0x9d, 0x5b, 0x5d, 0xad, 0xa7, 0x3b, 0x0d, 0x24, 0xc4, 0x19, 0x4a, 0x42, 0xe3, 0x11, + 0x68, 0xe5, 0x3c, 0x9f, 0x88, 0xd7, 0xa9, 0x76, 0xb5, 0x5e, 0xd3, 0x59, 0x03, 0xd6, 0x57, 0x0d, + 0x6c, 0x8d, 0x52, 0xd7, 0x41, 0xcc, 0x3b, 0xe1, 0x51, 0x44, 0xa5, 0xf1, 0x18, 0xe8, 0x89, 0x44, + 0xb1, 0x84, 0x1b, 0x44, 0x6d, 0x85, 0x9d, 0xe5, 0x6c, 0x5d, 0xa0, 0xb3, 0x34, 0x82, 0x22, 0x75, + 0x61, 0x8c, 0x98, 0xa7, 0x18, 0x6b, 0x0e, 0x60, 0x69, 0x54, 0x94, 0x32, 0x4c, 0x00, 0xb0, 0x2a, + 0x17, 0x11, 0x26, 0x15, 0xab, 0xee, 0xdc, 0x40, 0x8c, 0x3d, 0xd0, 0x22, 0x82, 0xe3, 0x10, 0xb2, + 0x34, 0xea, 0xd4, 0xd4, 0xef, 0x4d, 0x05, 0xbc, 0x4b, 0x23, 0xeb, 0x73, 0x0d, 0x34, 0x4f, 0x67, + 0xd4, 0x23, 0x0c, 0x13, 0xe3, 0x1c, 0xb4, 0x7c, 0x01, 0x5d, 0x89, 0xa1, 0x98, 0xa8, 0x5e, 0x74, + 0xfb, 0xc5, 0xd5, 0xf5, 0xfe, 0x71, 0x40, 0x65, 0x98, 0xba, 0x7d, 0xcc, 0xa3, 0x41, 0x31, 0xce, + 0x29, 0x72, 0x93, 0xa7, 0x94, 0xaf, 0x8e, 0x03, 0x39, 0x17, 0x24, 0xe9, 0xdb, 0xc3, 0xd1, 0xd1, + 0xf1, 0xb3, 0x51, 0xea, 0xbe, 0x21, 0x73, 0xa7, 0xe1, 0x0b, 0x5b, 0xe2, 0xd1, 0x24, 0x13, 0xe9, + 0x66, 0x03, 0x5d, 0x89, 0xcc, 0x15, 0xb4, 0x15, 0x56, 0x88, 0xfc, 0x00, 0x9a, 0xa5, 0x40, 0x25, + 0xc0, 0x7e, 0x79, 0x75, 0xbd, 0xff, 0xfc, 0x4f, 0x79, 0xc7, 0x38, 0x64, 0x3c, 0x8e, 0x8b, 0x81, + 0x38, 0x0d, 0x51, 0x4c, 0xe6, 0x09, 0x30, 0x30, 0x62, 0x9c, 0x51, 0x8c, 0xa6, 0xb0, 0xbc, 0xb3, + 0x9a, 0x9a, 0xd0, 0xdd, 0x32, 0xf2, 0xaa, 0xb8, 0x3c, 0x0b, 0x6c, 0xf9, 0x3c, 0x9e, 0xac, 0x13, + 0x6f, 0xab, 0xc4, 0x76, 0x06, 0xae, 0x72, 0x04, 0xd8, 0x5d, 0x57, 0x5c, 0x59, 0x0a, 0x26, 0x34, + 0xe8, 0xd4, 0xff, 0xba, 0xed, 0xd3, 0xf7, 0xe7, 0xe3, 0x31, 0x0d, 0x9c, 0x9d, 0xb2, 0xf2, 0xeb, + 0xa2, 0xf0, 0x98, 0x06, 0x86, 0x0f, 0xee, 0xa9, 0xae, 0x36, 0xc8, 0x1a, 0xff, 0x4c, 0x76, 0x27, + 0x2b, 0x7a, 0x83, 0xc7, 0xfa, 0xae, 0x81, 0xbd, 0xd5, 0x79, 0x14, 0xf3, 0xcc, 0x12, 0xf1, 0x98, + 0x06, 0x8c, 0xb2, 0x60, 0xc8, 0x7c, 0xfe, 0xff, 0xbc, 0xb1, 0xb1, 0x00, 0x99, 0x37, 0xaa, 0x9b, + 0x0b, 0x70, 0x08, 0xee, 0x47, 0x34, 0x49, 0x88, 0x07, 0x95, 0x63, 0x12, 0x88, 0x79, 0xca, 0x24, + 0x89, 0x95, 0x51, 0xaa, 0xce, 0x76, 0x1e, 0x54, 0x2b, 0x9b, 0x9c, 0xe4, 0x21, 0xfb, 0xed, 0xb7, + 0x85, 0xa9, 0x5d, 0x2e, 0x4c, 0xed, 0xe7, 0xc2, 0xd4, 0xbe, 0x2c, 0xcd, 0xca, 0xe5, 0xd2, 0xac, + 0xfc, 0x58, 0x9a, 0x95, 0x8f, 0x87, 0xbf, 0xef, 0xf7, 0x62, 0xfd, 0x9e, 0xa8, 0xd6, 0xdd, 0xba, + 0x7a, 0x1f, 0x8e, 0x7e, 0x05, 0x00, 0x00, 0xff, 0xff, 0x1b, 0xa1, 0x77, 0x79, 0x70, 0x04, 0x00, + 0x00, } func (m *IndexedBlock) Marshal() (dAtA []byte, err error) { @@ -406,6 +417,11 @@ func (m *PubRandCommit) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.EpochNum != 0 { + i = encodeVarintFinality(dAtA, i, uint64(m.EpochNum)) + i-- + dAtA[i] = 0x20 + } if len(m.Commitment) > 0 { i -= len(m.Commitment) copy(dAtA[i:], m.Commitment) @@ -607,6 +623,9 @@ func (m *PubRandCommit) Size() (n int) { if l > 0 { n += 1 + l + sovFinality(uint64(l)) } + if m.EpochNum != 0 { + n += 1 + sovFinality(uint64(m.EpochNum)) + } return n } @@ -895,6 +914,25 @@ func (m *PubRandCommit) Unmarshal(dAtA []byte) error { m.Commitment = []byte{} } iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochNum", wireType) + } + m.EpochNum = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFinality + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochNum |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipFinality(dAtA[iNdEx:]) diff --git a/x/finality/types/mocked_keepers.go b/x/finality/types/mocked_keepers.go index c546a68da..5af122cda 100644 --- a/x/finality/types/mocked_keepers.go +++ b/x/finality/types/mocked_keepers.go @@ -10,6 +10,7 @@ import ( types "github.com/babylonlabs-io/babylon/types" types0 "github.com/babylonlabs-io/babylon/x/btcstaking/types" + types1 "github.com/babylonlabs-io/babylon/x/epoching/types" gomock "github.com/golang/mock/gomock" ) @@ -66,20 +67,6 @@ func (mr *MockBTCStakingKeeperMockRecorder) GetFinalityProvider(ctx, fpBTCPK int return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFinalityProvider", reflect.TypeOf((*MockBTCStakingKeeper)(nil).GetFinalityProvider), ctx, fpBTCPK) } -// GetLastFinalizedEpoch mocks base method. -func (m *MockBTCStakingKeeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLastFinalizedEpoch", ctx) - ret0, _ := ret[0].(uint64) - return ret0 -} - -// GetLastFinalizedEpoch indicates an expected call of GetLastFinalizedEpoch. -func (mr *MockBTCStakingKeeperMockRecorder) GetLastFinalizedEpoch(ctx interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastFinalizedEpoch", reflect.TypeOf((*MockBTCStakingKeeper)(nil).GetLastFinalizedEpoch), ctx) -} - // GetParams mocks base method. func (m *MockBTCStakingKeeper) GetParams(ctx context.Context) types0.Params { m.ctrl.T.Helper() @@ -191,6 +178,57 @@ func (mr *MockBTCStakingKeeperMockRecorder) SlashFinalityProvider(ctx, fpBTCPK i return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SlashFinalityProvider", reflect.TypeOf((*MockBTCStakingKeeper)(nil).SlashFinalityProvider), ctx, fpBTCPK) } +// MockCheckpointingKeeper is a mock of CheckpointingKeeper interface. +type MockCheckpointingKeeper struct { + ctrl *gomock.Controller + recorder *MockCheckpointingKeeperMockRecorder +} + +// MockCheckpointingKeeperMockRecorder is the mock recorder for MockCheckpointingKeeper. +type MockCheckpointingKeeperMockRecorder struct { + mock *MockCheckpointingKeeper +} + +// NewMockCheckpointingKeeper creates a new mock instance. +func NewMockCheckpointingKeeper(ctrl *gomock.Controller) *MockCheckpointingKeeper { + mock := &MockCheckpointingKeeper{ctrl: ctrl} + mock.recorder = &MockCheckpointingKeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCheckpointingKeeper) EXPECT() *MockCheckpointingKeeperMockRecorder { + return m.recorder +} + +// GetEpoch mocks base method. +func (m *MockCheckpointingKeeper) GetEpoch(ctx context.Context) *types1.Epoch { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetEpoch", ctx) + ret0, _ := ret[0].(*types1.Epoch) + return ret0 +} + +// GetEpoch indicates an expected call of GetEpoch. +func (mr *MockCheckpointingKeeperMockRecorder) GetEpoch(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEpoch", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetEpoch), ctx) +} + +// GetLastFinalizedEpoch mocks base method. +func (m *MockCheckpointingKeeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLastFinalizedEpoch", ctx) + ret0, _ := ret[0].(uint64) + return ret0 +} + +// GetLastFinalizedEpoch indicates an expected call of GetLastFinalizedEpoch. +func (mr *MockCheckpointingKeeperMockRecorder) GetLastFinalizedEpoch(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastFinalizedEpoch", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetLastFinalizedEpoch), ctx) +} + // MockIncentiveKeeper is a mock of IncentiveKeeper interface. type MockIncentiveKeeper struct { ctrl *gomock.Controller diff --git a/x/finality/types/query.pb.go b/x/finality/types/query.pb.go index a0f7f3271..76aa68501 100644 --- a/x/finality/types/query.pb.go +++ b/x/finality/types/query.pb.go @@ -258,6 +258,8 @@ type PubRandCommitResponse struct { NumPubRand uint64 `protobuf:"varint,1,opt,name=num_pub_rand,json=numPubRand,proto3" json:"num_pub_rand,omitempty"` // commitment is the value of the commitment Commitment []byte `protobuf:"bytes,2,opt,name=commitment,proto3" json:"commitment,omitempty"` + // epoch_num defines the epoch number that the commit falls into + EpochNum uint64 `protobuf:"varint,3,opt,name=epoch_num,json=epochNum,proto3" json:"epoch_num,omitempty"` } func (m *PubRandCommitResponse) Reset() { *m = PubRandCommitResponse{} } @@ -307,6 +309,13 @@ func (m *PubRandCommitResponse) GetCommitment() []byte { return nil } +func (m *PubRandCommitResponse) GetEpochNum() uint64 { + if m != nil { + return m.EpochNum + } + return 0 +} + // QueryListPubRandCommitRequest is the request type for the // Query/ListPubRandCommit RPC method. type QueryListPubRandCommitRequest struct { @@ -1147,90 +1156,91 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/query.proto", fileDescriptor_32bddab77af6fdae) } var fileDescriptor_32bddab77af6fdae = []byte{ - // 1318 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdf, 0x6f, 0xdb, 0x54, - 0x14, 0xee, 0xcd, 0xd6, 0x6c, 0x3b, 0x4d, 0xb6, 0xee, 0xae, 0x1b, 0x25, 0xa3, 0x69, 0xea, 0x8d, - 0xb6, 0xb4, 0x9b, 0xbd, 0xa6, 0x65, 0x6c, 0x05, 0xb4, 0x35, 0xd0, 0xd2, 0x88, 0x2e, 0x64, 0x2e, - 0x9a, 0xb4, 0x3d, 0x60, 0xec, 0xd4, 0x49, 0xad, 0x26, 0xbe, 0x5e, 0xec, 0x44, 0x0d, 0xd3, 0x24, - 0x84, 0xc4, 0x1e, 0x10, 0x48, 0x48, 0xbc, 0xc0, 0xc3, 0x1e, 0x40, 0x88, 0x17, 0xfe, 0x0f, 0xb4, - 0xc7, 0x69, 0xf0, 0x80, 0x26, 0x51, 0xa1, 0x96, 0x3f, 0x04, 0xe5, 0xde, 0xeb, 0xc4, 0x4e, 0x9c, - 0x1f, 0x2d, 0x11, 0x6f, 0xf1, 0xf5, 0xf9, 0xf1, 0x7d, 0xdf, 0x39, 0x3e, 0xf7, 0xb4, 0x30, 0xa9, - 0xa9, 0x5a, 0xad, 0x48, 0x4c, 0x29, 0x6f, 0x98, 0x6a, 0xd1, 0x70, 0x6a, 0x52, 0x75, 0x41, 0x7a, - 0x58, 0xd1, 0xcb, 0x35, 0xd1, 0x2a, 0x13, 0x87, 0xe0, 0x73, 0xdc, 0x40, 0x74, 0x0d, 0xc4, 0xea, - 0x42, 0x6c, 0xac, 0x40, 0x0a, 0x84, 0xbe, 0x97, 0xea, 0xbf, 0x98, 0x69, 0xec, 0xb5, 0x02, 0x21, - 0x85, 0xa2, 0x2e, 0xa9, 0x96, 0x21, 0xa9, 0xa6, 0x49, 0x1c, 0xd5, 0x31, 0x88, 0x69, 0xf3, 0xb7, - 0x73, 0x39, 0x62, 0x97, 0x88, 0x2d, 0x69, 0xaa, 0xad, 0xb3, 0x0c, 0x52, 0x75, 0x41, 0xd3, 0x1d, - 0x75, 0x41, 0xb2, 0xd4, 0x82, 0x61, 0x52, 0x63, 0x6e, 0x9b, 0x08, 0x42, 0x65, 0xa9, 0x65, 0xb5, - 0xe4, 0x46, 0x13, 0x82, 0x2c, 0x1a, 0x10, 0xa9, 0x8d, 0x30, 0x06, 0xf8, 0x6e, 0x3d, 0x4f, 0x96, - 0x3a, 0xca, 0xfa, 0xc3, 0x8a, 0x6e, 0x3b, 0x42, 0x16, 0xce, 0xf9, 0x4e, 0x6d, 0x8b, 0x98, 0xb6, - 0x8e, 0x6f, 0x42, 0x98, 0x25, 0x18, 0x47, 0x09, 0x34, 0x3b, 0x92, 0xbc, 0x28, 0x06, 0x10, 0x17, - 0x99, 0x53, 0xea, 0xf8, 0xb3, 0xbd, 0xc9, 0x21, 0x99, 0x3b, 0x08, 0xdf, 0x20, 0x48, 0xd0, 0x90, - 0x1b, 0x86, 0xed, 0x64, 0x2b, 0x5a, 0xd1, 0xc8, 0xc9, 0xaa, 0xb9, 0x45, 0x4a, 0xa6, 0x6e, 0xbb, - 0x69, 0xf1, 0x14, 0x44, 0xf3, 0x96, 0xa2, 0x39, 0x39, 0xc5, 0xda, 0x51, 0xb6, 0xf5, 0x5d, 0x9a, - 0xe6, 0x94, 0x0c, 0x79, 0x2b, 0xe5, 0xe4, 0xb2, 0x3b, 0xeb, 0xfa, 0x2e, 0x5e, 0x03, 0x68, 0x2a, - 0x31, 0x1e, 0xa2, 0x30, 0xa6, 0x45, 0x26, 0x9b, 0x58, 0x97, 0x4d, 0x64, 0x85, 0xe1, 0xb2, 0x89, - 0x59, 0xb5, 0xa0, 0xf3, 0xf0, 0xb2, 0xc7, 0x53, 0x78, 0x11, 0x82, 0xa9, 0x2e, 0x78, 0x38, 0xe1, - 0x9f, 0x11, 0x44, 0xac, 0x8a, 0xa6, 0x94, 0x55, 0x73, 0x4b, 0x29, 0xa9, 0xd6, 0x38, 0x4a, 0x1c, - 0x9b, 0x1d, 0x49, 0xae, 0x05, 0xf2, 0xee, 0x19, 0x4e, 0xcc, 0x56, 0xb4, 0xfa, 0xe9, 0x1d, 0xd5, - 0x5a, 0x35, 0x9d, 0x72, 0x2d, 0xb5, 0xfc, 0x72, 0x6f, 0xf2, 0x7a, 0xc1, 0x70, 0xb6, 0x2b, 0x9a, - 0x98, 0x23, 0x25, 0x89, 0x47, 0x2d, 0xaa, 0x9a, 0x7d, 0xd5, 0x20, 0xee, 0xa3, 0xe4, 0xd4, 0x2c, - 0xdd, 0x16, 0x37, 0x73, 0xdb, 0x26, 0x29, 0x97, 0x79, 0x0c, 0x19, 0xac, 0x46, 0x30, 0xfc, 0x41, - 0x80, 0x28, 0x33, 0x3d, 0x45, 0x61, 0xa0, 0xbc, 0xaa, 0xc4, 0xde, 0x85, 0x33, 0x2d, 0x18, 0xf1, - 0x28, 0x1c, 0xdb, 0xd1, 0x6b, 0xb4, 0x12, 0xc7, 0xe5, 0xfa, 0x4f, 0x3c, 0x06, 0xc3, 0x55, 0xb5, - 0x58, 0xd1, 0x69, 0xa2, 0x88, 0xcc, 0x1e, 0x96, 0x43, 0x37, 0x90, 0x70, 0x1f, 0xce, 0x73, 0xf7, - 0xf7, 0x48, 0xa9, 0x64, 0x38, 0x0d, 0x1d, 0x13, 0x10, 0x31, 0x2b, 0x25, 0xc5, 0x95, 0x92, 0x47, - 0x03, 0xb3, 0x52, 0xe2, 0xf6, 0x38, 0x0e, 0x90, 0xa3, 0x3e, 0x25, 0xdd, 0x74, 0x78, 0x64, 0xcf, - 0x89, 0xf0, 0x15, 0x82, 0x09, 0xaf, 0xc0, 0xde, 0x24, 0xff, 0x7b, 0xf3, 0xfc, 0x11, 0x82, 0x78, - 0x27, 0x30, 0x9c, 0xf1, 0x2e, 0x9c, 0x6b, 0x34, 0x0e, 0xa3, 0xe1, 0xe9, 0x9f, 0x74, 0xcf, 0xfe, - 0x69, 0x8f, 0x28, 0xfa, 0x4e, 0xdd, 0xf2, 0xc8, 0xa3, 0x56, 0xcb, 0xf1, 0xe0, 0x9a, 0x81, 0xb4, - 0x54, 0xb3, 0x4b, 0x4b, 0xdc, 0xf6, 0xb6, 0xc4, 0x48, 0x72, 0x2e, 0x78, 0x2e, 0x04, 0xd1, 0xf2, - 0xb6, 0xcf, 0x3c, 0x9c, 0xa5, 0x1a, 0xa4, 0x8a, 0x24, 0xb7, 0xe3, 0x96, 0xf5, 0x02, 0x84, 0xb7, - 0x75, 0xa3, 0xb0, 0xed, 0xf0, 0x7c, 0xfc, 0x49, 0xb8, 0xc3, 0x07, 0x17, 0x37, 0xe6, 0xb2, 0xbf, - 0x05, 0xc3, 0x5a, 0xfd, 0x80, 0x0f, 0xa8, 0xa9, 0x40, 0x20, 0x69, 0x73, 0x4b, 0xdf, 0xd5, 0xb7, - 0x98, 0x27, 0xb3, 0x17, 0x7e, 0x44, 0x70, 0xa1, 0x51, 0x00, 0xfa, 0xa6, 0x31, 0x95, 0x6e, 0x41, - 0xd8, 0x76, 0x54, 0xa7, 0xc2, 0xa6, 0xde, 0xe9, 0xe4, 0x4c, 0xc7, 0xea, 0x19, 0x3c, 0xe8, 0x26, - 0x35, 0x97, 0xb9, 0xdb, 0xc0, 0xda, 0xee, 0x29, 0x82, 0x57, 0xda, 0x30, 0x36, 0x47, 0x33, 0x25, - 0x62, 0xf3, 0x16, 0xeb, 0x83, 0x39, 0x77, 0x18, 0x58, 0xc3, 0x08, 0x8b, 0xf0, 0x2a, 0x85, 0x77, - 0x8f, 0x38, 0xba, 0xbd, 0xe2, 0xac, 0xd3, 0x42, 0xf5, 0xaa, 0x23, 0x81, 0x58, 0x90, 0x13, 0xa7, - 0x75, 0x17, 0x4e, 0xb0, 0x2f, 0x9a, 0xf1, 0x8a, 0xa4, 0x6e, 0xbc, 0xdc, 0x9b, 0x5c, 0xea, 0x77, - 0x64, 0xa6, 0xd2, 0xd9, 0xc5, 0xa5, 0x6b, 0xd9, 0x8a, 0xf6, 0xa1, 0x5e, 0x93, 0xc3, 0x5a, 0x7d, - 0x0c, 0xd8, 0xc2, 0x4d, 0x18, 0xa3, 0x09, 0x57, 0xab, 0xc6, 0x96, 0x6e, 0xe6, 0xf4, 0xfe, 0xe7, - 0x87, 0x20, 0xc3, 0xf9, 0x16, 0xd7, 0x86, 0xfa, 0x27, 0x75, 0x7e, 0xc6, 0x3b, 0x6f, 0x22, 0x50, - 0xff, 0x86, 0x63, 0xc3, 0x5c, 0x78, 0x82, 0xb8, 0x6a, 0xf5, 0xa2, 0xba, 0xef, 0x3d, 0x37, 0x62, - 0xc4, 0x76, 0xd4, 0xb2, 0xa3, 0xf8, 0xb4, 0x1b, 0xa1, 0x67, 0x4c, 0xaa, 0x81, 0x75, 0xd7, 0x4f, - 0x88, 0x57, 0xa2, 0x05, 0x08, 0xa7, 0xf8, 0x36, 0x9c, 0x72, 0x31, 0xbb, 0x3d, 0xd6, 0x83, 0x63, - 0xd3, 0x7e, 0x70, 0x2d, 0xf6, 0x0e, 0xff, 0x02, 0x36, 0x8d, 0x82, 0x69, 0x98, 0x85, 0xb4, 0x99, - 0x27, 0x87, 0xa8, 0xdf, 0x67, 0x30, 0xde, 0xee, 0xcd, 0xf9, 0x7d, 0x02, 0x67, 0xf2, 0x96, 0x62, - 0xb3, 0x37, 0x8a, 0x61, 0xe6, 0x09, 0xaf, 0xe4, 0xb5, 0x40, 0x96, 0x6b, 0xfc, 0x77, 0xb6, 0x4c, - 0xea, 0x2c, 0xcb, 0x9e, 0x90, 0x7c, 0xf3, 0x89, 0xe6, 0x2d, 0xcf, 0xa1, 0xa0, 0xb5, 0xe7, 0x6e, - 0x54, 0xd9, 0x5f, 0x42, 0x74, 0xe4, 0x12, 0xfe, 0xe6, 0xf6, 0x92, 0x3f, 0x09, 0x67, 0xf8, 0x29, - 0x8c, 0xb6, 0x30, 0x74, 0x0b, 0x79, 0x54, 0x8a, 0xa7, 0x7d, 0x14, 0x07, 0x57, 0xe6, 0xb9, 0x5b, - 0x6c, 0xb8, 0xfb, 0xe7, 0x29, 0x3e, 0x0b, 0xd1, 0xcc, 0x47, 0x19, 0x65, 0x2d, 0x9d, 0x59, 0xd9, - 0x48, 0x3f, 0x58, 0x7d, 0x7f, 0x74, 0x08, 0x47, 0xe1, 0x54, 0xf3, 0x11, 0xe1, 0x13, 0x70, 0x6c, - 0x25, 0x73, 0x7f, 0x34, 0x94, 0xfc, 0x32, 0x0a, 0xc3, 0x54, 0x09, 0xfc, 0x39, 0x82, 0x30, 0xdb, - 0x48, 0x71, 0xe7, 0xc1, 0xed, 0x5f, 0x7f, 0x63, 0xb3, 0xbd, 0x0d, 0x19, 0x68, 0xe1, 0xd2, 0x17, - 0xbf, 0xff, 0xf3, 0x5d, 0x68, 0x02, 0x5f, 0x94, 0x3a, 0x6f, 0xe3, 0xf8, 0x2f, 0x04, 0x63, 0x41, - 0x7b, 0x21, 0x7e, 0xf3, 0xb0, 0x7b, 0x24, 0x83, 0x77, 0xfd, 0x68, 0xeb, 0xa7, 0x70, 0x8f, 0x82, - 0xcd, 0xe2, 0x8c, 0xd4, 0xed, 0x0f, 0x03, 0xc5, 0xe2, 0xf5, 0xb6, 0xa5, 0x47, 0xbe, 0x0f, 0xea, - 0xb1, 0x64, 0xd1, 0xc8, 0x74, 0xa9, 0x61, 0xa1, 0x95, 0xa2, 0x61, 0x3b, 0xf8, 0x05, 0x82, 0xb3, - 0x6d, 0x7b, 0x0b, 0x4e, 0x1e, 0x6a, 0xc9, 0x61, 0xcc, 0x16, 0x8f, 0xb0, 0x18, 0x09, 0x1f, 0x53, - 0x5a, 0x19, 0xbc, 0xf1, 0x1f, 0x68, 0xf9, 0x16, 0x35, 0x4a, 0xea, 0x09, 0x82, 0x61, 0xda, 0x7c, - 0x78, 0xba, 0x33, 0x28, 0xef, 0xa6, 0x12, 0x9b, 0xe9, 0x69, 0xc7, 0x01, 0x5f, 0xa1, 0x80, 0xa7, - 0xf1, 0xe5, 0x40, 0xc0, 0xec, 0x56, 0x96, 0x1e, 0xb1, 0x89, 0xff, 0x18, 0x7f, 0x8d, 0x00, 0x9a, - 0x17, 0x3e, 0x9e, 0xef, 0x2e, 0x91, 0x6f, 0x75, 0x89, 0x5d, 0xe9, 0xcf, 0xb8, 0xaf, 0x66, 0xe6, - 0xdb, 0xc2, 0x53, 0x04, 0x51, 0xdf, 0x5d, 0x8d, 0xc5, 0xce, 0x49, 0x82, 0x36, 0x81, 0x98, 0xd4, - 0xb7, 0x3d, 0xc7, 0x35, 0x4f, 0x71, 0xbd, 0x8e, 0x2f, 0x05, 0xe2, 0xaa, 0xd6, 0x7d, 0x9a, 0x72, - 0xfd, 0x8a, 0xe0, 0xa4, 0x7b, 0x05, 0xe1, 0x37, 0x3a, 0xa7, 0x6a, 0xb9, 0xfe, 0x63, 0x73, 0xfd, - 0x98, 0x72, 0x40, 0xeb, 0x14, 0x50, 0x0a, 0xdf, 0x3e, 0x6a, 0xc7, 0xb9, 0x37, 0x23, 0xfe, 0x1e, - 0x41, 0xd4, 0x77, 0xdf, 0x76, 0x53, 0x33, 0x68, 0x43, 0xe8, 0xa6, 0x66, 0xe0, 0x45, 0x2e, 0x4c, - 0x53, 0xf0, 0x09, 0x1c, 0x0f, 0x04, 0xdf, 0xbc, 0xb3, 0x7f, 0x41, 0x30, 0xe2, 0x99, 0xee, 0xb8, - 0x4b, 0x2f, 0xb5, 0xdf, 0xc6, 0xb1, 0xab, 0x7d, 0x5a, 0x73, 0x50, 0xcb, 0x14, 0xd4, 0x12, 0x4e, - 0x06, 0x82, 0xf2, 0xdd, 0x59, 0xad, 0x62, 0xe2, 0x1f, 0x10, 0x44, 0x7c, 0xd7, 0x50, 0x7f, 0xb9, - 0x1b, 0x0a, 0x8a, 0xfd, 0x9a, 0x73, 0xac, 0x73, 0x14, 0xeb, 0x65, 0x2c, 0xf4, 0xc6, 0x9a, 0xda, - 0x78, 0xb6, 0x1f, 0x47, 0xcf, 0xf7, 0xe3, 0xe8, 0xef, 0xfd, 0x38, 0xfa, 0xf6, 0x20, 0x3e, 0xf4, - 0xfc, 0x20, 0x3e, 0xf4, 0xe7, 0x41, 0x7c, 0xe8, 0x41, 0xb2, 0xf7, 0x12, 0xbb, 0xdb, 0x0c, 0x4c, - 0xf7, 0x59, 0x2d, 0x4c, 0xff, 0x67, 0xb3, 0xf8, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x6c, - 0x72, 0x7b, 0x91, 0x12, 0x00, 0x00, + // 1338 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdf, 0x6f, 0xd3, 0xd6, + 0x17, 0xef, 0x6d, 0x69, 0xa1, 0xa7, 0x09, 0x94, 0x4b, 0xe1, 0xdb, 0x6f, 0x18, 0x69, 0x30, 0xac, + 0xb0, 0x02, 0x36, 0x4d, 0x19, 0x03, 0xb6, 0x09, 0xc8, 0x46, 0x47, 0xb4, 0x92, 0x05, 0x33, 0x21, + 0x8d, 0x87, 0x79, 0x76, 0x7a, 0x93, 0x58, 0x8d, 0x7d, 0x4d, 0x6c, 0x47, 0xcd, 0x10, 0xd2, 0x34, + 0x69, 0x3c, 0x4c, 0x9b, 0x34, 0x69, 0x2f, 0xdb, 0x03, 0x0f, 0x9b, 0xa6, 0xbd, 0xec, 0xff, 0x98, + 0x78, 0x44, 0x6c, 0x0f, 0x13, 0xd2, 0xd0, 0x04, 0xfb, 0x43, 0xa6, 0xdc, 0x7b, 0x9d, 0xd8, 0x89, + 0xf3, 0x83, 0x2e, 0xda, 0x5b, 0x7c, 0x7c, 0x7e, 0x7c, 0xce, 0xe7, 0x1c, 0x9f, 0x73, 0x5a, 0x58, + 0x32, 0x74, 0xa3, 0x59, 0xa3, 0xb6, 0x52, 0x36, 0x6d, 0xbd, 0x66, 0x7a, 0x4d, 0xa5, 0xb1, 0xaa, + 0xdc, 0xf5, 0x49, 0xbd, 0x29, 0x3b, 0x75, 0xea, 0x51, 0x7c, 0x40, 0x28, 0xc8, 0x81, 0x82, 0xdc, + 0x58, 0x4d, 0x2d, 0x54, 0x68, 0x85, 0xb2, 0xf7, 0x4a, 0xeb, 0x17, 0x57, 0x4d, 0xbd, 0x52, 0xa1, + 0xb4, 0x52, 0x23, 0x8a, 0xee, 0x98, 0x8a, 0x6e, 0xdb, 0xd4, 0xd3, 0x3d, 0x93, 0xda, 0xae, 0x78, + 0xbb, 0x52, 0xa2, 0xae, 0x45, 0x5d, 0xc5, 0xd0, 0x5d, 0xc2, 0x23, 0x28, 0x8d, 0x55, 0x83, 0x78, + 0xfa, 0xaa, 0xe2, 0xe8, 0x15, 0xd3, 0x66, 0xca, 0x42, 0x37, 0x13, 0x87, 0xca, 0xd1, 0xeb, 0xba, + 0x15, 0x78, 0x93, 0xe2, 0x34, 0xda, 0x10, 0x99, 0x8e, 0xb4, 0x00, 0xf8, 0x66, 0x2b, 0x4e, 0x91, + 0x19, 0xaa, 0xe4, 0xae, 0x4f, 0x5c, 0x4f, 0x2a, 0xc2, 0x81, 0x88, 0xd4, 0x75, 0xa8, 0xed, 0x12, + 0x7c, 0x11, 0x66, 0x78, 0x80, 0x45, 0x94, 0x41, 0x27, 0xe7, 0xb2, 0x87, 0xe5, 0x98, 0xc4, 0x65, + 0x6e, 0x94, 0xdb, 0xf5, 0xe8, 0xd9, 0xd2, 0x84, 0x2a, 0x0c, 0xa4, 0xaf, 0x11, 0x64, 0x98, 0xcb, + 0x0d, 0xd3, 0xf5, 0x8a, 0xbe, 0x51, 0x33, 0x4b, 0xaa, 0x6e, 0x6f, 0x52, 0xcb, 0x26, 0x6e, 0x10, + 0x16, 0x1f, 0x85, 0x64, 0xd9, 0xd1, 0x0c, 0xaf, 0xa4, 0x39, 0x5b, 0x5a, 0x95, 0x6c, 0xb3, 0x30, + 0xb3, 0x2a, 0x94, 0x9d, 0x9c, 0x57, 0x2a, 0x6e, 0x5d, 0x27, 0xdb, 0x78, 0x1d, 0xa0, 0xc3, 0xc4, + 0xe2, 0x24, 0x83, 0xb1, 0x2c, 0x73, 0xda, 0xe4, 0x16, 0x6d, 0x32, 0x2f, 0x8c, 0xa0, 0x4d, 0x2e, + 0xea, 0x15, 0x22, 0xdc, 0xab, 0x21, 0x4b, 0xe9, 0xc9, 0x24, 0x1c, 0x1d, 0x80, 0x47, 0x24, 0xfc, + 0x13, 0x82, 0x84, 0xe3, 0x1b, 0x5a, 0x5d, 0xb7, 0x37, 0x35, 0x4b, 0x77, 0x16, 0x51, 0x66, 0xea, + 0xe4, 0x5c, 0x76, 0x3d, 0x36, 0xef, 0xa1, 0xee, 0xe4, 0xa2, 0x6f, 0xb4, 0xa4, 0x37, 0x74, 0xe7, + 0x9a, 0xed, 0xd5, 0x9b, 0xb9, 0x4b, 0x4f, 0x9f, 0x2d, 0x9d, 0xaf, 0x98, 0x5e, 0xd5, 0x37, 0xe4, + 0x12, 0xb5, 0x14, 0xe1, 0xb5, 0xa6, 0x1b, 0xee, 0x19, 0x93, 0x06, 0x8f, 0x8a, 0xd7, 0x74, 0x88, + 0x2b, 0xdf, 0x2a, 0x55, 0x6d, 0x5a, 0xaf, 0x0b, 0x1f, 0x2a, 0x38, 0x6d, 0x67, 0xf8, 0xbd, 0x18, + 0x52, 0x4e, 0x0c, 0x25, 0x85, 0x83, 0x0a, 0xb3, 0x92, 0x7a, 0x1b, 0xf6, 0x75, 0x61, 0xc4, 0xf3, + 0x30, 0xb5, 0x45, 0x9a, 0xac, 0x12, 0xbb, 0xd4, 0xd6, 0x4f, 0xbc, 0x00, 0xd3, 0x0d, 0xbd, 0xe6, + 0x13, 0x16, 0x28, 0xa1, 0xf2, 0x87, 0x4b, 0x93, 0x17, 0x90, 0xd4, 0x80, 0x83, 0xc2, 0xfc, 0x1d, + 0x6a, 0x59, 0xa6, 0xd7, 0xe6, 0x31, 0x03, 0x09, 0xdb, 0xb7, 0xb4, 0x80, 0x4a, 0xe1, 0x0d, 0x6c, + 0xdf, 0x12, 0xfa, 0x38, 0x0d, 0x50, 0x62, 0x36, 0x16, 0xb1, 0x3d, 0xe1, 0x39, 0x24, 0xc1, 0x87, + 0x61, 0x96, 0x38, 0xb4, 0x54, 0xd5, 0x6c, 0xdf, 0x5a, 0x9c, 0x62, 0xe6, 0x7b, 0x98, 0xa0, 0xe0, + 0x5b, 0xd2, 0x97, 0x08, 0x8e, 0x84, 0xd9, 0x0f, 0x23, 0xf8, 0xcf, 0x3b, 0xeb, 0xf7, 0x49, 0x48, + 0xf7, 0x03, 0x23, 0xe8, 0xd8, 0x86, 0x03, 0xed, 0xae, 0xe2, 0x39, 0x86, 0x9a, 0x2b, 0x3f, 0xb4, + 0xb9, 0x7a, 0x3d, 0xca, 0x11, 0x69, 0x50, 0x3b, 0x75, 0xde, 0xe9, 0x12, 0x8f, 0xaf, 0x53, 0x68, + 0x57, 0xa9, 0x07, 0xf4, 0xcb, 0x95, 0x70, 0xbf, 0xcc, 0x65, 0x57, 0xe2, 0x87, 0x46, 0x5c, 0x5a, + 0xe1, 0xde, 0x3a, 0x05, 0xfb, 0x19, 0x07, 0xb9, 0x1a, 0x2d, 0x6d, 0x05, 0x65, 0x3d, 0x04, 0x33, + 0x55, 0x62, 0x56, 0xaa, 0x9e, 0x88, 0x27, 0x9e, 0xa4, 0x1b, 0x62, 0xaa, 0x09, 0x65, 0x41, 0xfb, + 0x1b, 0x30, 0x6d, 0xb4, 0x04, 0x62, 0x7a, 0x1d, 0x8d, 0x05, 0x92, 0xb7, 0x37, 0xc9, 0x36, 0xd9, + 0xe4, 0x96, 0x5c, 0x5f, 0xfa, 0x01, 0xc1, 0xa1, 0x76, 0x01, 0xd8, 0x9b, 0xf6, 0xc8, 0xba, 0x0c, + 0x33, 0xae, 0xa7, 0x7b, 0x3e, 0x1f, 0x89, 0x7b, 0xb3, 0x27, 0xfa, 0x56, 0xcf, 0x14, 0x4e, 0x6f, + 0x31, 0x75, 0x55, 0x98, 0x8d, 0xad, 0xed, 0x1e, 0x22, 0xf8, 0x5f, 0x0f, 0xc6, 0xce, 0xdc, 0x66, + 0x89, 0xb8, 0xa2, 0xc5, 0x46, 0xc8, 0x5c, 0x18, 0x8c, 0xad, 0x61, 0xa4, 0x35, 0xf8, 0x3f, 0x83, + 0x77, 0x9b, 0x7a, 0xc4, 0xbd, 0xea, 0x5d, 0x67, 0x85, 0x1a, 0x56, 0x47, 0x0a, 0xa9, 0x38, 0x23, + 0x91, 0xd6, 0x4d, 0xd8, 0xcd, 0xbf, 0x68, 0x9e, 0x57, 0x22, 0x77, 0xe1, 0xe9, 0xb3, 0xa5, 0x73, + 0xa3, 0xce, 0xd3, 0x5c, 0xbe, 0xb8, 0x76, 0xee, 0x6c, 0xd1, 0x37, 0xde, 0x27, 0x4d, 0x75, 0xc6, + 0x68, 0x8d, 0x01, 0x57, 0xba, 0x08, 0x0b, 0x2c, 0xe0, 0xb5, 0x86, 0xb9, 0x49, 0xec, 0x12, 0x19, + 0x7d, 0x7e, 0x48, 0x2a, 0x1c, 0xec, 0x32, 0x6d, 0xb3, 0xbf, 0x87, 0x08, 0x99, 0xe8, 0xbc, 0x23, + 0xb1, 0xfc, 0xb7, 0x0d, 0xdb, 0xea, 0xd2, 0x03, 0x24, 0x58, 0x6b, 0x15, 0x35, 0x78, 0x1f, 0x5a, + 0x97, 0x09, 0xd7, 0xd3, 0xeb, 0x9e, 0x16, 0xe1, 0x6e, 0x8e, 0xc9, 0x38, 0x55, 0x63, 0xeb, 0xae, + 0x1f, 0x91, 0xa8, 0x44, 0x17, 0x10, 0x91, 0xe2, 0x9b, 0x30, 0x1b, 0x60, 0x0e, 0x7a, 0x6c, 0x48, + 0x8e, 0x1d, 0xfd, 0xf1, 0xb5, 0xd8, 0x5b, 0xe2, 0x0b, 0xb8, 0x65, 0x56, 0x6c, 0xd3, 0xae, 0xe4, + 0xed, 0x32, 0x7d, 0x89, 0xfa, 0x7d, 0x0a, 0x8b, 0xbd, 0xd6, 0x22, 0xbf, 0x8f, 0x61, 0x5f, 0xd9, + 0xd1, 0x5c, 0xfe, 0x46, 0x33, 0xed, 0x32, 0x15, 0x95, 0x3c, 0x1b, 0x9b, 0xe5, 0xba, 0xf8, 0x5d, + 0xac, 0xd3, 0x56, 0x96, 0xf5, 0x90, 0x4b, 0x71, 0x16, 0x25, 0xcb, 0x4e, 0x48, 0x28, 0x19, 0xbd, + 0xb1, 0xdb, 0x55, 0x8e, 0x96, 0x10, 0xed, 0xb8, 0x84, 0xbf, 0x06, 0xbd, 0x14, 0x0d, 0x22, 0x32, + 0xfc, 0x04, 0xe6, 0xbb, 0x32, 0x0c, 0x0a, 0xb9, 0xd3, 0x14, 0xf7, 0x46, 0x52, 0x1c, 0x5f, 0x99, + 0x57, 0x2e, 0xf3, 0xe1, 0x1e, 0x9d, 0xa7, 0x78, 0x3f, 0x24, 0x0b, 0x1f, 0x14, 0xb4, 0xf5, 0x7c, + 0xe1, 0xea, 0x46, 0xfe, 0xce, 0xb5, 0x77, 0xe7, 0x27, 0x70, 0x12, 0x66, 0x3b, 0x8f, 0x08, 0xef, + 0x86, 0xa9, 0xab, 0x85, 0x8f, 0xe6, 0x27, 0xb3, 0x5f, 0x24, 0x61, 0x9a, 0x31, 0x81, 0x3f, 0x43, + 0x30, 0xc3, 0xcf, 0x55, 0xdc, 0x7f, 0x70, 0x47, 0x6f, 0xe3, 0xd4, 0xc9, 0xe1, 0x8a, 0x1c, 0xb4, + 0x74, 0xec, 0xf3, 0xdf, 0xfe, 0xfe, 0x76, 0xf2, 0x08, 0x3e, 0xac, 0xf4, 0x3f, 0xd5, 0xf1, 0x9f, + 0x08, 0x16, 0xe2, 0x8e, 0x46, 0xfc, 0xfa, 0xcb, 0x1e, 0x99, 0x1c, 0xde, 0xf9, 0x9d, 0xdd, 0xa6, + 0xd2, 0x6d, 0x06, 0xb6, 0x88, 0x0b, 0xca, 0xa0, 0xbf, 0x1a, 0x34, 0x47, 0xd4, 0xdb, 0x55, 0xee, + 0x45, 0x3e, 0xa8, 0xfb, 0x8a, 0xc3, 0x3c, 0xb3, 0xa3, 0x86, 0xbb, 0xd6, 0x6a, 0xa6, 0xeb, 0xe1, + 0x27, 0x08, 0xf6, 0xf7, 0xdc, 0x2d, 0x38, 0xfb, 0x52, 0x47, 0x0e, 0xcf, 0x6c, 0x6d, 0x07, 0x87, + 0x91, 0xf4, 0x21, 0x4b, 0xab, 0x80, 0x37, 0xfe, 0x45, 0x5a, 0x91, 0x43, 0x8d, 0x25, 0xf5, 0x00, + 0xc1, 0x34, 0x6b, 0x3e, 0xbc, 0xdc, 0x1f, 0x54, 0xf8, 0x52, 0x49, 0x9d, 0x18, 0xaa, 0x27, 0x00, + 0x9f, 0x66, 0x80, 0x97, 0xf1, 0xf1, 0x58, 0xc0, 0x7c, 0x2b, 0x2b, 0xf7, 0xf8, 0xc4, 0xbf, 0x8f, + 0xbf, 0x42, 0x00, 0x9d, 0x85, 0x8f, 0x4f, 0x0d, 0xa6, 0x28, 0x72, 0xba, 0xa4, 0x4e, 0x8f, 0xa6, + 0x3c, 0x52, 0x33, 0x8b, 0x6b, 0xe1, 0x21, 0x82, 0x64, 0x64, 0x57, 0x63, 0xb9, 0x7f, 0x90, 0xb8, + 0x4b, 0x20, 0xa5, 0x8c, 0xac, 0x2f, 0x70, 0x9d, 0x62, 0xb8, 0x5e, 0xc5, 0xc7, 0x62, 0x71, 0x35, + 0x5a, 0x36, 0x1d, 0xba, 0x7e, 0x41, 0xb0, 0x27, 0x58, 0x41, 0xf8, 0xb5, 0xfe, 0xa1, 0xba, 0xd6, + 0x7f, 0x6a, 0x65, 0x14, 0x55, 0x01, 0xe8, 0x3a, 0x03, 0x94, 0xc3, 0x57, 0x76, 0xda, 0x71, 0xc1, + 0x66, 0xc4, 0xdf, 0x21, 0x48, 0x46, 0xf6, 0xed, 0x20, 0x36, 0xe3, 0x2e, 0x84, 0x41, 0x6c, 0xc6, + 0x2e, 0x72, 0x69, 0x99, 0x81, 0xcf, 0xe0, 0x74, 0x2c, 0xf8, 0xce, 0xce, 0xfe, 0x19, 0xc1, 0x5c, + 0x68, 0xba, 0xe3, 0x01, 0xbd, 0xd4, 0xbb, 0x8d, 0x53, 0x67, 0x46, 0xd4, 0x16, 0xa0, 0x2e, 0x31, + 0x50, 0xe7, 0x70, 0x36, 0x16, 0x54, 0x64, 0x67, 0x75, 0x93, 0x89, 0xbf, 0x47, 0x90, 0x88, 0xac, + 0xa1, 0xd1, 0x62, 0xb7, 0x19, 0x94, 0x47, 0x55, 0x17, 0x58, 0x57, 0x18, 0xd6, 0xe3, 0x58, 0x1a, + 0x8e, 0x35, 0xb7, 0xf1, 0xe8, 0x79, 0x1a, 0x3d, 0x7e, 0x9e, 0x46, 0x7f, 0x3d, 0x4f, 0xa3, 0x6f, + 0x5e, 0xa4, 0x27, 0x1e, 0xbf, 0x48, 0x4f, 0xfc, 0xf1, 0x22, 0x3d, 0x71, 0x27, 0x3b, 0xfc, 0x88, + 0xdd, 0xee, 0x38, 0x66, 0xf7, 0xac, 0x31, 0xc3, 0xfe, 0xa1, 0xb3, 0xf6, 0x4f, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xb3, 0x40, 0x11, 0x10, 0xae, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1842,6 +1852,11 @@ func (m *PubRandCommitResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.EpochNum != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.EpochNum)) + i-- + dAtA[i] = 0x18 + } if len(m.Commitment) > 0 { i -= len(m.Commitment) copy(dAtA[i:], m.Commitment) @@ -2563,6 +2578,9 @@ func (m *PubRandCommitResponse) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } + if m.EpochNum != 0 { + n += 1 + sovQuery(uint64(m.EpochNum)) + } return n } @@ -3354,6 +3372,25 @@ func (m *PubRandCommitResponse) Unmarshal(dAtA []byte) error { m.Commitment = []byte{} } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochNum", wireType) + } + m.EpochNum = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochNum |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/zoneconcierge/README.md b/x/zoneconcierge/README.md index f873f4030..046c5567a 100644 --- a/x/zoneconcierge/README.md +++ b/x/zoneconcierge/README.md @@ -211,9 +211,9 @@ message Params { ### ChainInfo The [chain info storage](./keeper/chain_info_indexer.go) maintains `ChainInfo` -for each PoS blockchain. The key is the PoS blockchain's `ChainID`, and the -value is a `ChainInfo` object. The `ChainInfo` is a structure storing the -information of a PoS blockchain that checkpoints to Babylon. +for each PoS blockchain. The key is the PoS blockchain's `ConsumerID`, which is the +ID of the IBC light client. The value is a `ChainInfo` object. The `ChainInfo` is +a structure storing the information of a PoS blockchain that checkpoints to Babylon. ```protobuf // ChainInfo is the information of a CZ @@ -235,14 +235,14 @@ message ChainInfo { The [epoch chain info storage](./keeper/epoch_chain_info_indexer.go) maintains `ChainInfo` at the end of each Babylon epoch for each PoS blockchain. The key is -the PoS blockchain's `ChainID` plus the epoch number, and the value is a +the PoS blockchain's `ConsumerID` plus the epoch number, and the value is a `ChainInfo` object. ### CanonicalChain The [canonical chain storage](./keeper/canonical_chain_indexer.go) maintains the metadata of canonical IBC headers of a PoS blockchain. The key is the consumer -chain's `ChainID` plus the height, and the value is a `IndexedHeader` object. +chain's `ConsumerID` plus the height, and the value is a `IndexedHeader` object. `IndexedHeader` is a structure storing IBC header's metadata. ```protobuf @@ -277,7 +277,7 @@ message IndexedHeader { ### Fork The [fork storage](./keeper/fork_indexer.go) maintains the metadata of canonical -IBC headers of a PoS blockchain. The key is the PoS blockchain's `ChainID` plus +IBC headers of a PoS blockchain. The key is the PoS blockchain's `ConsumerID` plus the height, and the value is a list of `IndexedHeader` objects, which represent fork headers at that height. @@ -421,9 +421,9 @@ Babylon. The logic is defined at is still canonical in the segment to the current tip of the BTC light client. 3. For each of these IBC channels: - 1. Find the `ChainID` of the counterparty chain (i.e., the PoS blockchain) in + 1. Find the `ConsumerID` of the counterparty chain (i.e., the PoS blockchain) in the IBC channel. - 2. Get the `ChainInfo` of the `ChainID` at the last finalized epoch. + 2. Get the `ChainInfo` of the `ConsumerID` at the last finalized epoch. 3. Get the metadata of the last finalized epoch and its corresponding raw checkpoint. 4. Generate the proof that the last PoS blockchain's canonical header is diff --git a/x/zoneconcierge/client/cli/query.go b/x/zoneconcierge/client/cli/query.go index ca0f1b682..7e55d19e9 100644 --- a/x/zoneconcierge/client/cli/query.go +++ b/x/zoneconcierge/client/cli/query.go @@ -31,13 +31,13 @@ func GetQueryCmd(queryRoute string) *cobra.Command { func CmdChainsInfo() *cobra.Command { cmd := &cobra.Command{ - Use: "chains-info ", - Short: "retrieve the latest info for a given list of chains", + Use: "chains-info ", + Short: "retrieve the latest info for a given list of consumers", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) queryClient := types.NewQueryClient(clientCtx) - req := types.QueryChainsInfoRequest{ChainIds: args} + req := types.QueryChainsInfoRequest{ConsumerIds: args} resp, err := queryClient.ChainsInfo(cmd.Context(), &req) if err != nil { return err @@ -53,15 +53,15 @@ func CmdChainsInfo() *cobra.Command { func CmdFinalizedChainsInfo() *cobra.Command { cmd := &cobra.Command{ - Use: "finalized-chains-info ", - Short: "retrieve the finalized info for a given list of chains", + Use: "finalized-chains-info ", + Short: "retrieve the finalized info for a given list of consumers", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { prove, _ := cmd.Flags().GetBool("prove") clientCtx := client.GetClientContextFromCmd(cmd) queryClient := types.NewQueryClient(clientCtx) - req := types.QueryFinalizedChainsInfoRequest{ChainIds: args, Prove: prove} + req := types.QueryFinalizedChainsInfoRequest{ConsumerIds: args, Prove: prove} resp, err := queryClient.FinalizedChainsInfo(cmd.Context(), &req) if err != nil { return err @@ -79,8 +79,8 @@ func CmdFinalizedChainsInfo() *cobra.Command { func CmdEpochChainsInfoInfo() *cobra.Command { cmd := &cobra.Command{ - Use: "epoch-chains-info ", - Short: "retrieve the latest info for a list of chains in a given epoch", + Use: "epoch-chains-info ", + Short: "retrieve the latest info for a list of consumers in a given epoch", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) @@ -90,7 +90,7 @@ func CmdEpochChainsInfoInfo() *cobra.Command { if err != nil { return err } - req := types.QueryEpochChainsInfoRequest{EpochNum: epoch, ChainIds: args[1:]} + req := types.QueryEpochChainsInfoRequest{EpochNum: epoch, ConsumerIds: args[1:]} resp, err := queryClient.EpochChainsInfo(cmd.Context(), &req) if err != nil { return err diff --git a/x/zoneconcierge/keeper/canonical_chain_indexer.go b/x/zoneconcierge/keeper/canonical_chain_indexer.go index 52d89b965..253c05c5c 100644 --- a/x/zoneconcierge/keeper/canonical_chain_indexer.go +++ b/x/zoneconcierge/keeper/canonical_chain_indexer.go @@ -3,6 +3,7 @@ package keeper import ( "context" "fmt" + "github.com/cosmos/cosmos-sdk/runtime" sdkerrors "cosmossdk.io/errors" @@ -12,10 +13,10 @@ import ( ) // FindClosestHeader finds the IndexedHeader that is closest to (but not after) the given height -func (k Keeper) FindClosestHeader(ctx context.Context, chainID string, height uint64) (*types.IndexedHeader, error) { - chainInfo, err := k.GetChainInfo(ctx, chainID) +func (k Keeper) FindClosestHeader(ctx context.Context, consumerID string, height uint64) (*types.IndexedHeader, error) { + chainInfo, err := k.GetChainInfo(ctx, consumerID) if err != nil { - return nil, fmt.Errorf("failed to get chain info for chain with ID %s: %w", chainID, err) + return nil, fmt.Errorf("failed to get chain info for chain with ID %s: %w", consumerID, err) } // if the given height is no lower than the latest header, return the latest header directly @@ -24,13 +25,13 @@ func (k Keeper) FindClosestHeader(ctx context.Context, chainID string, height ui } // the requested height is lower than the latest header, trace back until finding a timestamped header - store := k.canonicalChainStore(ctx, chainID) + store := k.canonicalChainStore(ctx, consumerID) heightBytes := sdk.Uint64ToBigEndian(height) iter := store.ReverseIterator(nil, heightBytes) defer iter.Close() // if there is no key within range [0, height], return error if !iter.Valid() { - return nil, fmt.Errorf("chain with ID %s does not have a timestamped header before height %d", chainID, height) + return nil, fmt.Errorf("chain with ID %s does not have a timestamped header before height %d", consumerID, height) } // find the header in bytes, decode and return headerBytes := iter.Value() @@ -39,8 +40,8 @@ func (k Keeper) FindClosestHeader(ctx context.Context, chainID string, height ui return &header, nil } -func (k Keeper) GetHeader(ctx context.Context, chainID string, height uint64) (*types.IndexedHeader, error) { - store := k.canonicalChainStore(ctx, chainID) +func (k Keeper) GetHeader(ctx context.Context, consumerID string, height uint64) (*types.IndexedHeader, error) { + store := k.canonicalChainStore(ctx, consumerID) heightBytes := sdk.Uint64ToBigEndian(height) if !store.Has(heightBytes) { return nil, types.ErrHeaderNotFound @@ -51,23 +52,23 @@ func (k Keeper) GetHeader(ctx context.Context, chainID string, height uint64) (* return &header, nil } -func (k Keeper) insertHeader(ctx context.Context, chainID string, header *types.IndexedHeader) error { +func (k Keeper) insertHeader(ctx context.Context, consumerID string, header *types.IndexedHeader) error { if header == nil { return sdkerrors.Wrapf(types.ErrInvalidHeader, "header is nil") } // NOTE: we can accept header without ancestor since IBC connection can be established at any height - store := k.canonicalChainStore(ctx, chainID) + store := k.canonicalChainStore(ctx, consumerID) store.Set(sdk.Uint64ToBigEndian(header.Height), k.cdc.MustMarshal(header)) return nil } // canonicalChainStore stores the canonical chain of a CZ, formed as a list of IndexedHeader -// prefix: CanonicalChainKey || chainID +// prefix: CanonicalChainKey || consumerID // key: height // value: IndexedHeader -func (k Keeper) canonicalChainStore(ctx context.Context, chainID string) prefix.Store { +func (k Keeper) canonicalChainStore(ctx context.Context, consumerID string) prefix.Store { storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) canonicalChainStore := prefix.NewStore(storeAdapter, types.CanonicalChainKey) - chainIDBytes := []byte(chainID) - return prefix.NewStore(canonicalChainStore, chainIDBytes) + consumerIDBytes := []byte(consumerID) + return prefix.NewStore(canonicalChainStore, consumerIDBytes) } diff --git a/x/zoneconcierge/keeper/canonical_chain_indexer_test.go b/x/zoneconcierge/keeper/canonical_chain_indexer_test.go index af484b32c..c13a7bed5 100644 --- a/x/zoneconcierge/keeper/canonical_chain_indexer_test.go +++ b/x/zoneconcierge/keeper/canonical_chain_indexer_test.go @@ -18,27 +18,27 @@ func FuzzCanonicalChainIndexer(f *testing.F) { babylonApp := app.Setup(t, false) zcKeeper := babylonApp.ZoneConciergeKeeper ctx := babylonApp.NewContext(false) - czChainID := "test-chainid" + czConsumerId := "test-consumerid" // simulate a random number of blocks numHeaders := datagen.RandomInt(r, 100) + 1 - headers := SimulateNewHeaders(ctx, r, &zcKeeper, czChainID, 0, numHeaders) + headers := SimulateNewHeaders(ctx, r, &zcKeeper, czConsumerId, 0, numHeaders) // check if the canonical chain index is correct or not for i := uint64(0); i < numHeaders; i++ { - header, err := zcKeeper.GetHeader(ctx, czChainID, i) + header, err := zcKeeper.GetHeader(ctx, czConsumerId, i) require.NoError(t, err) require.NotNil(t, header) - require.Equal(t, czChainID, header.ChainId) + require.Equal(t, czConsumerId, header.ConsumerId) require.Equal(t, i, header.Height) require.Equal(t, headers[i].Header.AppHash, header.Hash) } // check if the chain info is updated or not - chainInfo, err := zcKeeper.GetChainInfo(ctx, czChainID) + chainInfo, err := zcKeeper.GetChainInfo(ctx, czConsumerId) require.NoError(t, err) require.NotNil(t, chainInfo.LatestHeader) - require.Equal(t, czChainID, chainInfo.LatestHeader.ChainId) + require.Equal(t, czConsumerId, chainInfo.LatestHeader.ConsumerId) require.Equal(t, numHeaders-1, chainInfo.LatestHeader.Height) require.Equal(t, headers[numHeaders-1].Header.AppHash, chainInfo.LatestHeader.Hash) }) @@ -53,17 +53,17 @@ func FuzzFindClosestHeader(f *testing.F) { babylonApp := app.Setup(t, false) zcKeeper := babylonApp.ZoneConciergeKeeper ctx := babylonApp.NewContext(false) - czChainID := "test-chainid" + czConsumerId := "test-consumerid" // no header at the moment, FindClosestHeader invocation should give error - _, err := zcKeeper.FindClosestHeader(ctx, czChainID, 100) + _, err := zcKeeper.FindClosestHeader(ctx, czConsumerId, 100) require.Error(t, err) // simulate a random number of blocks numHeaders := datagen.RandomInt(r, 100) + 1 - headers := SimulateNewHeaders(ctx, r, &zcKeeper, czChainID, 0, numHeaders) + headers := SimulateNewHeaders(ctx, r, &zcKeeper, czConsumerId, 0, numHeaders) - header, err := zcKeeper.FindClosestHeader(ctx, czChainID, numHeaders) + header, err := zcKeeper.FindClosestHeader(ctx, czConsumerId, numHeaders) require.NoError(t, err) require.Equal(t, headers[len(headers)-1].Header.AppHash, header.Hash) @@ -72,12 +72,12 @@ func FuzzFindClosestHeader(f *testing.F) { // simulate a random number of blocks // where the new batch of headers has a gap with the previous batch - SimulateNewHeaders(ctx, r, &zcKeeper, czChainID, numHeaders+gap+1, numHeaders) + SimulateNewHeaders(ctx, r, &zcKeeper, czConsumerId, numHeaders+gap+1, numHeaders) // get a random height that is in this gap randomHeightInGap := datagen.RandomInt(r, int(gap+1)) + numHeaders // find the closest header with the given randomHeightInGap - header, err = zcKeeper.FindClosestHeader(ctx, czChainID, randomHeightInGap) + header, err = zcKeeper.FindClosestHeader(ctx, czConsumerId, randomHeightInGap) require.NoError(t, err) // the header should be the same as the last header in the last batch require.Equal(t, headers[len(headers)-1].Header.AppHash, header.Hash) diff --git a/x/zoneconcierge/keeper/chain_info_indexer.go b/x/zoneconcierge/keeper/chain_info_indexer.go index a3ae402d1..29deeea92 100644 --- a/x/zoneconcierge/keeper/chain_info_indexer.go +++ b/x/zoneconcierge/keeper/chain_info_indexer.go @@ -3,6 +3,7 @@ package keeper import ( "context" "fmt" + "github.com/cosmos/cosmos-sdk/runtime" errorsmod "cosmossdk.io/errors" @@ -12,20 +13,20 @@ import ( func (k Keeper) setChainInfo(ctx context.Context, chainInfo *types.ChainInfo) { store := k.chainInfoStore(ctx) - store.Set([]byte(chainInfo.ChainId), k.cdc.MustMarshal(chainInfo)) + store.Set([]byte(chainInfo.ConsumerId), k.cdc.MustMarshal(chainInfo)) } -func (k Keeper) InitChainInfo(ctx context.Context, chainID string) (*types.ChainInfo, error) { - if len(chainID) == 0 { - return nil, fmt.Errorf("chainID is empty") +func (k Keeper) InitChainInfo(ctx context.Context, consumerID string) (*types.ChainInfo, error) { + if len(consumerID) == 0 { + return nil, fmt.Errorf("consumerID is empty") } // ensure chain info has not been initialised yet - if k.HasChainInfo(ctx, chainID) { + if k.HasChainInfo(ctx, consumerID) { return nil, errorsmod.Wrapf(types.ErrInvalidChainInfo, "chain info has already initialized") } chainInfo := &types.ChainInfo{ - ChainId: chainID, + ConsumerId: consumerID, LatestHeader: nil, LatestForks: &types.Forks{ Headers: []*types.IndexedHeader{}, @@ -40,21 +41,21 @@ func (k Keeper) InitChainInfo(ctx context.Context, chainID string) (*types.Chain // HasChainInfo returns whether the chain info exists for a given ID // Since IBC does not provide API that allows to initialise chain info right before creating an IBC connection, // we can only check its existence every time, and return an empty one if it's not initialised yet. -func (k Keeper) HasChainInfo(ctx context.Context, chainID string) bool { +func (k Keeper) HasChainInfo(ctx context.Context, consumerId string) bool { store := k.chainInfoStore(ctx) - return store.Has([]byte(chainID)) + return store.Has([]byte(consumerId)) } // GetChainInfo returns the ChainInfo struct for a chain with a given ID // Since IBC does not provide API that allows to initialise chain info right before creating an IBC connection, // we can only check its existence every time, and return an empty one if it's not initialised yet. -func (k Keeper) GetChainInfo(ctx context.Context, chainID string) (*types.ChainInfo, error) { - if !k.HasChainInfo(ctx, chainID) { +func (k Keeper) GetChainInfo(ctx context.Context, consumerId string) (*types.ChainInfo, error) { + if !k.HasChainInfo(ctx, consumerId) { return nil, types.ErrChainInfoNotFound } store := k.chainInfoStore(ctx) - chainInfoBytes := store.Get([]byte(chainID)) + chainInfoBytes := store.Get([]byte(consumerId)) var chainInfo types.ChainInfo k.cdc.MustUnmarshal(chainInfoBytes, &chainInfo) return &chainInfo, nil @@ -66,14 +67,14 @@ func (k Keeper) GetChainInfo(ctx context.Context, chainID string) (*types.ChainI // Note that this function is triggered only upon receiving headers from the relayer, // and only a subset of headers in CZ are relayed. Thus TimestampedHeadersCount is not // equal to the total number of headers in CZ. -func (k Keeper) updateLatestHeader(ctx context.Context, chainID string, header *types.IndexedHeader) error { +func (k Keeper) updateLatestHeader(ctx context.Context, consumerId string, header *types.IndexedHeader) error { if header == nil { return errorsmod.Wrapf(types.ErrInvalidHeader, "header is nil") } - chainInfo, err := k.GetChainInfo(ctx, chainID) + chainInfo, err := k.GetChainInfo(ctx, consumerId) if err != nil { // chain info has not been initialised yet - return fmt.Errorf("failed to get chain info of %s: %w", chainID, err) + return fmt.Errorf("failed to get chain info of %s: %w", consumerId, err) } chainInfo.LatestHeader = header // replace the old latest header with the given one chainInfo.TimestampedHeadersCount++ // increment the number of timestamped headers @@ -87,12 +88,12 @@ func (k Keeper) updateLatestHeader(ctx context.Context, chainID string, header * // - If there is a fork header at the same height, add this fork to the set of latest fork headers // - If this fork header is newer than the previous one, replace the old fork headers with this fork header // - If this fork header is older than the current latest fork, ignore -func (k Keeper) tryToUpdateLatestForkHeader(ctx context.Context, chainID string, header *types.IndexedHeader) error { +func (k Keeper) tryToUpdateLatestForkHeader(ctx context.Context, consumerId string, header *types.IndexedHeader) error { if header == nil { return errorsmod.Wrapf(types.ErrInvalidHeader, "header is nil") } - chainInfo, err := k.GetChainInfo(ctx, chainID) + chainInfo, err := k.GetChainInfo(ctx, consumerId) if err != nil { return errorsmod.Wrapf(types.ErrChainInfoNotFound, "cannot insert fork header when chain info is not initialized") } @@ -117,23 +118,23 @@ func (k Keeper) tryToUpdateLatestForkHeader(ctx context.Context, chainID string, return nil } -// GetAllChainIDs gets all chain IDs that integrate Babylon -func (k Keeper) GetAllChainIDs(ctx context.Context) []string { - chainIDs := []string{} +// GetAllConsumerIDs gets IDs of all consumer that integrate Babylon +func (k Keeper) GetAllConsumerIDs(ctx context.Context) []string { + consumerIds := []string{} iter := k.chainInfoStore(ctx).Iterator(nil, nil) defer iter.Close() for ; iter.Valid(); iter.Next() { - chainIDBytes := iter.Key() - chainID := string(chainIDBytes) - chainIDs = append(chainIDs, chainID) + consumerIdBytes := iter.Key() + consumerId := string(consumerIdBytes) + consumerIds = append(consumerIds, consumerId) } - return chainIDs + return consumerIds } // msgChainInfoStore stores the information of canonical chains and forks for CZs // prefix: ChainInfoKey -// key: chainID +// key: consumerId // value: ChainInfo func (k Keeper) chainInfoStore(ctx context.Context) prefix.Store { storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) diff --git a/x/zoneconcierge/keeper/epoch_chain_info_indexer.go b/x/zoneconcierge/keeper/epoch_chain_info_indexer.go index 5584b008e..942f90001 100644 --- a/x/zoneconcierge/keeper/epoch_chain_info_indexer.go +++ b/x/zoneconcierge/keeper/epoch_chain_info_indexer.go @@ -13,12 +13,12 @@ import ( ) // GetEpochChainInfo gets the latest chain info of a given epoch for a given chain ID -func (k Keeper) GetEpochChainInfo(ctx context.Context, chainID string, epochNumber uint64) (*types.ChainInfoWithProof, error) { - if !k.EpochChainInfoExists(ctx, chainID, epochNumber) { +func (k Keeper) GetEpochChainInfo(ctx context.Context, consumerID string, epochNumber uint64) (*types.ChainInfoWithProof, error) { + if !k.EpochChainInfoExists(ctx, consumerID, epochNumber) { return nil, types.ErrEpochChainInfoNotFound } - store := k.epochChainInfoStore(ctx, chainID) + store := k.epochChainInfoStore(ctx, consumerID) epochNumberBytes := sdk.Uint64ToBigEndian(epochNumber) epochChainInfoBytes := store.Get(epochNumberBytes) var chainInfo types.ChainInfoWithProof @@ -26,24 +26,24 @@ func (k Keeper) GetEpochChainInfo(ctx context.Context, chainID string, epochNumb return &chainInfo, nil } -func (k Keeper) setEpochChainInfo(ctx context.Context, chainID string, epochNumber uint64, chainInfo *types.ChainInfoWithProof) { - store := k.epochChainInfoStore(ctx, chainID) +func (k Keeper) setEpochChainInfo(ctx context.Context, consumerID string, epochNumber uint64, chainInfo *types.ChainInfoWithProof) { + store := k.epochChainInfoStore(ctx, consumerID) store.Set(sdk.Uint64ToBigEndian(epochNumber), k.cdc.MustMarshal(chainInfo)) } // EpochChainInfoExists checks if the latest chain info exists of a given epoch for a given chain ID -func (k Keeper) EpochChainInfoExists(ctx context.Context, chainID string, epochNumber uint64) bool { - store := k.epochChainInfoStore(ctx, chainID) +func (k Keeper) EpochChainInfoExists(ctx context.Context, consumerID string, epochNumber uint64) bool { + store := k.epochChainInfoStore(ctx, consumerID) epochNumberBytes := sdk.Uint64ToBigEndian(epochNumber) return store.Has(epochNumberBytes) } // GetEpochHeaders gets the headers timestamped in a given epoch, in the ascending order -func (k Keeper) GetEpochHeaders(ctx context.Context, chainID string, epochNumber uint64) ([]*types.IndexedHeader, error) { +func (k Keeper) GetEpochHeaders(ctx context.Context, consumerID string, epochNumber uint64) ([]*types.IndexedHeader, error) { headers := []*types.IndexedHeader{} // find the last timestamped header of this chain in the epoch - epochChainInfoWithProof, err := k.GetEpochChainInfo(ctx, chainID, epochNumber) + epochChainInfoWithProof, err := k.GetEpochChainInfo(ctx, consumerID, epochNumber) if err != nil { return nil, err } @@ -57,7 +57,7 @@ func (k Keeper) GetEpochHeaders(ctx context.Context, chainID string, epochNumber headers = append(headers, epochChainInfo.LatestHeader) // append all previous headers until reaching the previous epoch - canonicalChainStore := k.canonicalChainStore(ctx, chainID) + canonicalChainStore := k.canonicalChainStore(ctx, consumerID) lastHeaderKey := sdk.Uint64ToBigEndian(epochChainInfo.LatestHeader.Height) // NOTE: even in ReverseIterator, start and end should still be specified in ascending order canonicalChainIter := canonicalChainStore.ReverseIterator(nil, lastHeaderKey) @@ -80,9 +80,9 @@ func (k Keeper) GetEpochHeaders(ctx context.Context, chainID string, epochNumber // recordEpochChainInfo records the chain info for a given epoch number of given chain ID // where the latest chain info is retrieved from the chain info indexer -func (k Keeper) recordEpochChainInfo(ctx context.Context, chainID string, epochNumber uint64) { +func (k Keeper) recordEpochChainInfo(ctx context.Context, consumerID string, epochNumber uint64) { // get the latest known chain info - chainInfo, err := k.GetChainInfo(ctx, chainID) + chainInfo, err := k.GetChainInfo(ctx, consumerID) if err != nil { k.Logger(sdk.UnwrapSDKContext(ctx)).Debug("chain info does not exist yet, nothing to record") return @@ -93,19 +93,19 @@ func (k Keeper) recordEpochChainInfo(ctx context.Context, chainID string, epochN } // NOTE: we can record epoch chain info without ancestor since IBC connection can be established at any height - k.setEpochChainInfo(ctx, chainID, epochNumber, chainInfoWithProof) + k.setEpochChainInfo(ctx, consumerID, epochNumber, chainInfoWithProof) } // recordEpochChainInfo records the chain info for a given epoch number of given chain ID // where the latest chain info is retrieved from the chain info indexer func (k Keeper) recordEpochChainInfoProofs(ctx context.Context, epochNumber uint64) { curEpoch := k.GetEpoch(ctx) - chainIDs := k.GetAllChainIDs(ctx) + consumerIDs := k.GetAllConsumerIDs(ctx) // save all inclusion proofs - for _, chainID := range chainIDs { + for _, consumerID := range consumerIDs { // retrieve chain info with empty proof - chainInfo, err := k.GetEpochChainInfo(ctx, chainID, epochNumber) + chainInfo, err := k.GetEpochChainInfo(ctx, consumerID, epochNumber) if err != nil { panic(err) // only programming error } @@ -116,24 +116,24 @@ func (k Keeper) recordEpochChainInfoProofs(ctx context.Context, epochNumber uint proofCZHeaderInEpoch, err := k.ProveCZHeaderInEpoch(ctx, lastHeaderInEpoch, curEpoch) if err != nil { // only programming error is possible here - panic(fmt.Errorf("failed to generate proofCZHeaderInEpoch for chain %s: %w", chainID, err)) + panic(fmt.Errorf("failed to generate proofCZHeaderInEpoch for consumer %s: %w", consumerID, err)) } chainInfo.ProofHeaderInEpoch = proofCZHeaderInEpoch // set chain info with proof back - k.setEpochChainInfo(ctx, chainID, epochNumber, chainInfo) + k.setEpochChainInfo(ctx, consumerID, epochNumber, chainInfo) } } } // epochChainInfoStore stores each epoch's latest ChainInfo for a CZ -// prefix: EpochChainInfoKey || chainID +// prefix: EpochChainInfoKey || consumerID // key: epochNumber // value: ChainInfoWithProof -func (k Keeper) epochChainInfoStore(ctx context.Context, chainID string) prefix.Store { +func (k Keeper) epochChainInfoStore(ctx context.Context, consumerID string) prefix.Store { storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) epochChainInfoStore := prefix.NewStore(storeAdapter, types.EpochChainInfoKey) - chainIDBytes := []byte(chainID) - return prefix.NewStore(epochChainInfoStore, chainIDBytes) + consumerIDBytes := []byte(consumerID) + return prefix.NewStore(epochChainInfoStore, consumerIDBytes) } diff --git a/x/zoneconcierge/keeper/epoch_chain_info_indexer_test.go b/x/zoneconcierge/keeper/epoch_chain_info_indexer_test.go index 59dc52c50..472c76dd5 100644 --- a/x/zoneconcierge/keeper/epoch_chain_info_indexer_test.go +++ b/x/zoneconcierge/keeper/epoch_chain_info_indexer_test.go @@ -20,7 +20,7 @@ func FuzzEpochChainInfoIndexer(f *testing.F) { babylonApp := app.Setup(t, false) zcKeeper := babylonApp.ZoneConciergeKeeper ctx := babylonApp.NewContext(false) - czChainID := "test-chainid" + consumerID := "test-consumerid" hooks := zcKeeper.Hooks() @@ -33,13 +33,13 @@ func FuzzEpochChainInfoIndexer(f *testing.F) { // invoke the hook a random number of times to simulate a random number of blocks numHeaders := datagen.RandomInt(r, 100) + 1 numForkHeaders := datagen.RandomInt(r, 10) + 1 - SimulateNewHeadersAndForks(ctx, r, &zcKeeper, czChainID, 0, numHeaders, numForkHeaders) + SimulateNewHeadersAndForks(ctx, r, &zcKeeper, consumerID, 0, numHeaders, numForkHeaders) // end this epoch hooks.AfterEpochEnds(ctx, epochNum) // check if the chain info of this epoch is recorded or not - chainInfoWithProof, err := zcKeeper.GetEpochChainInfo(ctx, czChainID, epochNum) + chainInfoWithProof, err := zcKeeper.GetEpochChainInfo(ctx, consumerID, epochNum) chainInfo := chainInfoWithProof.ChainInfo require.NoError(t, err) require.Equal(t, numHeaders-1, chainInfo.LatestHeader.Height) @@ -57,7 +57,7 @@ func FuzzGetEpochHeaders(f *testing.F) { babylonApp := app.Setup(t, false) zcKeeper := babylonApp.ZoneConciergeKeeper ctx := babylonApp.NewContext(false) - czChainID := "test-chainid" + consumerID := "test-consumerid" hooks := zcKeeper.Hooks() @@ -87,7 +87,7 @@ func FuzzGetEpochHeaders(f *testing.F) { numHeadersList = append(numHeadersList, datagen.RandomInt(r, 100)+1) numForkHeadersList = append(numForkHeadersList, datagen.RandomInt(r, 10)+1) // trigger hooks to append these headers and fork headers - expectedHeaders, _ := SimulateNewHeadersAndForks(ctx, r, &zcKeeper, czChainID, nextHeightList[i], numHeadersList[i], numForkHeadersList[i]) + expectedHeaders, _ := SimulateNewHeadersAndForks(ctx, r, &zcKeeper, consumerID, nextHeightList[i], numHeadersList[i], numForkHeadersList[i]) expectedHeadersMap[epochNum] = expectedHeaders // prepare nextHeight for the next request nextHeightList = append(nextHeightList, nextHeightList[i]+numHeadersList[i]) @@ -102,7 +102,7 @@ func FuzzGetEpochHeaders(f *testing.F) { for i := uint64(0); i < numReqs; i++ { epochNum := epochNumList[i] // check if the headers are same as expected - headers, err := zcKeeper.GetEpochHeaders(ctx, czChainID, epochNum) + headers, err := zcKeeper.GetEpochHeaders(ctx, consumerID, epochNum) require.NoError(t, err) require.Equal(t, len(expectedHeadersMap[epochNum]), len(headers)) for j := 0; j < len(expectedHeadersMap[epochNum]); j++ { diff --git a/x/zoneconcierge/keeper/fork_indexer.go b/x/zoneconcierge/keeper/fork_indexer.go index 68d98243f..936c13ea3 100644 --- a/x/zoneconcierge/keeper/fork_indexer.go +++ b/x/zoneconcierge/keeper/fork_indexer.go @@ -3,6 +3,7 @@ package keeper import ( "bytes" "context" + "github.com/cosmos/cosmos-sdk/runtime" sdkerrors "cosmossdk.io/errors" @@ -12,8 +13,8 @@ import ( ) // GetForks returns a list of forked headers at a given height -func (k Keeper) GetForks(ctx context.Context, chainID string, height uint64) *types.Forks { - store := k.forkStore(ctx, chainID) +func (k Keeper) GetForks(ctx context.Context, consumerID string, height uint64) *types.Forks { + store := k.forkStore(ctx, consumerID) heightBytes := sdk.Uint64ToBigEndian(height) // if no fork at the moment, create an empty struct if !store.Has(heightBytes) { @@ -28,12 +29,12 @@ func (k Keeper) GetForks(ctx context.Context, chainID string, height uint64) *ty } // insertForkHeader inserts a forked header to the list of forked headers at the same height -func (k Keeper) insertForkHeader(ctx context.Context, chainID string, header *types.IndexedHeader) error { +func (k Keeper) insertForkHeader(ctx context.Context, consumerID string, header *types.IndexedHeader) error { if header == nil { return sdkerrors.Wrapf(types.ErrInvalidHeader, "header is nil") } - store := k.forkStore(ctx, chainID) - forks := k.GetForks(ctx, chainID, header.Height) // if no fork at the height, forks will be an empty struct rather than nil + store := k.forkStore(ctx, consumerID) + forks := k.GetForks(ctx, consumerID, header.Height) // if no fork at the height, forks will be an empty struct rather than nil // if the header is already in forks, discard this header and return directly for _, h := range forks.Headers { if bytes.Equal(h.Hash, header.Hash) { @@ -47,12 +48,12 @@ func (k Keeper) insertForkHeader(ctx context.Context, chainID string, header *ty } // forkStore stores the forks for each CZ -// prefix: ForkKey || chainID +// prefix: ForkKey || consumerID // key: height that this fork starts from // value: a list of IndexedHeader, representing each header in the fork -func (k Keeper) forkStore(ctx context.Context, chainID string) prefix.Store { +func (k Keeper) forkStore(ctx context.Context, consumerID string) prefix.Store { storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) forkStore := prefix.NewStore(storeAdapter, types.ForkKey) - chainIDBytes := []byte(chainID) - return prefix.NewStore(forkStore, chainIDBytes) + consumerIDBytes := []byte(consumerID) + return prefix.NewStore(forkStore, consumerIDBytes) } diff --git a/x/zoneconcierge/keeper/fork_indexer_test.go b/x/zoneconcierge/keeper/fork_indexer_test.go index c1ef1a522..e1fb2a954 100644 --- a/x/zoneconcierge/keeper/fork_indexer_test.go +++ b/x/zoneconcierge/keeper/fork_indexer_test.go @@ -18,28 +18,27 @@ func FuzzForkIndexer(f *testing.F) { babylonApp := app.Setup(t, false) zcKeeper := babylonApp.ZoneConciergeKeeper ctx := babylonApp.NewContext(false) - czChainID := "test-chainid" + consumerID := "test-consumerid" // invoke the hook a random number of times to simulate a random number of blocks numHeaders := datagen.RandomInt(r, 100) + 1 numForkHeaders := datagen.RandomInt(r, 10) + 1 - _, forkHeaders := SimulateNewHeadersAndForks(ctx, r, &zcKeeper, czChainID, 0, numHeaders, numForkHeaders) + _, forkHeaders := SimulateNewHeadersAndForks(ctx, r, &zcKeeper, consumerID, 0, numHeaders, numForkHeaders) // check if the fork is updated or not - forks := zcKeeper.GetForks(ctx, czChainID, numHeaders-1) + forks := zcKeeper.GetForks(ctx, consumerID, numHeaders-1) require.Equal(t, numForkHeaders, uint64(len(forks.Headers))) for i := range forks.Headers { - require.Equal(t, czChainID, forks.Headers[i].ChainId) require.Equal(t, numHeaders-1, forks.Headers[i].Height) require.Equal(t, forkHeaders[i].Header.AppHash, forks.Headers[i].Hash) } // check if the chain info is updated or not - chainInfo, err := zcKeeper.GetChainInfo(ctx, czChainID) + chainInfo, err := zcKeeper.GetChainInfo(ctx, consumerID) require.NoError(t, err) require.Equal(t, numForkHeaders, uint64(len(chainInfo.LatestForks.Headers))) for i := range forks.Headers { - require.Equal(t, czChainID, chainInfo.LatestForks.Headers[i].ChainId) + require.Equal(t, consumerID, chainInfo.LatestForks.Headers[i].ConsumerId) require.Equal(t, numHeaders-1, chainInfo.LatestForks.Headers[i].Height) require.Equal(t, forkHeaders[i].Header.AppHash, chainInfo.LatestForks.Headers[i].Hash) } diff --git a/x/zoneconcierge/keeper/grpc_query.go b/x/zoneconcierge/keeper/grpc_query.go index 5cb71dfca..5b0e7ee62 100644 --- a/x/zoneconcierge/keeper/grpc_query.go +++ b/x/zoneconcierge/keeper/grpc_query.go @@ -31,11 +31,11 @@ func (k Keeper) ChainList(c context.Context, req *types.QueryChainListRequest) ( ctx := sdk.UnwrapSDKContext(c) - chainIDs := []string{} + ConsumerIds := []string{} store := k.chainInfoStore(ctx) pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { - chainID := string(key) - chainIDs = append(chainIDs, chainID) + ConsumerId := string(key) + ConsumerIds = append(ConsumerIds, ConsumerId) return nil }) if err != nil { @@ -43,8 +43,8 @@ func (k Keeper) ChainList(c context.Context, req *types.QueryChainListRequest) ( } resp := &types.QueryChainListResponse{ - ChainIds: chainIDs, - Pagination: pageRes, + ConsumerIds: ConsumerIds, + Pagination: pageRes, } return resp, nil } @@ -56,24 +56,24 @@ func (k Keeper) ChainsInfo(c context.Context, req *types.QueryChainsInfoRequest) } // return if no chain IDs are provided - if len(req.ChainIds) == 0 { - return nil, status.Error(codes.InvalidArgument, "chain IDs cannot be empty") + if len(req.ConsumerIds) == 0 { + return nil, status.Error(codes.InvalidArgument, "consumer IDs cannot be empty") } // return if chain IDs exceed the limit - if len(req.ChainIds) > maxQueryChainsInfoLimit { + if len(req.ConsumerIds) > maxQueryChainsInfoLimit { return nil, status.Errorf(codes.InvalidArgument, "cannot query more than %d chains", maxQueryChainsInfoLimit) } // return if chain IDs contain duplicates or empty strings - if err := bbntypes.CheckForDuplicatesAndEmptyStrings(req.ChainIds); err != nil { - return nil, status.Error(codes.InvalidArgument, types.ErrInvalidChainIDs.Wrap(err.Error()).Error()) + if err := bbntypes.CheckForDuplicatesAndEmptyStrings(req.ConsumerIds); err != nil { + return nil, status.Error(codes.InvalidArgument, types.ErrInvalidConsumerIDs.Wrap(err.Error()).Error()) } ctx := sdk.UnwrapSDKContext(c) var chainsInfo []*types.ChainInfo - for _, chainID := range req.ChainIds { - chainInfo, err := k.GetChainInfo(ctx, chainID) + for _, ConsumerId := range req.ConsumerIds { + chainInfo, err := k.GetChainInfo(ctx, ConsumerId) if err != nil { return nil, err } @@ -91,17 +91,17 @@ func (k Keeper) Header(c context.Context, req *types.QueryHeaderRequest) (*types return nil, status.Error(codes.InvalidArgument, "invalid request") } - if len(req.ChainId) == 0 { + if len(req.ConsumerId) == 0 { return nil, status.Error(codes.InvalidArgument, "chain ID cannot be empty") } ctx := sdk.UnwrapSDKContext(c) - header, err := k.GetHeader(ctx, req.ChainId, req.Height) + header, err := k.GetHeader(ctx, req.ConsumerId, req.Height) if err != nil { return nil, err } - forks := k.GetForks(ctx, req.ChainId, req.Height) + forks := k.GetForks(ctx, req.ConsumerId, req.Height) resp := &types.QueryHeaderResponse{ Header: header, ForkHeaders: forks, @@ -117,36 +117,36 @@ func (k Keeper) EpochChainsInfo(c context.Context, req *types.QueryEpochChainsIn } // return if no chain IDs are provided - if len(req.ChainIds) == 0 { - return nil, status.Error(codes.InvalidArgument, "chain IDs cannot be empty") + if len(req.ConsumerIds) == 0 { + return nil, status.Error(codes.InvalidArgument, "consumer IDs cannot be empty") } // return if chain IDs exceed the limit - if len(req.ChainIds) > maxQueryChainsInfoLimit { + if len(req.ConsumerIds) > maxQueryChainsInfoLimit { return nil, status.Errorf(codes.InvalidArgument, "cannot query more than %d chains", maxQueryChainsInfoLimit) } // return if chain IDs contain duplicates or empty strings - if err := bbntypes.CheckForDuplicatesAndEmptyStrings(req.ChainIds); err != nil { - return nil, status.Error(codes.InvalidArgument, types.ErrInvalidChainIDs.Wrap(err.Error()).Error()) + if err := bbntypes.CheckForDuplicatesAndEmptyStrings(req.ConsumerIds); err != nil { + return nil, status.Error(codes.InvalidArgument, types.ErrInvalidConsumerIDs.Wrap(err.Error()).Error()) } ctx := sdk.UnwrapSDKContext(c) var chainsInfo []*types.ChainInfo - for _, chainID := range req.ChainIds { + for _, ConsumerId := range req.ConsumerIds { // check if chain ID is valid - if !k.HasChainInfo(ctx, chainID) { - return nil, status.Error(codes.InvalidArgument, types.ErrChainInfoNotFound.Wrapf("chain ID %s", chainID).Error()) + if !k.HasChainInfo(ctx, ConsumerId) { + return nil, status.Error(codes.InvalidArgument, types.ErrChainInfoNotFound.Wrapf("chain ID %s", ConsumerId).Error()) } // if the chain info is not found in the given epoch, return with empty fields - if !k.EpochChainInfoExists(ctx, chainID, req.EpochNum) { - chainsInfo = append(chainsInfo, &types.ChainInfo{ChainId: chainID}) + if !k.EpochChainInfoExists(ctx, ConsumerId, req.EpochNum) { + chainsInfo = append(chainsInfo, &types.ChainInfo{ConsumerId: ConsumerId}) continue } // find the chain info of the given epoch - chainInfoWithProof, err := k.GetEpochChainInfo(ctx, chainID, req.EpochNum) + chainInfoWithProof, err := k.GetEpochChainInfo(ctx, ConsumerId, req.EpochNum) if err != nil { return nil, err } @@ -164,14 +164,14 @@ func (k Keeper) ListHeaders(c context.Context, req *types.QueryListHeadersReques return nil, status.Error(codes.InvalidArgument, "invalid request") } - if len(req.ChainId) == 0 { + if len(req.ConsumerId) == 0 { return nil, status.Error(codes.InvalidArgument, "chain ID cannot be empty") } ctx := sdk.UnwrapSDKContext(c) headers := []*types.IndexedHeader{} - store := k.canonicalChainStore(ctx, req.ChainId) + store := k.canonicalChainStore(ctx, req.ConsumerId) pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { var header types.IndexedHeader k.cdc.MustUnmarshal(value, &header) @@ -196,13 +196,13 @@ func (k Keeper) ListEpochHeaders(c context.Context, req *types.QueryListEpochHea return nil, status.Error(codes.InvalidArgument, "invalid request") } - if len(req.ChainId) == 0 { + if len(req.ConsumerId) == 0 { return nil, status.Error(codes.InvalidArgument, "chain ID cannot be empty") } ctx := sdk.UnwrapSDKContext(c) - headers, err := k.GetEpochHeaders(ctx, req.ChainId, req.EpochNum) + headers, err := k.GetEpochHeaders(ctx, req.ConsumerId, req.EpochNum) if err != nil { return nil, err } @@ -220,18 +220,18 @@ func (k Keeper) FinalizedChainsInfo(c context.Context, req *types.QueryFinalized } // return if no chain IDs are provided - if len(req.ChainIds) == 0 { + if len(req.ConsumerIds) == 0 { return nil, status.Error(codes.InvalidArgument, "chain ID cannot be empty") } // return if chain IDs exceed the limit - if len(req.ChainIds) > maxQueryChainsInfoLimit { + if len(req.ConsumerIds) > maxQueryChainsInfoLimit { return nil, status.Errorf(codes.InvalidArgument, "cannot query more than %d chains", maxQueryChainsInfoLimit) } // return if chain IDs contain duplicates or empty strings - if err := bbntypes.CheckForDuplicatesAndEmptyStrings(req.ChainIds); err != nil { - return nil, status.Error(codes.InvalidArgument, types.ErrInvalidChainIDs.Wrap(err.Error()).Error()) + if err := bbntypes.CheckForDuplicatesAndEmptyStrings(req.ConsumerIds); err != nil { + return nil, status.Error(codes.InvalidArgument, types.ErrInvalidConsumerIDs.Wrap(err.Error()).Error()) } ctx := sdk.UnwrapSDKContext(c) @@ -239,22 +239,22 @@ func (k Keeper) FinalizedChainsInfo(c context.Context, req *types.QueryFinalized // find the last finalised epoch lastFinalizedEpoch := k.GetLastFinalizedEpoch(ctx) - for _, chainID := range req.ChainIds { + for _, ConsumerId := range req.ConsumerIds { // check if chain ID is valid - if !k.HasChainInfo(ctx, chainID) { - return nil, status.Error(codes.InvalidArgument, types.ErrChainInfoNotFound.Wrapf("chain ID %s", chainID).Error()) + if !k.HasChainInfo(ctx, ConsumerId) { + return nil, status.Error(codes.InvalidArgument, types.ErrChainInfoNotFound.Wrapf("chain ID %s", ConsumerId).Error()) } - data := &types.FinalizedChainInfo{ChainId: chainID} + data := &types.FinalizedChainInfo{ConsumerId: ConsumerId} // if the chain info is not found in the last finalised epoch, return with empty fields - if !k.EpochChainInfoExists(ctx, chainID, lastFinalizedEpoch) { + if !k.EpochChainInfoExists(ctx, ConsumerId, lastFinalizedEpoch) { resp.FinalizedChainsInfo = append(resp.FinalizedChainsInfo, data) continue } // find the chain info in the last finalised epoch - chainInfoWithProof, err := k.GetEpochChainInfo(ctx, chainID, lastFinalizedEpoch) + chainInfoWithProof, err := k.GetEpochChainInfo(ctx, ConsumerId, lastFinalizedEpoch) if err != nil { return nil, err } @@ -309,7 +309,7 @@ func (k Keeper) FinalizedChainInfoUntilHeight(c context.Context, req *types.Quer return nil, status.Error(codes.InvalidArgument, "invalid request") } - if len(req.ChainId) == 0 { + if len(req.ConsumerId) == 0 { return nil, status.Error(codes.InvalidArgument, "chain ID cannot be empty") } @@ -319,7 +319,7 @@ func (k Keeper) FinalizedChainInfoUntilHeight(c context.Context, req *types.Quer // find the last finalised epoch lastFinalizedEpoch := k.GetLastFinalizedEpoch(ctx) // find the chain info in the last finalised epoch - chainInfoWithProof, err := k.GetEpochChainInfo(ctx, req.ChainId, lastFinalizedEpoch) + chainInfoWithProof, err := k.GetEpochChainInfo(ctx, req.ConsumerId, lastFinalizedEpoch) if err != nil { return nil, err } @@ -358,13 +358,13 @@ func (k Keeper) FinalizedChainInfoUntilHeight(c context.Context, req *types.Quer } } else { // the requested height is before the last finalised chain info // starting from the requested height, iterate backward until a timestamped header - closestHeader, err := k.FindClosestHeader(ctx, req.ChainId, req.Height) + closestHeader, err := k.FindClosestHeader(ctx, req.ConsumerId, req.Height) if err != nil { return nil, err } // assign the finalizedEpoch, and retrieve epoch info, raw ckpt and submission key finalizedEpoch = closestHeader.BabylonEpoch - chainInfoWithProof, err := k.GetEpochChainInfo(ctx, req.ChainId, finalizedEpoch) + chainInfoWithProof, err := k.GetEpochChainInfo(ctx, req.ConsumerId, finalizedEpoch) if err != nil { return nil, err } diff --git a/x/zoneconcierge/keeper/grpc_query_test.go b/x/zoneconcierge/keeper/grpc_query_test.go index 4885659e9..b160119a0 100644 --- a/x/zoneconcierge/keeper/grpc_query_test.go +++ b/x/zoneconcierge/keeper/grpc_query_test.go @@ -19,7 +19,7 @@ import ( ) type chainInfo struct { - chainID string + consumerID string numHeaders uint64 numForkHeaders uint64 headerStartHeight uint64 @@ -37,21 +37,21 @@ func FuzzChainList(f *testing.F) { // invoke the hook a random number of times with random chain IDs numHeaders := datagen.RandomInt(r, 100) + 1 - allChainIDs := []string{} + allConsumerIDs := []string{} for i := uint64(0); i < numHeaders; i++ { - var chainID string + var consumerID string // simulate the scenario that some headers belong to the same chain if i > 0 && datagen.OneInN(r, 2) { - chainID = allChainIDs[r.Intn(len(allChainIDs))] + consumerID = allConsumerIDs[r.Intn(len(allConsumerIDs))] } else { - chainID = datagen.GenRandomHexStr(r, 30) - allChainIDs = append(allChainIDs, chainID) + consumerID = datagen.GenRandomHexStr(r, 30) + allConsumerIDs = append(allConsumerIDs, consumerID) } - header := datagen.GenRandomIBCTMHeader(r, chainID, 0) - zcKeeper.HandleHeaderWithValidCommit(ctx, datagen.GenRandomByteArray(r, 32), datagen.HeaderToHeaderInfo(header), false) + header := datagen.GenRandomIBCTMHeader(r, 0) + zcKeeper.HandleHeaderWithValidCommit(ctx, datagen.GenRandomByteArray(r, 32), datagen.NewZCHeaderInfo(header, consumerID), false) } - limit := datagen.RandomInt(r, len(allChainIDs)) + 1 + limit := datagen.RandomInt(r, len(allConsumerIDs)) + 1 // make query to get actual chain IDs resp, err := zcKeeper.ChainList(ctx, &zctypes.QueryChainListRequest{ @@ -60,12 +60,12 @@ func FuzzChainList(f *testing.F) { }, }) require.NoError(t, err) - actualChainIDs := resp.ChainIds + actualConsumerIDs := resp.ConsumerIds - require.Equal(t, limit, uint64(len(actualChainIDs))) - allChainIDs = zcKeeper.GetAllChainIDs(ctx) + require.Equal(t, limit, uint64(len(actualConsumerIDs))) + allConsumerIDs = zcKeeper.GetAllConsumerIDs(ctx) for i := uint64(0); i < limit; i++ { - require.Equal(t, allChainIDs[i], actualChainIDs[i]) + require.Equal(t, allConsumerIDs[i], actualConsumerIDs[i]) } }) } @@ -81,31 +81,31 @@ func FuzzChainsInfo(f *testing.F) { ctx := babylonApp.NewContext(false) var ( - chainsInfo []chainInfo - chainIDs []string + chainsInfo []chainInfo + consumerIDs []string ) numChains := datagen.RandomInt(r, 100) + 1 for i := uint64(0); i < numChains; i++ { - chainID := datagen.GenRandomHexStr(r, 30) + consumerID := datagen.GenRandomHexStr(r, 30) numHeaders := datagen.RandomInt(r, 100) + 1 numForkHeaders := datagen.RandomInt(r, 10) + 1 - SimulateNewHeadersAndForks(ctx, r, &zcKeeper, chainID, 0, numHeaders, numForkHeaders) + SimulateNewHeadersAndForks(ctx, r, &zcKeeper, consumerID, 0, numHeaders, numForkHeaders) - chainIDs = append(chainIDs, chainID) + consumerIDs = append(consumerIDs, consumerID) chainsInfo = append(chainsInfo, chainInfo{ - chainID: chainID, + consumerID: consumerID, numHeaders: numHeaders, numForkHeaders: numForkHeaders, }) } resp, err := zcKeeper.ChainsInfo(ctx, &zctypes.QueryChainsInfoRequest{ - ChainIds: chainIDs, + ConsumerIds: consumerIDs, }) require.NoError(t, err) for i, respData := range resp.ChainsInfo { - require.Equal(t, chainsInfo[i].chainID, respData.ChainId) + require.Equal(t, chainsInfo[i].consumerID, respData.ConsumerId) require.Equal(t, chainsInfo[i].numHeaders-1, respData.LatestHeader.Height) require.Equal(t, chainsInfo[i].numForkHeaders, uint64(len(respData.LatestForks.Headers))) } @@ -121,22 +121,22 @@ func FuzzHeader(f *testing.F) { babylonApp := app.Setup(t, false) zcKeeper := babylonApp.ZoneConciergeKeeper ctx := babylonApp.NewContext(false) - czChainID := "test-chainid" + consumerID := "test-consumerid" // invoke the hook a random number of times to simulate a random number of blocks numHeaders := datagen.RandomInt(r, 100) + 2 numForkHeaders := datagen.RandomInt(r, 10) + 1 - headers, forkHeaders := SimulateNewHeadersAndForks(ctx, r, &zcKeeper, czChainID, 0, numHeaders, numForkHeaders) + headers, forkHeaders := SimulateNewHeadersAndForks(ctx, r, &zcKeeper, consumerID, 0, numHeaders, numForkHeaders) // find header at a random height and assert correctness against the expected header randomHeight := datagen.RandomInt(r, int(numHeaders-1)) - resp, err := zcKeeper.Header(ctx, &zctypes.QueryHeaderRequest{ChainId: czChainID, Height: randomHeight}) + resp, err := zcKeeper.Header(ctx, &zctypes.QueryHeaderRequest{ConsumerId: consumerID, Height: randomHeight}) require.NoError(t, err) require.Equal(t, headers[randomHeight].Header.AppHash, resp.Header.Hash) require.Len(t, resp.ForkHeaders.Headers, 0) // find the last header and fork headers then assert correctness - resp, err = zcKeeper.Header(ctx, &zctypes.QueryHeaderRequest{ChainId: czChainID, Height: numHeaders - 1}) + resp, err = zcKeeper.Header(ctx, &zctypes.QueryHeaderRequest{ConsumerId: consumerID, Height: numHeaders - 1}) require.NoError(t, err) require.Equal(t, headers[numHeaders-1].Header.AppHash, resp.Header.Hash) require.Len(t, resp.ForkHeaders.Headers, int(numForkHeaders)) @@ -160,10 +160,10 @@ func FuzzEpochChainsInfo(f *testing.F) { // generate a random number of chains numChains := datagen.RandomInt(r, 10) + 1 - var chainIDs []string + var consumerIDs []string for j := uint64(0); j < numChains; j++ { - chainID := datagen.GenRandomHexStr(r, 30) - chainIDs = append(chainIDs, chainID) + consumerID := datagen.GenRandomHexStr(r, 30) + consumerIDs = append(consumerIDs, consumerID) } // generate a random number of epochNums @@ -180,16 +180,16 @@ func FuzzEpochChainsInfo(f *testing.F) { epochToChainInfo := make(map[uint64]map[string]chainInfo) for _, epochNum := range epochNums { epochToChainInfo[epochNum] = make(map[string]chainInfo) - for j, chainID := range chainIDs { + for j, consumerID := range consumerIDs { // generate a random number of headers and fork headers for each chain numHeaders := datagen.RandomInt(r, 100) + 1 numForkHeaders := datagen.RandomInt(r, 10) + 1 // trigger hooks to append these headers and fork headers - SimulateNewHeadersAndForks(ctx, r, &zcKeeper, chainID, chainHeaderStartHeights[j], numHeaders, numForkHeaders) + SimulateNewHeadersAndForks(ctx, r, &zcKeeper, consumerID, chainHeaderStartHeights[j], numHeaders, numForkHeaders) - epochToChainInfo[epochNum][chainID] = chainInfo{ - chainID: chainID, + epochToChainInfo[epochNum][consumerID] = chainInfo{ + consumerID: consumerID, numHeaders: numHeaders, numForkHeaders: numForkHeaders, headerStartHeight: chainHeaderStartHeights[j], @@ -205,14 +205,14 @@ func FuzzEpochChainsInfo(f *testing.F) { // assert correctness of best case scenario for _, epochNum := range epochNums { - resp, err := zcKeeper.EpochChainsInfo(ctx, &zctypes.QueryEpochChainsInfoRequest{EpochNum: epochNum, ChainIds: chainIDs}) + resp, err := zcKeeper.EpochChainsInfo(ctx, &zctypes.QueryEpochChainsInfoRequest{EpochNum: epochNum, ConsumerIds: consumerIDs}) require.NoError(t, err) epochChainsInfo := resp.ChainsInfo require.Len(t, epochChainsInfo, int(numChains)) for _, info := range epochChainsInfo { - require.Equal(t, epochToChainInfo[epochNum][info.ChainId].numForkHeaders, uint64(len(info.LatestForks.Headers))) + require.Equal(t, epochToChainInfo[epochNum][info.ConsumerId].numForkHeaders, uint64(len(info.LatestForks.Headers))) - actualHeight := epochToChainInfo[epochNum][info.ChainId].headerStartHeight + (epochToChainInfo[epochNum][info.ChainId].numHeaders - 1) + actualHeight := epochToChainInfo[epochNum][info.ConsumerId].headerStartHeight + (epochToChainInfo[epochNum][info.ConsumerId].numHeaders - 1) require.Equal(t, actualHeight, info.LatestHeader.Height) } @@ -220,26 +220,26 @@ func FuzzEpochChainsInfo(f *testing.F) { // if num of chain ids exceed the max limit, query should fail largeNumChains := datagen.RandomInt(r, 10) + 101 - var maxChainIDs []string + var maxConsumerIDs []string for i := uint64(0); i < largeNumChains; i++ { - maxChainIDs = append(maxChainIDs, datagen.GenRandomHexStr(r, 30)) + maxConsumerIDs = append(maxConsumerIDs, datagen.GenRandomHexStr(r, 30)) } randomEpochNum := datagen.RandomInt(r, 10) + 1 - _, err := zcKeeper.EpochChainsInfo(ctx, &zctypes.QueryEpochChainsInfoRequest{EpochNum: randomEpochNum, ChainIds: maxChainIDs}) + _, err := zcKeeper.EpochChainsInfo(ctx, &zctypes.QueryEpochChainsInfoRequest{EpochNum: randomEpochNum, ConsumerIds: maxConsumerIDs}) require.Error(t, err) // if no input is passed in, query should fail - _, err = zcKeeper.EpochChainsInfo(ctx, &zctypes.QueryEpochChainsInfoRequest{EpochNum: randomEpochNum, ChainIds: nil}) + _, err = zcKeeper.EpochChainsInfo(ctx, &zctypes.QueryEpochChainsInfoRequest{EpochNum: randomEpochNum, ConsumerIds: nil}) require.Error(t, err) // if len of chain ids is 0, query should fail - _, err = zcKeeper.EpochChainsInfo(ctx, &zctypes.QueryEpochChainsInfoRequest{EpochNum: randomEpochNum, ChainIds: []string{}}) + _, err = zcKeeper.EpochChainsInfo(ctx, &zctypes.QueryEpochChainsInfoRequest{EpochNum: randomEpochNum, ConsumerIds: []string{}}) require.Error(t, err) // if chain ids contain duplicates, query should fail - randomChainID := datagen.GenRandomHexStr(r, 30) - dupChainIds := []string{randomChainID, randomChainID} - _, err = zcKeeper.EpochChainsInfo(ctx, &zctypes.QueryEpochChainsInfoRequest{EpochNum: randomEpochNum, ChainIds: dupChainIds}) + randomConsumerID := datagen.GenRandomHexStr(r, 30) + dupConsumerIds := []string{randomConsumerID, randomConsumerID} + _, err = zcKeeper.EpochChainsInfo(ctx, &zctypes.QueryEpochChainsInfoRequest{EpochNum: randomEpochNum, ConsumerIds: dupConsumerIds}) require.Error(t, err) }) } @@ -253,17 +253,17 @@ func FuzzListHeaders(f *testing.F) { babylonApp := app.Setup(t, false) zcKeeper := babylonApp.ZoneConciergeKeeper ctx := babylonApp.NewContext(false) - czChainID := "test-chainid" + consumerID := "test-consumerid" // invoke the hook a random number of times to simulate a random number of blocks numHeaders := datagen.RandomInt(r, 100) + 1 numForkHeaders := datagen.RandomInt(r, 10) + 1 - headers, _ := SimulateNewHeadersAndForks(ctx, r, &zcKeeper, czChainID, 0, numHeaders, numForkHeaders) + headers, _ := SimulateNewHeadersAndForks(ctx, r, &zcKeeper, consumerID, 0, numHeaders, numForkHeaders) // a request with randomised pagination limit := datagen.RandomInt(r, int(numHeaders)) + 1 req := &zctypes.QueryListHeadersRequest{ - ChainId: czChainID, + ConsumerId: consumerID, Pagination: &query.PageRequest{ Limit: limit, }, @@ -287,7 +287,7 @@ func FuzzListEpochHeaders(f *testing.F) { zcKeeper := babylonApp.ZoneConciergeKeeper epochingKeeper := babylonApp.EpochingKeeper ctx := babylonApp.NewContext(false) - czChainID := "test-chainid" + consumerID := "test-consumerid" hooks := zcKeeper.Hooks() @@ -318,7 +318,7 @@ func FuzzListEpochHeaders(f *testing.F) { numHeadersList = append(numHeadersList, datagen.RandomInt(r, 100)+1) numForkHeadersList = append(numForkHeadersList, datagen.RandomInt(r, 10)+1) // trigger hooks to append these headers and fork headers - expectedHeaders, _ := SimulateNewHeadersAndForks(ctx, r, &zcKeeper, czChainID, nextHeightList[i], numHeadersList[i], numForkHeadersList[i]) + expectedHeaders, _ := SimulateNewHeadersAndForks(ctx, r, &zcKeeper, consumerID, nextHeightList[i], numHeadersList[i], numForkHeadersList[i]) expectedHeadersMap[epochNum] = expectedHeaders // prepare nextHeight for the next request nextHeightList = append(nextHeightList, nextHeightList[i]+numHeadersList[i]) @@ -334,8 +334,8 @@ func FuzzListEpochHeaders(f *testing.F) { epochNum := epochNumList[i] // make request req := &zctypes.QueryListEpochHeadersRequest{ - ChainId: czChainID, - EpochNum: epochNum, + ConsumerId: consumerID, + EpochNum: epochNum, } resp, err := zcKeeper.ListEpochHeaders(ctx, req) require.NoError(t, err) @@ -400,22 +400,22 @@ func FuzzFinalizedChainInfo(f *testing.F) { hooks := zcKeeper.Hooks() var ( - chainsInfo []chainInfo - chainIDs []string + chainsInfo []chainInfo + consumerIDs []string ) numChains := datagen.RandomInt(r, 100) + 1 for i := uint64(0); i < numChains; i++ { - czChainIDLen := datagen.RandomInt(r, 40) + 10 - czChainID := string(datagen.GenRandomByteArray(r, czChainIDLen)) + consumerIDLen := datagen.RandomInt(r, 40) + 10 + consumerID := string(datagen.GenRandomByteArray(r, consumerIDLen)) // invoke the hook a random number of times to simulate a random number of blocks numHeaders := datagen.RandomInt(r, 100) + 1 numForkHeaders := datagen.RandomInt(r, 10) + 1 - SimulateNewHeadersAndForks(ctx, r, zcKeeper, czChainID, 0, numHeaders, numForkHeaders) + SimulateNewHeadersAndForks(ctx, r, zcKeeper, consumerID, 0, numHeaders, numForkHeaders) - chainIDs = append(chainIDs, czChainID) + consumerIDs = append(consumerIDs, consumerID) chainsInfo = append(chainsInfo, chainInfo{ - chainID: czChainID, + consumerID: consumerID, numHeaders: numHeaders, numForkHeaders: numForkHeaders, }) @@ -427,10 +427,10 @@ func FuzzFinalizedChainInfo(f *testing.F) { checkpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(epoch.EpochNumber).AnyTimes() // check if the chain info of this epoch is recorded or not - resp, err := zcKeeper.FinalizedChainsInfo(ctx, &zctypes.QueryFinalizedChainsInfoRequest{ChainIds: chainIDs, Prove: true}) + resp, err := zcKeeper.FinalizedChainsInfo(ctx, &zctypes.QueryFinalizedChainsInfoRequest{ConsumerIds: consumerIDs, Prove: true}) require.NoError(t, err) for i, respData := range resp.FinalizedChainsInfo { - require.Equal(t, chainsInfo[i].chainID, respData.FinalizedChainInfo.ChainId) + require.Equal(t, chainsInfo[i].consumerID, respData.FinalizedChainInfo.ConsumerId) require.Equal(t, chainsInfo[i].numHeaders-1, respData.FinalizedChainInfo.LatestHeader.Height) require.Equal(t, chainsInfo[i].numForkHeaders, uint64(len(respData.FinalizedChainInfo.LatestForks.Headers))) } diff --git a/x/zoneconcierge/keeper/header_handler.go b/x/zoneconcierge/keeper/header_handler.go index e4bfa635d..412664328 100644 --- a/x/zoneconcierge/keeper/header_handler.go +++ b/x/zoneconcierge/keeper/header_handler.go @@ -14,7 +14,7 @@ func (k Keeper) HandleHeaderWithValidCommit(ctx context.Context, txHash []byte, sdkCtx := sdk.UnwrapSDKContext(ctx) babylonHeader := sdkCtx.HeaderInfo() indexedHeader := types.IndexedHeader{ - ChainId: header.ChainId, + ConsumerId: header.ClientId, Hash: header.AppHash, Height: header.Height, Time: &header.Time, @@ -30,27 +30,27 @@ func (k Keeper) HandleHeaderWithValidCommit(ctx context.Context, txHash []byte, chainInfo *types.ChainInfo err error ) - if !k.HasChainInfo(ctx, indexedHeader.ChainId) { + if !k.HasChainInfo(ctx, indexedHeader.ConsumerId) { // chain info does not exist yet, initialise chain info for this chain - chainInfo, err = k.InitChainInfo(ctx, indexedHeader.ChainId) + chainInfo, err = k.InitChainInfo(ctx, indexedHeader.ConsumerId) if err != nil { - panic(fmt.Errorf("failed to initialize chain info of %s: %w", indexedHeader.ChainId, err)) + panic(fmt.Errorf("failed to initialize chain info of %s: %w", indexedHeader.ConsumerId, err)) } } else { // get chain info - chainInfo, err = k.GetChainInfo(ctx, indexedHeader.ChainId) + chainInfo, err = k.GetChainInfo(ctx, indexedHeader.ConsumerId) if err != nil { - panic(fmt.Errorf("failed to get chain info of %s: %w", indexedHeader.ChainId, err)) + panic(fmt.Errorf("failed to get chain info of %s: %w", indexedHeader.ConsumerId, err)) } } if isOnFork { // insert header to fork index - if err := k.insertForkHeader(ctx, indexedHeader.ChainId, &indexedHeader); err != nil { + if err := k.insertForkHeader(ctx, indexedHeader.ConsumerId, &indexedHeader); err != nil { panic(err) } // update the latest fork in chain info - if err := k.tryToUpdateLatestForkHeader(ctx, indexedHeader.ChainId, &indexedHeader); err != nil { + if err := k.tryToUpdateLatestForkHeader(ctx, indexedHeader.ConsumerId, &indexedHeader); err != nil { panic(err) } } else { @@ -62,11 +62,11 @@ func (k Keeper) HandleHeaderWithValidCommit(ctx context.Context, txHash []byte, } // insert header to canonical chain index - if err := k.insertHeader(ctx, indexedHeader.ChainId, &indexedHeader); err != nil { + if err := k.insertHeader(ctx, indexedHeader.ConsumerId, &indexedHeader); err != nil { panic(err) } // update the latest canonical header in chain info - if err := k.updateLatestHeader(ctx, indexedHeader.ChainId, &indexedHeader); err != nil { + if err := k.updateLatestHeader(ctx, indexedHeader.ConsumerId, &indexedHeader); err != nil { panic(err) } } diff --git a/x/zoneconcierge/keeper/hooks.go b/x/zoneconcierge/keeper/hooks.go index 8621183dc..f8d4c5031 100644 --- a/x/zoneconcierge/keeper/hooks.go +++ b/x/zoneconcierge/keeper/hooks.go @@ -23,8 +23,8 @@ func (k Keeper) Hooks() Hooks { return Hooks{k} } func (h Hooks) AfterEpochEnds(ctx context.Context, epoch uint64) { // upon an epoch has ended, index the current chain info for each CZ // TODO: do this together when epoch is sealed? - for _, chainID := range h.k.GetAllChainIDs(ctx) { - h.k.recordEpochChainInfo(ctx, chainID, epoch) + for _, consumerID := range h.k.GetAllConsumerIDs(ctx) { + h.k.recordEpochChainInfo(ctx, consumerID, epoch) } } diff --git a/x/zoneconcierge/keeper/ibc_packet_btc_timestamp.go b/x/zoneconcierge/keeper/ibc_packet_btc_timestamp.go index 7df7c61ad..447051973 100644 --- a/x/zoneconcierge/keeper/ibc_packet_btc_timestamp.go +++ b/x/zoneconcierge/keeper/ibc_packet_btc_timestamp.go @@ -6,7 +6,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" - ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" bbn "github.com/babylonlabs-io/babylon/types" btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" @@ -27,21 +26,16 @@ type finalizedInfo struct { BTCHeaders []*btclctypes.BTCHeaderInfo } -// getChainID gets the ID of the counterparty chain under the given channel -func (k Keeper) getChainID(ctx context.Context, channel channeltypes.IdentifiedChannel) (string, error) { +// getClientID gets the ID of the IBC client under the given channel +// We will use the client ID as the consumer ID to uniquely identify +// the consumer chain +func (k Keeper) getClientID(ctx context.Context, channel channeltypes.IdentifiedChannel) (string, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) - // get clientState under this channel - _, clientState, err := k.channelKeeper.GetChannelClientState(sdkCtx, channel.PortId, channel.ChannelId) + clientID, _, err := k.channelKeeper.GetChannelClientState(sdkCtx, channel.PortId, channel.ChannelId) if err != nil { return "", err } - // cast clientState to comet clientState - // TODO: support for chains other than Cosmos zones - cmtClientState, ok := clientState.(*ibctmtypes.ClientState) - if !ok { - return "", fmt.Errorf("client must be a Comet client, expected: %T, got: %T", &ibctmtypes.ClientState{}, cmtClientState) - } - return cmtClientState.ChainId, nil + return clientID, nil } // getFinalizedInfo returns metadata and proofs that are identical to all BTC timestamps in the same epoch @@ -99,7 +93,7 @@ func (k Keeper) getFinalizedInfo( // where the counterparty is a Cosmos zone func (k Keeper) createBTCTimestamp( ctx context.Context, - chainID string, + consumerID string, channel channeltypes.IdentifiedChannel, finalizedInfo *finalizedInfo, ) (*types.BTCTimestamp, error) { @@ -123,9 +117,9 @@ func (k Keeper) createBTCTimestamp( // NOTE: it's possible that this chain does not have chain info at the moment // In this case, skip sending BTC timestamp for this chain at this epoch epochNum := finalizedInfo.EpochInfo.EpochNumber - epochChainInfo, err := k.GetEpochChainInfo(ctx, chainID, epochNum) + epochChainInfo, err := k.GetEpochChainInfo(ctx, consumerID, epochNum) if err != nil { - return nil, fmt.Errorf("no epochChainInfo for chain %s at epoch %d", chainID, epochNum) + return nil, fmt.Errorf("no epochChainInfo for chain %s at epoch %d", consumerID, epochNum) } // construct BTC timestamp from everything @@ -235,16 +229,16 @@ func (k Keeper) BroadcastBTCTimestamps( // for each channel, construct and send BTC timestamp for _, channel := range openZCChannels { // get the ID of the chain under this channel - chainID, err := k.getChainID(ctx, channel) + consumerID, err := k.getClientID(ctx, channel) if err != nil { - k.Logger(sdkCtx).Error("failed to get chain ID, skip sending BTC timestamp for this chain", "channelID", channel.ChannelId, "error", err) + k.Logger(sdkCtx).Error("failed to get client ID, skip sending BTC timestamp for this consumer", "channelID", channel.ChannelId, "error", err) continue } // generate timestamp for this channel - btcTimestamp, err := k.createBTCTimestamp(ctx, chainID, channel, finalizedInfo) + btcTimestamp, err := k.createBTCTimestamp(ctx, consumerID, channel, finalizedInfo) if err != nil { - k.Logger(sdkCtx).Error("failed to generate BTC timestamp, skip sending BTC timestamp for this chain", "chainID", chainID, "error", err) + k.Logger(sdkCtx).Error("failed to generate BTC timestamp, skip sending BTC timestamp for this chain", "consumerID", consumerID, "error", err) continue } @@ -252,7 +246,7 @@ func (k Keeper) BroadcastBTCTimestamps( packet := types.NewBTCTimestampPacketData(btcTimestamp) // send IBC packet if err := k.SendIBCPacket(ctx, channel, packet); err != nil { - k.Logger(sdkCtx).Error("failed to send BTC timestamp IBC packet, skip sending BTC timestamp for this chain", "chainID", chainID, "channelID", channel.ChannelId, "error", err) + k.Logger(sdkCtx).Error("failed to send BTC timestamp IBC packet, skip sending BTC timestamp for this chain", "consumerID", consumerID, "channelID", channel.ChannelId, "error", err) continue } } diff --git a/x/zoneconcierge/keeper/keeper_test.go b/x/zoneconcierge/keeper/keeper_test.go index 1d5392735..a552219b8 100644 --- a/x/zoneconcierge/keeper/keeper_test.go +++ b/x/zoneconcierge/keeper/keeper_test.go @@ -11,32 +11,32 @@ import ( ) // SimulateNewHeaders generates a non-zero number of canonical headers -func SimulateNewHeaders(ctx context.Context, r *rand.Rand, k *zckeeper.Keeper, chainID string, startHeight uint64, numHeaders uint64) []*ibctmtypes.Header { +func SimulateNewHeaders(ctx context.Context, r *rand.Rand, k *zckeeper.Keeper, consumerID string, startHeight uint64, numHeaders uint64) []*ibctmtypes.Header { headers := []*ibctmtypes.Header{} // invoke the hook a number of times to simulate a number of blocks for i := uint64(0); i < numHeaders; i++ { - header := datagen.GenRandomIBCTMHeader(r, chainID, startHeight+i) - k.HandleHeaderWithValidCommit(ctx, datagen.GenRandomByteArray(r, 32), datagen.HeaderToHeaderInfo(header), false) + header := datagen.GenRandomIBCTMHeader(r, startHeight+i) + k.HandleHeaderWithValidCommit(ctx, datagen.GenRandomByteArray(r, 32), datagen.NewZCHeaderInfo(header, consumerID), false) headers = append(headers, header) } return headers } // SimulateNewHeadersAndForks generates a random non-zero number of canonical headers and fork headers -func SimulateNewHeadersAndForks(ctx context.Context, r *rand.Rand, k *zckeeper.Keeper, chainID string, startHeight uint64, numHeaders uint64, numForkHeaders uint64) ([]*ibctmtypes.Header, []*ibctmtypes.Header) { +func SimulateNewHeadersAndForks(ctx context.Context, r *rand.Rand, k *zckeeper.Keeper, consumerID string, startHeight uint64, numHeaders uint64, numForkHeaders uint64) ([]*ibctmtypes.Header, []*ibctmtypes.Header) { headers := []*ibctmtypes.Header{} // invoke the hook a number of times to simulate a number of blocks for i := uint64(0); i < numHeaders; i++ { - header := datagen.GenRandomIBCTMHeader(r, chainID, startHeight+i) - k.HandleHeaderWithValidCommit(ctx, datagen.GenRandomByteArray(r, 32), datagen.HeaderToHeaderInfo(header), false) + header := datagen.GenRandomIBCTMHeader(r, startHeight+i) + k.HandleHeaderWithValidCommit(ctx, datagen.GenRandomByteArray(r, 32), datagen.NewZCHeaderInfo(header, consumerID), false) headers = append(headers, header) } // generate a number of fork headers forkHeaders := []*ibctmtypes.Header{} for i := uint64(0); i < numForkHeaders; i++ { - header := datagen.GenRandomIBCTMHeader(r, chainID, startHeight+numHeaders-1) - k.HandleHeaderWithValidCommit(ctx, datagen.GenRandomByteArray(r, 32), datagen.HeaderToHeaderInfo(header), true) + header := datagen.GenRandomIBCTMHeader(r, startHeight+numHeaders-1) + k.HandleHeaderWithValidCommit(ctx, datagen.GenRandomByteArray(r, 32), datagen.NewZCHeaderInfo(header, consumerID), true) forkHeaders = append(forkHeaders, header) } return headers, forkHeaders diff --git a/x/zoneconcierge/keeper/proof_btc_timestamp.go b/x/zoneconcierge/keeper/proof_btc_timestamp.go index 248fe6b1a..5e9924ef7 100644 --- a/x/zoneconcierge/keeper/proof_btc_timestamp.go +++ b/x/zoneconcierge/keeper/proof_btc_timestamp.go @@ -13,7 +13,7 @@ import ( ) func (k Keeper) ProveCZHeaderInEpoch(_ context.Context, header *types.IndexedHeader, epoch *epochingtypes.Epoch) (*cmtcrypto.ProofOps, error) { - czHeaderKey := types.GetCZHeaderKey(header.ChainId, header.Height) + czHeaderKey := types.GetCZHeaderKey(header.ConsumerId, header.Height) _, _, proof, err := k.QueryStore(types.StoreKey, czHeaderKey, int64(epoch.GetSealerBlockHeight())) if err != nil { return nil, err diff --git a/x/zoneconcierge/keeper/proof_btc_timestamp_test.go b/x/zoneconcierge/keeper/proof_btc_timestamp_test.go index d58d3d666..97ef52fba 100644 --- a/x/zoneconcierge/keeper/proof_btc_timestamp_test.go +++ b/x/zoneconcierge/keeper/proof_btc_timestamp_test.go @@ -41,14 +41,14 @@ func FuzzProofCZHeaderInEpoch(f *testing.F) { } // handle a random header from a random consumer chain - chainID := datagen.GenRandomHexStr(r, 10) + consumerID := datagen.GenRandomHexStr(r, 10) height := datagen.RandomInt(r, 100) + 1 - ibctmHeader := datagen.GenRandomIBCTMHeader(r, chainID, height) - headerInfo := datagen.HeaderToHeaderInfo(ibctmHeader) + ibctmHeader := datagen.GenRandomIBCTMHeader(r, height) + headerInfo := datagen.NewZCHeaderInfo(ibctmHeader, consumerID) zck.HandleHeaderWithValidCommit(h.Ctx, datagen.GenRandomByteArray(r, 32), headerInfo, false) // ensure the header is successfully inserted - indexedHeader, err := zck.GetHeader(h.Ctx, chainID, height) + indexedHeader, err := zck.GetHeader(h.Ctx, consumerID, height) h.NoError(err) // enter the 1st block of the next epoch diff --git a/x/zoneconcierge/keeper/query_kvstore.go b/x/zoneconcierge/keeper/query_kvstore.go index eb1caf149..6f2568f4c 100644 --- a/x/zoneconcierge/keeper/query_kvstore.go +++ b/x/zoneconcierge/keeper/query_kvstore.go @@ -9,7 +9,7 @@ import ( // QueryStore queries a KV pair in the KVStore, where // - moduleStoreKey is the store key of a module, e.g., zctypes.StoreKey -// - key is the key of the queried KV pair, including the prefix, e.g., zctypes.EpochChainInfoKey || chainID in the chain info store +// - key is the key of the queried KV pair, including the prefix, e.g., zctypes.EpochChainInfoKey || consumerID in the chain info store // and returns // - key of this KV pair // - value of this KV pair diff --git a/x/zoneconcierge/types/btc_timestamp.go b/x/zoneconcierge/types/btc_timestamp.go index d54b04355..de88561d5 100644 --- a/x/zoneconcierge/types/btc_timestamp.go +++ b/x/zoneconcierge/types/btc_timestamp.go @@ -19,9 +19,9 @@ import ( epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) -func GetCZHeaderKey(chainID string, height uint64) []byte { +func GetCZHeaderKey(consumerID string, height uint64) []byte { key := CanonicalChainKey - key = append(key, []byte(chainID)...) + key = append(key, []byte(consumerID)...) key = append(key, sdk.Uint64ToBigEndian(height)...) return key } @@ -180,7 +180,7 @@ func VerifyCZHeaderInEpoch(header *IndexedHeader, epoch *epochingtypes.Epoch, pr return err } - if err := VerifyStore(root, StoreKey, GetCZHeaderKey(header.ChainId, header.Height), headerBytes, proof); err != nil { + if err := VerifyStore(root, StoreKey, GetCZHeaderKey(header.ConsumerId, header.Height), headerBytes, proof); err != nil { return errorsmod.Wrapf(ErrInvalidMerkleProof, "invalid inclusion proof for CZ header: %v", err) } diff --git a/x/zoneconcierge/types/btc_timestamp_test.go b/x/zoneconcierge/types/btc_timestamp_test.go index 24033ed88..4d62fe195 100644 --- a/x/zoneconcierge/types/btc_timestamp_test.go +++ b/x/zoneconcierge/types/btc_timestamp_test.go @@ -59,14 +59,14 @@ func FuzzBTCTimestamp(f *testing.F) { } // handle a random header from a random consumer chain - chainID := datagen.GenRandomHexStr(r, 10) + consumerID := datagen.GenRandomHexStr(r, 10) height := datagen.RandomInt(r, 100) + 1 - ibctmHeader := datagen.GenRandomIBCTMHeader(r, chainID, height) - headerInfo := datagen.HeaderToHeaderInfo(ibctmHeader) + ibctmHeader := datagen.GenRandomIBCTMHeader(r, height) + headerInfo := datagen.NewZCHeaderInfo(ibctmHeader, consumerID) zck.HandleHeaderWithValidCommit(h.Ctx, datagen.GenRandomByteArray(r, 32), headerInfo, false) // ensure the header is successfully inserted - indexedHeader, err := zck.GetHeader(h.Ctx, chainID, height) + indexedHeader, err := zck.GetHeader(h.Ctx, consumerID, height) h.NoError(err) // enter block 21, 1st block of epoch 3 diff --git a/x/zoneconcierge/types/errors.go b/x/zoneconcierge/types/errors.go index 8d033faf5..5a224e551 100644 --- a/x/zoneconcierge/types/errors.go +++ b/x/zoneconcierge/types/errors.go @@ -15,5 +15,5 @@ var ( ErrInvalidProofEpochSealed = errorsmod.Register(ModuleName, 1107, "invalid ProofEpochSealed") ErrInvalidMerkleProof = errorsmod.Register(ModuleName, 1108, "invalid Merkle inclusion proof") ErrInvalidChainInfo = errorsmod.Register(ModuleName, 1109, "invalid chain info") - ErrInvalidChainIDs = errorsmod.Register(ModuleName, 1110, "chain ids contain duplicates or empty strings") + ErrInvalidConsumerIDs = errorsmod.Register(ModuleName, 1110, "chain ids contain duplicates or empty strings") ) diff --git a/x/zoneconcierge/types/query.pb.go b/x/zoneconcierge/types/query.pb.go index c2f8f49dd..ae44fc9d3 100644 --- a/x/zoneconcierge/types/query.pb.go +++ b/x/zoneconcierge/types/query.pb.go @@ -118,8 +118,8 @@ func (m *QueryParamsResponse) GetParams() Params { // QueryHeaderRequest is request type for the Query/Header RPC method. type QueryHeaderRequest struct { - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - Height uint64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` + ConsumerId string `protobuf:"bytes,1,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` + Height uint64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` } func (m *QueryHeaderRequest) Reset() { *m = QueryHeaderRequest{} } @@ -155,9 +155,9 @@ func (m *QueryHeaderRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryHeaderRequest proto.InternalMessageInfo -func (m *QueryHeaderRequest) GetChainId() string { +func (m *QueryHeaderRequest) GetConsumerId() string { if m != nil { - return m.ChainId + return m.ConsumerId } return "" } @@ -270,8 +270,8 @@ func (m *QueryChainListRequest) GetPagination() *query.PageRequest { // QueryChainListResponse is response type for the Query/ChainList RPC method type QueryChainListResponse struct { - // chain_ids are IDs of the chains in ascending alphabetical order - ChainIds []string `protobuf:"bytes,1,rep,name=chain_ids,json=chainIds,proto3" json:"chain_ids,omitempty"` + // consumer_ids are IDs of the chains in ascending alphabetical order + ConsumerIds []string `protobuf:"bytes,1,rep,name=consumer_ids,json=consumerIds,proto3" json:"consumer_ids,omitempty"` // pagination defines the pagination in the response Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -309,9 +309,9 @@ func (m *QueryChainListResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryChainListResponse proto.InternalMessageInfo -func (m *QueryChainListResponse) GetChainIds() []string { +func (m *QueryChainListResponse) GetConsumerIds() []string { if m != nil { - return m.ChainIds + return m.ConsumerIds } return nil } @@ -325,7 +325,7 @@ func (m *QueryChainListResponse) GetPagination() *query.PageResponse { // QueryChainsInfoRequest is request type for the Query/ChainsInfo RPC method. type QueryChainsInfoRequest struct { - ChainIds []string `protobuf:"bytes,1,rep,name=chain_ids,json=chainIds,proto3" json:"chain_ids,omitempty"` + ConsumerIds []string `protobuf:"bytes,1,rep,name=consumer_ids,json=consumerIds,proto3" json:"consumer_ids,omitempty"` } func (m *QueryChainsInfoRequest) Reset() { *m = QueryChainsInfoRequest{} } @@ -361,9 +361,9 @@ func (m *QueryChainsInfoRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryChainsInfoRequest proto.InternalMessageInfo -func (m *QueryChainsInfoRequest) GetChainIds() []string { +func (m *QueryChainsInfoRequest) GetConsumerIds() []string { if m != nil { - return m.ChainIds + return m.ConsumerIds } return nil } @@ -416,8 +416,8 @@ func (m *QueryChainsInfoResponse) GetChainsInfo() []*ChainInfo { // QueryEpochChainsInfoRequest is request type for the Query/EpochChainsInfo RPC // method. type QueryEpochChainsInfoRequest struct { - EpochNum uint64 `protobuf:"varint,1,opt,name=epoch_num,json=epochNum,proto3" json:"epoch_num,omitempty"` - ChainIds []string `protobuf:"bytes,2,rep,name=chain_ids,json=chainIds,proto3" json:"chain_ids,omitempty"` + EpochNum uint64 `protobuf:"varint,1,opt,name=epoch_num,json=epochNum,proto3" json:"epoch_num,omitempty"` + ConsumerIds []string `protobuf:"bytes,2,rep,name=consumer_ids,json=consumerIds,proto3" json:"consumer_ids,omitempty"` } func (m *QueryEpochChainsInfoRequest) Reset() { *m = QueryEpochChainsInfoRequest{} } @@ -460,9 +460,9 @@ func (m *QueryEpochChainsInfoRequest) GetEpochNum() uint64 { return 0 } -func (m *QueryEpochChainsInfoRequest) GetChainIds() []string { +func (m *QueryEpochChainsInfoRequest) GetConsumerIds() []string { if m != nil { - return m.ChainIds + return m.ConsumerIds } return nil } @@ -516,7 +516,7 @@ func (m *QueryEpochChainsInfoResponse) GetChainsInfo() []*ChainInfo { // QueryListHeadersRequest is request type for the Query/ListHeaders RPC method. type QueryListHeadersRequest struct { - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + ConsumerId string `protobuf:"bytes,1,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` // pagination defines whether to have the pagination in the request Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -554,9 +554,9 @@ func (m *QueryListHeadersRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryListHeadersRequest proto.InternalMessageInfo -func (m *QueryListHeadersRequest) GetChainId() string { +func (m *QueryListHeadersRequest) GetConsumerId() string { if m != nil { - return m.ChainId + return m.ConsumerId } return "" } @@ -627,8 +627,8 @@ func (m *QueryListHeadersResponse) GetPagination() *query.PageResponse { // QueryListEpochHeadersRequest is request type for the Query/ListEpochHeaders // RPC method. type QueryListEpochHeadersRequest struct { - EpochNum uint64 `protobuf:"varint,1,opt,name=epoch_num,json=epochNum,proto3" json:"epoch_num,omitempty"` - ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + EpochNum uint64 `protobuf:"varint,1,opt,name=epoch_num,json=epochNum,proto3" json:"epoch_num,omitempty"` + ConsumerId string `protobuf:"bytes,2,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` } func (m *QueryListEpochHeadersRequest) Reset() { *m = QueryListEpochHeadersRequest{} } @@ -671,9 +671,9 @@ func (m *QueryListEpochHeadersRequest) GetEpochNum() uint64 { return 0 } -func (m *QueryListEpochHeadersRequest) GetChainId() string { +func (m *QueryListEpochHeadersRequest) GetConsumerId() string { if m != nil { - return m.ChainId + return m.ConsumerId } return "" } @@ -728,8 +728,8 @@ func (m *QueryListEpochHeadersResponse) GetHeaders() []*IndexedHeader { // QueryFinalizedChainsInfoRequest is request type for the // Query/FinalizedChainsInfo RPC method. type QueryFinalizedChainsInfoRequest struct { - // chain_ids is the list of ids of CZs - ChainIds []string `protobuf:"bytes,1,rep,name=chain_ids,json=chainIds,proto3" json:"chain_ids,omitempty"` + // consumer_ids is the list of ids of CZs + ConsumerIds []string `protobuf:"bytes,1,rep,name=consumer_ids,json=consumerIds,proto3" json:"consumer_ids,omitempty"` // prove indicates whether the querier wants to get proofs of this timestamp Prove bool `protobuf:"varint,2,opt,name=prove,proto3" json:"prove,omitempty"` } @@ -767,9 +767,9 @@ func (m *QueryFinalizedChainsInfoRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryFinalizedChainsInfoRequest proto.InternalMessageInfo -func (m *QueryFinalizedChainsInfoRequest) GetChainIds() []string { +func (m *QueryFinalizedChainsInfoRequest) GetConsumerIds() []string { if m != nil { - return m.ChainIds + return m.ConsumerIds } return nil } @@ -830,8 +830,8 @@ func (m *QueryFinalizedChainsInfoResponse) GetFinalizedChainsInfo() []*Finalized // QueryFinalizedChainInfoUntilHeightRequest is request type for the // Query/FinalizedChainInfoUntilHeight RPC method. type QueryFinalizedChainInfoUntilHeightRequest struct { - // chain_id is the ID of the CZ - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // consumer_id is the ID of the CZ + ConsumerId string `protobuf:"bytes,1,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` // height is the height of the CZ chain // such that the returned finalised chain info will be no later than this // height @@ -877,9 +877,9 @@ func (m *QueryFinalizedChainInfoUntilHeightRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryFinalizedChainInfoUntilHeightRequest proto.InternalMessageInfo -func (m *QueryFinalizedChainInfoUntilHeightRequest) GetChainId() string { +func (m *QueryFinalizedChainInfoUntilHeightRequest) GetConsumerId() string { if m != nil { - return m.ChainId + return m.ConsumerId } return "" } @@ -1012,81 +1012,81 @@ func init() { } var fileDescriptor_cd665af90102da38 = []byte{ - // 1182 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6f, 0x1b, 0xc5, - 0x17, 0xcf, 0xe6, 0x57, 0x93, 0xe7, 0x6f, 0xbf, 0x54, 0x93, 0xb4, 0x98, 0x6d, 0xeb, 0x44, 0x0b, - 0xa5, 0x69, 0x49, 0x76, 0x71, 0x4a, 0x1b, 0x95, 0x03, 0x55, 0x93, 0x92, 0x34, 0x2a, 0xaa, 0x9a, - 0x85, 0x80, 0xc4, 0xc5, 0xec, 0xae, 0xc7, 0xf6, 0x2a, 0xf1, 0x8e, 0xbb, 0xb3, 0x76, 0xeb, 0x86, - 0x70, 0x40, 0xbd, 0x83, 0xc4, 0x05, 0x71, 0xe2, 0xc4, 0x81, 0x43, 0x6f, 0xfc, 0x09, 0x48, 0x3d, - 0x70, 0xa8, 0xc4, 0x85, 0x13, 0x42, 0x09, 0xff, 0x06, 0x12, 0xda, 0x99, 0x59, 0x7b, 0x7f, 0xda, - 0xeb, 0x90, 0x9b, 0x67, 0xf6, 0xbd, 0xcf, 0xe7, 0xf3, 0xde, 0xbc, 0x99, 0xf7, 0x0c, 0x6f, 0x99, - 0x86, 0xd9, 0xdd, 0x27, 0x8e, 0xf6, 0x8c, 0x38, 0xd8, 0x22, 0x8e, 0x65, 0x63, 0xb7, 0x8e, 0xb5, - 0x4e, 0x59, 0x7b, 0xdc, 0xc6, 0x6e, 0x57, 0x6d, 0xb9, 0xc4, 0x23, 0xa8, 0x28, 0xac, 0xd4, 0x88, - 0x95, 0xda, 0x29, 0xcb, 0xf3, 0x75, 0x52, 0x27, 0xcc, 0x48, 0xf3, 0x7f, 0x71, 0x7b, 0xf9, 0x52, - 0x9d, 0x90, 0xfa, 0x3e, 0xd6, 0x8c, 0x96, 0xad, 0x19, 0x8e, 0x43, 0x3c, 0xc3, 0xb3, 0x89, 0x43, - 0xc5, 0xd7, 0xeb, 0x16, 0xa1, 0x4d, 0x42, 0x35, 0xd3, 0xa0, 0x98, 0xd3, 0x68, 0x9d, 0xb2, 0x89, - 0x3d, 0xa3, 0xac, 0xb5, 0x8c, 0xba, 0xed, 0x30, 0x63, 0x61, 0xbb, 0x1c, 0xe8, 0x33, 0x3d, 0xcb, - 0x6a, 0x60, 0x6b, 0xaf, 0x45, 0x6c, 0xc7, 0xf3, 0xf5, 0x45, 0x36, 0x84, 0xf5, 0xb5, 0xc0, 0xba, - 0xff, 0xc5, 0x76, 0xea, 0xbe, 0x75, 0xc2, 0x54, 0x09, 0x4c, 0x71, 0x8b, 0x58, 0x0d, 0x61, 0x15, - 0xfc, 0x8e, 0x93, 0x27, 0x92, 0x13, 0xcd, 0x03, 0xb7, 0xbe, 0x92, 0x69, 0xdd, 0x32, 0x5c, 0xa3, - 0x29, 0xa2, 0x57, 0xe6, 0x01, 0xed, 0xf8, 0x31, 0x3f, 0x62, 0x9b, 0x3a, 0x7e, 0xdc, 0xc6, 0xd4, - 0x53, 0x76, 0x61, 0x2e, 0xb2, 0x4b, 0x5b, 0xc4, 0xa1, 0x18, 0x7d, 0x00, 0xd3, 0xdc, 0xb9, 0x28, - 0x2d, 0x4a, 0x4b, 0x85, 0xd5, 0x45, 0x35, 0xeb, 0x24, 0x54, 0xee, 0xb9, 0x3e, 0xf9, 0xf2, 0xcf, - 0x85, 0x31, 0x5d, 0x78, 0x29, 0x5b, 0x82, 0xec, 0x3e, 0x36, 0xaa, 0xd8, 0x15, 0x64, 0xe8, 0x0d, - 0x98, 0xb1, 0x1a, 0x86, 0xed, 0x54, 0xec, 0x2a, 0xc3, 0x9d, 0xd5, 0xcf, 0xb0, 0xf5, 0x76, 0x15, - 0x5d, 0x80, 0xe9, 0x06, 0xb6, 0xeb, 0x0d, 0xaf, 0x38, 0xbe, 0x28, 0x2d, 0x4d, 0xea, 0x62, 0xa5, - 0xfc, 0x20, 0x09, 0x81, 0x01, 0x92, 0x10, 0x78, 0xc7, 0xb7, 0xf7, 0x77, 0x84, 0xc0, 0xab, 0xd9, - 0x02, 0xb7, 0x9d, 0x2a, 0x7e, 0x8a, 0xab, 0x02, 0x40, 0xb8, 0xa1, 0x75, 0xf8, 0x5f, 0x8d, 0xb8, - 0x7b, 0x15, 0xbe, 0xa4, 0x8c, 0xb6, 0xb0, 0xba, 0x90, 0x0d, 0xb3, 0x49, 0xdc, 0x3d, 0xaa, 0x17, - 0x7c, 0x27, 0x0e, 0x45, 0x95, 0x0a, 0x9c, 0x67, 0xda, 0x36, 0xfc, 0x20, 0x3e, 0xb2, 0xa9, 0x17, - 0x04, 0xba, 0x09, 0xd0, 0xaf, 0x28, 0xa1, 0xf0, 0x6d, 0x95, 0x97, 0x9f, 0xea, 0x97, 0x9f, 0xca, - 0xab, 0x5c, 0x94, 0x9f, 0xfa, 0xc8, 0xa8, 0x63, 0xe1, 0xab, 0x87, 0x3c, 0x95, 0xaf, 0xe0, 0x42, - 0x9c, 0x40, 0xc4, 0x7f, 0x11, 0x66, 0x83, 0x54, 0xfa, 0x67, 0x34, 0xb1, 0x34, 0xab, 0xcf, 0x88, - 0x5c, 0x52, 0xb4, 0x15, 0xa1, 0x1f, 0x17, 0x09, 0x1a, 0x46, 0xcf, 0x91, 0x23, 0xfc, 0x37, 0xc3, - 0xfc, 0x74, 0xdb, 0xa9, 0x91, 0x20, 0xc2, 0x41, 0xfc, 0x4a, 0x05, 0x5e, 0x4f, 0xb8, 0x09, 0xdd, - 0xf7, 0xa0, 0xc0, 0xcc, 0x68, 0xc5, 0x76, 0x6a, 0x84, 0x79, 0x16, 0x56, 0xdf, 0xcc, 0xce, 0x3a, - 0x83, 0x60, 0x08, 0x60, 0xf5, 0xd0, 0x94, 0xcf, 0xe0, 0x22, 0x23, 0xf8, 0xd0, 0xbf, 0x37, 0xa9, - 0xe2, 0xd8, 0x8d, 0xaa, 0x38, 0xed, 0x26, 0xcb, 0xfe, 0xa4, 0x3e, 0xc3, 0x36, 0x1e, 0xb6, 0x9b, - 0x51, 0xe5, 0xe3, 0x31, 0xe5, 0x55, 0xb8, 0x94, 0x0e, 0x7c, 0xaa, 0xf2, 0xbf, 0x14, 0xf9, 0xf1, - 0x4f, 0x54, 0xd4, 0x52, 0x8e, 0x2b, 0xb2, 0x99, 0x72, 0xaa, 0x27, 0x29, 0xaa, 0x9f, 0x24, 0x28, - 0x26, 0xe9, 0x45, 0x80, 0x77, 0xe1, 0x4c, 0x70, 0x23, 0x78, 0x70, 0xb9, 0x2f, 0x56, 0xe0, 0x77, - 0x7a, 0xd5, 0xf7, 0xa9, 0x38, 0x0c, 0x5f, 0x27, 0x3b, 0x90, 0x58, 0xae, 0x06, 0x1e, 0x73, 0x38, - 0x91, 0xe3, 0x91, 0x44, 0x2a, 0x26, 0x5c, 0xce, 0xc0, 0x3d, 0xb5, 0x24, 0x28, 0x9f, 0xc0, 0x02, - 0xe3, 0xd8, 0xb4, 0x1d, 0x63, 0xdf, 0x7e, 0x86, 0xab, 0xa3, 0x5d, 0x21, 0x34, 0x0f, 0x53, 0x2d, - 0x97, 0x74, 0x30, 0xd3, 0x3e, 0xa3, 0xf3, 0x85, 0xf2, 0x5c, 0x82, 0xc5, 0x6c, 0x58, 0xa1, 0xfe, - 0x0b, 0x38, 0x5f, 0x0b, 0x3e, 0x57, 0x92, 0xd5, 0xba, 0x3c, 0xe0, 0x89, 0x8b, 0xa0, 0x32, 0xd0, - 0xb9, 0x5a, 0x92, 0x49, 0xf1, 0xe0, 0x5a, 0x8a, 0x0a, 0xff, 0xd3, 0xae, 0xe3, 0xd9, 0xfb, 0xf7, - 0xd9, 0xd3, 0x7d, 0xf2, 0x47, 0xbf, 0x1f, 0xfc, 0x44, 0x38, 0xf8, 0x17, 0x13, 0x70, 0x3d, 0x0f, - 0xad, 0x48, 0xc3, 0x2e, 0xcc, 0xc7, 0xd2, 0x10, 0x64, 0x41, 0xca, 0x7b, 0x67, 0x51, 0x2d, 0xc1, - 0x84, 0x6e, 0x03, 0xf0, 0xa2, 0x63, 0x60, 0xbc, 0xba, 0xe5, 0x1e, 0x58, 0xaf, 0x91, 0x77, 0xca, - 0x2a, 0x2b, 0x2d, 0x9d, 0x97, 0x28, 0x73, 0x7d, 0x08, 0xff, 0x77, 0x8d, 0x27, 0x95, 0xfe, 0x48, - 0xc0, 0xe2, 0x0b, 0x57, 0x57, 0x64, 0x7c, 0xf0, 0x31, 0x74, 0xe3, 0xc9, 0x46, 0x6f, 0x4f, 0x3f, - 0xeb, 0x86, 0x97, 0x68, 0x17, 0x90, 0xe9, 0x59, 0x15, 0xda, 0x36, 0x9b, 0x36, 0xa5, 0x36, 0x71, - 0x2a, 0x7b, 0xb8, 0x5b, 0x9c, 0x8c, 0x61, 0x46, 0xe7, 0x95, 0x4e, 0x59, 0xfd, 0xb8, 0x67, 0xff, - 0x00, 0x77, 0xf5, 0x73, 0xa6, 0x67, 0x45, 0x76, 0xd0, 0x16, 0xcb, 0x3e, 0xa9, 0x15, 0xa7, 0x18, - 0x52, 0x79, 0x40, 0xeb, 0xf7, 0xcd, 0x52, 0x8a, 0x86, 0xfb, 0xaf, 0x3e, 0x3f, 0x0b, 0x53, 0xec, - 0xc0, 0xd0, 0x37, 0x12, 0x4c, 0xf3, 0x39, 0x01, 0x0d, 0x28, 0xbf, 0xe4, 0x78, 0x22, 0xaf, 0xe4, - 0xb4, 0xe6, 0x67, 0xae, 0x2c, 0x7d, 0xfd, 0xfb, 0xdf, 0xdf, 0x8d, 0x2b, 0x68, 0x51, 0x1b, 0x32, - 0x13, 0xa1, 0x17, 0x12, 0x4c, 0xf3, 0x3b, 0x3b, 0x54, 0x51, 0x64, 0x86, 0x19, 0xaa, 0x28, 0x3a, - 0xa7, 0x28, 0x5b, 0x4c, 0xd1, 0x5d, 0x74, 0x27, 0x5b, 0x51, 0xbf, 0x36, 0xb5, 0x83, 0xe0, 0xa6, - 0x1c, 0x6a, 0xfc, 0x21, 0xd1, 0x0e, 0xf8, 0x95, 0x38, 0x44, 0xdf, 0x4b, 0x30, 0xdb, 0x1b, 0x03, - 0x90, 0x36, 0x44, 0x45, 0x7c, 0x22, 0x91, 0xdf, 0xcd, 0xef, 0x90, 0x3f, 0x97, 0xfc, 0x71, 0x41, - 0x3f, 0x4a, 0x00, 0xfd, 0xd7, 0x01, 0xe5, 0xa2, 0x0a, 0xbf, 0x84, 0x72, 0x79, 0x04, 0x0f, 0xa1, - 0x6e, 0x85, 0xa9, 0xbb, 0x8a, 0xae, 0x0c, 0x53, 0xc7, 0x12, 0x8b, 0x7e, 0x91, 0xe0, 0xb5, 0x58, - 0x4f, 0x47, 0x37, 0x87, 0xb0, 0xa6, 0x0f, 0x17, 0xf2, 0xad, 0x51, 0xdd, 0x84, 0xe2, 0x1b, 0x4c, - 0xf1, 0x0a, 0x7a, 0x27, 0x5b, 0x31, 0x7f, 0x58, 0xc2, 0xba, 0x7f, 0x96, 0xa0, 0x10, 0x6a, 0xd3, - 0x68, 0x58, 0xa6, 0x92, 0x13, 0x85, 0xbc, 0x3a, 0x8a, 0x8b, 0xd0, 0xfa, 0x1e, 0xd3, 0xaa, 0xa2, - 0xe5, 0x6c, 0xad, 0xa2, 0xd1, 0x85, 0x4a, 0x16, 0xfd, 0x26, 0xc1, 0xb9, 0x78, 0x4f, 0x45, 0xb7, - 0x72, 0xd0, 0xa7, 0x34, 0x77, 0x79, 0x6d, 0x64, 0xbf, 0xfc, 0x37, 0x2e, 0xa9, 0x9d, 0xa7, 0x9e, - 0x6a, 0x07, 0xbd, 0x81, 0xe2, 0x10, 0xfd, 0x2a, 0xc1, 0x5c, 0x4a, 0x9f, 0x45, 0xb7, 0x87, 0x28, - 0xcb, 0x6e, 0xf9, 0xf2, 0xfb, 0x27, 0x71, 0x15, 0x71, 0xad, 0xb1, 0xb8, 0xca, 0x48, 0xcb, 0x8e, - 0x2b, 0xb5, 0xed, 0xa3, 0x7f, 0x24, 0xb8, 0x3c, 0xb0, 0x65, 0xa2, 0x8d, 0x91, 0x64, 0xa5, 0xf7, - 0x79, 0xf9, 0xde, 0x7f, 0x03, 0x11, 0x51, 0xee, 0xb0, 0x28, 0x1f, 0xa0, 0xed, 0xdc, 0x51, 0xa6, - 0xbc, 0x9c, 0x3e, 0x62, 0xef, 0xe5, 0x5c, 0xdf, 0x79, 0x79, 0x54, 0x92, 0x5e, 0x1d, 0x95, 0xa4, - 0xbf, 0x8e, 0x4a, 0xd2, 0xb7, 0xc7, 0xa5, 0xb1, 0x57, 0xc7, 0xa5, 0xb1, 0x3f, 0x8e, 0x4b, 0x63, - 0x9f, 0xaf, 0xd5, 0x6d, 0xaf, 0xd1, 0x36, 0x55, 0x8b, 0x34, 0x03, 0xba, 0x7d, 0xc3, 0xa4, 0x2b, - 0x36, 0xe9, 0xb1, 0x3f, 0x8d, 0xf1, 0x7b, 0xdd, 0x16, 0xa6, 0xe6, 0x34, 0xfb, 0x4b, 0x7d, 0xe3, - 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x09, 0x4f, 0xa5, 0xb2, 0xc6, 0x10, 0x00, 0x00, + // 1180 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcd, 0x6f, 0xdc, 0x44, + 0x14, 0x8f, 0x37, 0x1f, 0x34, 0x6f, 0x5b, 0xa8, 0x26, 0x69, 0x59, 0xb9, 0xed, 0x26, 0x18, 0x4a, + 0xd3, 0xd2, 0xd8, 0x6c, 0x2a, 0x1a, 0x15, 0x24, 0x10, 0x49, 0x48, 0x1b, 0x28, 0x51, 0x6b, 0xc8, + 0xa5, 0x02, 0x2d, 0xb6, 0x77, 0x76, 0xd7, 0x4a, 0xd6, 0xb3, 0xf5, 0x78, 0xb7, 0x4d, 0xa2, 0x48, + 0xa8, 0xe2, 0x4e, 0x25, 0x2e, 0x88, 0x13, 0x27, 0x6e, 0x20, 0x71, 0xe0, 0x4f, 0x40, 0xea, 0x8d, + 0x4a, 0x5c, 0x38, 0x21, 0x94, 0xf0, 0x87, 0x54, 0x9e, 0x19, 0xef, 0xfa, 0x33, 0x76, 0xd2, 0xdc, + 0xd6, 0x33, 0xef, 0xfd, 0xde, 0xef, 0x7d, 0xcd, 0x7b, 0x0b, 0x6f, 0x99, 0x86, 0xb9, 0xbd, 0x45, + 0x1c, 0x6d, 0x87, 0x38, 0xd8, 0x22, 0x8e, 0x65, 0x63, 0xb7, 0x85, 0xb5, 0x7e, 0x4d, 0x7b, 0xd8, + 0xc3, 0xee, 0xb6, 0xda, 0x75, 0x89, 0x47, 0x50, 0x45, 0x48, 0xa9, 0x11, 0x29, 0xb5, 0x5f, 0x93, + 0xa7, 0x5b, 0xa4, 0x45, 0x98, 0x90, 0xe6, 0xff, 0xe2, 0xf2, 0xf2, 0xc5, 0x16, 0x21, 0xad, 0x2d, + 0xac, 0x19, 0x5d, 0x5b, 0x33, 0x1c, 0x87, 0x78, 0x86, 0x67, 0x13, 0x87, 0x8a, 0xdb, 0x6b, 0x16, + 0xa1, 0x1d, 0x42, 0x35, 0xd3, 0xa0, 0x98, 0x9b, 0xd1, 0xfa, 0x35, 0x13, 0x7b, 0x46, 0x4d, 0xeb, + 0x1a, 0x2d, 0xdb, 0x61, 0xc2, 0x42, 0xf6, 0x7a, 0xc0, 0xcf, 0xf4, 0x2c, 0xab, 0x8d, 0xad, 0xcd, + 0x2e, 0xb1, 0x1d, 0xcf, 0xe7, 0x17, 0x39, 0x10, 0xd2, 0x57, 0x03, 0xe9, 0xe1, 0x8d, 0xed, 0xb4, + 0x7c, 0xe9, 0x84, 0xa8, 0x12, 0x88, 0xe2, 0x2e, 0xb1, 0xda, 0x42, 0x2a, 0xf8, 0x1d, 0x37, 0x9e, + 0x08, 0x4e, 0x34, 0x0e, 0x5c, 0xfa, 0x72, 0xa6, 0x74, 0xd7, 0x70, 0x8d, 0x8e, 0xf0, 0x5e, 0x99, + 0x06, 0x74, 0xdf, 0xf7, 0xf9, 0x1e, 0x3b, 0xd4, 0xf1, 0xc3, 0x1e, 0xa6, 0x9e, 0xb2, 0x01, 0x53, + 0x91, 0x53, 0xda, 0x25, 0x0e, 0xc5, 0xe8, 0x43, 0x98, 0xe0, 0xca, 0x15, 0x69, 0x56, 0x9a, 0x2b, + 0x2f, 0xcc, 0xaa, 0x59, 0x99, 0x50, 0xb9, 0xe6, 0xd2, 0xd8, 0xb3, 0x7f, 0x67, 0x46, 0x74, 0xa1, + 0xa5, 0x7c, 0x2e, 0x8c, 0xdd, 0xc1, 0x46, 0x03, 0xbb, 0xc2, 0x18, 0x9a, 0x81, 0xb2, 0x45, 0x1c, + 0xda, 0xeb, 0x60, 0xb7, 0x6e, 0x37, 0x18, 0xf4, 0xa4, 0x0e, 0xc1, 0xd1, 0x5a, 0x03, 0x9d, 0x87, + 0x89, 0x36, 0xb6, 0x5b, 0x6d, 0xaf, 0x52, 0x9a, 0x95, 0xe6, 0xc6, 0x74, 0xf1, 0xa5, 0xfc, 0x24, + 0x09, 0x9a, 0x01, 0x9e, 0xa0, 0xf9, 0x91, 0x2f, 0xef, 0x9f, 0x08, 0x9a, 0x57, 0xb2, 0x69, 0xae, + 0x39, 0x0d, 0xfc, 0x18, 0x37, 0x04, 0x80, 0x50, 0x43, 0x4b, 0x70, 0xba, 0x49, 0xdc, 0xcd, 0x3a, + 0xff, 0xa4, 0xcc, 0x6c, 0x79, 0x61, 0x26, 0x1b, 0x66, 0x95, 0xb8, 0x9b, 0x54, 0x2f, 0xfb, 0x4a, + 0x1c, 0x8a, 0x2a, 0x75, 0x38, 0xc7, 0xb8, 0x2d, 0xb7, 0x0d, 0xdb, 0xb9, 0x6b, 0x53, 0x2f, 0x70, + 0x77, 0x15, 0x60, 0x58, 0x57, 0x82, 0xe1, 0xdb, 0x2a, 0x2f, 0x42, 0xd5, 0x2f, 0x42, 0x95, 0xd7, + 0xba, 0x28, 0x42, 0xf5, 0x9e, 0xd1, 0xc2, 0x42, 0x57, 0x0f, 0x69, 0x2a, 0xdf, 0x49, 0x70, 0x3e, + 0x6e, 0x41, 0x04, 0xe0, 0x0d, 0x38, 0x1d, 0x8a, 0xa8, 0x9f, 0xad, 0xd1, 0xb9, 0x49, 0xbd, 0x3c, + 0x0c, 0x29, 0x45, 0xb7, 0x23, 0x2c, 0x4a, 0x22, 0x4e, 0x79, 0x2c, 0x38, 0x7e, 0x84, 0xc6, 0x07, + 0x61, 0x16, 0x74, 0xcd, 0x69, 0x92, 0xc0, 0xd1, 0x7c, 0x16, 0x4a, 0x1d, 0x5e, 0x4f, 0x28, 0x0b, + 0x1f, 0x56, 0xa0, 0x6c, 0xb1, 0xd3, 0xba, 0xed, 0x34, 0x09, 0x53, 0x2e, 0x2f, 0xbc, 0x99, 0x9d, + 0x02, 0x06, 0xc1, 0x10, 0xc0, 0x1a, 0xa0, 0x29, 0x5f, 0xc3, 0x05, 0x66, 0xe0, 0x13, 0xbf, 0x95, + 0x92, 0x14, 0x2f, 0xc0, 0x24, 0x6b, 0xb2, 0xba, 0xd3, 0xeb, 0xb0, 0x54, 0x8c, 0xe9, 0xa7, 0xd8, + 0xc1, 0x7a, 0xaf, 0x93, 0xe0, 0x5f, 0x4a, 0xf2, 0x6f, 0xc0, 0xc5, 0x74, 0xf8, 0x13, 0x75, 0xe2, + 0x89, 0x24, 0xc2, 0xe4, 0x27, 0x59, 0xd4, 0x57, 0xe1, 0xe6, 0x59, 0x4d, 0x49, 0xf4, 0x71, 0xca, + 0xed, 0x17, 0x09, 0x2a, 0x49, 0x12, 0xc2, 0xcf, 0x8f, 0xe1, 0x95, 0xa0, 0x57, 0xb8, 0x8f, 0x85, + 0x5b, 0x2e, 0xd0, 0x3b, 0xb9, 0x82, 0xfc, 0x4a, 0xe4, 0xc4, 0xe7, 0xc9, 0xf2, 0x12, 0x8b, 0xd8, + 0xa1, 0x39, 0x8f, 0x85, 0xb3, 0x14, 0x0f, 0xa7, 0x62, 0xc2, 0xa5, 0x0c, 0xf4, 0x13, 0x0b, 0x85, + 0xf2, 0x00, 0x66, 0x98, 0x8d, 0x55, 0xdb, 0x31, 0xb6, 0xec, 0x1d, 0xdc, 0x38, 0x4e, 0x6f, 0xa1, + 0x69, 0x18, 0xef, 0xba, 0xa4, 0x8f, 0x99, 0x13, 0xa7, 0x74, 0xfe, 0xe1, 0xbf, 0x1a, 0xb3, 0xd9, + 0xe0, 0xc2, 0x87, 0x6f, 0xe0, 0x5c, 0x33, 0xb8, 0xae, 0x27, 0x0b, 0xf8, 0xfa, 0x21, 0x0f, 0x61, + 0x04, 0x95, 0x81, 0x4e, 0x35, 0x93, 0x96, 0x94, 0x1d, 0xb8, 0x9a, 0xc2, 0xc2, 0xbf, 0xda, 0x70, + 0x3c, 0x7b, 0xeb, 0x0e, 0x7b, 0xe0, 0x5f, 0x76, 0x40, 0x0c, 0x43, 0x30, 0x1a, 0x0e, 0xc1, 0x6f, + 0xa3, 0x70, 0xad, 0x88, 0x71, 0x11, 0x8c, 0x0d, 0x98, 0x8e, 0x05, 0x23, 0x88, 0x85, 0x54, 0xb4, + 0x99, 0x51, 0x33, 0x61, 0x09, 0xdd, 0x02, 0xe0, 0x65, 0xc8, 0xc0, 0x78, 0xbd, 0xcb, 0x03, 0xb0, + 0xc1, 0xe8, 0xef, 0xd7, 0x54, 0x56, 0x66, 0x3a, 0x2f, 0x5a, 0xa6, 0xba, 0x0e, 0xaf, 0xba, 0xc6, + 0xa3, 0xfa, 0x70, 0x89, 0x60, 0xfe, 0x85, 0x2b, 0x2d, 0xb2, 0x70, 0xf8, 0x18, 0xba, 0xf1, 0x68, + 0x79, 0x70, 0xa6, 0x9f, 0x71, 0xc3, 0x9f, 0x68, 0x03, 0x90, 0xe9, 0x59, 0x75, 0xda, 0x33, 0x3b, + 0x36, 0xa5, 0x36, 0x71, 0xea, 0x9b, 0x78, 0xbb, 0x32, 0x16, 0xc3, 0x8c, 0x6e, 0x38, 0xfd, 0x9a, + 0xfa, 0xc5, 0x40, 0xfe, 0x33, 0xbc, 0xad, 0x9f, 0x35, 0x3d, 0x2b, 0x72, 0x82, 0x6e, 0xb3, 0xe8, + 0x93, 0x66, 0x65, 0x9c, 0x21, 0xd5, 0x0e, 0x59, 0x16, 0x7c, 0xb1, 0x94, 0xd2, 0xe1, 0xfa, 0x0b, + 0x4f, 0xcf, 0xc0, 0x38, 0x4b, 0x18, 0xfa, 0x5e, 0x82, 0x09, 0xbe, 0x59, 0xa0, 0x43, 0x8a, 0x30, + 0xb9, 0xd0, 0xc8, 0xf3, 0x05, 0xa5, 0x79, 0xce, 0x95, 0xb9, 0x27, 0x7f, 0xff, 0xff, 0x43, 0x49, + 0x41, 0xb3, 0x5a, 0xce, 0x16, 0x85, 0x7e, 0x97, 0x60, 0x82, 0xf7, 0x6f, 0x2e, 0xa3, 0xc8, 0xd6, + 0x93, 0xcb, 0x28, 0xba, 0xd3, 0x28, 0x9f, 0x32, 0x46, 0x2b, 0x68, 0x29, 0x9b, 0xd1, 0xb0, 0x36, + 0xb5, 0xdd, 0x50, 0xbf, 0xec, 0x69, 0xfc, 0x5d, 0xd1, 0x76, 0x79, 0x57, 0xec, 0xa1, 0x1f, 0x25, + 0x98, 0x1c, 0x2c, 0x0d, 0x48, 0xcb, 0x21, 0x12, 0x5f, 0x60, 0xe4, 0x77, 0x8b, 0x2b, 0x14, 0x0f, + 0x27, 0x7f, 0x65, 0xd0, 0xcf, 0x12, 0xc0, 0xf0, 0x99, 0x40, 0x85, 0x4c, 0x85, 0x1f, 0x46, 0xb9, + 0x76, 0x04, 0x0d, 0xc1, 0x6e, 0x9e, 0xb1, 0xbb, 0x82, 0x2e, 0xe7, 0xb1, 0x63, 0xb1, 0x45, 0x7f, + 0x48, 0xf0, 0x5a, 0x6c, 0xde, 0xa3, 0xf7, 0x72, 0xac, 0xa6, 0xaf, 0x1f, 0xf2, 0xcd, 0xa3, 0xaa, + 0x09, 0xc6, 0x37, 0x18, 0xe3, 0x79, 0xf4, 0x4e, 0x36, 0x63, 0xfe, 0xb6, 0x84, 0x79, 0xff, 0x2a, + 0x41, 0x39, 0x34, 0xbb, 0x51, 0x5e, 0xa4, 0x92, 0xcb, 0x86, 0xbc, 0x70, 0x14, 0x15, 0xc1, 0x75, + 0x91, 0x71, 0xad, 0x21, 0x2d, 0x9b, 0xab, 0x98, 0x7b, 0xd1, 0xaa, 0x45, 0x7f, 0x49, 0x70, 0x36, + 0x3e, 0x65, 0xd1, 0xcd, 0x02, 0x0c, 0x52, 0x86, 0xbe, 0xbc, 0x78, 0x64, 0xbd, 0xe2, 0x7d, 0x97, + 0x4a, 0x9f, 0x27, 0x80, 0x6a, 0xbb, 0x83, 0x5d, 0x63, 0x0f, 0xfd, 0x29, 0xc1, 0x54, 0xca, 0xd8, + 0x45, 0xb7, 0x72, 0xc8, 0x65, 0xef, 0x01, 0xf2, 0xfb, 0xc7, 0x51, 0x2d, 0x9e, 0x99, 0xd4, 0x2d, + 0x00, 0x7d, 0x5b, 0x82, 0x4b, 0x87, 0xce, 0x4e, 0xb4, 0x7c, 0x24, 0x5a, 0xe9, 0x63, 0x5f, 0x5e, + 0x79, 0x39, 0x10, 0xe1, 0xe5, 0x97, 0xcc, 0xcb, 0x75, 0x74, 0xb7, 0xb0, 0x97, 0xe9, 0x4f, 0xa8, + 0x0f, 0x3a, 0x78, 0x42, 0x97, 0xee, 0x3f, 0xdb, 0xaf, 0x4a, 0xcf, 0xf7, 0xab, 0xd2, 0x7f, 0xfb, + 0x55, 0xe9, 0xe9, 0x41, 0x75, 0xe4, 0xf9, 0x41, 0x75, 0xe4, 0x9f, 0x83, 0xea, 0xc8, 0x83, 0xc5, + 0x96, 0xed, 0xb5, 0x7b, 0xa6, 0x6a, 0x91, 0x4e, 0x60, 0x71, 0xcb, 0x30, 0xe9, 0xbc, 0x4d, 0x06, + 0x04, 0x1e, 0xc7, 0x28, 0x78, 0xdb, 0x5d, 0x4c, 0xcd, 0x09, 0xf6, 0x87, 0xfc, 0xc6, 0x8b, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x95, 0x86, 0xeb, 0x57, 0x04, 0x11, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1564,10 +1564,10 @@ func (m *QueryHeaderRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x10 } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + if len(m.ConsumerId) > 0 { + i -= len(m.ConsumerId) + copy(dAtA[i:], m.ConsumerId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerId))) i-- dAtA[i] = 0xa } @@ -1688,11 +1688,11 @@ func (m *QueryChainListResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x12 } - if len(m.ChainIds) > 0 { - for iNdEx := len(m.ChainIds) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ChainIds[iNdEx]) - copy(dAtA[i:], m.ChainIds[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainIds[iNdEx]))) + if len(m.ConsumerIds) > 0 { + for iNdEx := len(m.ConsumerIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ConsumerIds[iNdEx]) + copy(dAtA[i:], m.ConsumerIds[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerIds[iNdEx]))) i-- dAtA[i] = 0xa } @@ -1720,11 +1720,11 @@ func (m *QueryChainsInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l - if len(m.ChainIds) > 0 { - for iNdEx := len(m.ChainIds) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ChainIds[iNdEx]) - copy(dAtA[i:], m.ChainIds[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainIds[iNdEx]))) + if len(m.ConsumerIds) > 0 { + for iNdEx := len(m.ConsumerIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ConsumerIds[iNdEx]) + copy(dAtA[i:], m.ConsumerIds[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerIds[iNdEx]))) i-- dAtA[i] = 0xa } @@ -1789,11 +1789,11 @@ func (m *QueryEpochChainsInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, er _ = i var l int _ = l - if len(m.ChainIds) > 0 { - for iNdEx := len(m.ChainIds) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ChainIds[iNdEx]) - copy(dAtA[i:], m.ChainIds[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainIds[iNdEx]))) + if len(m.ConsumerIds) > 0 { + for iNdEx := len(m.ConsumerIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ConsumerIds[iNdEx]) + copy(dAtA[i:], m.ConsumerIds[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerIds[iNdEx]))) i-- dAtA[i] = 0x12 } @@ -1875,10 +1875,10 @@ func (m *QueryListHeadersRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x12 } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + if len(m.ConsumerId) > 0 { + i -= len(m.ConsumerId) + copy(dAtA[i:], m.ConsumerId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerId))) i-- dAtA[i] = 0xa } @@ -1954,10 +1954,10 @@ func (m *QueryListEpochHeadersRequest) MarshalToSizedBuffer(dAtA []byte) (int, e _ = i var l int _ = l - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + if len(m.ConsumerId) > 0 { + i -= len(m.ConsumerId) + copy(dAtA[i:], m.ConsumerId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerId))) i-- dAtA[i] = 0x12 } @@ -2036,11 +2036,11 @@ func (m *QueryFinalizedChainsInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int i-- dAtA[i] = 0x10 } - if len(m.ChainIds) > 0 { - for iNdEx := len(m.ChainIds) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ChainIds[iNdEx]) - copy(dAtA[i:], m.ChainIds[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainIds[iNdEx]))) + if len(m.ConsumerIds) > 0 { + for iNdEx := len(m.ConsumerIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ConsumerIds[iNdEx]) + copy(dAtA[i:], m.ConsumerIds[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerIds[iNdEx]))) i-- dAtA[i] = 0xa } @@ -2120,10 +2120,10 @@ func (m *QueryFinalizedChainInfoUntilHeightRequest) MarshalToSizedBuffer(dAtA [] i-- dAtA[i] = 0x10 } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + if len(m.ConsumerId) > 0 { + i -= len(m.ConsumerId) + copy(dAtA[i:], m.ConsumerId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerId))) i-- dAtA[i] = 0xa } @@ -2250,7 +2250,7 @@ func (m *QueryHeaderRequest) Size() (n int) { } var l int _ = l - l = len(m.ChainId) + l = len(m.ConsumerId) if l > 0 { n += 1 + l + sovQuery(uint64(l)) } @@ -2296,8 +2296,8 @@ func (m *QueryChainListResponse) Size() (n int) { } var l int _ = l - if len(m.ChainIds) > 0 { - for _, s := range m.ChainIds { + if len(m.ConsumerIds) > 0 { + for _, s := range m.ConsumerIds { l = len(s) n += 1 + l + sovQuery(uint64(l)) } @@ -2315,8 +2315,8 @@ func (m *QueryChainsInfoRequest) Size() (n int) { } var l int _ = l - if len(m.ChainIds) > 0 { - for _, s := range m.ChainIds { + if len(m.ConsumerIds) > 0 { + for _, s := range m.ConsumerIds { l = len(s) n += 1 + l + sovQuery(uint64(l)) } @@ -2348,8 +2348,8 @@ func (m *QueryEpochChainsInfoRequest) Size() (n int) { if m.EpochNum != 0 { n += 1 + sovQuery(uint64(m.EpochNum)) } - if len(m.ChainIds) > 0 { - for _, s := range m.ChainIds { + if len(m.ConsumerIds) > 0 { + for _, s := range m.ConsumerIds { l = len(s) n += 1 + l + sovQuery(uint64(l)) } @@ -2378,7 +2378,7 @@ func (m *QueryListHeadersRequest) Size() (n int) { } var l int _ = l - l = len(m.ChainId) + l = len(m.ConsumerId) if l > 0 { n += 1 + l + sovQuery(uint64(l)) } @@ -2417,7 +2417,7 @@ func (m *QueryListEpochHeadersRequest) Size() (n int) { if m.EpochNum != 0 { n += 1 + sovQuery(uint64(m.EpochNum)) } - l = len(m.ChainId) + l = len(m.ConsumerId) if l > 0 { n += 1 + l + sovQuery(uint64(l)) } @@ -2445,8 +2445,8 @@ func (m *QueryFinalizedChainsInfoRequest) Size() (n int) { } var l int _ = l - if len(m.ChainIds) > 0 { - for _, s := range m.ChainIds { + if len(m.ConsumerIds) > 0 { + for _, s := range m.ConsumerIds { l = len(s) n += 1 + l + sovQuery(uint64(l)) } @@ -2478,7 +2478,7 @@ func (m *QueryFinalizedChainInfoUntilHeightRequest) Size() (n int) { } var l int _ = l - l = len(m.ChainId) + l = len(m.ConsumerId) if l > 0 { n += 1 + l + sovQuery(uint64(l)) } @@ -2690,7 +2690,7 @@ func (m *QueryHeaderRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2718,7 +2718,7 @@ func (m *QueryHeaderRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ConsumerId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 0 { @@ -2999,7 +2999,7 @@ func (m *QueryChainListResponse) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerIds", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3027,7 +3027,7 @@ func (m *QueryChainListResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainIds = append(m.ChainIds, string(dAtA[iNdEx:postIndex])) + m.ConsumerIds = append(m.ConsumerIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 2: if wireType != 2 { @@ -3117,7 +3117,7 @@ func (m *QueryChainsInfoRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerIds", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3145,7 +3145,7 @@ func (m *QueryChainsInfoRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainIds = append(m.ChainIds, string(dAtA[iNdEx:postIndex])) + m.ConsumerIds = append(m.ConsumerIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -3302,7 +3302,7 @@ func (m *QueryEpochChainsInfoRequest) Unmarshal(dAtA []byte) error { } case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerIds", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3330,7 +3330,7 @@ func (m *QueryEpochChainsInfoRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainIds = append(m.ChainIds, string(dAtA[iNdEx:postIndex])) + m.ConsumerIds = append(m.ConsumerIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -3468,7 +3468,7 @@ func (m *QueryListHeadersRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3496,7 +3496,7 @@ func (m *QueryListHeadersRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ConsumerId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -3725,7 +3725,7 @@ func (m *QueryListEpochHeadersRequest) Unmarshal(dAtA []byte) error { } case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3753,7 +3753,7 @@ func (m *QueryListEpochHeadersRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ConsumerId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -3891,7 +3891,7 @@ func (m *QueryFinalizedChainsInfoRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerIds", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3919,7 +3919,7 @@ func (m *QueryFinalizedChainsInfoRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainIds = append(m.ChainIds, string(dAtA[iNdEx:postIndex])) + m.ConsumerIds = append(m.ConsumerIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 2: if wireType != 0 { @@ -4077,7 +4077,7 @@ func (m *QueryFinalizedChainInfoUntilHeightRequest) Unmarshal(dAtA []byte) error switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4105,7 +4105,7 @@ func (m *QueryFinalizedChainInfoUntilHeightRequest) Unmarshal(dAtA []byte) error if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ConsumerId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 0 { diff --git a/x/zoneconcierge/types/query.pb.gw.go b/x/zoneconcierge/types/query.pb.gw.go index fc22099f6..de98ae8af 100644 --- a/x/zoneconcierge/types/query.pb.gw.go +++ b/x/zoneconcierge/types/query.pb.gw.go @@ -62,15 +62,15 @@ func request_Query_Header_0(ctx context.Context, marshaler runtime.Marshaler, cl _ = err ) - val, ok = pathParams["chain_id"] + val, ok = pathParams["consumer_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "consumer_id") } - protoReq.ChainId, err = runtime.String(val) + protoReq.ConsumerId, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "consumer_id", err) } val, ok = pathParams["height"] @@ -100,15 +100,15 @@ func local_request_Query_Header_0(ctx context.Context, marshaler runtime.Marshal _ = err ) - val, ok = pathParams["chain_id"] + val, ok = pathParams["consumer_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "consumer_id") } - protoReq.ChainId, err = runtime.String(val) + protoReq.ConsumerId, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "consumer_id", err) } val, ok = pathParams["height"] @@ -236,7 +236,7 @@ func local_request_Query_EpochChainsInfo_0(ctx context.Context, marshaler runtim } var ( - filter_Query_ListHeaders_0 = &utilities.DoubleArray{Encoding: map[string]int{"chain_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} + filter_Query_ListHeaders_0 = &utilities.DoubleArray{Encoding: map[string]int{"consumer_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} ) func request_Query_ListHeaders_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -250,15 +250,15 @@ func request_Query_ListHeaders_0(ctx context.Context, marshaler runtime.Marshale _ = err ) - val, ok = pathParams["chain_id"] + val, ok = pathParams["consumer_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "consumer_id") } - protoReq.ChainId, err = runtime.String(val) + protoReq.ConsumerId, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "consumer_id", err) } if err := req.ParseForm(); err != nil { @@ -284,15 +284,15 @@ func local_request_Query_ListHeaders_0(ctx context.Context, marshaler runtime.Ma _ = err ) - val, ok = pathParams["chain_id"] + val, ok = pathParams["consumer_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "consumer_id") } - protoReq.ChainId, err = runtime.String(val) + protoReq.ConsumerId, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "consumer_id", err) } if err := req.ParseForm(); err != nil { @@ -318,15 +318,15 @@ func request_Query_ListEpochHeaders_0(ctx context.Context, marshaler runtime.Mar _ = err ) - val, ok = pathParams["chain_id"] + val, ok = pathParams["consumer_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "consumer_id") } - protoReq.ChainId, err = runtime.String(val) + protoReq.ConsumerId, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "consumer_id", err) } val, ok = pathParams["epoch_num"] @@ -356,15 +356,15 @@ func local_request_Query_ListEpochHeaders_0(ctx context.Context, marshaler runti _ = err ) - val, ok = pathParams["chain_id"] + val, ok = pathParams["consumer_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "consumer_id") } - protoReq.ChainId, err = runtime.String(val) + protoReq.ConsumerId, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "consumer_id", err) } val, ok = pathParams["epoch_num"] @@ -420,7 +420,7 @@ func local_request_Query_FinalizedChainsInfo_0(ctx context.Context, marshaler ru } var ( - filter_Query_FinalizedChainInfoUntilHeight_0 = &utilities.DoubleArray{Encoding: map[string]int{"chain_id": 0, "height": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} + filter_Query_FinalizedChainInfoUntilHeight_0 = &utilities.DoubleArray{Encoding: map[string]int{"consumer_id": 0, "height": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} ) func request_Query_FinalizedChainInfoUntilHeight_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -434,15 +434,15 @@ func request_Query_FinalizedChainInfoUntilHeight_0(ctx context.Context, marshale _ = err ) - val, ok = pathParams["chain_id"] + val, ok = pathParams["consumer_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "consumer_id") } - protoReq.ChainId, err = runtime.String(val) + protoReq.ConsumerId, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "consumer_id", err) } val, ok = pathParams["height"] @@ -479,15 +479,15 @@ func local_request_Query_FinalizedChainInfoUntilHeight_0(ctx context.Context, ma _ = err ) - val, ok = pathParams["chain_id"] + val, ok = pathParams["consumer_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "consumer_id") } - protoReq.ChainId, err = runtime.String(val) + protoReq.ConsumerId, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "consumer_id", err) } val, ok = pathParams["height"] @@ -953,7 +953,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie var ( pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "zoneconcierge", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Header_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6}, []string{"babylon", "zoneconcierge", "v1", "chain_info", "chain_id", "header", "height"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_Header_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6}, []string{"babylon", "zoneconcierge", "v1", "chain_info", "consumer_id", "header", "height"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_ChainList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "zoneconcierge", "v1", "chains"}, "", runtime.AssumeColonVerbOpt(false))) @@ -961,13 +961,13 @@ var ( pattern_Query_EpochChainsInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "zoneconcierge", "v1", "epoch_chains_info"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ListHeaders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"babylon", "zoneconcierge", "v1", "headers", "chain_id"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_ListHeaders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"babylon", "zoneconcierge", "v1", "headers", "consumer_id"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ListEpochHeaders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6}, []string{"babylon", "zoneconcierge", "v1", "headers", "chain_id", "epochs", "epoch_num"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_ListEpochHeaders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6}, []string{"babylon", "zoneconcierge", "v1", "headers", "consumer_id", "epochs", "epoch_num"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_FinalizedChainsInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "zoneconcierge", "v1", "finalized_chains_info"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_FinalizedChainInfoUntilHeight_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 5}, []string{"babylon", "zoneconcierge", "v1", "finalized_chain_info", "chain_id", "height"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_FinalizedChainInfoUntilHeight_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 5}, []string{"babylon", "zoneconcierge", "v1", "finalized_chain_info", "consumer_id", "height"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/x/zoneconcierge/types/zoneconcierge.go b/x/zoneconcierge/types/zoneconcierge.go index 0a052a01a..91c970ebe 100644 --- a/x/zoneconcierge/types/zoneconcierge.go +++ b/x/zoneconcierge/types/zoneconcierge.go @@ -46,8 +46,8 @@ func (p *ProofEpochSealed) ValidateBasic() error { } func (ih *IndexedHeader) ValidateBasic() error { - if len(ih.ChainId) == 0 { - return fmt.Errorf("empty ChainID") + if len(ih.ConsumerId) == 0 { + return fmt.Errorf("empty ConsumerID") } if len(ih.Hash) == 0 { return fmt.Errorf("empty Hash") @@ -66,7 +66,7 @@ func (ih *IndexedHeader) Equal(ih2 *IndexedHeader) bool { return false } - if ih.ChainId != ih2.ChainId { + if ih.ConsumerId != ih2.ConsumerId { return false } if !bytes.Equal(ih.Hash, ih2.Hash) { @@ -92,7 +92,7 @@ func (ci *ChainInfo) Equal(ci2 *ChainInfo) bool { return false } - if ci.ChainId != ci2.ChainId { + if ci.ConsumerId != ci2.ConsumerId { return false } if !ci.LatestHeader.Equal(ci2.LatestHeader) { @@ -110,8 +110,8 @@ func (ci *ChainInfo) Equal(ci2 *ChainInfo) bool { } func (ci *ChainInfo) ValidateBasic() error { - if len(ci.ChainId) == 0 { - return ErrInvalidChainInfo.Wrap("ChainID is empty") + if len(ci.ConsumerId) == 0 { + return ErrInvalidChainInfo.Wrap("ConsumerId is empty") } else if ci.LatestHeader == nil { return ErrInvalidChainInfo.Wrap("LatestHeader is nil") } else if ci.LatestForks == nil { diff --git a/x/zoneconcierge/types/zoneconcierge.pb.go b/x/zoneconcierge/types/zoneconcierge.pb.go index 8e3d792b7..cd5023d6d 100644 --- a/x/zoneconcierge/types/zoneconcierge.pb.go +++ b/x/zoneconcierge/types/zoneconcierge.pb.go @@ -34,8 +34,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // IndexedHeader is the metadata of a CZ header type IndexedHeader struct { - // chain_id is the unique ID of the chain - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // consumer_id is the unique ID of the consumer + ConsumerId string `protobuf:"bytes,1,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` // hash is the hash of this header Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` // height is the height of this header on CZ ledger @@ -92,9 +92,9 @@ func (m *IndexedHeader) XXX_DiscardUnknown() { var xxx_messageInfo_IndexedHeader proto.InternalMessageInfo -func (m *IndexedHeader) GetChainId() string { +func (m *IndexedHeader) GetConsumerId() string { if m != nil { - return m.ChainId + return m.ConsumerId } return "" } @@ -211,8 +211,8 @@ func (m *Forks) GetHeaders() []*IndexedHeader { // ChainInfo is the information of a CZ type ChainInfo struct { - // chain_id is the ID of the chain - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // consumer_id is the ID of the consumer + ConsumerId string `protobuf:"bytes,1,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` // latest_header is the latest header in CZ's canonical chain LatestHeader *IndexedHeader `protobuf:"bytes,2,opt,name=latest_header,json=latestHeader,proto3" json:"latest_header,omitempty"` // latest_forks is the latest forks, formed as a series of IndexedHeader (from @@ -256,9 +256,9 @@ func (m *ChainInfo) XXX_DiscardUnknown() { var xxx_messageInfo_ChainInfo proto.InternalMessageInfo -func (m *ChainInfo) GetChainId() string { +func (m *ChainInfo) GetConsumerId() string { if m != nil { - return m.ChainId + return m.ConsumerId } return "" } @@ -343,8 +343,8 @@ func (m *ChainInfoWithProof) GetProofHeaderInEpoch() *crypto.ProofOps { // FinalizedChainInfo is the information of a CZ that is BTC-finalised type FinalizedChainInfo struct { - // chain_id is the ID of the chain - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // consumer_id is the ID of the consumer + ConsumerId string `protobuf:"bytes,1,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` // finalized_chain_info is the info of the CZ FinalizedChainInfo *ChainInfo `protobuf:"bytes,2,opt,name=finalized_chain_info,json=finalizedChainInfo,proto3" json:"finalized_chain_info,omitempty"` // epoch_info is the metadata of the last BTC-finalised epoch @@ -391,9 +391,9 @@ func (m *FinalizedChainInfo) XXX_DiscardUnknown() { var xxx_messageInfo_FinalizedChainInfo proto.InternalMessageInfo -func (m *FinalizedChainInfo) GetChainId() string { +func (m *FinalizedChainInfo) GetConsumerId() string { if m != nil { - return m.ChainId + return m.ConsumerId } return "" } @@ -639,68 +639,68 @@ func init() { } var fileDescriptor_ab886e1868e5c5cd = []byte{ - // 968 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdd, 0x6e, 0x1b, 0x45, - 0x14, 0xce, 0xc6, 0x4e, 0xd2, 0x1c, 0xc7, 0x6d, 0x98, 0xa4, 0xd4, 0x0d, 0xc2, 0xb1, 0x5c, 0xa9, - 0xb8, 0x88, 0xae, 0x65, 0x83, 0x84, 0xe0, 0x0e, 0x5b, 0x2d, 0x4d, 0x41, 0xfc, 0xac, 0xdd, 0x82, - 0x10, 0x68, 0xb5, 0x3f, 0x63, 0xef, 0x2a, 0xeb, 0x1d, 0x6b, 0x67, 0xe2, 0xc6, 0x79, 0x8a, 0xbe, - 0x05, 0xdc, 0xf2, 0x00, 0xdc, 0x73, 0xd9, 0x4b, 0xee, 0x40, 0xc9, 0x2b, 0x70, 0xc3, 0x1d, 0x9a, - 0x33, 0x33, 0xeb, 0x75, 0x22, 0x93, 0x70, 0x13, 0xed, 0xcc, 0x7c, 0xe7, 0x9c, 0xef, 0x7c, 0xe7, - 0xc7, 0x81, 0x0f, 0x7c, 0xcf, 0x9f, 0x27, 0x2c, 0x6d, 0x9f, 0xb1, 0x94, 0x06, 0x2c, 0x0d, 0x62, - 0x9a, 0x8d, 0x69, 0x7b, 0xd6, 0x59, 0xbe, 0xb0, 0xa7, 0x19, 0x13, 0x8c, 0xd4, 0x34, 0xda, 0x5e, - 0x7e, 0x9c, 0x75, 0x0e, 0xf6, 0xc7, 0x6c, 0xcc, 0x10, 0xd4, 0x96, 0x5f, 0x0a, 0x7f, 0x70, 0x38, - 0x66, 0x6c, 0x9c, 0xd0, 0x36, 0x9e, 0xfc, 0x93, 0x51, 0x5b, 0xc4, 0x13, 0xca, 0x85, 0x37, 0x99, - 0x6a, 0xc0, 0xbb, 0x82, 0xa6, 0x21, 0xcd, 0x26, 0x71, 0x2a, 0xda, 0x41, 0x36, 0x9f, 0x0a, 0x26, - 0xb1, 0x6c, 0xa4, 0x9f, 0x73, 0x76, 0xbe, 0x08, 0x82, 0x88, 0x06, 0xc7, 0x53, 0x26, 0x91, 0xb3, - 0xce, 0xf2, 0x85, 0x46, 0x3f, 0x34, 0xe8, 0xc5, 0x4b, 0x9c, 0x8e, 0x11, 0x9d, 0x70, 0xf7, 0x98, - 0xce, 0x35, 0xee, 0xd1, 0x4a, 0xdc, 0x15, 0x97, 0x4d, 0x03, 0xa5, 0x53, 0x16, 0x44, 0x1a, 0x65, - 0xbe, 0x35, 0xc6, 0x2e, 0x90, 0x4c, 0xe2, 0x71, 0x24, 0xff, 0xd2, 0x9c, 0x65, 0xe1, 0x46, 0xe1, - 0x9b, 0xbf, 0xad, 0x43, 0xf5, 0x28, 0x0d, 0xe9, 0x29, 0x0d, 0x9f, 0x51, 0x2f, 0xa4, 0x19, 0xb9, - 0x0f, 0xb7, 0x82, 0xc8, 0x8b, 0x53, 0x37, 0x0e, 0x6b, 0x56, 0xc3, 0x6a, 0x6d, 0x3b, 0x5b, 0x78, - 0x3e, 0x0a, 0x09, 0x81, 0x72, 0xe4, 0xf1, 0xa8, 0xb6, 0xde, 0xb0, 0x5a, 0x3b, 0x0e, 0x7e, 0x93, - 0xb7, 0x61, 0x33, 0xa2, 0xd2, 0x6d, 0xad, 0xd4, 0xb0, 0x5a, 0x65, 0x47, 0x9f, 0xc8, 0x47, 0x50, - 0x96, 0xfa, 0xd6, 0xca, 0x0d, 0xab, 0x55, 0xe9, 0x1e, 0xd8, 0x4a, 0x7c, 0xdb, 0x88, 0x6f, 0x0f, - 0x8d, 0xf8, 0xbd, 0xf2, 0xeb, 0x3f, 0x0f, 0x2d, 0x07, 0xd1, 0xc4, 0x86, 0x3d, 0x9d, 0x80, 0x1b, - 0x21, 0x1d, 0x17, 0x03, 0x6e, 0x60, 0xc0, 0xb7, 0xf4, 0x93, 0x22, 0xfa, 0x4c, 0x46, 0xef, 0xc2, - 0xdd, 0xcb, 0x78, 0x45, 0x66, 0x13, 0xc9, 0xec, 0x2d, 0x5b, 0x28, 0x66, 0x0f, 0xa0, 0x6a, 0x6c, - 0x50, 0xbc, 0xda, 0x16, 0x62, 0x77, 0xf4, 0xe5, 0x13, 0x79, 0x47, 0x1e, 0xc2, 0x1d, 0x03, 0x12, - 0xa7, 0x8a, 0xc4, 0x2d, 0x24, 0x61, 0x6c, 0x87, 0xa7, 0x92, 0x40, 0xf3, 0x39, 0x6c, 0x3c, 0x65, - 0xd9, 0x31, 0x27, 0x9f, 0xc1, 0x96, 0x62, 0xc0, 0x6b, 0xa5, 0x46, 0xa9, 0x55, 0xe9, 0xbe, 0x67, - 0xaf, 0xea, 0x4f, 0x7b, 0x49, 0x70, 0xc7, 0xd8, 0x35, 0xff, 0xb6, 0x60, 0xbb, 0x8f, 0x52, 0xa7, - 0x23, 0xf6, 0x5f, 0x75, 0xf8, 0x12, 0xaa, 0x89, 0x27, 0x28, 0x17, 0x3a, 0x69, 0x2c, 0xc8, 0xff, - 0x88, 0xb8, 0xa3, 0xac, 0x75, 0xc1, 0x7b, 0xa0, 0xcf, 0xee, 0x48, 0x66, 0x82, 0x75, 0xac, 0x74, - 0x0f, 0x57, 0x3b, 0xc3, 0x84, 0x9d, 0x8a, 0x32, 0x52, 0xd9, 0x7f, 0x0a, 0xf7, 0xf3, 0x69, 0xa2, - 0xa1, 0xa6, 0xc5, 0xdd, 0x80, 0x9d, 0xa4, 0x02, 0x5b, 0xa0, 0xec, 0xdc, 0x2b, 0x00, 0x54, 0x64, - 0xde, 0x97, 0xcf, 0xcd, 0x5f, 0x2c, 0x20, 0x79, 0xda, 0xdf, 0xc5, 0x22, 0xfa, 0x46, 0x0e, 0x1d, - 0xe9, 0x01, 0xe8, 0xfc, 0xd3, 0x11, 0x43, 0x05, 0x2a, 0xdd, 0x07, 0xab, 0x49, 0xe5, 0x1e, 0x9c, - 0xed, 0x20, 0xd7, 0xf0, 0x2b, 0xb8, 0x8b, 0x13, 0x6c, 0x9a, 0x23, 0x36, 0x25, 0x57, 0x82, 0xbd, - 0x63, 0x2f, 0x26, 0xde, 0x56, 0x13, 0x6f, 0x63, 0xf0, 0xaf, 0xa7, 0xdc, 0x21, 0x68, 0xa9, 0x98, - 0x1e, 0xa9, 0xae, 0x68, 0xfe, 0x5a, 0x02, 0xf2, 0x34, 0x4e, 0xbd, 0x24, 0x3e, 0xa3, 0xe1, 0x8d, - 0x4a, 0xf5, 0x02, 0xf6, 0x47, 0xc6, 0xc0, 0x2d, 0xe4, 0xb3, 0x7e, 0xf3, 0x7c, 0xc8, 0xe8, 0x6a, - 0xc4, 0x4f, 0x00, 0x30, 0x11, 0xe5, 0xac, 0xa4, 0x67, 0xcc, 0x38, 0xcb, 0x77, 0xc2, 0xac, 0x63, - 0x23, 0x71, 0x67, 0x1b, 0xaf, 0xb4, 0x26, 0xb7, 0x33, 0xef, 0x95, 0xbb, 0xd8, 0x2e, 0x7a, 0x44, - 0x17, 0xdd, 0xb3, 0xb4, 0x89, 0xa4, 0x0f, 0xc7, 0x7b, 0xd5, 0xcf, 0xef, 0x9c, 0x6a, 0x56, 0x3c, - 0x92, 0x17, 0x40, 0x7c, 0x11, 0xb8, 0xfc, 0xc4, 0x9f, 0xc4, 0x9c, 0xc7, 0x2c, 0x95, 0xcb, 0x0d, - 0x27, 0xb6, 0xe8, 0x73, 0x79, 0x45, 0xce, 0x3a, 0xf6, 0x20, 0xc7, 0x7f, 0x41, 0xe7, 0xce, 0xae, - 0x2f, 0x82, 0xa5, 0x1b, 0xf2, 0x39, 0x6c, 0x60, 0x01, 0x70, 0x92, 0x2b, 0xdd, 0xce, 0x6a, 0xa5, - 0xb0, 0x62, 0x57, 0xab, 0xe2, 0x28, 0xfb, 0xe6, 0x3f, 0x16, 0xec, 0x22, 0x04, 0x95, 0x18, 0x50, - 0x2f, 0xa1, 0x21, 0x71, 0xa0, 0x3a, 0xf3, 0x92, 0x38, 0xf4, 0x04, 0xcb, 0x5c, 0x4e, 0x45, 0xcd, - 0xc2, 0x99, 0x7d, 0xbc, 0x5a, 0x83, 0x97, 0x06, 0x2e, 0x3b, 0xb4, 0x97, 0x70, 0xc9, 0x7a, 0x27, - 0xf7, 0x31, 0xa0, 0x82, 0x3c, 0x81, 0x5d, 0xd5, 0x6c, 0x85, 0xca, 0xdc, 0xa0, 0xcf, 0x6e, 0x4f, - 0x73, 0x72, 0x58, 0x9f, 0xe7, 0xb0, 0x57, 0x74, 0x33, 0xf3, 0x12, 0x24, 0x58, 0xba, 0xde, 0xd3, - 0xee, 0xc2, 0xd3, 0x4b, 0x2f, 0x19, 0x50, 0xd1, 0xfc, 0x79, 0x1d, 0xee, 0xad, 0x90, 0x87, 0x0c, - 0xa0, 0xa6, 0xe2, 0x04, 0x67, 0x57, 0xc6, 0xc3, 0xba, 0x3e, 0xd8, 0x3e, 0x1a, 0xf7, 0xcf, 0x96, - 0x06, 0x84, 0x7c, 0x0f, 0xa4, 0x48, 0x9e, 0xa3, 0xda, 0x5a, 0x85, 0xf7, 0xaf, 0x29, 0x61, 0xa1, - 0x3e, 0xc5, 0x54, 0x74, 0xc5, 0x7e, 0x32, 0xa3, 0xac, 0x3d, 0xcb, 0x66, 0x11, 0x82, 0x86, 0x7a, - 0xdb, 0x3e, 0x5a, 0xdd, 0x69, 0xc3, 0xcc, 0x4b, 0xb9, 0x17, 0x88, 0x98, 0xa9, 0xbe, 0xd8, 0x2b, - 0xf8, 0x36, 0x5e, 0x9a, 0x3f, 0xc2, 0x9d, 0xde, 0xb0, 0x8f, 0xea, 0x0c, 0xe8, 0x78, 0x42, 0x53, - 0x41, 0x8e, 0xa0, 0x22, 0x1b, 0xdb, 0x6c, 0x75, 0xd5, 0x21, 0xad, 0x62, 0x9c, 0xe2, 0xcf, 0xe9, - 0xac, 0x63, 0xf7, 0x86, 0x7d, 0xa3, 0xc6, 0x88, 0x39, 0xe0, 0x8b, 0x40, 0xef, 0xb9, 0xde, 0xb7, - 0xbf, 0x9f, 0xd7, 0xad, 0x37, 0xe7, 0x75, 0xeb, 0xaf, 0xf3, 0xba, 0xf5, 0xfa, 0xa2, 0xbe, 0xf6, - 0xe6, 0xa2, 0xbe, 0xf6, 0xc7, 0x45, 0x7d, 0xed, 0x87, 0x8f, 0xc7, 0xb1, 0x88, 0x4e, 0x7c, 0x3b, - 0x60, 0x93, 0xb6, 0xf6, 0x9c, 0x78, 0x3e, 0x7f, 0x1c, 0x33, 0x73, 0x6c, 0x9f, 0x5e, 0xfa, 0x77, - 0x48, 0xcc, 0xa7, 0x94, 0xfb, 0x9b, 0xf8, 0x4b, 0xfa, 0xe1, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, - 0xa3, 0x29, 0xc3, 0x31, 0x34, 0x09, 0x00, 0x00, + // 974 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x5f, 0x6f, 0x1b, 0x45, + 0x10, 0xcf, 0xc5, 0x4e, 0x4a, 0xc6, 0x71, 0x1b, 0x36, 0x29, 0x35, 0x41, 0x38, 0x96, 0x2b, 0x15, + 0x17, 0xd1, 0xb3, 0x6c, 0x90, 0x10, 0xbc, 0x61, 0xab, 0xa5, 0x2e, 0x88, 0x3f, 0x67, 0xb7, 0x20, + 0x04, 0x3a, 0xdd, 0x9f, 0xb5, 0xef, 0x94, 0xf3, 0xad, 0x75, 0xbb, 0x76, 0xe3, 0x7c, 0x8a, 0x7e, + 0x0b, 0xf8, 0x06, 0x7c, 0x00, 0x5e, 0x78, 0xec, 0x23, 0x6f, 0xa0, 0xe4, 0x53, 0xc0, 0x13, 0xda, + 0xd9, 0xdd, 0xf3, 0xb9, 0x91, 0x95, 0xf6, 0x25, 0xba, 0x9d, 0xfd, 0xcd, 0xcc, 0x6f, 0xe6, 0x37, + 0xb3, 0x0e, 0x7c, 0xe4, 0x7b, 0xfe, 0x32, 0x61, 0x69, 0xfb, 0x9c, 0xa5, 0x34, 0x60, 0x69, 0x10, + 0xd3, 0x6c, 0x42, 0xdb, 0x8b, 0xce, 0xba, 0xc1, 0x9e, 0x65, 0x4c, 0x30, 0x52, 0xd3, 0x68, 0x7b, + 0xfd, 0x72, 0xd1, 0x39, 0x3e, 0x9a, 0xb0, 0x09, 0x43, 0x50, 0x5b, 0x7e, 0x29, 0xfc, 0xf1, 0xc9, + 0x84, 0xb1, 0x49, 0x42, 0xdb, 0x78, 0xf2, 0xe7, 0xe3, 0xb6, 0x88, 0xa7, 0x94, 0x0b, 0x6f, 0x3a, + 0xd3, 0x80, 0xf7, 0x05, 0x4d, 0x43, 0x9a, 0x4d, 0xe3, 0x54, 0xb4, 0x83, 0x6c, 0x39, 0x13, 0x4c, + 0x62, 0xd9, 0x58, 0x5f, 0xe7, 0xec, 0x7c, 0x11, 0x04, 0x11, 0x0d, 0x4e, 0x67, 0x4c, 0x22, 0x17, + 0x9d, 0x75, 0x83, 0x46, 0xdf, 0x33, 0xe8, 0xd5, 0x4d, 0x9c, 0x4e, 0x10, 0x9d, 0x70, 0xf7, 0x94, + 0x2e, 0x35, 0xee, 0xfe, 0x46, 0xdc, 0x95, 0x90, 0x4d, 0x03, 0xa5, 0x33, 0x16, 0x44, 0x1a, 0x65, + 0xbe, 0x35, 0xc6, 0x2e, 0x90, 0x4c, 0xe2, 0x49, 0x24, 0xff, 0xd2, 0x9c, 0x65, 0xc1, 0xa2, 0xf0, + 0xcd, 0x3f, 0xb6, 0xa1, 0x3a, 0x48, 0x43, 0x7a, 0x46, 0xc3, 0xc7, 0xd4, 0x0b, 0x69, 0x46, 0x4e, + 0xa0, 0x12, 0xb0, 0x94, 0xcf, 0xa7, 0x34, 0x73, 0xe3, 0xb0, 0x66, 0x35, 0xac, 0xd6, 0x9e, 0x03, + 0xc6, 0x34, 0x08, 0x09, 0x81, 0x72, 0xe4, 0xf1, 0xa8, 0xb6, 0xdd, 0xb0, 0x5a, 0xfb, 0x0e, 0x7e, + 0x93, 0x77, 0x60, 0x37, 0xa2, 0x32, 0x78, 0xad, 0xd4, 0xb0, 0x5a, 0x65, 0x47, 0x9f, 0xc8, 0x27, + 0x50, 0x96, 0x5d, 0xae, 0x95, 0x1b, 0x56, 0xab, 0xd2, 0x3d, 0xb6, 0x95, 0x04, 0xb6, 0x91, 0xc0, + 0x1e, 0x19, 0x09, 0x7a, 0xe5, 0x17, 0x7f, 0x9f, 0x58, 0x0e, 0xa2, 0x89, 0x0d, 0x87, 0xba, 0x0c, + 0x37, 0x42, 0x52, 0x2e, 0x26, 0xdc, 0xc1, 0x84, 0x6f, 0xeb, 0x2b, 0x45, 0xf7, 0xb1, 0xcc, 0xde, + 0x85, 0xdb, 0xaf, 0xe2, 0x15, 0x99, 0x5d, 0x24, 0x73, 0xb8, 0xee, 0xa1, 0x98, 0xdd, 0x85, 0xaa, + 0xf1, 0xc1, 0x16, 0xd6, 0x6e, 0x20, 0x76, 0x5f, 0x1b, 0x1f, 0x4a, 0x1b, 0xb9, 0x07, 0xb7, 0x0c, + 0x48, 0x9c, 0x29, 0x12, 0x6f, 0x21, 0x09, 0xe3, 0x3b, 0x3a, 0x93, 0x04, 0x9a, 0x4f, 0x60, 0xe7, + 0x11, 0xcb, 0x4e, 0x39, 0xf9, 0x02, 0x6e, 0x28, 0x06, 0xbc, 0x56, 0x6a, 0x94, 0x5a, 0x95, 0xee, + 0x07, 0xf6, 0xa6, 0x29, 0xb5, 0xd7, 0xda, 0xee, 0x18, 0xbf, 0xe6, 0x7f, 0x16, 0xec, 0xf5, 0x23, + 0x2f, 0x4e, 0x07, 0xe9, 0x98, 0x5d, 0xaf, 0xc6, 0xd7, 0x50, 0x4d, 0x3c, 0x41, 0xb9, 0xd0, 0xa5, + 0xa3, 0x2c, 0x6f, 0x90, 0x77, 0x5f, 0x79, 0x6b, 0xf1, 0x7b, 0xa0, 0xcf, 0xee, 0x58, 0xd6, 0x83, + 0x6a, 0x56, 0xba, 0x27, 0x9b, 0x83, 0x61, 0xd9, 0x4e, 0x45, 0x39, 0xa9, 0x1e, 0x7c, 0x0e, 0xef, + 0xe6, 0x9b, 0x45, 0x43, 0x4d, 0x8b, 0xbb, 0x01, 0x9b, 0xa7, 0x02, 0x07, 0xa1, 0xec, 0xdc, 0x29, + 0x00, 0x54, 0x66, 0xde, 0x97, 0xd7, 0xcd, 0xdf, 0x2c, 0x20, 0x79, 0xf1, 0x3f, 0xc4, 0x22, 0xfa, + 0x4e, 0x2e, 0x20, 0xe9, 0x01, 0x04, 0xd2, 0xea, 0xc6, 0xe9, 0x98, 0x61, 0x13, 0x2a, 0xdd, 0xbb, + 0x9b, 0x49, 0xe5, 0x11, 0x9c, 0xbd, 0x20, 0xef, 0xe4, 0x37, 0x70, 0x1b, 0xb7, 0xd9, 0x8c, 0x48, + 0x6c, 0x84, 0x57, 0x0d, 0x7b, 0xcf, 0x5e, 0x6d, 0xbf, 0xad, 0xb6, 0xdf, 0xc6, 0xe4, 0xdf, 0xce, + 0xb8, 0x43, 0xd0, 0x53, 0x31, 0x1d, 0xa8, 0xd9, 0x68, 0xfe, 0x5e, 0x02, 0xf2, 0x28, 0x4e, 0xbd, + 0x24, 0x3e, 0xa7, 0xe1, 0x1b, 0x08, 0xf6, 0x14, 0x8e, 0xc6, 0xc6, 0xcd, 0x2d, 0x54, 0xb5, 0xfd, + 0xfa, 0x55, 0x91, 0xf1, 0xd5, 0xbc, 0x9f, 0x01, 0x60, 0x39, 0x2a, 0x58, 0x49, 0xef, 0x9b, 0x09, + 0x96, 0xbf, 0x12, 0x8b, 0x8e, 0x8d, 0xf4, 0x9d, 0x3d, 0x34, 0xe9, 0xce, 0xdc, 0xcc, 0xbc, 0xe7, + 0xee, 0xea, 0xbd, 0xd1, 0xeb, 0xba, 0x9a, 0xa1, 0xb5, 0xb7, 0x49, 0xc6, 0x70, 0xbc, 0xe7, 0xfd, + 0xdc, 0xe6, 0x54, 0xb3, 0xe2, 0x91, 0x3c, 0x05, 0xe2, 0x8b, 0xc0, 0xe5, 0x73, 0x7f, 0x1a, 0x73, + 0x1e, 0xb3, 0x54, 0x3e, 0x77, 0xb8, 0xbd, 0xc5, 0x98, 0xeb, 0x8f, 0xe6, 0xa2, 0x63, 0x0f, 0x73, + 0xfc, 0x57, 0x74, 0xe9, 0x1c, 0xf8, 0x22, 0x58, 0xb3, 0x90, 0x2f, 0x61, 0x07, 0x65, 0xc0, 0xad, + 0xae, 0x74, 0x3b, 0x9b, 0x3b, 0x85, 0xba, 0x5d, 0xd5, 0xc6, 0x51, 0xfe, 0xcd, 0x7f, 0x2d, 0x38, + 0x40, 0x08, 0x76, 0x62, 0x48, 0xbd, 0x84, 0x86, 0xc4, 0x81, 0xea, 0xc2, 0x4b, 0xe2, 0xd0, 0x13, + 0x2c, 0x73, 0x39, 0x15, 0x35, 0x0b, 0xf7, 0xf7, 0xc1, 0xe6, 0x1e, 0x3c, 0x33, 0x70, 0x39, 0xa7, + 0xbd, 0x84, 0x4b, 0xd6, 0xfb, 0x79, 0x8c, 0x21, 0x15, 0xe4, 0x21, 0x1c, 0xa8, 0x91, 0x2b, 0x28, + 0xf3, 0x1a, 0xd3, 0x76, 0x73, 0x96, 0x93, 0x43, 0x7d, 0x9e, 0xc0, 0x61, 0x31, 0xcc, 0xc2, 0x4b, + 0x90, 0x60, 0xe9, 0xfa, 0x48, 0x07, 0xab, 0x48, 0xcf, 0xbc, 0x64, 0x48, 0x45, 0xf3, 0xd7, 0x6d, + 0xb8, 0xb3, 0xa1, 0x3d, 0x64, 0x08, 0x35, 0x95, 0x27, 0x38, 0xbf, 0xb2, 0x24, 0xd6, 0xf5, 0xc9, + 0x8e, 0xd0, 0xb9, 0x7f, 0xbe, 0xb6, 0x26, 0xe4, 0x47, 0x20, 0x45, 0xf2, 0x1c, 0xbb, 0xad, 0xbb, + 0xf0, 0xe1, 0x35, 0x12, 0x16, 0xf4, 0x29, 0x96, 0xa2, 0x15, 0xfb, 0xc5, 0x2c, 0xb4, 0x8e, 0x2c, + 0x87, 0x45, 0x08, 0x1a, 0xea, 0x97, 0xf7, 0xfe, 0xe6, 0x49, 0x1b, 0x65, 0x5e, 0xca, 0xbd, 0x40, + 0xc4, 0x4c, 0xcd, 0xc5, 0x61, 0x21, 0xb6, 0x89, 0xd2, 0xfc, 0x19, 0x6e, 0xf5, 0x46, 0x7d, 0xec, + 0xce, 0x90, 0x4e, 0xa6, 0x34, 0x15, 0x64, 0x00, 0x15, 0x39, 0xd8, 0xe6, 0x85, 0x57, 0x13, 0xd2, + 0x2a, 0xe6, 0x29, 0xfe, 0xc0, 0x2e, 0x3a, 0x76, 0x6f, 0xd4, 0x37, 0xdd, 0x18, 0x33, 0x07, 0x7c, + 0x11, 0xe8, 0xd7, 0xae, 0xf7, 0xfd, 0x9f, 0x17, 0x75, 0xeb, 0xe5, 0x45, 0xdd, 0xfa, 0xe7, 0xa2, + 0x6e, 0xbd, 0xb8, 0xac, 0x6f, 0xbd, 0xbc, 0xac, 0x6f, 0xfd, 0x75, 0x59, 0xdf, 0xfa, 0xe9, 0xd3, + 0x49, 0x2c, 0xa2, 0xb9, 0x6f, 0x07, 0x6c, 0xda, 0xd6, 0x91, 0x13, 0xcf, 0xe7, 0x0f, 0x62, 0x66, + 0x8e, 0xed, 0xb3, 0x57, 0xfe, 0x41, 0x12, 0xcb, 0x19, 0xe5, 0xfe, 0x2e, 0xfe, 0xaa, 0x7e, 0xfc, + 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xc7, 0xfb, 0xb5, 0x46, 0x09, 0x00, 0x00, } func (m *IndexedHeader) Marshal() (dAtA []byte, err error) { @@ -769,10 +769,10 @@ func (m *IndexedHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintZoneconcierge(dAtA, i, uint64(len(m.ChainId))) + if len(m.ConsumerId) > 0 { + i -= len(m.ConsumerId) + copy(dAtA[i:], m.ConsumerId) + i = encodeVarintZoneconcierge(dAtA, i, uint64(len(m.ConsumerId))) i-- dAtA[i] = 0xa } @@ -865,10 +865,10 @@ func (m *ChainInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintZoneconcierge(dAtA, i, uint64(len(m.ChainId))) + if len(m.ConsumerId) > 0 { + i -= len(m.ConsumerId) + copy(dAtA[i:], m.ConsumerId) + i = encodeVarintZoneconcierge(dAtA, i, uint64(len(m.ConsumerId))) i-- dAtA[i] = 0xa } @@ -1002,10 +1002,10 @@ func (m *FinalizedChainInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintZoneconcierge(dAtA, i, uint64(len(m.ChainId))) + if len(m.ConsumerId) > 0 { + i -= len(m.ConsumerId) + copy(dAtA[i:], m.ConsumerId) + i = encodeVarintZoneconcierge(dAtA, i, uint64(len(m.ConsumerId))) i-- dAtA[i] = 0xa } @@ -1188,7 +1188,7 @@ func (m *IndexedHeader) Size() (n int) { } var l int _ = l - l = len(m.ChainId) + l = len(m.ConsumerId) if l > 0 { n += 1 + l + sovZoneconcierge(uint64(l)) } @@ -1241,7 +1241,7 @@ func (m *ChainInfo) Size() (n int) { } var l int _ = l - l = len(m.ChainId) + l = len(m.ConsumerId) if l > 0 { n += 1 + l + sovZoneconcierge(uint64(l)) } @@ -1282,7 +1282,7 @@ func (m *FinalizedChainInfo) Size() (n int) { } var l int _ = l - l = len(m.ChainId) + l = len(m.ConsumerId) if l > 0 { n += 1 + l + sovZoneconcierge(uint64(l)) } @@ -1407,7 +1407,7 @@ func (m *IndexedHeader) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1435,7 +1435,7 @@ func (m *IndexedHeader) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ConsumerId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -1768,7 +1768,7 @@ func (m *ChainInfo) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1796,7 +1796,7 @@ func (m *ChainInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ConsumerId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -2063,7 +2063,7 @@ func (m *FinalizedChainInfo) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2091,7 +2091,7 @@ func (m *FinalizedChainInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ConsumerId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 {