From 0df1525c40905f760639a8022fab87ede2b12889 Mon Sep 17 00:00:00 2001 From: WayToFuture Date: Mon, 20 Mar 2023 15:47:59 +0800 Subject: [PATCH 01/10] feat: add challenger address to validators (#129) --- go.mod | 2 +- go.sum | 4 +- proto/cosmos/staking/v1beta1/staking.proto | 8 +- proto/cosmos/staking/v1beta1/tx.proto | 12 +- simapp/simd/cmd/testnet.go | 2 +- simapp/test_helpers.go | 1 + testutil/network/network.go | 2 +- x/genutil/client/cli/gentx.go | 15 +- x/genutil/client/testutil/suite.go | 4 + x/genutil/gentx_test.go | 6 +- x/genutil/types/genesis_state_test.go | 8 +- x/gov/abci_test.go | 4 +- x/oracle/keeper/keeper.go | 6 +- x/oracle/keeper/keeper_test.go | 8 +- x/slashing/app_test.go | 2 +- x/staking/app_test.go | 4 +- x/staking/client/cli/flags.go | 18 +- x/staking/client/cli/tx.go | 29 +- x/staking/client/testutil/create_validator.go | 116 +- x/staking/keeper/genesis.go | 3 +- x/staking/keeper/msg_server.go | 65 +- x/staking/keeper/validator.go | 56 +- x/staking/simulation/operations.go | 4 +- x/staking/teststaking/helper.go | 4 +- x/staking/types/errors.go | 15 +- x/staking/types/events.go | 3 +- x/staking/types/exported.go | 3 +- x/staking/types/keys.go | 25 +- x/staking/types/msg.go | 24 +- x/staking/types/msg_test.go | 8 +- x/staking/types/staking.pb.go | 1237 +++++++++-------- x/staking/types/tx.pb.go | 247 ++-- x/staking/types/validator.go | 48 +- 33 files changed, 1151 insertions(+), 842 deletions(-) diff --git a/go.mod b/go.mod index f5ea4b631f..80707ef32b 100644 --- a/go.mod +++ b/go.mod @@ -185,7 +185,7 @@ replace ( github.com/jhump/protoreflect => github.com/jhump/protoreflect v1.9.0 - github.com/tendermint/tendermint => github.com/bnb-chain/greenfield-tendermint v0.0.2 + github.com/tendermint/tendermint => github.com/bnb-chain/greenfield-tendermint v0.0.3 ) retract v0.46.2 diff --git a/go.sum b/go.sum index 25053b5efb..4fa4f355a3 100644 --- a/go.sum +++ b/go.sum @@ -157,8 +157,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/bnb-chain/greenfield-tendermint v0.0.2 h1:SNb3C9QhYklaLgY6onimLHR42IlB6NQJvQqwmj/1ybM= -github.com/bnb-chain/greenfield-tendermint v0.0.2/go.mod h1:/v9z9F6cq0+f7EGG92lYSLBcPYQDILoK91X8YM28hWo= +github.com/bnb-chain/greenfield-tendermint v0.0.3 h1:oWD58n7U5phHpVyfnezhg6WBxITRQpRwOWOhKDQ/kVE= +github.com/bnb-chain/greenfield-tendermint v0.0.3/go.mod h1:/v9z9F6cq0+f7EGG92lYSLBcPYQDILoK91X8YM28hWo= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= diff --git a/proto/cosmos/staking/v1beta1/staking.proto b/proto/cosmos/staking/v1beta1/staking.proto index 5db5884850..c62722f102 100644 --- a/proto/cosmos/staking/v1beta1/staking.proto +++ b/proto/cosmos/staking/v1beta1/staking.proto @@ -127,10 +127,12 @@ message Validator { // self_del_address defines the address of the validator for self delegation. string self_del_address = 12 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - // relayer_address defines the address of the validator's authorized relayer/operator;. + // relayer_address defines the address of the validator's authorized relayer;. string relayer_address = 13 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - // relayer_bls_key defines the bls pubkey of the validator's authorized relayer/operator; - bytes relayer_bls_key = 14; + // challenger_address defines the address of the validator's authorized challenger;. + string challenger_address = 14 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // bls_key defines the bls pubkey of the validator's authorized relayer/challenger/operator; + bytes bls_key = 15; } // BondStatus is the status of a validator. diff --git a/proto/cosmos/staking/v1beta1/tx.proto b/proto/cosmos/staking/v1beta1/tx.proto index 8bbb201758..7cc331ac59 100644 --- a/proto/cosmos/staking/v1beta1/tx.proto +++ b/proto/cosmos/staking/v1beta1/tx.proto @@ -60,9 +60,10 @@ message MsgCreateValidator { google.protobuf.Any pubkey = 6 [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey"]; cosmos.base.v1beta1.Coin value = 7 [(gogoproto.nullable) = false]; - string from = 8 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - string relayer_address = 9 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - string relayer_bls_key = 10; + string from = 8 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string relayer_address = 9 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string challenger_address = 10 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string bls_key = 11; } // MsgCreateValidatorResponse defines the Msg/CreateValidator response type. @@ -87,8 +88,9 @@ message MsgEditValidator { string min_self_delegation = 4 [(cosmos_proto.scalar) = "cosmos.Int", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int"]; - string relayer_address = 5 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - string relayer_bls_key = 6; // The BLS pubkey for the authorized relayer + string relayer_address = 5 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string challenger_address = 6 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string bls_key = 7; // The BLS pubkey for the authorized relayer/challenger } // MsgEditValidatorResponse defines the Msg/EditValidator response type. diff --git a/simapp/simd/cmd/testnet.go b/simapp/simd/cmd/testnet.go index 1725c5c2e5..9c5d7a2c4d 100644 --- a/simapp/simd/cmd/testnet.go +++ b/simapp/simd/cmd/testnet.go @@ -299,7 +299,7 @@ func initTestnetFiles( stakingtypes.NewDescription(nodeDirName, "", "", "", ""), stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()), sdk.OneInt(), - addr, addr, addr, blsPk, + addr, addr, addr, addr, blsPk, ) if err != nil { return err diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index bb5a092fd3..34806f87d0 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -172,6 +172,7 @@ func genesisStateWithValSet(t *testing.T, validator := stakingtypes.Validator{ OperatorAddress: sdk.AccAddress(val.Address).String(), RelayerAddress: sdk.AccAddress(val.Address).String(), + ChallengerAddress: sdk.AccAddress(val.Address).String(), ConsensusPubkey: pkAny, Jailed: false, Status: stakingtypes.Bonded, diff --git a/testutil/network/network.go b/testutil/network/network.go index ebf5caca5a..18fc0c41c9 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -416,7 +416,7 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) { stakingtypes.NewDescription(nodeDirName, "", "", "", ""), stakingtypes.NewCommissionRates(commission, sdk.OneDec(), sdk.OneDec()), sdk.OneInt(), - addr, addr, addr, blsPubKey, + addr, addr, addr, addr, blsPubKey, ) if err != nil { return nil, err diff --git a/x/genutil/client/cli/gentx.go b/x/genutil/client/cli/gentx.go index 32792099e0..4c959c07f1 100644 --- a/x/genutil/client/cli/gentx.go +++ b/x/genutil/client/cli/gentx.go @@ -34,9 +34,9 @@ func GenTxCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfig, genBalI fsCreateValidator, defaultsDesc := cli.CreateValidatorMsgFlagSet(ipDefault) cmd := &cobra.Command{ - Use: "gentx [key_name] [amount] [validator] [relayer] [relayer_blskey]", + Use: "gentx [key_name] [amount] [validator] [relayer] [challenger] [blskey]", Short: "Generate a genesis tx carrying a self delegation", - Args: cobra.ExactArgs(5), + Args: cobra.ExactArgs(6), Long: fmt.Sprintf(`Generate a genesis transaction that creates a validator with a self-delegation, that is signed by the key in the Keyring referenced by a given name. A node ID and consensus pubkey may optionally be provided. If they are omitted, they will be retrieved from the priv_validator.json @@ -162,15 +162,20 @@ $ %s gentx my-key-name 1000000stake \ if err != nil { return err } - blsPk := args[4] + challenger, err := sdk.AccAddressFromHexUnsafe(args[4]) + if err != nil { + return err + } + blsPk := args[5] if len(blsPk) != 2*sdk.BLSPubKeyLength { - return errors.New("invalid relayer bls pubkey") + return errors.New("invalid bls pubkey") } createValCfg.Validator = validator createValCfg.Delegator = addr createValCfg.Relayer = relayer - createValCfg.RelayerBlsKey = blsPk + createValCfg.Challenger = challenger + createValCfg.BlsKey = blsPk // create a 'create-validator' message txBldr, msg, err := cli.BuildCreateValidatorMsg(clientCtx, createValCfg, txFactory, true) diff --git a/x/genutil/client/testutil/suite.go b/x/genutil/client/testutil/suite.go index 63641063be..c29421cbe2 100644 --- a/x/genutil/client/testutil/suite.go +++ b/x/genutil/client/testutil/suite.go @@ -69,6 +69,7 @@ func (s *IntegrationTestSuite) TestGenTxCmd() { amount.String(), val.Address.String(), val.Address.String(), + val.Address.String(), blsPk, }, expError: true, @@ -81,6 +82,7 @@ func (s *IntegrationTestSuite) TestGenTxCmd() { amount.String(), val.Address.String(), val.Address.String(), + val.Address.String(), blsPk, }, expError: false, @@ -94,6 +96,7 @@ func (s *IntegrationTestSuite) TestGenTxCmd() { amount.String(), val.Address.String(), val.Address.String(), + val.Address.String(), blsPk, }, expError: true, @@ -107,6 +110,7 @@ func (s *IntegrationTestSuite) TestGenTxCmd() { amount.String(), val.Address.String(), val.Address.String(), + val.Address.String(), blsPk, }, expError: false, diff --git a/x/genutil/gentx_test.go b/x/genutil/gentx_test.go index 2c90600bdf..c09cdacbe5 100644 --- a/x/genutil/gentx_test.go +++ b/x/genutil/gentx_test.go @@ -61,12 +61,14 @@ func (suite *GenTxTestSuite) SetupTest() { suite.msg1, err = stakingtypes.NewMsgCreateValidator( sdk.AccAddress(pk1.Address()), pk1, amount, desc, comm, one, - sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk) + sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), + sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk) suite.NoError(err) suite.msg2, err = stakingtypes.NewMsgCreateValidator( sdk.AccAddress(pk2.Address()), pk1, amount, desc, comm, one, - sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), blsPk) + sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), + sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk1.Address()), blsPk) suite.NoError(err) } diff --git a/x/genutil/types/genesis_state_test.go b/x/genutil/types/genesis_state_test.go index 879e3af262..9b53383dd4 100644 --- a/x/genutil/types/genesis_state_test.go +++ b/x/genutil/types/genesis_state_test.go @@ -44,7 +44,8 @@ func TestValidateGenesisMultipleMessages(t *testing.T) { msg1, err := stakingtypes.NewMsgCreateValidator( sdk.AccAddress(pk1.Address()), pk1, sdk.NewInt64Coin(sdk.DefaultBondDenom, 50), desc, comm, sdk.OneInt(), - sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk1) + sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), + sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk1) require.NoError(t, err) blsSecretKey2, _ := bls.RandKey() @@ -52,7 +53,8 @@ func TestValidateGenesisMultipleMessages(t *testing.T) { msg2, err := stakingtypes.NewMsgCreateValidator( sdk.AccAddress(pk2.Address()), pk2, sdk.NewInt64Coin(sdk.DefaultBondDenom, 50), desc, comm, sdk.OneInt(), - sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), blsPk2) + sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), + sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), blsPk2) require.NoError(t, err) txGen := simapp.MakeTestEncodingConfig().TxConfig @@ -73,7 +75,7 @@ func TestValidateGenesisBadMessage(t *testing.T) { msg1 := stakingtypes.NewMsgEditValidator( sdk.AccAddress(pk1.Address()), desc, nil, nil, - sdk.AccAddress(pk1.Address()), blsPk, + sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk, ) txGen := simapp.MakeTestEncodingConfig().TxConfig diff --git a/x/gov/abci_test.go b/x/gov/abci_test.go index 20cddf3576..fe7f41f2fe 100644 --- a/x/gov/abci_test.go +++ b/x/gov/abci_test.go @@ -381,8 +381,8 @@ func createValidators(t *testing.T, stakingMsgSvr stakingtypes.MsgServer, ctx sd valCreateMsg, err := stakingtypes.NewMsgCreateValidator( addrs[i], pubkeys[i], sdk.NewCoin(sdk.DefaultBondDenom, valTokens), TestDescription, TestCommissionRates, sdk.OneInt(), - sdk.AccAddress(addrs[i]), sdk.AccAddress(addrs[i]), sdk.AccAddress(addrs[i]), blsPk, - ) + sdk.AccAddress(addrs[i]), sdk.AccAddress(addrs[i]), + sdk.AccAddress(addrs[i]), sdk.AccAddress(addrs[i]), blsPk) require.NoError(t, err) res, err := stakingMsgSvr.CreateValidator(sdk.WrapSDKContext(ctx), valCreateMsg) require.NoError(t, err) diff --git a/x/oracle/keeper/keeper.go b/x/oracle/keeper/keeper.go index c11b703cb4..8d53373099 100644 --- a/x/oracle/keeper/keeper.go +++ b/x/oracle/keeper/keeper.go @@ -107,7 +107,7 @@ func (k Keeper) IsRelayerValid(ctx sdk.Context, relayer sdk.AccAddress, validato return false, err } - if inturnRelayer.BlsPubKey == hex.EncodeToString(vldr.RelayerBlsKey) { + if inturnRelayer.BlsPubKey == hex.EncodeToString(vldr.BlsKey) { return true, nil } @@ -153,7 +153,7 @@ func (k Keeper) CheckClaim(ctx sdk.Context, claim *types.MsgClaim) (sdk.AccAddre signedRelayers = append(signedRelayers, val.RelayerAddress) - votePubKey, err := bls.PublicKeyFromBytes(val.RelayerBlsKey) + votePubKey, err := bls.PublicKeyFromBytes(val.BlsKey) if err != nil { return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrBlsPubKey, fmt.Sprintf("BLS public key converts failed: %v", err)) } @@ -208,7 +208,7 @@ func (k Keeper) GetInturnRelayer(ctx sdk.Context, relayerInterval uint64) (*type inturnRelayer := validators[inTurnRelayerIndex] res := &types.QueryInturnRelayerResponse{ - BlsPubKey: hex.EncodeToString(inturnRelayer.RelayerBlsKey), + BlsPubKey: hex.EncodeToString(inturnRelayer.BlsKey), RelayInterval: &types.RelayInterval{ Start: start, End: end, diff --git a/x/oracle/keeper/keeper_test.go b/x/oracle/keeper/keeper_test.go index 1665f85f84..b93467075c 100644 --- a/x/oracle/keeper/keeper_test.go +++ b/x/oracle/keeper/keeper_test.go @@ -162,7 +162,7 @@ func (s *TestSuite) TestKeeper_IsRelayerValid() { val := newValidator(s.T(), sdk.AccAddress(pk.Address()), pk) privKey, _ := blst.RandKey() - val.RelayerBlsKey = privKey.PublicKey().Marshal() + val.BlsKey = privKey.PublicKey().Marshal() vals[i] = val } @@ -279,13 +279,13 @@ func createValidators(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers blsKeys := []bls.SecretKey{privKey1, privKey2, privKey3} val1 := teststaking.NewValidator(t, valAddrs[0], pks[0]) - val1.RelayerBlsKey = privKey1.PublicKey().Marshal() + val1.BlsKey = privKey1.PublicKey().Marshal() val2 := teststaking.NewValidator(t, valAddrs[1], pks[1]) - val2.RelayerBlsKey = privKey2.PublicKey().Marshal() + val2.BlsKey = privKey2.PublicKey().Marshal() val3 := teststaking.NewValidator(t, valAddrs[2], pks[2]) - val3.RelayerBlsKey = privKey3.PublicKey().Marshal() + val3.BlsKey = privKey3.PublicKey().Marshal() vals := []stakingtypes.Validator{val1, val2, val3} diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index a2c835b758..cf587a771b 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -71,7 +71,7 @@ func TestSlashingMsgs(t *testing.T) { createValidatorMsg, err := stakingtypes.NewMsgCreateValidator( addr1, valKey.PubKey(), bondCoin, description, commission, sdk.OneInt(), - addr1, addr1, addr1, blsPk, + addr1, addr1, addr1, addr1, blsPk, ) require.NoError(t, err) diff --git a/x/staking/app_test.go b/x/staking/app_test.go index 69a75daeea..c887c04243 100644 --- a/x/staking/app_test.go +++ b/x/staking/app_test.go @@ -72,7 +72,7 @@ func TestStakingMsgs(t *testing.T) { createValidatorMsg, err := types.NewMsgCreateValidator( addr1, valKey.PubKey(), bondCoin, description, commissionRates, sdk.OneInt(), - addr1, addr1, addr1, blsPubKey, + addr1, addr1, addr1, addr1, blsPubKey, ) require.NoError(t, err) @@ -97,7 +97,7 @@ func TestStakingMsgs(t *testing.T) { description = types.NewDescription("bar_moniker", "", "", "", "") editValidatorMsg := types.NewMsgEditValidator( addr1, description, nil, nil, - sdk.AccAddress(""), "", + sdk.AccAddress(""), sdk.AccAddress(""), "", ) header = tmproto.Header{ChainID: simapp.DefaultChainId, Height: app.LastBlockHeight() + 1} diff --git a/x/staking/client/cli/flags.go b/x/staking/client/cli/flags.go index 20c9cb12dc..0ad647e94d 100644 --- a/x/staking/client/cli/flags.go +++ b/x/staking/client/cli/flags.go @@ -32,8 +32,9 @@ const ( FlagNodeID = "node-id" FlagIP = "ip" - FlagAddressRelayer = "addr-relayer" - FlagBlsKeyRelayer = "bls-key-relayer" + FlagAddressRelayer = "addr-relayer" + FlagAddressChallenger = "addr-challenger" + FlagBlsKey = "bls-key" ) // common flagsets to add to various functions @@ -90,10 +91,17 @@ func FlagSetRelayerAddress() *flag.FlagSet { return fs } -// FlagSetRelayerBlsKey Returns the flagset for relayer bls pubkey related operations. -func FlagSetRelayerBlsKey() *flag.FlagSet { +// FlagSetBlsKey Returns the flagset for bls pubkey related operations. +func FlagSetBlsKey() *flag.FlagSet { fs := flag.NewFlagSet("", flag.ContinueOnError) - fs.String(FlagBlsKeyRelayer, "", "The relayer bls pubkey of the validator") + fs.String(FlagBlsKey, "", "The bls pubkey of the validator") + return fs +} + +// FlagSetChallengerAddress Returns the flagset for challenger address related operations. +func FlagSetChallengerAddress() *flag.FlagSet { + fs := flag.NewFlagSet("", flag.ContinueOnError) + fs.String(FlagAddressChallenger, "", "The challenger address of the validator") return fs } diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 78214b862e..90402d74a6 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -69,6 +69,7 @@ func NewEditValidatorCmd() *cobra.Command { details, _ := cmd.Flags().GetString(FlagDetails) description := types.NewDescription(moniker, identity, website, security, details) relayer := sdk.AccAddress("") + challenger := sdk.AccAddress("") var newRate *sdk.Dec @@ -95,7 +96,6 @@ func NewEditValidatorCmd() *cobra.Command { } relayerAddr, _ := cmd.Flags().GetString(FlagAddressRelayer) - blsPk, _ := cmd.Flags().GetString(FlagBlsKeyRelayer) if relayerAddr != "" { relayer, err = sdk.AccAddressFromHexUnsafe(relayerAddr) if err != nil { @@ -103,9 +103,19 @@ func NewEditValidatorCmd() *cobra.Command { } } + challengerAddr, _ := cmd.Flags().GetString(FlagAddressChallenger) + if challengerAddr != "" { + challenger, err = sdk.AccAddressFromHexUnsafe(challengerAddr) + if err != nil { + return fmt.Errorf("invalid challenger address: %v", err) + } + } + + blsPk, _ := cmd.Flags().GetString(FlagBlsKey) + msg := types.NewMsgEditValidator( valAddr, description, newRate, newMinSelfDelegation, - relayer, blsPk, + relayer, challenger, blsPk, ) return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) @@ -116,7 +126,8 @@ func NewEditValidatorCmd() *cobra.Command { cmd.Flags().AddFlagSet(flagSetCommissionUpdate()) cmd.Flags().AddFlagSet(FlagSetMinSelfDelegation()) cmd.Flags().AddFlagSet(FlagSetRelayerAddress()) - cmd.Flags().AddFlagSet(FlagSetRelayerBlsKey()) + cmd.Flags().AddFlagSet(FlagSetChallengerAddress()) + cmd.Flags().AddFlagSet(FlagSetBlsKey()) flags.AddTxFlagsToCmd(cmd) return cmd @@ -359,10 +370,11 @@ type TxCreateValidatorConfig struct { Details string Identity string - Validator sdk.AccAddress - Delegator sdk.AccAddress - Relayer sdk.AccAddress - RelayerBlsKey string + Validator sdk.AccAddress + Delegator sdk.AccAddress + Relayer sdk.AccAddress + Challenger sdk.AccAddress + BlsKey string } func PrepareConfigForTxCreateValidator(flagSet *flag.FlagSet, moniker, nodeID, chainID string, valPubKey cryptotypes.PubKey) (TxCreateValidatorConfig, error) { @@ -497,8 +509,7 @@ func BuildCreateValidatorMsg(clientCtx client.Context, config TxCreateValidatorC msg, err := types.NewMsgCreateValidator( config.Validator, config.PubKey, amount, description, commissionRates, minSelfDelegation, - from, config.Delegator, config.Relayer, config.RelayerBlsKey, - ) + from, config.Delegator, config.Relayer, config.Challenger, config.BlsKey) if err != nil { return txBldr, msg, err } diff --git a/x/staking/client/testutil/create_validator.go b/x/staking/client/testutil/create_validator.go index bc64a8fc54..a2d066c21c 100644 --- a/x/staking/client/testutil/create_validator.go +++ b/x/staking/client/testutil/create_validator.go @@ -29,54 +29,69 @@ import ( ) type testParams struct { - discription string - proposalID string - enableGrant bool - from string - relayerAddress string - relayerBlsKey string + description string + proposalID string + enableGrant bool + from string + relayerAddress string + challengerAddress string + blsKey string } var testcases = []testParams{ { - discription: "crate success", - proposalID: "1", - enableGrant: true, - from: "0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2", - relayerAddress: "0x8b70dC9B691fCeB4e1c69dF8cbF8c077AD4b5853", - relayerBlsKey: "926f1853304b482634d1ca8ef9652524228202d2a3ca376f3e5ab040430c42703f9de038a41917f944cf4e653cbed45a", + description: "crate success", + proposalID: "1", + enableGrant: true, + from: "0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2", + relayerAddress: "0x8b70dC9B691fCeB4e1c69dF8cbF8c077AD4b5853", + challengerAddress: "0xD1d6bF74282782B0b3eb1413c901D6eCF02e8e28", + blsKey: "926f1853304b482634d1ca8ef9652524228202d2a3ca376f3e5ab040430c42703f9de038a41917f944cf4e653cbed45a", }, { - discription: "no grant delegate authorization to gov module account", - proposalID: "2", - enableGrant: false, - from: "0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2", - relayerAddress: "0x36B810C7E246b1c042335bAF1933Da71C5B5AeC5", - relayerBlsKey: "a4c392f233e140b124c35a509d8880c52bd9bc3d13042fec3d84c1d55cc4d5be30fe3003d096bc33bc924af563a8de9f", + description: "no grant delegate authorization to gov module account", + proposalID: "2", + enableGrant: false, + from: "0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2", + relayerAddress: "0x36B810C7E246b1c042335bAF1933Da71C5B5AeC5", + challengerAddress: "0x95CD3fB2037847780fA454DA719e6a01F43D4E2f", + blsKey: "a4c392f233e140b124c35a509d8880c52bd9bc3d13042fec3d84c1d55cc4d5be30fe3003d096bc33bc924af563a8de9f", }, { - discription: "duplicated relayer address", - proposalID: "3", - enableGrant: true, - from: "0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2", - relayerAddress: "0x8b70dC9B691fCeB4e1c69dF8cbF8c077AD4b5853", - relayerBlsKey: "819a55435aed37ff4f917d3644c74da1f6354c0d4fbc7ca425ebe6b98a0416fc4ef5eb13fceffb3a109eec4af12bba0a", + description: "duplicated relayer address", + proposalID: "3", + enableGrant: true, + from: "0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2", + relayerAddress: "0x8b70dC9B691fCeB4e1c69dF8cbF8c077AD4b5853", + challengerAddress: "0x95CD3fB2037847780fA454DA719e6a01F43D4E2f", + blsKey: "819a55435aed37ff4f917d3644c74da1f6354c0d4fbc7ca425ebe6b98a0416fc4ef5eb13fceffb3a109eec4af12bba0a", }, { - discription: "duplicated relayer bls pub key", - proposalID: "4", - enableGrant: true, - from: "0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2", - relayerAddress: "0x9E6de7BF11C459E8dA3a5f36c1A87A6FfaDCbA9d", - relayerBlsKey: "926f1853304b482634d1ca8ef9652524228202d2a3ca376f3e5ab040430c42703f9de038a41917f944cf4e653cbed45a", + description: "duplicated bls pub key", + proposalID: "4", + enableGrant: true, + from: "0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2", + relayerAddress: "0x9E6de7BF11C459E8dA3a5f36c1A87A6FfaDCbA9d", + challengerAddress: "0x95CD3fB2037847780fA454DA719e6a01F43D4E2f", + blsKey: "926f1853304b482634d1ca8ef9652524228202d2a3ca376f3e5ab040430c42703f9de038a41917f944cf4e653cbed45a", }, { - discription: "invalid from", - proposalID: "5", - enableGrant: true, - from: "0x8b70dC9B691fCeB4e1c69dF8cbF8c077AD4b5853", - relayerAddress: "0x73Fd0b049bBF30b3A165e5b2eAf9895B015A2515", - relayerBlsKey: "b700697ccca38c0d56cde325571dc5412de99a0fa2c28eeb1078cb4eeaa31c238720bee9cce47422e986a7af4f3b19c8", + description: "duplicated challenger address", + proposalID: "5", + enableGrant: true, + from: "0x7b5Fe22B5446f7C62Ea27B8BD71CeF94e03f3dF2", + relayerAddress: "0x8b70dC9B691fCeB4e1c69dF8cbF8c077AD4b5853", + challengerAddress: "0xD1d6bF74282782B0b3eb1413c901D6eCF02e8e28", + blsKey: "819a55435aed37ff4f917d3644c74da1f6354c0d4fbc7ca425ebe6b98a0416fc4ef5eb13fceffb3a109eec4af12bba0a", + }, + { + description: "invalid from", + proposalID: "6", + enableGrant: true, + from: "0x8b70dC9B691fCeB4e1c69dF8cbF8c077AD4b5853", + relayerAddress: "0x73Fd0b049bBF30b3A165e5b2eAf9895B015A2515", + challengerAddress: "0x95CD3fB2037847780fA454DA719e6a01F43D4E2f", + blsKey: "b700697ccca38c0d56cde325571dc5412de99a0fa2c28eeb1078cb4eeaa31c238720bee9cce47422e986a7af4f3b19c8", }, } @@ -181,7 +196,7 @@ func (s *CreateValidatorTestSuite) TestQueryDuplicatedRelayerAddress() { s.Require().Equal(v1.ProposalStatus_PROPOSAL_STATUS_FAILED, proposal.Status, out.String()) } -func (s *CreateValidatorTestSuite) TestQueryDuplicatedRelayerBlsKey() { +func (s *CreateValidatorTestSuite) TestQueryDuplicatedBlsKey() { clientCtx := s.network.Validators[0].ClientCtx proposalID := s.proposalIDs[3] @@ -194,10 +209,23 @@ func (s *CreateValidatorTestSuite) TestQueryDuplicatedRelayerBlsKey() { s.Require().Equal(v1.ProposalStatus_PROPOSAL_STATUS_FAILED, proposal.Status, out.String()) } -func (s *CreateValidatorTestSuite) TestQueryInvalidFromAddress() { +func (s *CreateValidatorTestSuite) TestQueryDuplicatedChallengerAddress() { clientCtx := s.network.Validators[0].ClientCtx proposalID := s.proposalIDs[4] + // query proposal + args := []string{proposalID, fmt.Sprintf("--%s=json", tmcli.OutputFlag)} + out, err := clitestutil.ExecTestCLICmd(clientCtx, govcli.GetCmdQueryProposal(), args) + s.Require().NoError(err) + var proposal v1.Proposal + s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &proposal), out.String()) + s.Require().Equal(v1.ProposalStatus_PROPOSAL_STATUS_FAILED, proposal.Status, out.String()) +} + +func (s *CreateValidatorTestSuite) TestQueryInvalidFromAddress() { + clientCtx := s.network.Validators[0].ClientCtx + proposalID := s.proposalIDs[5] + // query proposal, should not be found because of invalid from the proposal will be rejected. args := []string{proposalID, fmt.Sprintf("--%s=json", tmcli.OutputFlag)} _, err := clitestutil.ExecTestCLICmd(clientCtx, govcli.GetCmdQueryProposal(), args) @@ -246,7 +274,7 @@ func (s *CreateValidatorTestSuite) submitProposal(params testParams) sdk.AccAddr } args := append([]string{ - s.createValidatorProposal(newVal, params.from, params.relayerAddress, params.relayerBlsKey).Name(), + s.createValidatorProposal(newVal, params.from, params.relayerAddress, params.challengerAddress, params.blsKey).Name(), fmt.Sprintf("--%s=%s", flags.FlagFrom, newVal.String()), fmt.Sprintf("--gas=%s", fmt.Sprintf("%d", flags.DefaultGasLimit+100000)), }, commonArgs...) @@ -270,7 +298,9 @@ func (s *CreateValidatorTestSuite) voteProposal(proposalID string) { s.Require().NoError(err) } -func (s *CreateValidatorTestSuite) createValidatorProposal(valAddr sdk.AccAddress, from string, relayerAddress string, relayerBlsKey string) *os.File { +func (s *CreateValidatorTestSuite) createValidatorProposal(valAddr sdk.AccAddress, from string, + relayerAddress string, challengerAddress string, blsKey string, +) *os.File { pubKey := base64.StdEncoding.EncodeToString(ed25519.GenPrivKey().PubKey().Bytes()) propMetadata := []byte{42} proposal := fmt.Sprintf(` @@ -303,7 +333,8 @@ func (s *CreateValidatorTestSuite) createValidatorProposal(valAddr sdk.AccAddres }, "from":"%s", "relayer_address":"%s", - "relayer_bls_key":"%s" + "challenger_address":"%s", + "bls_key":"%s" } ], "metadata": "%s", @@ -314,7 +345,8 @@ func (s *CreateValidatorTestSuite) createValidatorProposal(valAddr sdk.AccAddres pubKey, from, relayerAddress, - relayerBlsKey, + challengerAddress, + blsKey, base64.StdEncoding.EncodeToString(propMetadata), sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens), ) diff --git a/x/staking/keeper/genesis.go b/x/staking/keeper/genesis.go index 7d3da39f1c..58d015218f 100644 --- a/x/staking/keeper/genesis.go +++ b/x/staking/keeper/genesis.go @@ -34,7 +34,8 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) (res []ab // Manually set indices for the first time k.SetValidatorByConsAddr(ctx, validator) k.SetValidatorByRelayerAddress(ctx, validator) - k.SetValidatorByRelayerBlsKey(ctx, validator) + k.SetValidatorByChallengerAddress(ctx, validator) + k.SetValidatorByBlsKey(ctx, validator) k.SetValidatorByPowerIndex(ctx, validator) // Call the creation hook if not exported diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index c68b3c1b0f..76ac0f7678 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -88,13 +88,22 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa return nil, types.ErrValidatorRelayerAddressExists } - // check to see if the relayer bls pubkey has been registered before - blsPk, err := hex.DecodeString(msg.RelayerBlsKey) + // check to see if the challenger address has been registered before + challengerAddr, err := sdk.AccAddressFromHexUnsafe(msg.ChallengerAddress) + if err != nil { + return nil, err + } + if _, found := k.GetValidatorByChallengerAddr(ctx, challengerAddr); found { + return nil, types.ErrValidatorChallengerAddressExists + } + + // check to see if the bls pubkey has been registered before + blsPk, err := hex.DecodeString(msg.BlsKey) if err != nil || len(blsPk) != sdk.BLSPubKeyLength { - return nil, types.ErrValidatorRelayerInvalidBlsKey + return nil, types.ErrValidatorInvalidBlsKey } - if _, found := k.GetValidatorByRelayerBlsKey(ctx, blsPk); found { - return nil, types.ErrValidatorRelayerBlsKeyExists + if _, found := k.GetValidatorByBlsKey(ctx, blsPk); found { + return nil, types.ErrValidatorBlsKeyExists } bondDenom := k.BondDenom(ctx) @@ -126,7 +135,7 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa } } - validator, err := types.NewValidator(valAddr, pk, msg.Description, delAddr, relayerAddr, blsPk) + validator, err := types.NewValidator(valAddr, pk, msg.Description, delAddr, relayerAddr, challengerAddr, blsPk) if err != nil { return nil, err } @@ -149,7 +158,8 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa k.SetValidator(ctx, validator) k.SetValidatorByRelayerAddress(ctx, validator) - k.SetValidatorByRelayerBlsKey(ctx, validator) + k.SetValidatorByChallengerAddress(ctx, validator) + k.SetValidatorByBlsKey(ctx, validator) k.SetValidatorByConsAddr(ctx, validator) k.SetNewValidatorByPowerIndex(ctx, validator) @@ -186,7 +196,8 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa sdk.NewAttribute(types.AttributeKeyValidator, msg.ValidatorAddress), sdk.NewAttribute(types.AttributeKeySelfDelAddress, validator.SelfDelAddress), sdk.NewAttribute(types.AttributeKeyRelayerAddress, validator.RelayerAddress), - sdk.NewAttribute(types.AttributeKeyRelayerBlsKey, string(validator.RelayerBlsKey)), + sdk.NewAttribute(types.AttributeKeyChallengerAddress, validator.ChallengerAddress), + sdk.NewAttribute(types.AttributeKeyBlsKey, string(validator.BlsKey)), sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Value.String()), ), sdk.NewEvent( @@ -263,20 +274,37 @@ func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValida } } - // replace relayer bls pubkey - if len(msg.RelayerBlsKey) != 0 { - blsPk, err := hex.DecodeString(msg.RelayerBlsKey) + // replace challenger address + if len(msg.ChallengerAddress) != 0 { + challengerAddr, err := sdk.AccAddressFromHexUnsafe(msg.ChallengerAddress) + if err != nil { + return nil, err + } + if tmpValidator, found := k.GetValidatorByChallengerAddr(ctx, challengerAddr); found { + if tmpValidator.OperatorAddress != validator.OperatorAddress { + return nil, types.ErrValidatorChallengerAddressExists + } + } else { + k.DeleteValidatorByChallengerAddress(ctx, validator) + validator.ChallengerAddress = challengerAddr.String() + k.SetValidatorByChallengerAddress(ctx, validator) + } + } + + // replace bls pubkey + if len(msg.BlsKey) != 0 { + blsPk, err := hex.DecodeString(msg.BlsKey) if err != nil || len(blsPk) != sdk.BLSPubKeyLength { - return nil, types.ErrValidatorRelayerInvalidBlsKey + return nil, types.ErrValidatorInvalidBlsKey } - if tmpValidator, found := k.GetValidatorByRelayerBlsKey(ctx, blsPk); found { + if tmpValidator, found := k.GetValidatorByBlsKey(ctx, blsPk); found { if tmpValidator.OperatorAddress != validator.OperatorAddress { - return nil, types.ErrValidatorRelayerBlsKeyExists + return nil, types.ErrValidatorBlsKeyExists } } else { - k.DeleteValidatorByRelayerBlsKey(ctx, validator) - validator.RelayerBlsKey = blsPk - k.SetValidatorByRelayerBlsKey(ctx, validator) + k.DeleteValidatorByBlsKey(ctx, validator) + validator.BlsKey = blsPk + k.SetValidatorByBlsKey(ctx, validator) } } @@ -288,7 +316,8 @@ func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValida sdk.NewAttribute(types.AttributeKeyCommissionRate, validator.Commission.String()), sdk.NewAttribute(types.AttributeKeyMinSelfDelegation, validator.MinSelfDelegation.String()), sdk.NewAttribute(types.AttributeKeyRelayerAddress, validator.RelayerAddress), - sdk.NewAttribute(types.AttributeKeyRelayerBlsKey, string(validator.RelayerBlsKey)), + sdk.NewAttribute(types.AttributeKeyChallengerAddress, validator.ChallengerAddress), + sdk.NewAttribute(types.AttributeKeyBlsKey, string(validator.BlsKey)), ), sdk.NewEvent( sdk.EventTypeMessage, diff --git a/x/staking/keeper/validator.go b/x/staking/keeper/validator.go index f201de1473..9317e62b04 100644 --- a/x/staking/keeper/validator.go +++ b/x/staking/keeper/validator.go @@ -57,11 +57,23 @@ func (k Keeper) GetValidatorByRelayerAddr(ctx sdk.Context, relayerAddr sdk.AccAd return k.GetValidator(ctx, opAddr) } -// get a single validator by relayer bls pubkey -func (k Keeper) GetValidatorByRelayerBlsKey(ctx sdk.Context, blsPk []byte) (validator types.Validator, found bool) { +// get a single validator by bls pubkey +func (k Keeper) GetValidatorByBlsKey(ctx sdk.Context, blsPk []byte) (validator types.Validator, found bool) { store := ctx.KVStore(k.storeKey) - opAddr := store.Get(types.GetValidatorByRelayerBlsKey(blsPk)) + opAddr := store.Get(types.GetValidatorByBlsKey(blsPk)) + if opAddr == nil { + return validator, false + } + + return k.GetValidator(ctx, opAddr) +} + +// GetValidatorByChallengerAddr gets a single validator by challenger address +func (k Keeper) GetValidatorByChallengerAddr(ctx sdk.Context, challengerAddr sdk.AccAddress) (validator types.Validator, found bool) { + store := ctx.KVStore(k.storeKey) + + opAddr := store.Get(types.GetValidatorByChallengerAddrKey(challengerAddr)) if opAddr == nil { return validator, false } @@ -87,32 +99,47 @@ func (k Keeper) SetValidator(ctx sdk.Context, validator types.Validator) { // validator index func (k Keeper) SetValidatorByRelayerAddress(ctx sdk.Context, validator types.Validator) error { - blsPk := validator.GetRelayer() + relayer := validator.GetRelayer() store := ctx.KVStore(k.storeKey) - store.Set(types.GetValidatorByRelayerAddrKey(blsPk), validator.GetOperator()) + store.Set(types.GetValidatorByRelayerAddrKey(relayer), validator.GetOperator()) return nil } // validator index func (k Keeper) DeleteValidatorByRelayerAddress(ctx sdk.Context, validator types.Validator) { - blsPk := validator.GetRelayer() + relayer := validator.GetRelayer() + store := ctx.KVStore(k.storeKey) + store.Delete(types.GetValidatorByRelayerAddrKey(relayer)) +} + +// validator index +func (k Keeper) SetValidatorByChallengerAddress(ctx sdk.Context, validator types.Validator) error { + challenger := validator.GetChallenger() + store := ctx.KVStore(k.storeKey) + store.Set(types.GetValidatorByChallengerAddrKey(challenger), validator.GetOperator()) + return nil +} + +// validator index +func (k Keeper) DeleteValidatorByChallengerAddress(ctx sdk.Context, validator types.Validator) { + challenger := validator.GetChallenger() store := ctx.KVStore(k.storeKey) - store.Delete(types.GetValidatorByRelayerAddrKey(blsPk)) + store.Delete(types.GetValidatorByChallengerAddrKey(challenger)) } // validator index -func (k Keeper) SetValidatorByRelayerBlsKey(ctx sdk.Context, validator types.Validator) error { - blsPk := validator.GetRelayerBlsKey() +func (k Keeper) SetValidatorByBlsKey(ctx sdk.Context, validator types.Validator) error { + blsPk := validator.GetBlsKey() store := ctx.KVStore(k.storeKey) - store.Set(types.GetValidatorByRelayerBlsKey(blsPk), validator.GetOperator()) + store.Set(types.GetValidatorByBlsKey(blsPk), validator.GetOperator()) return nil } // validator index -func (k Keeper) DeleteValidatorByRelayerBlsKey(ctx sdk.Context, validator types.Validator) { - blsPk := validator.GetRelayerBlsKey() +func (k Keeper) DeleteValidatorByBlsKey(ctx sdk.Context, validator types.Validator) { + blsPk := validator.GetBlsKey() store := ctx.KVStore(k.storeKey) - store.Delete(types.GetValidatorByRelayerBlsKey(blsPk)) + store.Delete(types.GetValidatorByBlsKey(blsPk)) } // validator index @@ -234,7 +261,8 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.AccAddress) { store := ctx.KVStore(k.storeKey) store.Delete(types.GetValidatorKey(address)) store.Delete(types.GetValidatorByRelayerAddrKey(validator.GetRelayer())) - store.Delete(types.GetValidatorByRelayerBlsKey(validator.RelayerBlsKey)) + store.Delete(types.GetValidatorByChallengerAddrKey(validator.GetChallenger())) + store.Delete(types.GetValidatorByBlsKey(validator.BlsKey)) store.Delete(types.GetValidatorByConsAddrKey(valConsAddr)) store.Delete(types.GetValidatorsByPowerIndexKey(validator, k.PowerReduction(ctx))) diff --git a/x/staking/simulation/operations.go b/x/staking/simulation/operations.go index a8052bbf90..096c6c6207 100644 --- a/x/staking/simulation/operations.go +++ b/x/staking/simulation/operations.go @@ -155,7 +155,7 @@ func SimulateMsgCreateValidator(ak types.AccountKeeper, bk types.BankKeeper, k k msg, err := types.NewMsgCreateValidator( address, simAccount.ConsKey.PubKey(), selfDelegation, description, commission, sdk.OneInt(), - address, address, address, blsPk, + address, address, address, address, blsPk, ) if err != nil { return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to create CreateValidator message"), nil, err @@ -217,7 +217,7 @@ func SimulateMsgEditValidator(ak types.AccountKeeper, bk types.BankKeeper, k kee simtypes.RandStringOfLength(r, 10), ) - msg := types.NewMsgEditValidator(address, description, &newCommissionRate, nil, address, "") + msg := types.NewMsgEditValidator(address, description, &newCommissionRate, nil, address, address, "") txCtx := simulation.OperationInput{ R: r, diff --git a/x/staking/teststaking/helper.go b/x/staking/teststaking/helper.go index d09e032310..eaf7f90abf 100644 --- a/x/staking/teststaking/helper.go +++ b/x/staking/teststaking/helper.go @@ -58,7 +58,7 @@ func (sh *Helper) CreateValidatorMsg(addr sdk.AccAddress, pk cryptotypes.PubKey, msg, err := stakingtypes.NewMsgCreateValidator( addr, pk, coin, stakingtypes.Description{}, sh.Commission, sdk.OneInt(), - addr, addr, addr, blsPk, + addr, addr, addr, addr, blsPk, ) require.NoError(sh.t, err) return msg @@ -75,7 +75,7 @@ func (sh *Helper) createValidator(addr sdk.AccAddress, pk cryptotypes.PubKey, co msg, err := stakingtypes.NewMsgCreateValidator( addr, pk, coin, stakingtypes.Description{}, sh.Commission, sdk.OneInt(), - addr, addr, addr, blsPk, + addr, addr, addr, addr, blsPk, ) require.NoError(sh.t, err) res, err := sh.msgSrvr.CreateValidator(sdk.WrapSDKContext(sh.Ctx.WithBlockHeight(0)), msg) diff --git a/x/staking/types/errors.go b/x/staking/types/errors.go index e400d0e440..9a62074d4b 100644 --- a/x/staking/types/errors.go +++ b/x/staking/types/errors.go @@ -51,11 +51,12 @@ var ( ErrEmptyValidatorPubKey = sdkerrors.Register(ModuleName, 39, "empty validator public key") ErrCommissionLTMinRate = sdkerrors.Register(ModuleName, 40, "commission cannot be less than min rate") - ErrValidatorRelayerAddressExists = sdkerrors.Register(ModuleName, 41, "validator already exist for this relayer address; must use new relayer address") - ErrValidatorRelayerInvalidBlsKey = sdkerrors.Register(ModuleName, 42, "validator relayer bls pubkey is invalid") - ErrValidatorRelayerBlsKeyExists = sdkerrors.Register(ModuleName, 43, "validator already exist for this relayer bls pubkey; must use new bls pubkey") - ErrDelegationNotAllowed = sdkerrors.Register(ModuleName, 44, "delegation is not allowed") - ErrRedelegationNotAllowed = sdkerrors.Register(ModuleName, 45, "redelegation is not allowed") - ErrInvalidSigner = sdkerrors.Register(ModuleName, 46, "invalid signer") - ErrInvalidMinSelfDelegation = sdkerrors.Register(ModuleName, 47, "invalid minimum self delegation, must no less than the chain level minimum self delegation") + ErrValidatorRelayerAddressExists = sdkerrors.Register(ModuleName, 41, "validator already exist for this relayer address; must use new relayer address") + ErrValidatorChallengerAddressExists = sdkerrors.Register(ModuleName, 42, "validator already exist for this challenger address; must use new relayer address") + ErrValidatorInvalidBlsKey = sdkerrors.Register(ModuleName, 43, "validator bls pubkey is invalid") + ErrValidatorBlsKeyExists = sdkerrors.Register(ModuleName, 44, "validator already exist for this bls pubkey; must use new bls pubkey") + ErrDelegationNotAllowed = sdkerrors.Register(ModuleName, 45, "delegation is not allowed") + ErrRedelegationNotAllowed = sdkerrors.Register(ModuleName, 46, "redelegation is not allowed") + ErrInvalidSigner = sdkerrors.Register(ModuleName, 47, "invalid signer") + ErrInvalidMinSelfDelegation = sdkerrors.Register(ModuleName, 48, "invalid minimum self delegation, must no less than the chain level minimum self delegation") ) diff --git a/x/staking/types/events.go b/x/staking/types/events.go index 386eeec0e6..bc108faef6 100644 --- a/x/staking/types/events.go +++ b/x/staking/types/events.go @@ -16,7 +16,8 @@ const ( AttributeKeyMinSelfDelegation = "min_self_delegation" AttributeKeySelfDelAddress = "self_del_address" AttributeKeyRelayerAddress = "relayer_address" - AttributeKeyRelayerBlsKey = "relayer_bls_key" + AttributeKeyChallengerAddress = "challenger_address" + AttributeKeyBlsKey = "bls_key" AttributeKeySrcValidator = "source_validator" AttributeKeyDstValidator = "destination_validator" AttributeKeyDelegator = "delegator" diff --git a/x/staking/types/exported.go b/x/staking/types/exported.go index 6d21f536ca..f2f163828f 100644 --- a/x/staking/types/exported.go +++ b/x/staking/types/exported.go @@ -26,7 +26,8 @@ type ValidatorI interface { GetOperator() sdk.AccAddress // operator address to receive/return validators coins GetSelfDelegator() sdk.AccAddress // validator address used for self delegation GetRelayer() sdk.AccAddress // validator authorized relayer/operator address - GetRelayerBlsKey() []byte // validator authorized relayer/operator's bls pubkey + GetChallenger() sdk.AccAddress // validator authorized challenger/operator address + GetBlsKey() []byte // validator authorized relayer/challenger's bls pubkey ConsPubKey() (cryptotypes.PubKey, error) // validation consensus pubkey (cryptotypes.PubKey) TmConsPublicKey() (tmprotocrypto.PublicKey, error) // validation consensus pubkey (Tendermint) GetConsAddr() (sdk.ConsAddress, error) // validation consensus address diff --git a/x/staking/types/keys.go b/x/staking/types/keys.go index 03e494e219..01ebbf8cc6 100644 --- a/x/staking/types/keys.go +++ b/x/staking/types/keys.go @@ -33,11 +33,12 @@ var ( LastValidatorPowerKey = []byte{0x11} // prefix for each key to a validator index, for bonded validators LastTotalPowerKey = []byte{0x12} // prefix for the total power - ValidatorsKey = []byte{0x21} // prefix for each key to a validator - ValidatorsByConsAddrKey = []byte{0x22} // prefix for each key to a validator index, by pubkey - ValidatorsByPowerIndexKey = []byte{0x23} // prefix for each key to a validator index, sorted by power - ValidatorsByRelayerAddrKey = []byte{0x24} // prefix for each key to a validator index, by relayer address - ValidatorsByRelayerBlsKey = []byte{0x25} // prefix for each key to a validator index, by relayer's bls pubkey + ValidatorsKey = []byte{0x21} // prefix for each key to a validator + ValidatorsByConsAddrKey = []byte{0x22} // prefix for each key to a validator index, by pubkey + ValidatorsByPowerIndexKey = []byte{0x23} // prefix for each key to a validator index, sorted by power + ValidatorsByRelayerAddrKey = []byte{0x24} // prefix for each key to a validator index, by relayer address + ValidatorsByChallengerAddrKey = []byte{0x25} // prefix for each key to a validator index, by challenger address + ValidatorsByBlsKey = []byte{0x26} // prefix for each key to a validator index, by relayer/challenger's bls pubkey DelegationKey = []byte{0x31} // key for a delegation UnbondingDelegationKey = []byte{0x32} // key for an unbonding-delegation @@ -66,15 +67,21 @@ func GetValidatorByConsAddrKey(addr sdk.ConsAddress) []byte { } // GetValidatorByRelayerAddrKey creates the key for the validator with relayer address -// VALUE: validator operator address ([]byte) +// VALUE: validator relayer address ([]byte) func GetValidatorByRelayerAddrKey(relayerAddr sdk.AccAddress) []byte { return append(ValidatorsByRelayerAddrKey, address.MustLengthPrefix(relayerAddr)...) } -// GetValidatorByRelayerBlsKey creates the key for the validator with bls pubkey +// GetValidatorByChallengerAddrKey creates the key for the validator with challenger address +// VALUE: validator challenger address ([]byte) +func GetValidatorByChallengerAddrKey(challengerAddr sdk.AccAddress) []byte { + return append(ValidatorsByChallengerAddrKey, address.MustLengthPrefix(challengerAddr)...) +} + +// GetValidatorByBlsKey creates the key for the validator with bls pubkey // VALUE: validator operator address ([]byte) -func GetValidatorByRelayerBlsKey(blsPk []byte) []byte { - return append(ValidatorsByRelayerBlsKey, address.MustLengthPrefix(blsPk)...) +func GetValidatorByBlsKey(blsPk []byte) []byte { + return append(ValidatorsByBlsKey, address.MustLengthPrefix(blsPk)...) } // AddressFromValidatorsKey creates the validator operator address from ValidatorsKey diff --git a/x/staking/types/msg.go b/x/staking/types/msg.go index e4fb44b6d3..50d50fc0cb 100644 --- a/x/staking/types/msg.go +++ b/x/staking/types/msg.go @@ -34,7 +34,7 @@ var ( func NewMsgCreateValidator( valAddr sdk.AccAddress, pubKey cryptotypes.PubKey, //nolint:interfacer selfDelegation sdk.Coin, description Description, commission CommissionRates, minSelfDelegation math.Int, - from sdk.AccAddress, selfDelAddr sdk.AccAddress, relayerAddr sdk.AccAddress, relayerBlsKey string, + from sdk.AccAddress, selfDelAddr sdk.AccAddress, relayerAddr sdk.AccAddress, challengerAddr sdk.AccAddress, blsKey string, ) (*MsgCreateValidator, error) { var pkAny *codectypes.Any if pubKey != nil { @@ -53,7 +53,8 @@ func NewMsgCreateValidator( MinSelfDelegation: minSelfDelegation, From: from.String(), RelayerAddress: relayerAddr.String(), - RelayerBlsKey: relayerBlsKey, + ChallengerAddress: challengerAddr.String(), + BlsKey: blsKey, }, nil } @@ -91,13 +92,16 @@ func (msg MsgCreateValidator) ValidateBasic() error { if _, err := sdk.AccAddressFromHexUnsafe(msg.RelayerAddress); err != nil { return sdkerrors.ErrInvalidAddress.Wrapf("invalid relayer address: %s", err) } + if _, err := sdk.AccAddressFromHexUnsafe(msg.ChallengerAddress); err != nil { + return sdkerrors.ErrInvalidAddress.Wrapf("invalid challenger address: %s", err) + } if msg.Pubkey == nil { return ErrEmptyValidatorPubKey } - if len(msg.RelayerBlsKey) != 2*sdk.BLSPubKeyLength { - return ErrValidatorRelayerInvalidBlsKey + if len(msg.BlsKey) != 2*sdk.BLSPubKeyLength { + return ErrValidatorInvalidBlsKey } if !msg.Value.IsValid() || !msg.Value.Amount.IsPositive() { @@ -141,7 +145,7 @@ func (msg MsgCreateValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) //nolint:interfacer func NewMsgEditValidator( valAddr sdk.AccAddress, description Description, newRate *sdk.Dec, newMinSelfDelegation *math.Int, - newRelayerAddr sdk.AccAddress, newRelayerBlsKey string, + newRelayerAddr sdk.AccAddress, newChallengerAddr sdk.AccAddress, newBlsKey string, ) *MsgEditValidator { return &MsgEditValidator{ Description: description, @@ -149,7 +153,8 @@ func NewMsgEditValidator( ValidatorAddress: valAddr.String(), MinSelfDelegation: newMinSelfDelegation, RelayerAddress: newRelayerAddr.String(), - RelayerBlsKey: newRelayerBlsKey, + ChallengerAddress: newChallengerAddr.String(), + BlsKey: newBlsKey, } } @@ -184,6 +189,13 @@ func (msg MsgEditValidator) ValidateBasic() error { } } + if len(msg.ChallengerAddress) != 0 { + _, err := sdk.AccAddressFromHexUnsafe(msg.ChallengerAddress) + if err != nil { + return sdkerrors.ErrInvalidAddress.Wrapf("invalid challenger address: %s", err) + } + } + if msg.Description == (Description{}) { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description") } diff --git a/x/staking/types/msg_test.go b/x/staking/types/msg_test.go index 0b77897218..2f1c63cee7 100644 --- a/x/staking/types/msg_test.go +++ b/x/staking/types/msg_test.go @@ -43,7 +43,8 @@ func TestMsgDecode(t *testing.T) { msg, err := types.NewMsgCreateValidator( valAddr1, pk1, coinPos, types.Description{}, commission1, sdk.OneInt(), - sdk.AccAddress(valAddr1), sdk.AccAddress(valAddr1), sdk.AccAddress(valAddr1), blsPk, + sdk.AccAddress(valAddr1), sdk.AccAddress(valAddr1), + sdk.AccAddress(valAddr1), sdk.AccAddress(valAddr1), blsPk, ) require.NoError(t, err) msgSerialized, err := cdc.MarshalInterface(msg) @@ -91,7 +92,8 @@ func TestMsgCreateValidator(t *testing.T) { msg, err := types.NewMsgCreateValidator( tc.validatorAddr, tc.pubkey, tc.bond, description, tc.CommissionRates, tc.minSelfDelegation, - sdk.AccAddress(tc.validatorAddr), sdk.AccAddress(tc.validatorAddr), sdk.AccAddress(tc.validatorAddr), blsPk, + sdk.AccAddress(tc.validatorAddr), sdk.AccAddress(tc.validatorAddr), + sdk.AccAddress(tc.validatorAddr), sdk.AccAddress(tc.validatorAddr), blsPk, ) require.NoError(t, err) if tc.expectPass { @@ -125,7 +127,7 @@ func TestMsgEditValidator(t *testing.T) { msg := types.NewMsgEditValidator( tc.validatorAddr, description, &newRate, &tc.minSelfDelegation, - sdk.AccAddress(tc.validatorAddr), blsPk) + sdk.AccAddress(tc.validatorAddr), sdk.AccAddress(tc.validatorAddr), blsPk) if tc.expectPass { require.Nil(t, msg.ValidateBasic(), "test: %v", tc.name) } else { diff --git a/x/staking/types/staking.pb.go b/x/staking/types/staking.pb.go index 778746091b..41e32a7a76 100644 --- a/x/staking/types/staking.pb.go +++ b/x/staking/types/staking.pb.go @@ -338,10 +338,12 @@ type Validator struct { MinSelfDelegation github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,11,opt,name=min_self_delegation,json=minSelfDelegation,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"min_self_delegation"` // self_del_address defines the address of the validator for self delegation. SelfDelAddress string `protobuf:"bytes,12,opt,name=self_del_address,json=selfDelAddress,proto3" json:"self_del_address,omitempty"` - // relayer_address defines the address of the validator's authorized relayer/operator;. + // relayer_address defines the address of the validator's authorized relayer;. RelayerAddress string `protobuf:"bytes,13,opt,name=relayer_address,json=relayerAddress,proto3" json:"relayer_address,omitempty"` - // relayer_bls_key defines the bls pubkey of the validator's authorized relayer/operator; - RelayerBlsKey []byte `protobuf:"bytes,14,opt,name=relayer_bls_key,json=relayerBlsKey,proto3" json:"relayer_bls_key,omitempty"` + // challenger_address defines the address of the validator's authorized challenger;. + ChallengerAddress string `protobuf:"bytes,14,opt,name=challenger_address,json=challengerAddress,proto3" json:"challenger_address,omitempty"` + // bls_key defines the bls pubkey of the validator's authorized relayer/challenger/operator; + BlsKey []byte `protobuf:"bytes,15,opt,name=bls_key,json=blsKey,proto3" json:"bls_key,omitempty"` } func (m *Validator) Reset() { *m = Validator{} } @@ -1150,116 +1152,117 @@ func init() { } var fileDescriptor_64c30c6cf92913c9 = []byte{ - // 1734 bytes of a gzipped FileDescriptorProto + // 1750 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0x4d, 0x6c, 0x1b, 0xc7, - 0x15, 0xe6, 0x52, 0x0c, 0x45, 0x3d, 0x4a, 0xa4, 0x34, 0x56, 0x52, 0x9a, 0x68, 0x49, 0x96, 0x4d, - 0x1d, 0xa5, 0x88, 0xa9, 0x5a, 0x05, 0x02, 0x54, 0x28, 0x50, 0x98, 0x22, 0x53, 0xab, 0x4e, 0x5c, - 0x66, 0x29, 0xab, 0xe8, 0x0f, 0xba, 0x18, 0xee, 0x8e, 0xa8, 0xa9, 0xf6, 0x87, 0xd8, 0x19, 0xba, - 0x22, 0xd0, 0x02, 0x05, 0x7a, 0x49, 0x7d, 0xca, 0x31, 0x17, 0x03, 0x06, 0xd2, 0x63, 0x8e, 0x41, - 0x2f, 0x3d, 0xf4, 0x1a, 0xe4, 0x64, 0xe4, 0xd4, 0xb4, 0x85, 0x1a, 0xd8, 0x97, 0xa2, 0xa7, 0xa2, - 0xa7, 0x5e, 0x5a, 0x04, 0xf3, 0xb3, 0x3f, 0x26, 0x45, 0x59, 0x0a, 0x14, 0x20, 0x40, 0x2e, 0x12, - 0x67, 0xe6, 0xbd, 0x6f, 0xde, 0xfb, 0xe6, 0xbd, 0x37, 0xf3, 0x16, 0x5e, 0xb4, 0x03, 0xe6, 0x05, - 0x6c, 0x93, 0x71, 0x7c, 0x44, 0xfd, 0xe1, 0xe6, 0xbd, 0x1b, 0x03, 0xc2, 0xf1, 0x8d, 0x68, 0xdc, - 0x1a, 0x85, 0x01, 0x0f, 0xd0, 0x0b, 0x4a, 0xaa, 0x15, 0xcd, 0x6a, 0xa9, 0xea, 0xfa, 0x30, 0x18, - 0x06, 0x52, 0x64, 0x53, 0xfc, 0x52, 0xd2, 0xd5, 0xab, 0xc3, 0x20, 0x18, 0xba, 0x64, 0x53, 0x8e, - 0x06, 0xe3, 0x83, 0x4d, 0xec, 0x4f, 0xf4, 0x52, 0x6d, 0x7a, 0xc9, 0x19, 0x87, 0x98, 0xd3, 0xc0, - 0xd7, 0xeb, 0xf5, 0xe9, 0x75, 0x4e, 0x3d, 0xc2, 0x38, 0xf6, 0x46, 0x11, 0xb6, 0xb2, 0xc4, 0x52, - 0x9b, 0x6a, 0xb3, 0x34, 0xb6, 0x76, 0x65, 0x80, 0x19, 0x89, 0xfd, 0xb0, 0x03, 0x1a, 0x61, 0x7f, - 0x95, 0x13, 0xdf, 0x21, 0xa1, 0x47, 0x7d, 0xbe, 0xc9, 0x27, 0x23, 0xc2, 0xd4, 0x5f, 0xb5, 0xda, - 0xfc, 0xbd, 0x01, 0xa5, 0x5b, 0x94, 0xf1, 0x20, 0xa4, 0x36, 0x76, 0x77, 0xfd, 0x83, 0x00, 0xbd, - 0x0a, 0xf9, 0x43, 0x82, 0x1d, 0x12, 0x56, 0x8c, 0x86, 0xb1, 0x51, 0xdc, 0xaa, 0xb4, 0x12, 0x84, - 0x96, 0xd2, 0xbd, 0x25, 0xd7, 0xdb, 0xb9, 0x0f, 0x4e, 0xea, 0x19, 0x53, 0x4b, 0xa3, 0xef, 0x43, - 0xfe, 0x1e, 0x76, 0x19, 0xe1, 0x95, 0x6c, 0x63, 0x61, 0xa3, 0xb8, 0xf5, 0xf5, 0xd6, 0xe9, 0xf4, - 0xb5, 0xf6, 0xb1, 0x4b, 0x1d, 0xcc, 0x83, 0x18, 0x40, 0xa9, 0x35, 0xdf, 0xcb, 0x42, 0x79, 0x27, - 0xf0, 0x3c, 0xca, 0x18, 0x0d, 0x7c, 0x13, 0x73, 0xc2, 0x50, 0x0f, 0x72, 0x21, 0xe6, 0x44, 0x9a, - 0xb2, 0xd4, 0xfe, 0x9e, 0x90, 0xff, 0xeb, 0x49, 0xfd, 0xda, 0x90, 0xf2, 0xc3, 0xf1, 0xa0, 0x65, - 0x07, 0x9e, 0x26, 0x43, 0xff, 0xbb, 0xce, 0x9c, 0x23, 0xed, 0x5f, 0x87, 0xd8, 0x1f, 0xbd, 0x7f, - 0x1d, 0xb4, 0x0d, 0x1d, 0x62, 0x9b, 0x12, 0x09, 0xfd, 0x18, 0x0a, 0x1e, 0x3e, 0xb6, 0x24, 0x6a, - 0xf6, 0x12, 0x50, 0x17, 0x3d, 0x7c, 0x2c, 0x6c, 0x45, 0x0e, 0x94, 0x05, 0xb0, 0x7d, 0x88, 0xfd, - 0x21, 0x51, 0xf8, 0x0b, 0x97, 0x80, 0xbf, 0xe2, 0xe1, 0xe3, 0x1d, 0x89, 0x29, 0x76, 0xd9, 0x2e, - 0xbc, 0xf3, 0xb0, 0x9e, 0xf9, 0xe7, 0xc3, 0xba, 0xd1, 0xfc, 0x93, 0x01, 0x90, 0xd0, 0x85, 0x7e, - 0x0e, 0xab, 0x76, 0x3c, 0x92, 0xdb, 0x33, 0x7d, 0x80, 0x2f, 0xcd, 0x3b, 0x88, 0x29, 0xb2, 0xdb, - 0x05, 0x61, 0xe8, 0xa3, 0x93, 0xba, 0x61, 0x96, 0xed, 0xa9, 0x73, 0xe8, 0x42, 0x71, 0x3c, 0x72, - 0x30, 0x27, 0x96, 0x08, 0x4d, 0x49, 0x5c, 0x71, 0xab, 0xda, 0x52, 0x71, 0xdb, 0x8a, 0xe2, 0xb6, - 0xb5, 0x17, 0xc5, 0xad, 0xc2, 0x7a, 0xfb, 0x1f, 0x75, 0xc3, 0x04, 0xa5, 0x28, 0x96, 0x52, 0xd6, - 0xbf, 0x67, 0x40, 0xb1, 0x43, 0x98, 0x1d, 0xd2, 0x91, 0x48, 0x04, 0x54, 0x81, 0x45, 0x2f, 0xf0, - 0xe9, 0x91, 0x0e, 0xbb, 0x25, 0x33, 0x1a, 0xa2, 0x2a, 0x14, 0xa8, 0x43, 0x7c, 0x4e, 0xf9, 0x44, - 0x1d, 0x98, 0x19, 0x8f, 0x85, 0xd6, 0xaf, 0xc8, 0x80, 0xd1, 0x88, 0x6b, 0x33, 0x1a, 0xa2, 0x97, - 0x61, 0x95, 0x11, 0x7b, 0x1c, 0x52, 0x3e, 0xb1, 0xec, 0xc0, 0xe7, 0xd8, 0xe6, 0x95, 0x9c, 0x14, - 0x29, 0x47, 0xf3, 0x3b, 0x6a, 0x5a, 0x80, 0x38, 0x84, 0x63, 0xea, 0xb2, 0xca, 0x73, 0x0a, 0x44, - 0x0f, 0x53, 0xe6, 0xfe, 0x77, 0x11, 0x96, 0xe2, 0xb8, 0x45, 0x3b, 0xb0, 0x1a, 0x8c, 0x48, 0x28, - 0x7e, 0x5b, 0xd8, 0x71, 0x42, 0xc2, 0x98, 0x8e, 0xd0, 0xca, 0x47, 0xef, 0x5f, 0x5f, 0xd7, 0x74, - 0xdf, 0x54, 0x2b, 0x7d, 0x1e, 0x52, 0x7f, 0x68, 0x96, 0x23, 0x0d, 0x3d, 0x8d, 0x7e, 0x22, 0x0e, - 0xcc, 0x67, 0xc4, 0x67, 0x63, 0x66, 0x8d, 0xc6, 0x83, 0x23, 0x32, 0xd1, 0xbc, 0xae, 0xcf, 0xf0, - 0x7a, 0xd3, 0x9f, 0xb4, 0x2b, 0x1f, 0x26, 0xd0, 0x76, 0x38, 0x19, 0xf1, 0xa0, 0xd5, 0x1b, 0x0f, - 0x6e, 0x93, 0x89, 0x38, 0x2d, 0x8d, 0xd3, 0x93, 0x30, 0xe8, 0x05, 0xc8, 0xff, 0x12, 0x53, 0x97, - 0x38, 0x92, 0x95, 0x82, 0xa9, 0x47, 0x68, 0x1b, 0xf2, 0x8c, 0x63, 0x3e, 0x66, 0x92, 0x8a, 0xd2, - 0x56, 0x73, 0x5e, 0x64, 0xb4, 0x03, 0xdf, 0xe9, 0x4b, 0x49, 0x53, 0x6b, 0xa0, 0x3d, 0xc8, 0xf3, - 0xe0, 0x88, 0xf8, 0x9a, 0xa4, 0x0b, 0x45, 0xf5, 0xae, 0xcf, 0x53, 0x51, 0xbd, 0xeb, 0x73, 0x53, - 0x63, 0xa1, 0x21, 0xac, 0x3a, 0xc4, 0x25, 0x43, 0x49, 0x25, 0x3b, 0xc4, 0x21, 0x61, 0x95, 0xfc, - 0x25, 0x64, 0x4d, 0x39, 0x46, 0xed, 0x4b, 0x50, 0x74, 0x1b, 0x8a, 0x4e, 0x12, 0x6e, 0x95, 0x45, - 0x49, 0xf4, 0x37, 0xe6, 0xf9, 0x9f, 0x8a, 0x4c, 0x5d, 0xa4, 0xd2, 0xda, 0x22, 0xb8, 0xc6, 0xfe, - 0x20, 0xf0, 0x1d, 0xea, 0x0f, 0xad, 0x43, 0x42, 0x87, 0x87, 0xbc, 0x52, 0x68, 0x18, 0x1b, 0x0b, - 0x66, 0x39, 0x9e, 0xbf, 0x25, 0xa7, 0xd1, 0x6d, 0x28, 0x25, 0xa2, 0x32, 0x77, 0x96, 0x2e, 0x90, - 0x3b, 0x2b, 0xb1, 0xae, 0x58, 0x45, 0xb7, 0x00, 0x92, 0xc4, 0xac, 0x80, 0x04, 0x6a, 0x3e, 0x3b, - 0xbb, 0xb5, 0x0b, 0x29, 0x5d, 0xe4, 0xc2, 0x15, 0x8f, 0xfa, 0x16, 0x23, 0xee, 0x81, 0xa5, 0xa9, - 0x12, 0x90, 0xc5, 0x4b, 0x38, 0xda, 0x35, 0x8f, 0xfa, 0x7d, 0xe2, 0x1e, 0x74, 0x62, 0x58, 0xd4, - 0x16, 0xc9, 0xa8, 0x76, 0x8a, 0xf3, 0x65, 0xf9, 0x19, 0xf9, 0x52, 0x62, 0x0a, 0x23, 0x4a, 0x97, - 0x9b, 0x50, 0x0e, 0x89, 0x8b, 0x27, 0x24, 0x49, 0xb9, 0x95, 0x67, 0x41, 0x68, 0x85, 0x08, 0xe2, - 0x5a, 0x02, 0x31, 0x70, 0x99, 0x25, 0x12, 0xae, 0xd4, 0x30, 0x36, 0x96, 0xcd, 0x15, 0x3d, 0xdd, - 0x76, 0xd9, 0x6d, 0x32, 0xd9, 0x5e, 0x7e, 0xeb, 0x61, 0x3d, 0xa3, 0x53, 0x3f, 0xd3, 0xec, 0xc1, - 0xf2, 0x3e, 0x8e, 0xcc, 0x20, 0x0c, 0xbd, 0x0a, 0x4b, 0x38, 0x1a, 0x54, 0x8c, 0xc6, 0xc2, 0x99, - 0x26, 0x24, 0xa2, 0xaa, 0x98, 0xfc, 0xf6, 0xef, 0x0d, 0xa3, 0xf9, 0x07, 0x03, 0xf2, 0x9d, 0xfd, - 0x1e, 0xa6, 0x21, 0xea, 0xc2, 0x5a, 0x12, 0xff, 0xe7, 0x2d, 0x25, 0x49, 0xca, 0x44, 0x9e, 0x75, - 0x61, 0xed, 0x5e, 0x54, 0x9d, 0x62, 0x98, 0xec, 0xb3, 0x60, 0x62, 0x15, 0x3d, 0x3f, 0xe5, 0x78, - 0x17, 0x16, 0x95, 0x95, 0x0c, 0x6d, 0xc3, 0x73, 0x23, 0xf1, 0x43, 0xfa, 0x5b, 0xdc, 0xaa, 0xcd, - 0xcd, 0x1b, 0x29, 0xaf, 0xe3, 0x4d, 0xa9, 0x34, 0xff, 0x67, 0x00, 0x74, 0xf6, 0xf7, 0xf7, 0x42, - 0x3a, 0x72, 0x09, 0xbf, 0x2c, 0x8f, 0x5f, 0x87, 0xe7, 0x13, 0x8f, 0x59, 0x68, 0x9f, 0xdb, 0xeb, - 0x2b, 0xb1, 0x5a, 0x3f, 0xb4, 0x4f, 0x45, 0x73, 0x18, 0x8f, 0xd1, 0x16, 0xce, 0x8d, 0xd6, 0x61, - 0xfc, 0x74, 0x1a, 0xfb, 0x50, 0x4c, 0xdc, 0x67, 0xa8, 0x03, 0x05, 0xae, 0x7f, 0x6b, 0x36, 0x9b, - 0xf3, 0xd9, 0x8c, 0xd4, 0x34, 0xa3, 0xb1, 0x66, 0xf3, 0xff, 0x82, 0xd4, 0x24, 0xc1, 0xbe, 0x50, - 0x61, 0x24, 0xae, 0x0a, 0x5d, 0xca, 0x2f, 0xe3, 0x01, 0xa4, 0xb1, 0xa6, 0x58, 0xfd, 0x5d, 0x16, - 0xae, 0xdc, 0x8d, 0x8a, 0xe3, 0x17, 0x96, 0x89, 0x1e, 0x2c, 0x12, 0x9f, 0x87, 0x54, 0x52, 0x21, - 0xce, 0xfa, 0xdb, 0xf3, 0xce, 0xfa, 0x14, 0x5f, 0xba, 0x3e, 0x0f, 0x27, 0xfa, 0xe4, 0x23, 0x98, - 0x29, 0x16, 0xfe, 0x96, 0x85, 0xca, 0x3c, 0x4d, 0xf4, 0x12, 0x94, 0xed, 0x90, 0xc8, 0x89, 0xe8, - 0x92, 0x32, 0xe4, 0x25, 0x55, 0x8a, 0xa6, 0xf5, 0x1d, 0xf5, 0x06, 0x88, 0xf7, 0x9e, 0x08, 0x2c, - 0x21, 0x7a, 0xe1, 0x07, 0x5e, 0x29, 0x51, 0x96, 0xb7, 0x14, 0x81, 0x32, 0xf5, 0x29, 0xa7, 0xd8, - 0xb5, 0x06, 0xd8, 0xc5, 0xbe, 0xfd, 0x59, 0x1e, 0xc2, 0xb3, 0xf7, 0x4a, 0x49, 0x83, 0xb6, 0x15, - 0x26, 0xda, 0x87, 0xc5, 0x08, 0x3e, 0x77, 0x09, 0xf0, 0x11, 0x58, 0xea, 0xd1, 0xf7, 0x71, 0x16, - 0xd6, 0x4c, 0xe2, 0x7c, 0xb9, 0x68, 0xfd, 0x19, 0x80, 0x4a, 0x38, 0x51, 0x07, 0x3f, 0x03, 0xb3, - 0xb3, 0x09, 0xbc, 0xa4, 0xf0, 0x3a, 0x8c, 0xa7, 0xb8, 0xfd, 0x30, 0x0b, 0xcb, 0x69, 0x6e, 0xbf, - 0x04, 0xf7, 0x02, 0xda, 0x4d, 0xaa, 0x41, 0x4e, 0x56, 0x83, 0x97, 0xe7, 0x55, 0x83, 0x99, 0xa8, - 0x3b, 0xbb, 0x0c, 0x7c, 0xb2, 0x00, 0xf9, 0x1e, 0x0e, 0xb1, 0xc7, 0xd0, 0x0f, 0x67, 0xde, 0x9b, - 0xaa, 0x09, 0xbc, 0x3a, 0x13, 0x73, 0x1d, 0xfd, 0x0d, 0x42, 0x85, 0xdc, 0x3b, 0xa7, 0x3c, 0x37, - 0xbf, 0x09, 0x25, 0xd1, 0xd1, 0xc6, 0xae, 0x28, 0x12, 0x57, 0x64, 0x4b, 0x1a, 0x37, 0x43, 0x0c, - 0xd5, 0xa1, 0x28, 0xc4, 0x92, 0x42, 0x27, 0x64, 0xc0, 0xc3, 0xc7, 0x5d, 0x35, 0x83, 0xae, 0x03, - 0x3a, 0x8c, 0xbf, 0x31, 0x58, 0x09, 0x05, 0x42, 0x6e, 0x2d, 0x59, 0x89, 0xc4, 0xbf, 0x06, 0x20, - 0xac, 0xb0, 0x1c, 0xe2, 0x07, 0x9e, 0x6e, 0xc9, 0x96, 0xc4, 0x4c, 0x47, 0x4c, 0xa0, 0x5f, 0xab, - 0xa7, 0xeb, 0x54, 0xb3, 0xab, 0xbb, 0x86, 0xd7, 0x2f, 0x16, 0xa9, 0xff, 0x39, 0xa9, 0x57, 0x27, - 0xd8, 0x73, 0xb7, 0x9b, 0xa7, 0x40, 0x36, 0xe5, 0x53, 0xf6, 0xe9, 0x26, 0x79, 0xde, 0xc3, 0x79, - 0xf1, 0x73, 0x79, 0x38, 0xa7, 0xf2, 0xe5, 0x5d, 0x03, 0x50, 0xb2, 0x60, 0x12, 0x36, 0x12, 0x3d, - 0x9f, 0xe8, 0x08, 0x52, 0x56, 0x18, 0x67, 0x77, 0x04, 0x89, 0x7e, 0xd4, 0x11, 0xa4, 0xf2, 0xef, - 0xbb, 0x49, 0x39, 0xcd, 0xea, 0x88, 0xd1, 0x30, 0x03, 0xcc, 0x48, 0xaa, 0xab, 0xa0, 0x91, 0xf6, - 0x4c, 0xc5, 0xcc, 0x34, 0x3f, 0x36, 0xe0, 0xea, 0x4c, 0xec, 0xc6, 0xc6, 0xfe, 0x02, 0x50, 0x98, - 0x5a, 0x94, 0x91, 0x30, 0xd1, 0x46, 0x5f, 0x38, 0x15, 0xd6, 0xc2, 0x99, 0xca, 0xfc, 0x79, 0xdd, - 0x08, 0x39, 0x79, 0x02, 0x7f, 0x36, 0x60, 0x3d, 0x6d, 0x4c, 0xec, 0xd6, 0x1d, 0x58, 0x4e, 0xdb, - 0xa2, 0x1d, 0x7a, 0xf1, 0x3c, 0x0e, 0x69, 0x5f, 0x9e, 0xd2, 0x47, 0x6f, 0x26, 0x65, 0x42, 0x7d, - 0x49, 0xbb, 0x71, 0x6e, 0x6e, 0x22, 0x9b, 0xa6, 0xcb, 0x45, 0x2e, 0x7a, 0x33, 0xe5, 0x7a, 0x41, - 0xe0, 0xa2, 0xdf, 0xc0, 0x9a, 0x1f, 0x70, 0x4b, 0xe4, 0x14, 0x71, 0x2c, 0xdd, 0xd6, 0xab, 0x5a, - 0xfb, 0xe6, 0xc5, 0x28, 0xfb, 0xd7, 0x49, 0x7d, 0x16, 0x6a, 0x8a, 0xc7, 0xb2, 0x1f, 0xf0, 0xb6, - 0x5c, 0xdf, 0x53, 0x4d, 0x7f, 0x08, 0x2b, 0x4f, 0x6f, 0xad, 0x6a, 0xf3, 0x1b, 0x17, 0xde, 0x7a, - 0xe5, 0xac, 0x6d, 0x97, 0x07, 0xa9, 0x3d, 0xb7, 0x0b, 0xe2, 0x0c, 0xff, 0xfd, 0xb0, 0x6e, 0x7c, - 0xeb, 0x8f, 0x06, 0x40, 0xf2, 0x7d, 0x03, 0xbd, 0x02, 0x5f, 0x69, 0xff, 0xe8, 0x4e, 0xc7, 0xea, - 0xef, 0xdd, 0xdc, 0xbb, 0xdb, 0xb7, 0xee, 0xde, 0xe9, 0xf7, 0xba, 0x3b, 0xbb, 0xaf, 0xed, 0x76, - 0x3b, 0xab, 0x99, 0x6a, 0xf9, 0xfe, 0x83, 0x46, 0xf1, 0xae, 0xcf, 0x46, 0xc4, 0xa6, 0x07, 0x94, - 0x38, 0xe8, 0x1a, 0xac, 0x3f, 0x2d, 0x2d, 0x46, 0xdd, 0xce, 0xaa, 0x51, 0x5d, 0xbe, 0xff, 0xa0, - 0x51, 0x50, 0x6f, 0x31, 0xe2, 0xa0, 0x0d, 0x78, 0x7e, 0x56, 0x6e, 0xf7, 0xce, 0x0f, 0x56, 0xb3, - 0xd5, 0x95, 0xfb, 0x0f, 0x1a, 0x4b, 0xf1, 0xa3, 0x0d, 0x35, 0x01, 0xa5, 0x25, 0x35, 0xde, 0x42, - 0x15, 0xee, 0x3f, 0x68, 0xe4, 0x15, 0x6d, 0xd5, 0xdc, 0x5b, 0xef, 0xd6, 0x32, 0xed, 0xd7, 0x3e, - 0x78, 0x5c, 0x33, 0x1e, 0x3d, 0xae, 0x19, 0x9f, 0x3c, 0xae, 0x19, 0x6f, 0x3f, 0xa9, 0x65, 0x1e, - 0x3d, 0xa9, 0x65, 0xfe, 0xf2, 0xa4, 0x96, 0xf9, 0xe9, 0x2b, 0x67, 0x32, 0x76, 0x1c, 0x7f, 0xe6, - 0x96, 0xdc, 0x0d, 0xf2, 0xf2, 0x0a, 0xf8, 0xce, 0xa7, 0x01, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x44, - 0xf4, 0xa2, 0x05, 0x17, 0x00, 0x00, + 0x15, 0xe6, 0x52, 0x0c, 0x45, 0x3d, 0x4a, 0xa4, 0x34, 0x56, 0x12, 0x9a, 0x68, 0x49, 0x96, 0x4d, + 0x13, 0xa5, 0x88, 0xa9, 0x5a, 0x05, 0x02, 0x54, 0x28, 0x50, 0x98, 0x22, 0x13, 0xab, 0x4e, 0x5c, + 0x86, 0x94, 0x55, 0xf4, 0x07, 0x5d, 0x0c, 0x77, 0x47, 0xe4, 0x56, 0xbb, 0xb3, 0xc4, 0xce, 0xd0, + 0x15, 0x81, 0x16, 0x28, 0xd0, 0x4b, 0xea, 0x53, 0x8e, 0xb9, 0x18, 0x30, 0x90, 0x1e, 0x73, 0x2a, + 0x82, 0x5e, 0x7a, 0xe8, 0x35, 0xc8, 0xc9, 0xc8, 0xa9, 0x69, 0x0b, 0x35, 0xb0, 0x2f, 0x45, 0x4f, + 0x45, 0xef, 0x2d, 0x82, 0xf9, 0xd9, 0x1f, 0x91, 0xa2, 0x7e, 0x02, 0x05, 0x08, 0x90, 0x8b, 0xc4, + 0x99, 0x79, 0xef, 0x9b, 0xf7, 0xbe, 0x79, 0xef, 0xcd, 0x9b, 0x85, 0x17, 0x2c, 0x9f, 0x79, 0x3e, + 0xdb, 0x64, 0x1c, 0x1f, 0x3a, 0x74, 0xb0, 0x79, 0xff, 0x66, 0x9f, 0x70, 0x7c, 0x33, 0x1c, 0x37, + 0x46, 0x81, 0xcf, 0x7d, 0xf4, 0x9c, 0x92, 0x6a, 0x84, 0xb3, 0x5a, 0xaa, 0xbc, 0x3e, 0xf0, 0x07, + 0xbe, 0x14, 0xd9, 0x14, 0xbf, 0x94, 0x74, 0xf9, 0xfa, 0xc0, 0xf7, 0x07, 0x2e, 0xd9, 0x94, 0xa3, + 0xfe, 0xf8, 0x60, 0x13, 0xd3, 0x89, 0x5e, 0xaa, 0x4c, 0x2f, 0xd9, 0xe3, 0x00, 0x73, 0xc7, 0xa7, + 0x7a, 0xbd, 0x3a, 0xbd, 0xce, 0x1d, 0x8f, 0x30, 0x8e, 0xbd, 0x51, 0x88, 0xad, 0x2c, 0x31, 0xd5, + 0xa6, 0xda, 0x2c, 0x8d, 0xad, 0x5d, 0xe9, 0x63, 0x46, 0x22, 0x3f, 0x2c, 0xdf, 0x09, 0xb1, 0xbf, + 0xc6, 0x09, 0xb5, 0x49, 0xe0, 0x39, 0x94, 0x6f, 0xf2, 0xc9, 0x88, 0x30, 0xf5, 0x57, 0xad, 0xd6, + 0x7f, 0x6f, 0x40, 0xe1, 0xb6, 0xc3, 0xb8, 0x1f, 0x38, 0x16, 0x76, 0x77, 0xe9, 0x81, 0x8f, 0x5e, + 0x85, 0xec, 0x90, 0x60, 0x9b, 0x04, 0x25, 0xa3, 0x66, 0x6c, 0xe4, 0xb7, 0x4a, 0x8d, 0x18, 0xa1, + 0xa1, 0x74, 0x6f, 0xcb, 0xf5, 0x66, 0xe6, 0xc3, 0xe3, 0x6a, 0xaa, 0xab, 0xa5, 0xd1, 0x0f, 0x20, + 0x7b, 0x1f, 0xbb, 0x8c, 0xf0, 0x52, 0xba, 0xb6, 0xb0, 0x91, 0xdf, 0xfa, 0x46, 0xe3, 0x74, 0xfa, + 0x1a, 0xfb, 0xd8, 0x75, 0x6c, 0xcc, 0xfd, 0x08, 0x40, 0xa9, 0xd5, 0xdf, 0x4f, 0x43, 0x71, 0xc7, + 0xf7, 0x3c, 0x87, 0x31, 0xc7, 0xa7, 0x5d, 0xcc, 0x09, 0x43, 0x1d, 0xc8, 0x04, 0x98, 0x13, 0x69, + 0xca, 0x52, 0xf3, 0xfb, 0x42, 0xfe, 0x6f, 0xc7, 0xd5, 0x17, 0x07, 0x0e, 0x1f, 0x8e, 0xfb, 0x0d, + 0xcb, 0xf7, 0x34, 0x19, 0xfa, 0xdf, 0x0d, 0x66, 0x1f, 0x6a, 0xff, 0x5a, 0xc4, 0xfa, 0xf8, 0x83, + 0x1b, 0xa0, 0x6d, 0x68, 0x11, 0xab, 0x2b, 0x91, 0xd0, 0x8f, 0x21, 0xe7, 0xe1, 0x23, 0x53, 0xa2, + 0xa6, 0xaf, 0x00, 0x75, 0xd1, 0xc3, 0x47, 0xc2, 0x56, 0x64, 0x43, 0x51, 0x00, 0x5b, 0x43, 0x4c, + 0x07, 0x44, 0xe1, 0x2f, 0x5c, 0x01, 0xfe, 0x8a, 0x87, 0x8f, 0x76, 0x24, 0xa6, 0xd8, 0x65, 0x3b, + 0xf7, 0xee, 0xa3, 0x6a, 0xea, 0x5f, 0x8f, 0xaa, 0x46, 0xfd, 0xcf, 0x06, 0x40, 0x4c, 0x17, 0xfa, + 0x39, 0xac, 0x5a, 0xd1, 0x48, 0x6e, 0xcf, 0xf4, 0x01, 0xbe, 0x34, 0xef, 0x20, 0xa6, 0xc8, 0x6e, + 0xe6, 0x84, 0xa1, 0x8f, 0x8f, 0xab, 0x46, 0xb7, 0x68, 0x4d, 0x9d, 0x43, 0x1b, 0xf2, 0xe3, 0x91, + 0x8d, 0x39, 0x31, 0x45, 0x68, 0x4a, 0xe2, 0xf2, 0x5b, 0xe5, 0x86, 0x8a, 0xdb, 0x46, 0x18, 0xb7, + 0x8d, 0xbd, 0x30, 0x6e, 0x15, 0xd6, 0x3b, 0xff, 0xac, 0x1a, 0x5d, 0x50, 0x8a, 0x62, 0x29, 0x61, + 0xfd, 0xfb, 0x06, 0xe4, 0x5b, 0x84, 0x59, 0x81, 0x33, 0x12, 0x89, 0x80, 0x4a, 0xb0, 0xe8, 0xf9, + 0xd4, 0x39, 0xd4, 0x61, 0xb7, 0xd4, 0x0d, 0x87, 0xa8, 0x0c, 0x39, 0xc7, 0x26, 0x94, 0x3b, 0x7c, + 0xa2, 0x0e, 0xac, 0x1b, 0x8d, 0x85, 0xd6, 0xaf, 0x48, 0x9f, 0x39, 0x21, 0xd7, 0xdd, 0x70, 0x88, + 0x5e, 0x86, 0x55, 0x46, 0xac, 0x71, 0xe0, 0xf0, 0x89, 0x69, 0xf9, 0x94, 0x63, 0x8b, 0x97, 0x32, + 0x52, 0xa4, 0x18, 0xce, 0xef, 0xa8, 0x69, 0x01, 0x62, 0x13, 0x8e, 0x1d, 0x97, 0x95, 0x9e, 0x51, + 0x20, 0x7a, 0x98, 0x30, 0xf7, 0x8f, 0x39, 0x58, 0x8a, 0xe2, 0x16, 0xed, 0xc0, 0xaa, 0x3f, 0x22, + 0x81, 0xf8, 0x6d, 0x62, 0xdb, 0x0e, 0x08, 0x63, 0x3a, 0x42, 0x4b, 0x1f, 0x7f, 0x70, 0x63, 0x5d, + 0xd3, 0x7d, 0x4b, 0xad, 0xf4, 0x78, 0xe0, 0xd0, 0x41, 0xb7, 0x18, 0x6a, 0xe8, 0x69, 0xf4, 0x13, + 0x71, 0x60, 0x94, 0x11, 0xca, 0xc6, 0xcc, 0x1c, 0x8d, 0xfb, 0x87, 0x64, 0xa2, 0x79, 0x5d, 0x9f, + 0xe1, 0xf5, 0x16, 0x9d, 0x34, 0x4b, 0x1f, 0xc5, 0xd0, 0x56, 0x30, 0x19, 0x71, 0xbf, 0xd1, 0x19, + 0xf7, 0xef, 0x90, 0x89, 0x38, 0x2d, 0x8d, 0xd3, 0x91, 0x30, 0xe8, 0x39, 0xc8, 0xfe, 0x12, 0x3b, + 0x2e, 0xb1, 0x25, 0x2b, 0xb9, 0xae, 0x1e, 0xa1, 0x6d, 0xc8, 0x32, 0x8e, 0xf9, 0x98, 0x49, 0x2a, + 0x0a, 0x5b, 0xf5, 0x79, 0x91, 0xd1, 0xf4, 0xa9, 0xdd, 0x93, 0x92, 0x5d, 0xad, 0x81, 0xf6, 0x20, + 0xcb, 0xfd, 0x43, 0x42, 0x35, 0x49, 0x97, 0x8a, 0xea, 0x5d, 0xca, 0x13, 0x51, 0xbd, 0x4b, 0x79, + 0x57, 0x63, 0xa1, 0x01, 0xac, 0xda, 0xc4, 0x25, 0x03, 0x49, 0x25, 0x1b, 0xe2, 0x80, 0xb0, 0x52, + 0xf6, 0x0a, 0xb2, 0xa6, 0x18, 0xa1, 0xf6, 0x24, 0x28, 0xba, 0x03, 0x79, 0x3b, 0x0e, 0xb7, 0xd2, + 0xa2, 0x24, 0xfa, 0x9b, 0xf3, 0xfc, 0x4f, 0x44, 0xa6, 0x2e, 0x52, 0x49, 0x6d, 0x11, 0x5c, 0x63, + 0xda, 0xf7, 0xa9, 0xed, 0xd0, 0x81, 0x39, 0x24, 0xce, 0x60, 0xc8, 0x4b, 0xb9, 0x9a, 0xb1, 0xb1, + 0xd0, 0x2d, 0x46, 0xf3, 0xb7, 0xe5, 0x34, 0xba, 0x03, 0x85, 0x58, 0x54, 0xe6, 0xce, 0xd2, 0x25, + 0x72, 0x67, 0x25, 0xd2, 0x15, 0xab, 0xe8, 0x36, 0x40, 0x9c, 0x98, 0x25, 0x90, 0x40, 0xf5, 0xf3, + 0xb3, 0x5b, 0xbb, 0x90, 0xd0, 0x45, 0x2e, 0x5c, 0xf3, 0x1c, 0x6a, 0x32, 0xe2, 0x1e, 0x98, 0x9a, + 0x2a, 0x01, 0x99, 0xbf, 0x82, 0xa3, 0x5d, 0xf3, 0x1c, 0xda, 0x23, 0xee, 0x41, 0x2b, 0x82, 0x45, + 0x4d, 0x91, 0x8c, 0x6a, 0xa7, 0x28, 0x5f, 0x96, 0xcf, 0xc9, 0x97, 0x02, 0x53, 0x18, 0x61, 0xba, + 0xdc, 0x82, 0x62, 0x40, 0x5c, 0x3c, 0x21, 0x71, 0xca, 0xad, 0x9c, 0x07, 0xa1, 0x15, 0x42, 0x88, + 0xd7, 0x01, 0x59, 0x43, 0xec, 0xba, 0x84, 0x0e, 0x12, 0x28, 0x85, 0x73, 0x50, 0xd6, 0x62, 0x9d, + 0x10, 0xe8, 0x79, 0x58, 0xec, 0xbb, 0xcc, 0x14, 0x19, 0x5b, 0xac, 0x19, 0x1b, 0xcb, 0xdd, 0x6c, + 0xdf, 0x65, 0x77, 0xc8, 0x64, 0x7b, 0xf9, 0xed, 0x47, 0xd5, 0x94, 0x2e, 0x1a, 0xa9, 0x7a, 0x07, + 0x96, 0xf7, 0x71, 0xe8, 0x00, 0x61, 0xe8, 0x55, 0x58, 0xc2, 0xe1, 0xa0, 0x64, 0xd4, 0x16, 0xce, + 0xdc, 0x36, 0x16, 0x55, 0x65, 0xe8, 0xb7, 0xff, 0xa8, 0x19, 0xf5, 0x3f, 0x18, 0x90, 0x6d, 0xed, + 0x77, 0xb0, 0x13, 0xa0, 0x36, 0xac, 0xc5, 0x99, 0x73, 0xd1, 0x22, 0x14, 0x27, 0x5b, 0xe8, 0x4a, + 0x1b, 0xd6, 0xee, 0x87, 0x75, 0x2d, 0x82, 0x49, 0x9f, 0x07, 0x13, 0xa9, 0xe8, 0xf9, 0x29, 0xc7, + 0xdb, 0xb0, 0xa8, 0xac, 0x64, 0x68, 0x1b, 0x9e, 0x19, 0x89, 0x1f, 0xd2, 0xdf, 0xfc, 0x56, 0x65, + 0x6e, 0xc6, 0x49, 0x79, 0x1d, 0xa9, 0x4a, 0xa5, 0xfe, 0x3f, 0x03, 0xa0, 0xb5, 0xbf, 0xbf, 0x17, + 0x38, 0x23, 0x97, 0xf0, 0xab, 0xf2, 0xf8, 0x0d, 0x78, 0x36, 0xf6, 0x98, 0x05, 0xd6, 0x85, 0xbd, + 0xbe, 0x16, 0xa9, 0xf5, 0x02, 0xeb, 0x54, 0x34, 0x9b, 0xf1, 0x08, 0x6d, 0xe1, 0xc2, 0x68, 0x2d, + 0xc6, 0x4f, 0xa7, 0xb1, 0x07, 0xf9, 0xd8, 0x7d, 0x86, 0x5a, 0x90, 0xe3, 0xfa, 0xb7, 0x66, 0xb3, + 0x3e, 0x9f, 0xcd, 0x50, 0x4d, 0x33, 0x1a, 0x69, 0xd6, 0xff, 0x2f, 0x48, 0x8d, 0x53, 0xf3, 0x4b, + 0x15, 0x46, 0xe2, 0x92, 0xd1, 0x97, 0xc0, 0x55, 0xb4, 0x4e, 0x1a, 0x6b, 0x8a, 0xd5, 0xdf, 0xa5, + 0xe1, 0xda, 0xbd, 0xb0, 0xac, 0x7e, 0x69, 0x99, 0xe8, 0xc0, 0x22, 0xa1, 0x3c, 0x70, 0x24, 0x15, + 0xe2, 0xac, 0xbf, 0x33, 0xef, 0xac, 0x4f, 0xf1, 0xa5, 0x4d, 0x79, 0x30, 0xd1, 0x27, 0x1f, 0xc2, + 0x4c, 0xb1, 0xf0, 0xf7, 0x34, 0x94, 0xe6, 0x69, 0xa2, 0x97, 0xa0, 0x68, 0x05, 0x44, 0x4e, 0x84, + 0xd7, 0x9b, 0x21, 0xaf, 0xb7, 0x42, 0x38, 0xad, 0x6f, 0xb7, 0x37, 0x41, 0x74, 0x8a, 0x22, 0xb0, + 0x84, 0xe8, 0xa5, 0x5b, 0xc3, 0x42, 0xac, 0x2c, 0xef, 0x37, 0x02, 0x45, 0x87, 0x3a, 0xdc, 0xc1, + 0xae, 0xd9, 0xc7, 0x2e, 0xa6, 0xd6, 0xe7, 0x69, 0xa1, 0x67, 0x6f, 0xa4, 0x82, 0x06, 0x6d, 0x2a, + 0x4c, 0xb4, 0x0f, 0x8b, 0x21, 0x7c, 0xe6, 0x0a, 0xe0, 0x43, 0xb0, 0x44, 0xbb, 0xf8, 0x49, 0x1a, + 0xd6, 0xba, 0xc4, 0xfe, 0x6a, 0xd1, 0xfa, 0x33, 0x00, 0x95, 0x70, 0xa2, 0x0e, 0x7e, 0x0e, 0x66, + 0x67, 0x13, 0x78, 0x49, 0xe1, 0xb5, 0x18, 0x4f, 0x70, 0xfb, 0x51, 0x1a, 0x96, 0x93, 0xdc, 0x7e, + 0x05, 0xee, 0x05, 0xb4, 0x1b, 0x57, 0x83, 0x8c, 0xac, 0x06, 0x2f, 0xcf, 0xab, 0x06, 0x33, 0x51, + 0x77, 0x76, 0x19, 0xf8, 0x74, 0x01, 0xb2, 0x1d, 0x1c, 0x60, 0x8f, 0xa1, 0x1f, 0xce, 0x74, 0xaa, + 0xea, 0xf9, 0x78, 0x7d, 0x26, 0xe6, 0x5a, 0xfa, 0xeb, 0x85, 0x0a, 0xb9, 0x77, 0x4f, 0x69, 0x54, + 0xbf, 0x05, 0x05, 0xf1, 0x16, 0x8e, 0x5c, 0x51, 0x24, 0xae, 0xc8, 0xc7, 0x6c, 0xf4, 0x8c, 0x62, + 0xa8, 0x0a, 0x79, 0x21, 0x16, 0x17, 0x3a, 0x21, 0x03, 0x1e, 0x3e, 0x6a, 0xab, 0x19, 0x74, 0x03, + 0xd0, 0x30, 0xfa, 0x3a, 0x61, 0xc6, 0x14, 0x08, 0xb9, 0xb5, 0x78, 0x25, 0x14, 0xff, 0x3a, 0x80, + 0xb0, 0xc2, 0xb4, 0x09, 0xf5, 0x3d, 0xfd, 0x98, 0x5b, 0x12, 0x33, 0x2d, 0x31, 0x81, 0x7e, 0xad, + 0x9a, 0xde, 0xa9, 0x67, 0xb2, 0x7e, 0x6f, 0xbc, 0x71, 0xb9, 0x48, 0xfd, 0xef, 0x71, 0xb5, 0x3c, + 0xc1, 0x9e, 0xbb, 0x5d, 0x3f, 0x05, 0xb2, 0x2e, 0x9b, 0xe0, 0x93, 0xcf, 0xeb, 0x79, 0x2d, 0xf7, + 0xe2, 0x17, 0xd2, 0x72, 0x27, 0xf2, 0xe5, 0x3d, 0x03, 0x50, 0xbc, 0xd0, 0x25, 0x6c, 0x24, 0x5e, + 0x8b, 0xe2, 0x2d, 0x91, 0xb0, 0xc2, 0x38, 0xfb, 0x2d, 0x11, 0xeb, 0x87, 0x6f, 0x89, 0x44, 0xfe, + 0x7d, 0x2f, 0x2e, 0xa7, 0x69, 0x1d, 0x31, 0x1a, 0xa6, 0x8f, 0x19, 0x49, 0xbc, 0x47, 0x9c, 0x50, + 0x7b, 0xa6, 0x62, 0xa6, 0xea, 0x9f, 0x18, 0x70, 0x7d, 0x26, 0x76, 0x23, 0x63, 0x7f, 0x01, 0x28, + 0x48, 0x2c, 0xca, 0x48, 0x98, 0x68, 0xa3, 0x2f, 0x9d, 0x0a, 0x6b, 0xc1, 0x4c, 0x65, 0xfe, 0xa2, + 0x6e, 0x84, 0x8c, 0x3c, 0x81, 0xbf, 0x18, 0xb0, 0x9e, 0x34, 0x26, 0x72, 0xeb, 0x2e, 0x2c, 0x27, + 0x6d, 0xd1, 0x0e, 0xbd, 0x70, 0x11, 0x87, 0xb4, 0x2f, 0x27, 0xf4, 0xd1, 0x5b, 0x71, 0x99, 0x50, + 0xdf, 0xe0, 0x6e, 0x5e, 0x98, 0x9b, 0xd0, 0xa6, 0xe9, 0x72, 0x91, 0x09, 0x7b, 0xa6, 0x4c, 0xc7, + 0xf7, 0x5d, 0xf4, 0x1b, 0x58, 0xa3, 0x3e, 0x37, 0x45, 0x4e, 0x11, 0xdb, 0xd4, 0x1f, 0x04, 0x54, + 0xad, 0x7d, 0xeb, 0x72, 0x94, 0xfd, 0xfb, 0xb8, 0x3a, 0x0b, 0x35, 0xc5, 0x63, 0x91, 0xfa, 0xbc, + 0x29, 0xd7, 0xf7, 0xd4, 0xe7, 0x82, 0x00, 0x56, 0x4e, 0x6e, 0xad, 0x6a, 0xf3, 0x9b, 0x97, 0xde, + 0x7a, 0xe5, 0xac, 0x6d, 0x97, 0xfb, 0x89, 0x3d, 0xb7, 0x73, 0xe2, 0x0c, 0xff, 0xf3, 0xa8, 0x6a, + 0x7c, 0xfb, 0x4f, 0x06, 0x40, 0xfc, 0x65, 0x04, 0xbd, 0x02, 0xcf, 0x37, 0x7f, 0x74, 0xb7, 0x65, + 0xf6, 0xf6, 0x6e, 0xed, 0xdd, 0xeb, 0x99, 0xf7, 0xee, 0xf6, 0x3a, 0xed, 0x9d, 0xdd, 0xd7, 0x76, + 0xdb, 0xad, 0xd5, 0x54, 0xb9, 0xf8, 0xe0, 0x61, 0x2d, 0x7f, 0x8f, 0xb2, 0x11, 0xb1, 0x9c, 0x03, + 0x87, 0xd8, 0xe8, 0x45, 0x58, 0x3f, 0x29, 0x2d, 0x46, 0xed, 0xd6, 0xaa, 0x51, 0x5e, 0x7e, 0xf0, + 0xb0, 0x96, 0x53, 0xbd, 0x18, 0xb1, 0xd1, 0x06, 0x3c, 0x3b, 0x2b, 0xb7, 0x7b, 0xf7, 0xf5, 0xd5, + 0x74, 0x79, 0xe5, 0xc1, 0xc3, 0xda, 0x52, 0xd4, 0xb4, 0xa1, 0x3a, 0xa0, 0xa4, 0xa4, 0xc6, 0x5b, + 0x28, 0xc3, 0x83, 0x87, 0xb5, 0xac, 0xa2, 0xad, 0x9c, 0x79, 0xfb, 0xbd, 0x4a, 0xaa, 0xf9, 0xda, + 0x87, 0x4f, 0x2a, 0xc6, 0xe3, 0x27, 0x15, 0xe3, 0xd3, 0x27, 0x15, 0xe3, 0x9d, 0xa7, 0x95, 0xd4, + 0xe3, 0xa7, 0x95, 0xd4, 0x5f, 0x9f, 0x56, 0x52, 0x3f, 0x7d, 0xe5, 0x4c, 0xc6, 0x8e, 0xa2, 0x0f, + 0xe4, 0x92, 0xbb, 0x7e, 0x56, 0x5e, 0x01, 0xdf, 0xfd, 0x2c, 0x00, 0x00, 0xff, 0xff, 0xcd, 0xff, + 0xf2, 0xe4, 0x3f, 0x17, 0x00, 0x00, } func (this *Pool) Description() (desc *github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet) { @@ -1268,481 +1271,482 @@ func (this *Pool) Description() (desc *github_com_gogo_protobuf_protoc_gen_gogo_ func StakingDescription() (desc *github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet) { d := &github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet{} var gzipped = []byte{ - // 7580 bytes of a gzipped FileDescriptorSet + // 7599 bytes of a gzipped FileDescriptorSet 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7c, 0x7b, 0x90, 0x24, 0xc9, - 0x79, 0xd7, 0xf4, 0x63, 0xfa, 0xf1, 0x75, 0x4f, 0x4f, 0x4d, 0xce, 0xec, 0x6e, 0xef, 0xdc, 0xdd, - 0xcc, 0x5c, 0xdf, 0x63, 0xf7, 0x5e, 0xb3, 0x77, 0x7b, 0xb7, 0xbb, 0xb7, 0xbd, 0x96, 0x8e, 0xee, - 0xe9, 0xde, 0xdd, 0xd9, 0x9d, 0x47, 0x5f, 0xf5, 0xcc, 0xde, 0xc3, 0x98, 0x8a, 0x9a, 0xea, 0x9c, - 0x9e, 0xba, 0xa9, 0xae, 0x2a, 0x57, 0x55, 0xef, 0xee, 0x5c, 0x18, 0xe2, 0x14, 0xc2, 0x20, 0x2d, - 0x01, 0xc8, 0x98, 0xc0, 0xb2, 0xac, 0x15, 0x77, 0x96, 0x41, 0x46, 0x08, 0xb0, 0x2d, 0x21, 0x30, - 0x0e, 0x40, 0x40, 0x00, 0x42, 0x7f, 0x10, 0xb2, 0xff, 0xc0, 0x36, 0x98, 0x43, 0x9c, 0x14, 0x20, - 0x84, 0xc0, 0xc2, 0x1c, 0x11, 0x26, 0x14, 0x26, 0x88, 0x7c, 0xd5, 0xa3, 0x1f, 0xd3, 0x3d, 0xeb, - 0x3d, 0xd9, 0x11, 0xfa, 0x6b, 0x3a, 0xbf, 0xfc, 0x7e, 0xbf, 0xfc, 0xf2, 0xcb, 0x2f, 0x33, 0xbf, - 0xcc, 0xaa, 0x1a, 0xf8, 0x17, 0x97, 0x60, 0xa9, 0x6d, 0x59, 0x6d, 0x03, 0x9f, 0xb1, 0x1d, 0xcb, - 0xb3, 0x76, 0xba, 0xbb, 0x67, 0x5a, 0xd8, 0xd5, 0x1c, 0xdd, 0xf6, 0x2c, 0x67, 0x99, 0xca, 0xd0, - 0x34, 0xd3, 0x58, 0x16, 0x1a, 0xa5, 0x75, 0x98, 0xb9, 0xac, 0x1b, 0xb8, 0xe6, 0x2b, 0x36, 0xb1, - 0x87, 0x5e, 0x84, 0xe4, 0xae, 0x6e, 0xe0, 0x62, 0x6c, 0x29, 0x71, 0x3a, 0x77, 0xf6, 0xd1, 0xe5, - 0x1e, 0xd0, 0x72, 0x14, 0xd1, 0x20, 0x62, 0x99, 0x22, 0x4a, 0xdf, 0x4a, 0xc2, 0xec, 0x80, 0x5a, - 0x84, 0x20, 0x69, 0xaa, 0x1d, 0xc2, 0x18, 0x3b, 0x9d, 0x95, 0xe9, 0x6f, 0x54, 0x84, 0xb4, 0xad, - 0x6a, 0xfb, 0x6a, 0x1b, 0x17, 0xe3, 0x54, 0x2c, 0x8a, 0x68, 0x01, 0xa0, 0x85, 0x6d, 0x6c, 0xb6, - 0xb0, 0xa9, 0x1d, 0x14, 0x13, 0x4b, 0x89, 0xd3, 0x59, 0x39, 0x24, 0x41, 0x4f, 0xc1, 0x8c, 0xdd, - 0xdd, 0x31, 0x74, 0x4d, 0x09, 0xa9, 0xc1, 0x52, 0xe2, 0xf4, 0xa4, 0x2c, 0xb1, 0x8a, 0x5a, 0xa0, - 0x7c, 0x0a, 0xa6, 0x6f, 0x61, 0x75, 0x3f, 0xac, 0x9a, 0xa3, 0xaa, 0x05, 0x22, 0x0e, 0x29, 0xae, - 0x40, 0xbe, 0x83, 0x5d, 0x57, 0x6d, 0x63, 0xc5, 0x3b, 0xb0, 0x71, 0x31, 0x49, 0x7b, 0xbf, 0xd4, - 0xd7, 0xfb, 0xde, 0x9e, 0xe7, 0x38, 0x6a, 0xeb, 0xc0, 0xc6, 0xa8, 0x02, 0x59, 0x6c, 0x76, 0x3b, - 0x8c, 0x61, 0x72, 0x88, 0xff, 0xea, 0x66, 0xb7, 0xd3, 0xcb, 0x92, 0x21, 0x30, 0x4e, 0x91, 0x76, - 0xb1, 0x73, 0x53, 0xd7, 0x70, 0x31, 0x45, 0x09, 0x4e, 0xf5, 0x11, 0x34, 0x59, 0x7d, 0x2f, 0x87, - 0xc0, 0xa1, 0x15, 0xc8, 0xe2, 0xdb, 0x1e, 0x36, 0x5d, 0xdd, 0x32, 0x8b, 0x69, 0x4a, 0xf2, 0xd8, - 0x80, 0x51, 0xc4, 0x46, 0xab, 0x97, 0x22, 0xc0, 0xa1, 0xf3, 0x90, 0xb6, 0x6c, 0x4f, 0xb7, 0x4c, - 0xb7, 0x98, 0x59, 0x8a, 0x9d, 0xce, 0x9d, 0x7d, 0x70, 0x60, 0x20, 0x6c, 0x32, 0x1d, 0x59, 0x28, - 0xa3, 0x55, 0x90, 0x5c, 0xab, 0xeb, 0x68, 0x58, 0xd1, 0xac, 0x16, 0x56, 0x74, 0x73, 0xd7, 0x2a, - 0x66, 0x29, 0xc1, 0x62, 0x7f, 0x47, 0xa8, 0xe2, 0x8a, 0xd5, 0xc2, 0xab, 0xe6, 0xae, 0x25, 0x17, - 0xdc, 0x48, 0x19, 0x1d, 0x87, 0x94, 0x7b, 0x60, 0x7a, 0xea, 0xed, 0x62, 0x9e, 0x46, 0x08, 0x2f, - 0x95, 0x7e, 0x35, 0x05, 0xd3, 0xe3, 0x84, 0xd8, 0x25, 0x98, 0xdc, 0x25, 0xbd, 0x2c, 0xc6, 0x8f, - 0xe2, 0x03, 0x86, 0x89, 0x3a, 0x31, 0x75, 0x8f, 0x4e, 0xac, 0x40, 0xce, 0xc4, 0xae, 0x87, 0x5b, - 0x2c, 0x22, 0x12, 0x63, 0xc6, 0x14, 0x30, 0x50, 0x7f, 0x48, 0x25, 0xef, 0x29, 0xa4, 0x5e, 0x85, - 0x69, 0xdf, 0x24, 0xc5, 0x51, 0xcd, 0xb6, 0x88, 0xcd, 0x33, 0xa3, 0x2c, 0x59, 0xae, 0x0b, 0x9c, - 0x4c, 0x60, 0x72, 0x01, 0x47, 0xca, 0xa8, 0x06, 0x60, 0x99, 0xd8, 0xda, 0x55, 0x5a, 0x58, 0x33, - 0x8a, 0x99, 0x21, 0x5e, 0xda, 0x24, 0x2a, 0x7d, 0x5e, 0xb2, 0x98, 0x54, 0x33, 0xd0, 0xc5, 0x20, - 0xd4, 0xd2, 0x43, 0x22, 0x65, 0x9d, 0x4d, 0xb2, 0xbe, 0x68, 0xdb, 0x86, 0x82, 0x83, 0x49, 0xdc, - 0xe3, 0x16, 0xef, 0x59, 0x96, 0x1a, 0xb1, 0x3c, 0xb2, 0x67, 0x32, 0x87, 0xb1, 0x8e, 0x4d, 0x39, - 0xe1, 0x22, 0x7a, 0x04, 0x7c, 0x81, 0x42, 0xc3, 0x0a, 0xe8, 0x2a, 0x94, 0x17, 0xc2, 0x0d, 0xb5, - 0x83, 0xe7, 0xdf, 0x84, 0x42, 0xd4, 0x3d, 0x68, 0x0e, 0x26, 0x5d, 0x4f, 0x75, 0x3c, 0x1a, 0x85, - 0x93, 0x32, 0x2b, 0x20, 0x09, 0x12, 0xd8, 0x6c, 0xd1, 0x55, 0x6e, 0x52, 0x26, 0x3f, 0xd1, 0x9f, - 0x08, 0x3a, 0x9c, 0xa0, 0x1d, 0x7e, 0xbc, 0x7f, 0x44, 0x23, 0xcc, 0xbd, 0xfd, 0x9e, 0xbf, 0x00, - 0x53, 0x91, 0x0e, 0x8c, 0xdb, 0x74, 0xe9, 0x27, 0xe0, 0xd8, 0x40, 0x6a, 0xf4, 0x2a, 0xcc, 0x75, - 0x4d, 0xdd, 0xf4, 0xb0, 0x63, 0x3b, 0x98, 0x44, 0x2c, 0x6b, 0xaa, 0xf8, 0x5f, 0xd3, 0x43, 0x62, - 0x6e, 0x3b, 0xac, 0xcd, 0x58, 0xe4, 0xd9, 0x6e, 0xbf, 0xf0, 0xc9, 0x6c, 0xe6, 0xdb, 0x69, 0xe9, - 0xad, 0xb7, 0xde, 0x7a, 0x2b, 0x5e, 0xfa, 0x67, 0x29, 0x98, 0x1b, 0x34, 0x67, 0x06, 0x4e, 0xdf, - 0xe3, 0x90, 0x32, 0xbb, 0x9d, 0x1d, 0xec, 0x50, 0x27, 0x4d, 0xca, 0xbc, 0x84, 0x2a, 0x30, 0x69, - 0xa8, 0x3b, 0xd8, 0x28, 0x26, 0x97, 0x62, 0xa7, 0x0b, 0x67, 0x9f, 0x1a, 0x6b, 0x56, 0x2e, 0xaf, - 0x11, 0x88, 0xcc, 0x90, 0xe8, 0xc3, 0x90, 0xe4, 0x4b, 0x34, 0x61, 0x78, 0x72, 0x3c, 0x06, 0x32, - 0x97, 0x64, 0x8a, 0x43, 0x0f, 0x40, 0x96, 0xfc, 0x65, 0xb1, 0x91, 0xa2, 0x36, 0x67, 0x88, 0x80, - 0xc4, 0x05, 0x9a, 0x87, 0x0c, 0x9d, 0x26, 0x2d, 0x2c, 0xb6, 0x36, 0xbf, 0x4c, 0x02, 0xab, 0x85, - 0x77, 0xd5, 0xae, 0xe1, 0x29, 0x37, 0x55, 0xa3, 0x8b, 0x69, 0xc0, 0x67, 0xe5, 0x3c, 0x17, 0xde, - 0x20, 0x32, 0xb4, 0x08, 0x39, 0x36, 0xab, 0x74, 0xb3, 0x85, 0x6f, 0xd3, 0xd5, 0x73, 0x52, 0x66, - 0x13, 0x6d, 0x95, 0x48, 0x48, 0xf3, 0x6f, 0xb8, 0x96, 0x29, 0x42, 0x93, 0x36, 0x41, 0x04, 0xb4, - 0xf9, 0x0b, 0xbd, 0x0b, 0xf7, 0x43, 0x83, 0xbb, 0xd7, 0x37, 0x97, 0x4e, 0xc1, 0x34, 0xd5, 0x78, - 0x9e, 0x0f, 0xbd, 0x6a, 0x14, 0x67, 0x96, 0x62, 0xa7, 0x33, 0x72, 0x81, 0x89, 0x37, 0xb9, 0xb4, - 0xf4, 0xe5, 0x38, 0x24, 0xe9, 0xc2, 0x32, 0x0d, 0xb9, 0xad, 0xd7, 0x1a, 0x75, 0xa5, 0xb6, 0xb9, - 0x5d, 0x5d, 0xab, 0x4b, 0x31, 0x54, 0x00, 0xa0, 0x82, 0xcb, 0x6b, 0x9b, 0x95, 0x2d, 0x29, 0xee, - 0x97, 0x57, 0x37, 0xb6, 0xce, 0xbf, 0x20, 0x25, 0x7c, 0xc0, 0x36, 0x13, 0x24, 0xc3, 0x0a, 0xcf, - 0x9f, 0x95, 0x26, 0x91, 0x04, 0x79, 0x46, 0xb0, 0xfa, 0x6a, 0xbd, 0x76, 0xfe, 0x05, 0x29, 0x15, - 0x95, 0x3c, 0x7f, 0x56, 0x4a, 0xa3, 0x29, 0xc8, 0x52, 0x49, 0x75, 0x73, 0x73, 0x4d, 0xca, 0xf8, - 0x9c, 0xcd, 0x2d, 0x79, 0x75, 0xe3, 0x8a, 0x94, 0xf5, 0x39, 0xaf, 0xc8, 0x9b, 0xdb, 0x0d, 0x09, - 0x7c, 0x86, 0xf5, 0x7a, 0xb3, 0x59, 0xb9, 0x52, 0x97, 0x72, 0xbe, 0x46, 0xf5, 0xb5, 0xad, 0x7a, - 0x53, 0xca, 0x47, 0xcc, 0x7a, 0xfe, 0xac, 0x34, 0xe5, 0x37, 0x51, 0xdf, 0xd8, 0x5e, 0x97, 0x0a, - 0x68, 0x06, 0xa6, 0x58, 0x13, 0xc2, 0x88, 0xe9, 0x1e, 0xd1, 0xf9, 0x17, 0x24, 0x29, 0x30, 0x84, - 0xb1, 0xcc, 0x44, 0x04, 0xe7, 0x5f, 0x90, 0x50, 0x69, 0x05, 0x26, 0x69, 0x18, 0x22, 0x04, 0x85, - 0xb5, 0x4a, 0xb5, 0xbe, 0xa6, 0x6c, 0x36, 0xb6, 0x56, 0x37, 0x37, 0x2a, 0x6b, 0x52, 0x2c, 0x90, - 0xc9, 0xf5, 0x97, 0xb7, 0x57, 0xe5, 0x7a, 0x4d, 0x8a, 0x87, 0x65, 0x8d, 0x7a, 0x65, 0xab, 0x5e, - 0x93, 0x12, 0x25, 0x0d, 0xe6, 0x06, 0x2d, 0xa8, 0x03, 0xa7, 0x50, 0x28, 0x16, 0xe2, 0x43, 0x62, - 0x81, 0x72, 0xf5, 0xc6, 0x42, 0xe9, 0x9b, 0x71, 0x98, 0x1d, 0xb0, 0xa9, 0x0c, 0x6c, 0xe4, 0x25, - 0x98, 0x64, 0xb1, 0xcc, 0xb6, 0xd9, 0x27, 0x06, 0xee, 0x4e, 0x34, 0xb2, 0xfb, 0xb6, 0x5a, 0x8a, - 0x0b, 0xa7, 0x1a, 0x89, 0x21, 0xa9, 0x06, 0xa1, 0xe8, 0x0b, 0xd8, 0x1f, 0xeb, 0x5b, 0xfc, 0xd9, - 0xfe, 0x78, 0x7e, 0x9c, 0xfd, 0x91, 0xca, 0x8e, 0xb6, 0x09, 0x4c, 0x0e, 0xd8, 0x04, 0x2e, 0xc1, - 0x4c, 0x1f, 0xd1, 0xd8, 0x8b, 0xf1, 0x47, 0x63, 0x50, 0x1c, 0xe6, 0x9c, 0x11, 0x4b, 0x62, 0x3c, - 0xb2, 0x24, 0x5e, 0xea, 0xf5, 0xe0, 0xc3, 0xc3, 0x07, 0xa1, 0x6f, 0xac, 0x3f, 0x17, 0x83, 0xe3, - 0x83, 0x53, 0xca, 0x81, 0x36, 0x7c, 0x18, 0x52, 0x1d, 0xec, 0xed, 0x59, 0x22, 0xad, 0x7a, 0x7c, - 0xc0, 0x66, 0x4d, 0xaa, 0x7b, 0x07, 0x9b, 0xa3, 0xc2, 0xbb, 0x7d, 0x62, 0x58, 0x5e, 0xc8, 0xac, - 0xe9, 0xb3, 0xf4, 0xe3, 0x71, 0x38, 0x36, 0x90, 0x7c, 0xa0, 0xa1, 0x0f, 0x01, 0xe8, 0xa6, 0xdd, - 0xf5, 0x58, 0xea, 0xc4, 0x56, 0xe2, 0x2c, 0x95, 0xd0, 0xc5, 0x8b, 0xac, 0xb2, 0x5d, 0xcf, 0xaf, - 0x4f, 0xd0, 0x7a, 0x60, 0x22, 0xaa, 0xf0, 0x62, 0x60, 0x68, 0x92, 0x1a, 0xba, 0x30, 0xa4, 0xa7, - 0x7d, 0x81, 0xf9, 0x2c, 0x48, 0x9a, 0xa1, 0x63, 0xd3, 0x53, 0x5c, 0xcf, 0xc1, 0x6a, 0x47, 0x37, - 0xdb, 0x74, 0xab, 0xc9, 0x94, 0x27, 0x77, 0x55, 0xc3, 0xc5, 0xf2, 0x34, 0xab, 0x6e, 0x8a, 0x5a, - 0x82, 0xa0, 0x01, 0xe4, 0x84, 0x10, 0xa9, 0x08, 0x82, 0x55, 0xfb, 0x88, 0xd2, 0x4f, 0x65, 0x21, - 0x17, 0x4a, 0xc0, 0xd1, 0xc3, 0x90, 0x7f, 0x43, 0xbd, 0xa9, 0x2a, 0xe2, 0x50, 0xc5, 0x3c, 0x91, - 0x23, 0xb2, 0x06, 0x3f, 0x58, 0x3d, 0x0b, 0x73, 0x54, 0xc5, 0xea, 0x7a, 0xd8, 0x51, 0x34, 0x43, - 0x75, 0x5d, 0xea, 0xb4, 0x0c, 0x55, 0x45, 0xa4, 0x6e, 0x93, 0x54, 0xad, 0x88, 0x1a, 0x74, 0x0e, - 0x66, 0x29, 0xa2, 0xd3, 0x35, 0x3c, 0xdd, 0x36, 0xb0, 0x42, 0x8e, 0x79, 0x2e, 0xdd, 0x72, 0x7c, - 0xcb, 0x66, 0x88, 0xc6, 0x3a, 0x57, 0x20, 0x16, 0xb9, 0xa8, 0x06, 0x0f, 0x51, 0x58, 0x1b, 0x9b, - 0xd8, 0x51, 0x3d, 0xac, 0xe0, 0x1f, 0xef, 0xaa, 0x86, 0xab, 0xa8, 0x66, 0x4b, 0xd9, 0x53, 0xdd, - 0xbd, 0xe2, 0x1c, 0x21, 0xa8, 0xc6, 0x8b, 0x31, 0xf9, 0x24, 0x51, 0xbc, 0xc2, 0xf5, 0xea, 0x54, - 0xad, 0x62, 0xb6, 0xae, 0xaa, 0xee, 0x1e, 0x2a, 0xc3, 0x71, 0xca, 0xe2, 0x7a, 0x8e, 0x6e, 0xb6, - 0x15, 0x6d, 0x0f, 0x6b, 0xfb, 0x4a, 0xd7, 0xdb, 0x7d, 0xb1, 0xf8, 0x40, 0xb8, 0x7d, 0x6a, 0x61, - 0x93, 0xea, 0xac, 0x10, 0x95, 0x6d, 0x6f, 0xf7, 0x45, 0xd4, 0x84, 0x3c, 0x19, 0x8c, 0x8e, 0xfe, - 0x26, 0x56, 0x76, 0x2d, 0x87, 0xee, 0xa1, 0x85, 0x01, 0x4b, 0x53, 0xc8, 0x83, 0xcb, 0x9b, 0x1c, - 0xb0, 0x6e, 0xb5, 0x70, 0x79, 0xb2, 0xd9, 0xa8, 0xd7, 0x6b, 0x72, 0x4e, 0xb0, 0x5c, 0xb6, 0x1c, - 0x12, 0x50, 0x6d, 0xcb, 0x77, 0x70, 0x8e, 0x05, 0x54, 0xdb, 0x12, 0xee, 0x3d, 0x07, 0xb3, 0x9a, - 0xc6, 0xfa, 0xac, 0x6b, 0x0a, 0x3f, 0x8c, 0xb9, 0x45, 0x29, 0xe2, 0x2c, 0x4d, 0xbb, 0xc2, 0x14, - 0x78, 0x8c, 0xbb, 0xe8, 0x22, 0x1c, 0x0b, 0x9c, 0x15, 0x06, 0xce, 0xf4, 0xf5, 0xb2, 0x17, 0x7a, - 0x0e, 0x66, 0xed, 0x83, 0x7e, 0x20, 0x8a, 0xb4, 0x68, 0x1f, 0xf4, 0xc2, 0x2e, 0xc0, 0x9c, 0xbd, - 0x67, 0xf7, 0xe3, 0x9e, 0x0c, 0xe3, 0x90, 0xbd, 0x67, 0xf7, 0x02, 0x1f, 0xa3, 0x27, 0x73, 0x07, - 0x6b, 0xaa, 0x87, 0x5b, 0xc5, 0x13, 0x61, 0xf5, 0x50, 0x05, 0x5a, 0x06, 0x49, 0xd3, 0x14, 0x6c, - 0xaa, 0x3b, 0x06, 0x56, 0x54, 0x07, 0x9b, 0xaa, 0x5b, 0x5c, 0xa4, 0xca, 0x49, 0xcf, 0xe9, 0x62, - 0xb9, 0xa0, 0x69, 0x75, 0x5a, 0x59, 0xa1, 0x75, 0xe8, 0x49, 0x98, 0xb1, 0x76, 0xde, 0xd0, 0x58, - 0x44, 0x2a, 0xb6, 0x83, 0x77, 0xf5, 0xdb, 0xc5, 0x47, 0xa9, 0x7b, 0xa7, 0x49, 0x05, 0x8d, 0xc7, - 0x06, 0x15, 0xa3, 0x27, 0x40, 0xd2, 0xdc, 0x3d, 0xd5, 0xb1, 0xe9, 0x92, 0xec, 0xda, 0xaa, 0x86, - 0x8b, 0x8f, 0x31, 0x55, 0x26, 0xdf, 0x10, 0x62, 0x32, 0x23, 0xdc, 0x5b, 0xfa, 0xae, 0x27, 0x18, - 0x4f, 0xb1, 0x19, 0x41, 0x65, 0x9c, 0xed, 0x34, 0x48, 0xc4, 0x13, 0x91, 0x86, 0x4f, 0x53, 0xb5, - 0x82, 0xbd, 0x67, 0x87, 0xdb, 0x7d, 0x04, 0xa6, 0x88, 0x66, 0xd0, 0xe8, 0x13, 0x2c, 0x71, 0xb3, - 0xf7, 0x42, 0x2d, 0xbe, 0x00, 0xc7, 0x89, 0x52, 0x07, 0x7b, 0x6a, 0x4b, 0xf5, 0xd4, 0x90, 0xf6, - 0xd3, 0x54, 0x9b, 0xb8, 0x7d, 0x9d, 0x57, 0x46, 0xec, 0x74, 0xba, 0x3b, 0x07, 0x7e, 0x60, 0x3d, - 0xc3, 0xec, 0x24, 0x32, 0x11, 0x5a, 0x1f, 0x58, 0x72, 0x5e, 0x2a, 0x43, 0x3e, 0x1c, 0xf7, 0x28, - 0x0b, 0x2c, 0xf2, 0xa5, 0x18, 0x49, 0x82, 0x56, 0x36, 0x6b, 0x24, 0x7d, 0x79, 0xbd, 0x2e, 0xc5, - 0x49, 0x1a, 0xb5, 0xb6, 0xba, 0x55, 0x57, 0xe4, 0xed, 0x8d, 0xad, 0xd5, 0xf5, 0xba, 0x94, 0x08, - 0x25, 0xf6, 0xd7, 0x92, 0x99, 0xc7, 0xa5, 0x53, 0x24, 0x6b, 0x28, 0x44, 0x4f, 0x6a, 0xe8, 0x47, - 0xe0, 0x84, 0xb8, 0x56, 0x71, 0xb1, 0xa7, 0xdc, 0xd2, 0x1d, 0x3a, 0x21, 0x3b, 0x2a, 0xdb, 0x1c, - 0xfd, 0xf8, 0x99, 0xe3, 0x5a, 0x4d, 0xec, 0xbd, 0xa2, 0x3b, 0x64, 0xba, 0x75, 0x54, 0x0f, 0xad, - 0xc1, 0xa2, 0x69, 0x29, 0xae, 0xa7, 0x9a, 0x2d, 0xd5, 0x69, 0x29, 0xc1, 0x85, 0x96, 0xa2, 0x6a, - 0x1a, 0x76, 0x5d, 0x8b, 0x6d, 0x84, 0x3e, 0xcb, 0x83, 0xa6, 0xd5, 0xe4, 0xca, 0xc1, 0x0e, 0x51, - 0xe1, 0xaa, 0x3d, 0xe1, 0x9b, 0x18, 0x16, 0xbe, 0x0f, 0x40, 0xb6, 0xa3, 0xda, 0x0a, 0x36, 0x3d, - 0xe7, 0x80, 0xe6, 0xe7, 0x19, 0x39, 0xd3, 0x51, 0xed, 0x3a, 0x29, 0xff, 0x40, 0x8e, 0x49, 0xd7, - 0x92, 0x99, 0xa4, 0x34, 0x79, 0x2d, 0x99, 0x99, 0x94, 0x52, 0xd7, 0x92, 0x99, 0x94, 0x94, 0xbe, - 0x96, 0xcc, 0x64, 0xa4, 0xec, 0xb5, 0x64, 0x26, 0x2b, 0x41, 0xe9, 0xbd, 0x04, 0xe4, 0xc3, 0x19, - 0x3c, 0x39, 0x10, 0x69, 0x74, 0x0f, 0x8b, 0xd1, 0x55, 0xee, 0x91, 0x43, 0xf3, 0xfd, 0xe5, 0x15, - 0xb2, 0xb9, 0x95, 0x53, 0x2c, 0x5d, 0x96, 0x19, 0x92, 0x24, 0x16, 0x24, 0xfc, 0x30, 0x4b, 0x4f, - 0x32, 0x32, 0x2f, 0xa1, 0x2b, 0x90, 0x7a, 0xc3, 0xa5, 0xdc, 0x29, 0xca, 0xfd, 0xe8, 0xe1, 0xdc, - 0xd7, 0x9a, 0x94, 0x3c, 0x7b, 0xad, 0xa9, 0x6c, 0x6c, 0xca, 0xeb, 0x95, 0x35, 0x99, 0xc3, 0xd1, - 0x49, 0x48, 0x1a, 0xea, 0x9b, 0x07, 0xd1, 0x6d, 0x90, 0x8a, 0xc6, 0x1d, 0x96, 0x93, 0x90, 0xbc, - 0x85, 0xd5, 0xfd, 0xe8, 0xe6, 0x43, 0x45, 0x1f, 0xe0, 0xf4, 0x38, 0x03, 0x93, 0xd4, 0x5f, 0x08, - 0x80, 0x7b, 0x4c, 0x9a, 0x40, 0x19, 0x48, 0xae, 0x6c, 0xca, 0x64, 0x8a, 0x48, 0x90, 0x67, 0x52, - 0xa5, 0xb1, 0x5a, 0x5f, 0xa9, 0x4b, 0xf1, 0xd2, 0x39, 0x48, 0x31, 0x27, 0x90, 0xe9, 0xe3, 0xbb, - 0x41, 0x9a, 0xe0, 0x45, 0xce, 0x11, 0x13, 0xb5, 0xdb, 0xeb, 0xd5, 0xba, 0x2c, 0xc5, 0xfb, 0x06, - 0xbf, 0xe4, 0x42, 0x3e, 0x9c, 0x99, 0xff, 0x60, 0x8e, 0xe7, 0x5f, 0x89, 0x41, 0x2e, 0x94, 0x69, - 0x93, 0x14, 0x49, 0x35, 0x0c, 0xeb, 0x96, 0xa2, 0x1a, 0xba, 0xea, 0xf2, 0xd0, 0x00, 0x2a, 0xaa, - 0x10, 0xc9, 0xb8, 0x43, 0xf7, 0x03, 0x9a, 0x34, 0x93, 0x52, 0xaa, 0xf4, 0x99, 0x18, 0x48, 0xbd, - 0xa9, 0x6e, 0x8f, 0x99, 0xb1, 0x3f, 0x4a, 0x33, 0x4b, 0x9f, 0x8e, 0x41, 0x21, 0x9a, 0xdf, 0xf6, - 0x98, 0xf7, 0xf0, 0x1f, 0xa9, 0x79, 0xdf, 0x88, 0xc3, 0x54, 0x24, 0xab, 0x1d, 0xd7, 0xba, 0x1f, - 0x87, 0x19, 0xbd, 0x85, 0x3b, 0xb6, 0xe5, 0x61, 0x53, 0x3b, 0x50, 0x0c, 0x7c, 0x13, 0x1b, 0xc5, - 0x12, 0x5d, 0x34, 0xce, 0x1c, 0x9e, 0x37, 0x2f, 0xaf, 0x06, 0xb8, 0x35, 0x02, 0x2b, 0xcf, 0xae, - 0xd6, 0xea, 0xeb, 0x8d, 0xcd, 0xad, 0xfa, 0xc6, 0xca, 0x6b, 0xca, 0xf6, 0xc6, 0xf5, 0x8d, 0xcd, - 0x57, 0x36, 0x64, 0x49, 0xef, 0x51, 0xfb, 0x00, 0xa7, 0x7d, 0x03, 0xa4, 0x5e, 0xa3, 0xd0, 0x09, - 0x18, 0x64, 0x96, 0x34, 0x81, 0x66, 0x61, 0x7a, 0x63, 0x53, 0x69, 0xae, 0xd6, 0xea, 0x4a, 0xfd, - 0xf2, 0xe5, 0xfa, 0xca, 0x56, 0x93, 0xdd, 0x84, 0xf8, 0xda, 0x5b, 0x91, 0x09, 0x5e, 0xfa, 0x54, - 0x02, 0x66, 0x07, 0x58, 0x82, 0x2a, 0xfc, 0x0c, 0xc3, 0x8e, 0x55, 0xcf, 0x8c, 0x63, 0xfd, 0x32, - 0xc9, 0x22, 0x1a, 0xaa, 0xe3, 0xf1, 0x23, 0xcf, 0x13, 0x40, 0xbc, 0x64, 0x7a, 0xfa, 0xae, 0x8e, - 0x1d, 0x7e, 0xc3, 0xc4, 0x0e, 0x36, 0xd3, 0x81, 0x9c, 0x5d, 0x32, 0x3d, 0x0d, 0xc8, 0xb6, 0x5c, - 0xdd, 0xd3, 0x6f, 0x62, 0x45, 0x37, 0xc5, 0x75, 0x14, 0x39, 0xe8, 0x24, 0x65, 0x49, 0xd4, 0xac, - 0x9a, 0x9e, 0xaf, 0x6d, 0xe2, 0xb6, 0xda, 0xa3, 0x4d, 0x16, 0xf3, 0x84, 0x2c, 0x89, 0x1a, 0x5f, - 0xfb, 0x61, 0xc8, 0xb7, 0xac, 0x2e, 0xc9, 0xfe, 0x98, 0x1e, 0xd9, 0x3b, 0x62, 0x72, 0x8e, 0xc9, - 0x7c, 0x15, 0x9e, 0xd7, 0x07, 0xf7, 0x60, 0x79, 0x39, 0xc7, 0x64, 0x4c, 0xe5, 0x14, 0x4c, 0xab, - 0xed, 0xb6, 0x43, 0xc8, 0x05, 0x11, 0x3b, 0xa9, 0x14, 0x7c, 0x31, 0x55, 0x9c, 0xbf, 0x06, 0x19, - 0xe1, 0x07, 0xb2, 0x79, 0x13, 0x4f, 0x28, 0x36, 0x3b, 0x7e, 0xc7, 0x4f, 0x67, 0xe5, 0x8c, 0x29, - 0x2a, 0x1f, 0x86, 0xbc, 0xee, 0x2a, 0xc1, 0xb5, 0x7e, 0x7c, 0x29, 0x7e, 0x3a, 0x23, 0xe7, 0x74, - 0xd7, 0xbf, 0x12, 0x2d, 0x7d, 0x2e, 0x0e, 0x85, 0xe8, 0x63, 0x09, 0x54, 0x83, 0x8c, 0x61, 0x69, - 0x2a, 0x0d, 0x2d, 0xf6, 0x4c, 0xec, 0xf4, 0x88, 0x27, 0x19, 0xcb, 0x6b, 0x5c, 0x5f, 0xf6, 0x91, - 0xf3, 0xff, 0x36, 0x06, 0x19, 0x21, 0x46, 0xc7, 0x21, 0x69, 0xab, 0xde, 0x1e, 0xa5, 0x9b, 0xac, - 0xc6, 0xa5, 0x98, 0x4c, 0xcb, 0x44, 0xee, 0xda, 0xaa, 0x49, 0x43, 0x80, 0xcb, 0x49, 0x99, 0x8c, - 0xab, 0x81, 0xd5, 0x16, 0x3d, 0x06, 0x59, 0x9d, 0x0e, 0x36, 0x3d, 0x57, 0x8c, 0x2b, 0x97, 0xaf, - 0x70, 0x31, 0x7a, 0x0a, 0x66, 0x3c, 0x47, 0xd5, 0x8d, 0x88, 0x6e, 0x92, 0xea, 0x4a, 0xa2, 0xc2, - 0x57, 0x2e, 0xc3, 0x49, 0xc1, 0xdb, 0xc2, 0x9e, 0xaa, 0xed, 0xe1, 0x56, 0x00, 0x4a, 0xd1, 0xeb, - 0x8e, 0x13, 0x5c, 0xa1, 0xc6, 0xeb, 0x05, 0xb6, 0xf4, 0xeb, 0x31, 0x98, 0x11, 0x07, 0xb7, 0x96, - 0xef, 0xac, 0x75, 0x00, 0xd5, 0x34, 0x2d, 0x2f, 0xec, 0xae, 0xfe, 0x50, 0xee, 0xc3, 0x2d, 0x57, - 0x7c, 0x90, 0x1c, 0x22, 0x98, 0xef, 0x00, 0x04, 0x35, 0x43, 0xdd, 0xb6, 0x08, 0x39, 0xfe, 0xcc, - 0x89, 0x3e, 0xb8, 0x64, 0x47, 0x7d, 0x60, 0x22, 0x72, 0xc2, 0x43, 0x73, 0x30, 0xb9, 0x83, 0xdb, - 0xba, 0xc9, 0x6f, 0x92, 0x59, 0x41, 0x5c, 0xc8, 0x24, 0xfd, 0x0b, 0x99, 0xea, 0x9f, 0x81, 0x59, - 0xcd, 0xea, 0xf4, 0x9a, 0x5b, 0x95, 0x7a, 0xae, 0x1b, 0xdc, 0xab, 0xb1, 0xd7, 0x9f, 0xe1, 0x4a, - 0x6d, 0xcb, 0x50, 0xcd, 0xf6, 0xb2, 0xe5, 0xb4, 0x83, 0x07, 0xaf, 0x24, 0xe3, 0x71, 0x43, 0x8f, - 0x5f, 0xed, 0x9d, 0xdf, 0x8f, 0xc5, 0x7e, 0x3e, 0x9e, 0xb8, 0xd2, 0xa8, 0x7e, 0x3e, 0x3e, 0x7f, - 0x85, 0x01, 0x1b, 0xc2, 0x19, 0x32, 0xde, 0x35, 0xb0, 0x46, 0x3a, 0x08, 0xdf, 0x79, 0x0a, 0xe6, - 0xda, 0x56, 0xdb, 0xa2, 0x4c, 0x67, 0xc8, 0x2f, 0xfe, 0xe4, 0x36, 0xeb, 0x4b, 0xe7, 0x47, 0x3e, - 0xe6, 0x2d, 0x6f, 0xc0, 0x2c, 0x57, 0x56, 0xe8, 0xa3, 0x23, 0x76, 0xb0, 0x41, 0x87, 0xde, 0xaa, - 0x15, 0x7f, 0xf9, 0x5b, 0x74, 0xfb, 0x96, 0x67, 0x38, 0x94, 0xd4, 0xb1, 0xb3, 0x4f, 0x59, 0x86, - 0x63, 0x11, 0x3e, 0x36, 0x49, 0xb1, 0x33, 0x82, 0xf1, 0x5f, 0x72, 0xc6, 0xd9, 0x10, 0x63, 0x93, - 0x43, 0xcb, 0x2b, 0x30, 0x75, 0x14, 0xae, 0x7f, 0xc5, 0xb9, 0xf2, 0x38, 0x4c, 0x72, 0x05, 0xa6, - 0x29, 0x89, 0xd6, 0x75, 0x3d, 0xab, 0x43, 0x57, 0xc0, 0xc3, 0x69, 0xfe, 0xf5, 0xb7, 0xd8, 0xac, - 0x29, 0x10, 0xd8, 0x8a, 0x8f, 0x2a, 0x97, 0x81, 0x3e, 0x2d, 0x6b, 0x61, 0xcd, 0x18, 0xc1, 0xf0, - 0x55, 0x6e, 0x88, 0xaf, 0x5f, 0xbe, 0x01, 0x73, 0xe4, 0x37, 0x5d, 0xa0, 0xc2, 0x96, 0x8c, 0xbe, - 0x82, 0x2b, 0xfe, 0xfa, 0x47, 0xd9, 0xc4, 0x9c, 0xf5, 0x09, 0x42, 0x36, 0x85, 0x46, 0xb1, 0x8d, - 0x3d, 0x0f, 0x3b, 0xae, 0xa2, 0x1a, 0x83, 0xcc, 0x0b, 0xdd, 0x61, 0x14, 0x7f, 0xf6, 0xbb, 0xd1, - 0x51, 0xbc, 0xc2, 0x90, 0x15, 0xc3, 0x28, 0x6f, 0xc3, 0x89, 0x01, 0x51, 0x31, 0x06, 0xe7, 0xa7, - 0x38, 0xe7, 0x5c, 0x5f, 0x64, 0x10, 0xda, 0x06, 0x08, 0xb9, 0x3f, 0x96, 0x63, 0x70, 0xfe, 0x1c, - 0xe7, 0x44, 0x1c, 0x2b, 0x86, 0x94, 0x30, 0x5e, 0x83, 0x99, 0x9b, 0xd8, 0xd9, 0xb1, 0x5c, 0x7e, - 0x6f, 0x34, 0x06, 0xdd, 0xa7, 0x39, 0xdd, 0x34, 0x07, 0xd2, 0x8b, 0x24, 0xc2, 0x75, 0x11, 0x32, - 0xbb, 0xaa, 0x86, 0xc7, 0xa0, 0xb8, 0xcb, 0x29, 0xd2, 0x44, 0x9f, 0x40, 0x2b, 0x90, 0x6f, 0x5b, - 0x7c, 0x8f, 0x1a, 0x0d, 0xff, 0x0c, 0x87, 0xe7, 0x04, 0x86, 0x53, 0xd8, 0x96, 0xdd, 0x35, 0xc8, - 0x06, 0x36, 0x9a, 0xe2, 0xaf, 0x0b, 0x0a, 0x81, 0xe1, 0x14, 0x47, 0x70, 0xeb, 0xdb, 0x82, 0xc2, - 0x0d, 0xf9, 0xf3, 0x25, 0xc8, 0x59, 0xa6, 0x71, 0x60, 0x99, 0xe3, 0x18, 0xf1, 0x0e, 0x67, 0x00, - 0x0e, 0x21, 0x04, 0x97, 0x20, 0x3b, 0xee, 0x40, 0xfc, 0x8d, 0xef, 0x8a, 0xe9, 0x21, 0x46, 0xe0, - 0x0a, 0x4c, 0x8b, 0x05, 0x4a, 0xb7, 0xcc, 0x31, 0x28, 0xfe, 0x26, 0xa7, 0x28, 0x84, 0x60, 0xbc, - 0x1b, 0x1e, 0x76, 0xbd, 0x36, 0x1e, 0x87, 0xe4, 0x73, 0xa2, 0x1b, 0x1c, 0xc2, 0x5d, 0xb9, 0x83, - 0x4d, 0x6d, 0x6f, 0x3c, 0x86, 0x5f, 0x14, 0xae, 0x14, 0x18, 0x42, 0xb1, 0x02, 0x53, 0x1d, 0xd5, - 0x71, 0xf7, 0x54, 0x63, 0xac, 0xe1, 0xf8, 0x5b, 0x9c, 0x23, 0xef, 0x83, 0xb8, 0x47, 0xba, 0xe6, - 0x51, 0x68, 0x3e, 0x2f, 0x3c, 0x12, 0x82, 0xf1, 0xa9, 0xe7, 0x7a, 0xf4, 0x92, 0xed, 0x28, 0x6c, - 0x7f, 0x5b, 0x4c, 0x3d, 0x86, 0x5d, 0x0f, 0x33, 0x5e, 0x82, 0xac, 0xab, 0xbf, 0x39, 0x16, 0xcd, - 0x17, 0xc4, 0x48, 0x53, 0x00, 0x01, 0xbf, 0x06, 0x27, 0x07, 0x6e, 0x13, 0x63, 0x90, 0xfd, 0x1d, - 0x4e, 0x76, 0x7c, 0xc0, 0x56, 0xc1, 0x97, 0x84, 0xa3, 0x52, 0xfe, 0x5d, 0xb1, 0x24, 0xe0, 0x1e, - 0xae, 0x06, 0x39, 0x35, 0xb8, 0xea, 0xee, 0xd1, 0xbc, 0xf6, 0xf7, 0x84, 0xd7, 0x18, 0x36, 0xe2, - 0xb5, 0x2d, 0x38, 0xce, 0x19, 0x8f, 0x36, 0xae, 0xbf, 0x24, 0x16, 0x56, 0x86, 0xde, 0x8e, 0x8e, - 0xee, 0x8f, 0xc2, 0xbc, 0xef, 0x4e, 0x91, 0x9e, 0xba, 0x4a, 0x47, 0xb5, 0xc7, 0x60, 0xfe, 0x65, - 0xce, 0x2c, 0x56, 0x7c, 0x3f, 0xbf, 0x75, 0xd7, 0x55, 0x9b, 0x90, 0xbf, 0x0a, 0x45, 0x41, 0xde, - 0x35, 0x1d, 0xac, 0x59, 0x6d, 0x53, 0x7f, 0x13, 0xb7, 0xc6, 0xa0, 0xfe, 0x95, 0x9e, 0xa1, 0xda, - 0x0e, 0xc1, 0x09, 0xf3, 0x2a, 0x48, 0x7e, 0xae, 0xa2, 0xe8, 0x1d, 0xdb, 0x72, 0xbc, 0x11, 0x8c, - 0x5f, 0x14, 0x23, 0xe5, 0xe3, 0x56, 0x29, 0xac, 0x5c, 0x07, 0xf6, 0xe4, 0x79, 0xdc, 0x90, 0xfc, - 0x12, 0x27, 0x9a, 0x0a, 0x50, 0x7c, 0xe1, 0xd0, 0xac, 0x8e, 0xad, 0x3a, 0xe3, 0xac, 0x7f, 0x7f, - 0x5f, 0x2c, 0x1c, 0x1c, 0xc2, 0x17, 0x0e, 0x92, 0xd1, 0x91, 0xdd, 0x7e, 0x0c, 0x86, 0x2f, 0x8b, - 0x85, 0x43, 0x60, 0x38, 0x85, 0x48, 0x18, 0xc6, 0xa0, 0xf8, 0x07, 0x82, 0x42, 0x60, 0x08, 0xc5, - 0xcb, 0xc1, 0x46, 0xeb, 0xe0, 0xb6, 0xee, 0x7a, 0x0e, 0x4b, 0x8a, 0x0f, 0xa7, 0xfa, 0x87, 0xdf, - 0x8d, 0x26, 0x61, 0x72, 0x08, 0x4a, 0x56, 0x22, 0x7e, 0xed, 0x4a, 0xcf, 0x4c, 0xa3, 0x0d, 0xfb, - 0x55, 0xb1, 0x12, 0x85, 0x60, 0xc4, 0xb6, 0x50, 0x86, 0x48, 0xdc, 0xae, 0x91, 0x93, 0xc2, 0x18, - 0x74, 0xff, 0xa8, 0xc7, 0xb8, 0xa6, 0xc0, 0x12, 0xce, 0x50, 0xfe, 0xd3, 0x35, 0xf7, 0xf1, 0xc1, - 0x58, 0xd1, 0xf9, 0x6b, 0x3d, 0xf9, 0xcf, 0x36, 0x43, 0xb2, 0x35, 0x64, 0xba, 0x27, 0x9f, 0x42, - 0xa3, 0xde, 0x33, 0x2a, 0x7e, 0xe4, 0x7d, 0xde, 0xdf, 0x68, 0x3a, 0x55, 0x5e, 0x23, 0x41, 0x1e, - 0x4d, 0x7a, 0x46, 0x93, 0x7d, 0xf4, 0x7d, 0x3f, 0xce, 0x23, 0x39, 0x4f, 0xf9, 0x32, 0x4c, 0x45, - 0x12, 0x9e, 0xd1, 0x54, 0x7f, 0x96, 0x53, 0xe5, 0xc3, 0xf9, 0x4e, 0xf9, 0x1c, 0x24, 0x49, 0xf2, - 0x32, 0x1a, 0xfe, 0x93, 0x1c, 0x4e, 0xd5, 0xcb, 0x1f, 0x82, 0x8c, 0x48, 0x5a, 0x46, 0x43, 0xff, - 0x1c, 0x87, 0xfa, 0x10, 0x02, 0x17, 0x09, 0xcb, 0x68, 0xf8, 0x9f, 0x17, 0x70, 0x01, 0x21, 0xf0, - 0xf1, 0x5d, 0xf8, 0x95, 0xbf, 0x90, 0xe4, 0x9b, 0x8e, 0xf0, 0xdd, 0x25, 0x48, 0xf3, 0x4c, 0x65, - 0x34, 0xfa, 0xe3, 0xbc, 0x71, 0x81, 0x28, 0x5f, 0x80, 0xc9, 0x31, 0x1d, 0xfe, 0x17, 0x39, 0x94, - 0xe9, 0x97, 0x57, 0x20, 0x17, 0xca, 0x4e, 0x46, 0xc3, 0xff, 0x12, 0x87, 0x87, 0x51, 0xc4, 0x74, - 0x9e, 0x9d, 0x8c, 0x26, 0xf8, 0xcb, 0xc2, 0x74, 0x8e, 0x20, 0x6e, 0x13, 0x89, 0xc9, 0x68, 0xf4, - 0x27, 0x84, 0xd7, 0x05, 0xa4, 0xfc, 0x12, 0x64, 0xfd, 0xcd, 0x66, 0x34, 0xfe, 0xa7, 0x38, 0x3e, - 0xc0, 0x10, 0x0f, 0x84, 0x36, 0xbb, 0xd1, 0x14, 0x7f, 0x45, 0x78, 0x20, 0x84, 0x22, 0xd3, 0xa8, - 0x37, 0x81, 0x19, 0xcd, 0xf4, 0xd3, 0x62, 0x1a, 0xf5, 0xe4, 0x2f, 0x64, 0x34, 0xe9, 0x9a, 0x3f, - 0x9a, 0xe2, 0xaf, 0x8a, 0xd1, 0xa4, 0xfa, 0xc4, 0x8c, 0xde, 0x8c, 0x60, 0x34, 0xc7, 0xcf, 0x08, - 0x33, 0x7a, 0x12, 0x82, 0x72, 0x03, 0x50, 0x7f, 0x36, 0x30, 0x9a, 0xef, 0x93, 0x9c, 0x6f, 0xa6, - 0x2f, 0x19, 0x28, 0xbf, 0x02, 0xc7, 0x07, 0x67, 0x02, 0xa3, 0x59, 0x7f, 0xf6, 0xfd, 0x9e, 0xb3, - 0x5b, 0x38, 0x11, 0x28, 0x6f, 0x05, 0x5b, 0x4a, 0x38, 0x0b, 0x18, 0x4d, 0xfb, 0xa9, 0xf7, 0xa3, - 0x0b, 0x77, 0x38, 0x09, 0x28, 0x57, 0x00, 0x82, 0x0d, 0x78, 0x34, 0xd7, 0xa7, 0x39, 0x57, 0x08, - 0x44, 0xa6, 0x06, 0xdf, 0x7f, 0x47, 0xe3, 0xef, 0x8a, 0xa9, 0xc1, 0x11, 0x64, 0x6a, 0x88, 0xad, - 0x77, 0x34, 0xfa, 0x33, 0x62, 0x6a, 0x08, 0x08, 0x89, 0xec, 0xd0, 0xee, 0x36, 0x9a, 0xe1, 0x1d, - 0x11, 0xd9, 0x21, 0x54, 0x79, 0x03, 0x66, 0xfa, 0x36, 0xc4, 0xd1, 0x54, 0x3f, 0xcf, 0xa9, 0xa4, - 0xde, 0xfd, 0x30, 0xbc, 0x79, 0xf1, 0xcd, 0x70, 0x34, 0xdb, 0x67, 0x7b, 0x36, 0x2f, 0xbe, 0x17, - 0x96, 0x2f, 0x41, 0xc6, 0xec, 0x1a, 0x06, 0x99, 0x3c, 0xe8, 0xf0, 0x77, 0x03, 0x8b, 0xff, 0xed, - 0xfb, 0xdc, 0x3b, 0x02, 0x50, 0x3e, 0x07, 0x93, 0xb8, 0xb3, 0x83, 0x5b, 0xa3, 0x90, 0xdf, 0xf9, - 0xbe, 0x58, 0x30, 0x89, 0x76, 0xf9, 0x25, 0x00, 0x76, 0x35, 0x42, 0x1f, 0x06, 0x8e, 0xc0, 0xfe, - 0xf7, 0xef, 0xf3, 0x97, 0x71, 0x02, 0x48, 0x40, 0xc0, 0x5e, 0xed, 0x39, 0x9c, 0xe0, 0xbb, 0x51, - 0x02, 0x3a, 0x22, 0x17, 0x21, 0xfd, 0x86, 0x6b, 0x99, 0x9e, 0xda, 0x1e, 0x85, 0xfe, 0x1f, 0x1c, - 0x2d, 0xf4, 0x89, 0xc3, 0x3a, 0x96, 0x83, 0x3d, 0xb5, 0xed, 0x8e, 0xc2, 0xfe, 0x4f, 0x8e, 0xf5, - 0x01, 0x04, 0xac, 0xa9, 0xae, 0x37, 0x4e, 0xbf, 0x7f, 0x57, 0x80, 0x05, 0x80, 0x18, 0x4d, 0x7e, - 0xef, 0xe3, 0x83, 0x51, 0xd8, 0xef, 0x09, 0xa3, 0xb9, 0x7e, 0xf9, 0x43, 0x90, 0x25, 0x3f, 0xd9, - 0x1b, 0x76, 0x23, 0xc0, 0xff, 0x8b, 0x83, 0x03, 0x04, 0x69, 0xd9, 0xf5, 0x5a, 0x9e, 0x3e, 0xda, - 0xd9, 0xbf, 0xc7, 0x47, 0x5a, 0xe8, 0x97, 0x2b, 0x90, 0x73, 0xbd, 0x56, 0xab, 0xcb, 0xf3, 0xd3, - 0x11, 0xf0, 0xff, 0xfd, 0x7d, 0xff, 0xca, 0xc2, 0xc7, 0x90, 0xd1, 0xbe, 0xb5, 0xef, 0xd9, 0x16, - 0x7d, 0xe0, 0x31, 0x8a, 0xe1, 0x7d, 0xce, 0x10, 0x82, 0x94, 0x57, 0x20, 0x4f, 0xfa, 0xe2, 0x60, - 0x1b, 0xd3, 0xa7, 0x53, 0x23, 0x28, 0xfe, 0x0f, 0x77, 0x40, 0x04, 0x54, 0xfd, 0xb1, 0xaf, 0xbe, - 0xb7, 0x10, 0xfb, 0xfa, 0x7b, 0x0b, 0xb1, 0x6f, 0xbc, 0xb7, 0x10, 0xfb, 0xc4, 0x37, 0x17, 0x26, - 0xbe, 0xfe, 0xcd, 0x85, 0x89, 0xdf, 0xfa, 0xe6, 0xc2, 0xc4, 0xe0, 0x5b, 0x62, 0xb8, 0x62, 0x5d, - 0xb1, 0xd8, 0xfd, 0xf0, 0xeb, 0xa5, 0xb6, 0xee, 0xed, 0x75, 0x77, 0x96, 0x35, 0xab, 0x43, 0xaf, - 0x71, 0x83, 0xdb, 0x5a, 0xff, 0x90, 0x03, 0x1f, 0x89, 0x93, 0x03, 0x73, 0xf4, 0x2e, 0x57, 0x35, - 0x0f, 0x86, 0x7c, 0xab, 0x33, 0x3f, 0xf0, 0x62, 0xb8, 0x74, 0x15, 0x12, 0x15, 0xf3, 0x00, 0x9d, - 0x64, 0x6b, 0x9e, 0xd2, 0x75, 0x0c, 0xfe, 0xe6, 0x57, 0x9a, 0x94, 0xb7, 0x1d, 0x03, 0xcd, 0x05, - 0xaf, 0x67, 0xc6, 0x4e, 0xe7, 0xf9, 0x3b, 0x97, 0x65, 0xe9, 0x93, 0x6f, 0x2f, 0x4e, 0xfc, 0xd2, - 0xdb, 0x8b, 0x13, 0xdf, 0x7b, 0x67, 0x71, 0xe2, 0xad, 0xdf, 0x59, 0x9a, 0xa8, 0xee, 0xf7, 0xf6, - 0xf6, 0x2b, 0x23, 0x7b, 0x9c, 0xa9, 0x98, 0x07, 0xb4, 0xc3, 0x8d, 0xd8, 0xeb, 0x93, 0xf4, 0xd2, - 0x5b, 0x5c, 0x72, 0x2f, 0xf4, 0x5e, 0x72, 0xbf, 0x82, 0x0d, 0xe3, 0xba, 0x69, 0xdd, 0x32, 0xb7, - 0x88, 0xda, 0x4e, 0x8a, 0xbd, 0x52, 0x0c, 0x3f, 0x1d, 0x87, 0x85, 0xbe, 0xfb, 0x6c, 0x1e, 0x05, - 0xc3, 0x3e, 0x5a, 0x2a, 0x43, 0xa6, 0x26, 0x82, 0xab, 0x08, 0x69, 0x17, 0x6b, 0x96, 0xd9, 0x72, - 0x69, 0xb7, 0x13, 0xb2, 0x28, 0x92, 0x6e, 0x9b, 0xaa, 0x69, 0xb9, 0xfc, 0x4d, 0x49, 0x56, 0xa8, - 0xfe, 0x5c, 0xec, 0x68, 0x63, 0x3a, 0x25, 0x5a, 0x12, 0xdd, 0x7c, 0x6e, 0xe4, 0xb5, 0xff, 0x3e, - 0xe9, 0xa5, 0xdf, 0x89, 0xc8, 0xd5, 0xff, 0xb8, 0x5e, 0xf9, 0x99, 0x38, 0x2c, 0xf6, 0x7a, 0x85, - 0x4c, 0x2d, 0xd7, 0x53, 0x3b, 0xf6, 0x30, 0xb7, 0x5c, 0x82, 0xec, 0x96, 0xd0, 0x39, 0xb2, 0x5f, - 0xee, 0x1e, 0xd1, 0x2f, 0x05, 0xbf, 0x29, 0xe1, 0x98, 0xb3, 0x63, 0x3a, 0xc6, 0xef, 0xc7, 0x3d, - 0x79, 0xe6, 0xff, 0xa6, 0xe0, 0xa4, 0x66, 0xb9, 0x1d, 0xcb, 0x55, 0xd8, 0x54, 0x60, 0x05, 0xee, - 0x93, 0x7c, 0xb8, 0x6a, 0xf4, 0x83, 0x92, 0xd2, 0x75, 0x98, 0x5d, 0x25, 0xcb, 0x05, 0x39, 0x06, - 0x05, 0x8f, 0x78, 0x06, 0xbe, 0x4c, 0xba, 0x14, 0xc9, 0xf8, 0xf9, 0x23, 0xa6, 0xb0, 0xa8, 0xf4, - 0x91, 0x18, 0x48, 0x4d, 0x4d, 0x35, 0x54, 0xe7, 0x0f, 0x4b, 0x85, 0x2e, 0x00, 0xd0, 0x8f, 0x90, - 0x82, 0xaf, 0x86, 0x0a, 0x67, 0x8b, 0xcb, 0xe1, 0xce, 0x2d, 0xb3, 0x96, 0xe8, 0x27, 0x09, 0x59, - 0xaa, 0x4b, 0x7e, 0x3e, 0xf9, 0x2a, 0x40, 0x50, 0x81, 0x1e, 0x80, 0x13, 0xcd, 0x95, 0xca, 0x5a, - 0x45, 0x56, 0xd8, 0xdb, 0xed, 0x1b, 0xcd, 0x46, 0x7d, 0x65, 0xf5, 0xf2, 0x6a, 0xbd, 0x26, 0x4d, - 0xa0, 0xe3, 0x80, 0xc2, 0x95, 0xfe, 0x8b, 0x29, 0xc7, 0x60, 0x26, 0x2c, 0x67, 0xaf, 0xc8, 0xc7, - 0x49, 0xaa, 0xa8, 0x77, 0x6c, 0x03, 0xd3, 0x67, 0x7f, 0x8a, 0x2e, 0xbc, 0x36, 0x3a, 0x0b, 0xf9, - 0x37, 0xff, 0x8e, 0xbd, 0x36, 0x3d, 0x1b, 0xc0, 0x7d, 0x9f, 0x97, 0xd7, 0x60, 0x46, 0xd5, 0x34, - 0x6c, 0x47, 0x28, 0x47, 0xac, 0xd5, 0x84, 0x90, 0x3e, 0xcd, 0xe4, 0xc8, 0x80, 0xed, 0x02, 0xa4, - 0x5c, 0xda, 0xfb, 0x51, 0x14, 0x5f, 0xe3, 0x14, 0x5c, 0xbd, 0x6c, 0xc2, 0x0c, 0x49, 0xfd, 0x54, - 0x07, 0x87, 0xcc, 0x38, 0xfc, 0xa2, 0xe1, 0x1f, 0x7f, 0xf1, 0x59, 0xfa, 0x6c, 0xf3, 0xe1, 0xe8, - 0xb0, 0x0c, 0x08, 0x27, 0x59, 0xe2, 0xdc, 0x81, 0xa1, 0x18, 0x0a, 0xa2, 0x3d, 0x6e, 0xf0, 0xe1, - 0x8d, 0xfd, 0x13, 0xde, 0xd8, 0xc2, 0xa0, 0x18, 0x08, 0xb5, 0x34, 0xc5, 0x59, 0x59, 0x45, 0xb5, - 0x3e, 0x6c, 0x4e, 0xbf, 0xfe, 0x54, 0x68, 0x7b, 0x62, 0x94, 0xfc, 0xcf, 0x33, 0x94, 0xf9, 0x52, - 0xb8, 0x19, 0x7f, 0xee, 0xfd, 0x66, 0x02, 0x16, 0xb8, 0xf2, 0x8e, 0xea, 0xe2, 0x33, 0x37, 0x9f, - 0xdb, 0xc1, 0x9e, 0xfa, 0xdc, 0x19, 0xcd, 0xd2, 0xc5, 0x5a, 0x3d, 0xcb, 0xa7, 0x23, 0xa9, 0x5f, - 0xe6, 0xf5, 0x83, 0x37, 0xae, 0xf9, 0xe1, 0xd3, 0xb8, 0xb4, 0x0d, 0xc9, 0x15, 0x4b, 0x37, 0xc9, - 0x52, 0xd5, 0xc2, 0xa6, 0xd5, 0xe1, 0xb3, 0x87, 0x15, 0xd0, 0x73, 0x90, 0x52, 0x3b, 0x56, 0xd7, - 0xf4, 0xd8, 0xcc, 0xa9, 0x9e, 0xfc, 0xea, 0xbb, 0x8b, 0x13, 0xff, 0xfe, 0xdd, 0xc5, 0xc4, 0xaa, - 0xe9, 0xfd, 0xc6, 0x97, 0x9e, 0x01, 0x4e, 0xb5, 0x6a, 0x7a, 0x32, 0x57, 0x2c, 0x27, 0xbf, 0xfd, - 0xf6, 0x62, 0xac, 0xf4, 0x2a, 0xa4, 0x6b, 0x58, 0xbb, 0x17, 0xe6, 0x1a, 0xd6, 0x42, 0xcc, 0x35, - 0xac, 0xf5, 0x30, 0x5f, 0x80, 0xcc, 0xaa, 0xe9, 0xb1, 0x37, 0xd1, 0x9f, 0x82, 0x84, 0x6e, 0xb2, - 0x97, 0x1b, 0x0f, 0xb5, 0x8d, 0x68, 0x11, 0x60, 0x0d, 0x6b, 0x3e, 0xb0, 0x85, 0xb5, 0x5e, 0x60, - 0x7f, 0xd3, 0x44, 0xab, 0x5a, 0xfb, 0xad, 0xff, 0xbc, 0x30, 0xf1, 0xd6, 0x7b, 0x0b, 0x13, 0x43, - 0x87, 0xb8, 0x34, 0x74, 0x88, 0xdd, 0xd6, 0x3e, 0x5b, 0x91, 0xfd, 0x91, 0xfd, 0x7c, 0x12, 0x1e, - 0xa2, 0x1f, 0x28, 0x39, 0x1d, 0xdd, 0xf4, 0xce, 0x68, 0xce, 0x81, 0xed, 0xd1, 0x94, 0xc5, 0xda, - 0xe5, 0x03, 0x3b, 0x13, 0x54, 0x2f, 0xb3, 0xea, 0x21, 0xf9, 0xc8, 0x2e, 0x4c, 0x36, 0x08, 0x8e, - 0xb8, 0xd8, 0xb3, 0x3c, 0xd5, 0xe0, 0xfb, 0x0f, 0x2b, 0x10, 0x29, 0xfb, 0xa8, 0x29, 0xce, 0xa4, - 0xba, 0xf8, 0x9e, 0xc9, 0xc0, 0xea, 0x2e, 0x7b, 0x37, 0x3c, 0x41, 0xd3, 0x94, 0x0c, 0x11, 0xd0, - 0xd7, 0xc0, 0xe7, 0x60, 0x52, 0xed, 0xb2, 0x97, 0x18, 0x12, 0x24, 0x7f, 0xa1, 0x85, 0xd2, 0x75, - 0x48, 0xf3, 0x47, 0xa9, 0x48, 0x82, 0xc4, 0x3e, 0x3e, 0xa0, 0xed, 0xe4, 0x65, 0xf2, 0x13, 0x2d, - 0xc3, 0x24, 0x35, 0x9e, 0x7f, 0xf4, 0x52, 0x5c, 0xee, 0xb3, 0x7e, 0x99, 0x1a, 0x29, 0x33, 0xb5, - 0xd2, 0x35, 0xc8, 0xd4, 0xac, 0x8e, 0x6e, 0x5a, 0x51, 0xb6, 0x2c, 0x63, 0xa3, 0x36, 0xdb, 0x5d, - 0x1e, 0x15, 0x32, 0x2b, 0xa0, 0xe3, 0x90, 0x62, 0xdf, 0x0a, 0xf0, 0x17, 0x31, 0x78, 0xa9, 0xb4, - 0x02, 0x69, 0xca, 0xbd, 0x69, 0x93, 0xc5, 0xdf, 0x7f, 0x2d, 0x33, 0xcb, 0xbf, 0x1c, 0xe3, 0xf4, - 0xf1, 0xc0, 0x58, 0x04, 0xc9, 0x96, 0xea, 0xa9, 0xbc, 0xdf, 0xf4, 0x77, 0xe9, 0xc3, 0x90, 0xe1, - 0x24, 0x2e, 0x3a, 0x0b, 0x09, 0xcb, 0x76, 0xf9, 0xab, 0x14, 0xf3, 0xc3, 0xba, 0xb2, 0x69, 0x57, - 0x93, 0x24, 0x66, 0x64, 0xa2, 0x5c, 0x95, 0x87, 0x86, 0xc5, 0x8b, 0xa1, 0xb0, 0x08, 0x0d, 0x79, - 0xe8, 0x27, 0x1b, 0xd2, 0xbe, 0x70, 0xf0, 0x83, 0xe5, 0x9d, 0x38, 0x2c, 0x84, 0x6a, 0x6f, 0x62, - 0xc7, 0xd5, 0x2d, 0x93, 0x45, 0x14, 0x8f, 0x16, 0x14, 0x32, 0x92, 0xd7, 0x0f, 0x09, 0x97, 0x0f, - 0x41, 0xa2, 0x62, 0xdb, 0x68, 0x1e, 0x32, 0xb4, 0xac, 0x59, 0x2c, 0x5e, 0x92, 0xb2, 0x5f, 0x26, - 0x75, 0xae, 0xb5, 0xeb, 0xdd, 0x52, 0x1d, 0xff, 0x73, 0x3a, 0x51, 0x2e, 0x5d, 0x84, 0xec, 0x8a, - 0x65, 0xba, 0xd8, 0x74, 0xbb, 0x34, 0xb3, 0xd9, 0x31, 0x2c, 0x6d, 0x9f, 0x33, 0xb0, 0x02, 0x71, - 0xb8, 0x6a, 0xdb, 0x14, 0x99, 0x94, 0xc9, 0x4f, 0x36, 0x67, 0xab, 0xcd, 0xa1, 0x2e, 0xba, 0x78, - 0x74, 0x17, 0xf1, 0x4e, 0xfa, 0x3e, 0xfa, 0x83, 0x18, 0x3c, 0xd8, 0x3f, 0xa1, 0xf6, 0xf1, 0x81, - 0x7b, 0xd4, 0xf9, 0xf4, 0x2a, 0x64, 0x1b, 0xf4, 0x9b, 0xf6, 0xeb, 0xf8, 0x00, 0xcd, 0x43, 0x1a, - 0xb7, 0xce, 0x9e, 0x3b, 0xf7, 0xdc, 0x45, 0x16, 0xed, 0x57, 0x27, 0x64, 0x21, 0x40, 0x0b, 0x90, - 0x75, 0xb1, 0x66, 0x9f, 0x3d, 0x77, 0x7e, 0xff, 0x39, 0x16, 0x5e, 0x57, 0x27, 0xe4, 0x40, 0x54, - 0xce, 0x90, 0x5e, 0x7f, 0xfb, 0x9d, 0xc5, 0x58, 0x75, 0x12, 0x12, 0x6e, 0xb7, 0xf3, 0x81, 0xc6, - 0xc8, 0xa7, 0x26, 0x61, 0x29, 0x8c, 0xa4, 0xf9, 0xdf, 0x4d, 0xd5, 0xd0, 0x5b, 0x6a, 0xf0, 0xdf, - 0x08, 0xa4, 0x90, 0x0f, 0xa8, 0xc6, 0x90, 0x9d, 0xe2, 0x50, 0x4f, 0x96, 0x7e, 0x25, 0x06, 0xf9, - 0x1b, 0x82, 0xb9, 0x89, 0x3d, 0x74, 0x09, 0xc0, 0x6f, 0x49, 0x4c, 0x9b, 0x07, 0x96, 0x7b, 0xdb, - 0x5a, 0xf6, 0x31, 0x72, 0x48, 0x1d, 0x5d, 0xa0, 0x81, 0x68, 0x5b, 0x2e, 0xff, 0xc4, 0x6a, 0x04, - 0xd4, 0x57, 0x46, 0x4f, 0x03, 0xa2, 0x2b, 0x9c, 0x72, 0xd3, 0xf2, 0x74, 0xb3, 0xad, 0xd8, 0xd6, - 0x2d, 0xfe, 0xe1, 0x6a, 0x42, 0x96, 0x68, 0xcd, 0x0d, 0x5a, 0xd1, 0x20, 0x72, 0x62, 0x74, 0xd6, - 0x67, 0x21, 0xc9, 0xba, 0xda, 0x6a, 0x39, 0xd8, 0x75, 0xf9, 0x22, 0x26, 0x8a, 0xe8, 0x12, 0xa4, - 0xed, 0xee, 0x8e, 0x22, 0x56, 0x8c, 0xdc, 0xd9, 0x07, 0x07, 0xcd, 0x7f, 0x11, 0x1f, 0x7c, 0x05, - 0x48, 0xd9, 0xdd, 0x1d, 0x12, 0x2d, 0x0f, 0x43, 0x7e, 0x80, 0x31, 0xb9, 0x9b, 0x81, 0x1d, 0xf4, - 0x5f, 0x29, 0xf0, 0x1e, 0x28, 0xb6, 0xa3, 0x5b, 0x8e, 0xee, 0x1d, 0xd0, 0xf7, 0xa1, 0x12, 0xb2, - 0x24, 0x2a, 0x1a, 0x5c, 0x5e, 0xda, 0x87, 0xe9, 0x26, 0x4d, 0xe2, 0x02, 0xcb, 0xcf, 0x05, 0xf6, - 0xc5, 0x46, 0xdb, 0x37, 0xd4, 0xb2, 0x78, 0x9f, 0x65, 0xd5, 0x97, 0x87, 0x46, 0xe7, 0x85, 0xa3, - 0x47, 0x67, 0x74, 0xb7, 0xfb, 0xdd, 0x93, 0x91, 0xc9, 0xc9, 0x82, 0x33, 0xbc, 0x7c, 0x8d, 0x1b, - 0x98, 0xa3, 0xce, 0x68, 0xf3, 0x87, 0x6f, 0xaa, 0xf3, 0x23, 0x96, 0xd1, 0xf9, 0x91, 0x53, 0xa8, - 0x74, 0x11, 0xa6, 0x1a, 0xaa, 0xe3, 0x35, 0xb1, 0x77, 0x15, 0xab, 0x2d, 0xec, 0x44, 0x77, 0xdd, - 0x29, 0xb1, 0xeb, 0x22, 0x48, 0xd2, 0xad, 0x95, 0xed, 0x3a, 0xf4, 0x77, 0x69, 0x0f, 0x92, 0xf4, - 0x9d, 0x48, 0x7f, 0x47, 0xe6, 0x08, 0xb6, 0x23, 0x93, 0xb5, 0xf4, 0xc0, 0xc3, 0xae, 0xb8, 0x34, - 0xa0, 0x05, 0xf4, 0x82, 0xd8, 0x57, 0x13, 0x87, 0xef, 0xab, 0x3c, 0x10, 0xf9, 0xee, 0x6a, 0x40, - 0xba, 0x4a, 0x96, 0xe2, 0xd5, 0x9a, 0x6f, 0x48, 0x2c, 0x30, 0x04, 0xad, 0xc3, 0xb4, 0xad, 0x3a, - 0x1e, 0xfd, 0x3c, 0x64, 0x8f, 0xf6, 0x82, 0xc7, 0xfa, 0x62, 0xff, 0xcc, 0x8b, 0x74, 0x96, 0xb7, - 0x32, 0x65, 0x87, 0x85, 0xa5, 0xff, 0x92, 0x84, 0x14, 0x77, 0xc6, 0x87, 0x20, 0xcd, 0xdd, 0xca, - 0xa3, 0xf3, 0xa1, 0xe5, 0xfe, 0x8d, 0x69, 0xd9, 0xdf, 0x40, 0x38, 0x9f, 0xc0, 0xa0, 0xc7, 0x21, - 0xa3, 0xed, 0xa9, 0xba, 0xa9, 0xe8, 0x2d, 0x9e, 0x10, 0xe6, 0xde, 0x7b, 0x77, 0x31, 0xbd, 0x42, - 0x64, 0xab, 0x35, 0x39, 0x4d, 0x2b, 0x57, 0x5b, 0x24, 0x13, 0xd8, 0xc3, 0x7a, 0x7b, 0xcf, 0xe3, - 0x33, 0x8c, 0x97, 0xd0, 0x8b, 0x90, 0x24, 0x01, 0xc1, 0x3f, 0x1e, 0x9c, 0xef, 0xcb, 0xf0, 0xfd, - 0x23, 0x74, 0x35, 0x43, 0x1a, 0xfe, 0xc4, 0x7f, 0x5a, 0x8c, 0xc9, 0x14, 0x81, 0x56, 0x60, 0xca, - 0x50, 0x5d, 0x4f, 0xa1, 0x3b, 0x18, 0x69, 0x7e, 0x92, 0x52, 0x9c, 0xec, 0x77, 0x08, 0x77, 0x2c, - 0x37, 0x3d, 0x47, 0x50, 0x4c, 0xd4, 0x42, 0xa7, 0x41, 0xa2, 0x24, 0x9a, 0xd5, 0xe9, 0xe8, 0x1e, - 0xcb, 0xad, 0x52, 0xd4, 0xef, 0x05, 0x22, 0x5f, 0xa1, 0x62, 0x9a, 0x61, 0x3d, 0x00, 0x59, 0xfa, - 0xb9, 0x12, 0x55, 0x61, 0x2f, 0xe2, 0x66, 0x88, 0x80, 0x56, 0x9e, 0x82, 0xe9, 0x60, 0x7d, 0x64, - 0x2a, 0x19, 0xc6, 0x12, 0x88, 0xa9, 0xe2, 0xb3, 0x30, 0x67, 0xe2, 0xdb, 0xf4, 0xd5, 0xe0, 0x88, - 0x76, 0x96, 0x6a, 0x23, 0x52, 0x77, 0x23, 0x8a, 0x78, 0x0c, 0x0a, 0x9a, 0x70, 0x3e, 0xd3, 0x05, - 0xaa, 0x3b, 0xe5, 0x4b, 0xa9, 0xda, 0x49, 0xc8, 0xa8, 0xb6, 0xcd, 0x14, 0x72, 0x7c, 0x7d, 0xb4, - 0x6d, 0x5a, 0xf5, 0x24, 0xcc, 0xd0, 0x3e, 0x3a, 0xd8, 0xed, 0x1a, 0x1e, 0x27, 0xc9, 0x53, 0x9d, - 0x69, 0x52, 0x21, 0x33, 0x39, 0xd5, 0x7d, 0x04, 0xa6, 0xf0, 0x4d, 0xbd, 0x85, 0x4d, 0x0d, 0x33, - 0xbd, 0x29, 0xaa, 0x97, 0x17, 0x42, 0xaa, 0xf4, 0x04, 0xf8, 0xeb, 0x9e, 0x22, 0xd6, 0xe4, 0x02, - 0xe3, 0x13, 0xf2, 0x0a, 0x13, 0x97, 0x8a, 0x90, 0xac, 0xa9, 0x9e, 0x4a, 0x12, 0x0c, 0xef, 0x36, - 0xdb, 0x68, 0xf2, 0x32, 0xf9, 0x59, 0xfa, 0x76, 0x1c, 0x92, 0x37, 0x2c, 0x0f, 0xa3, 0xe7, 0x43, - 0x09, 0x60, 0x61, 0x50, 0x3c, 0x37, 0xf5, 0xb6, 0x89, 0x5b, 0xeb, 0x6e, 0x3b, 0xf4, 0xbf, 0x05, - 0x82, 0x70, 0x8a, 0x47, 0xc2, 0x69, 0x0e, 0x26, 0x1d, 0xab, 0x6b, 0xb6, 0xc4, 0x3b, 0xac, 0xb4, - 0x80, 0xea, 0x90, 0xf1, 0xa3, 0x24, 0x39, 0x2a, 0x4a, 0xa6, 0x49, 0x94, 0x90, 0x18, 0xe6, 0x02, - 0x39, 0xbd, 0xc3, 0x83, 0xa5, 0x0a, 0x59, 0x7f, 0xf1, 0xe2, 0xd1, 0x36, 0x5e, 0xc0, 0x06, 0x30, - 0xb2, 0x99, 0xf8, 0x63, 0xef, 0x3b, 0x8f, 0x45, 0x9c, 0xe4, 0x57, 0x70, 0xef, 0x45, 0xc2, 0x8a, - 0xff, 0x9f, 0x83, 0x34, 0xed, 0x57, 0x10, 0x56, 0xec, 0x7f, 0x1d, 0x3c, 0x08, 0x59, 0x57, 0x6f, - 0x9b, 0xaa, 0xd7, 0x75, 0x30, 0x8f, 0xbc, 0x40, 0x50, 0xfa, 0x4a, 0x0c, 0x52, 0x2c, 0x92, 0x43, - 0x7e, 0x8b, 0x0d, 0xf6, 0x5b, 0x7c, 0x98, 0xdf, 0x12, 0xf7, 0xee, 0xb7, 0x0a, 0x80, 0x6f, 0x8c, - 0xcb, 0x3f, 0x3f, 0x1f, 0x90, 0x31, 0x30, 0x13, 0x9b, 0x7a, 0x9b, 0x4f, 0xd4, 0x10, 0xa8, 0xf4, - 0x1f, 0x63, 0x24, 0x89, 0xe5, 0xf5, 0xa8, 0x02, 0x53, 0xc2, 0x2e, 0x65, 0xd7, 0x50, 0xdb, 0x3c, - 0x76, 0x1e, 0x1a, 0x6a, 0xdc, 0x65, 0x43, 0x6d, 0xcb, 0x39, 0x6e, 0x0f, 0x29, 0x0c, 0x1e, 0x87, - 0xf8, 0x90, 0x71, 0x88, 0x0c, 0x7c, 0xe2, 0xde, 0x06, 0x3e, 0x32, 0x44, 0xc9, 0xde, 0x21, 0xfa, - 0x62, 0x9c, 0x1e, 0x66, 0x6c, 0xcb, 0x55, 0x8d, 0x1f, 0xc4, 0x8c, 0x78, 0x00, 0xb2, 0xb6, 0x65, - 0x28, 0xac, 0x86, 0xbd, 0xdb, 0x9d, 0xb1, 0x2d, 0x43, 0xee, 0x1b, 0xf6, 0xc9, 0xfb, 0x34, 0x5d, - 0x52, 0xf7, 0xc1, 0x6b, 0xe9, 0x5e, 0xaf, 0x39, 0x90, 0x67, 0xae, 0xe0, 0x7b, 0xd9, 0xb3, 0xc4, - 0x07, 0x74, 0x73, 0x8c, 0xf5, 0xef, 0xbd, 0xcc, 0x6c, 0xa6, 0x29, 0x73, 0x3d, 0x82, 0x60, 0x4b, - 0xff, 0xa0, 0x53, 0x70, 0x38, 0x2c, 0x65, 0xae, 0x57, 0xfa, 0x6b, 0x31, 0x80, 0x35, 0xe2, 0x59, - 0xda, 0x5f, 0xb2, 0x0b, 0xb9, 0xd4, 0x04, 0x25, 0xd2, 0xf2, 0xc2, 0xb0, 0x41, 0xe3, 0xed, 0xe7, - 0xdd, 0xb0, 0xdd, 0x2b, 0x30, 0x15, 0x04, 0xa3, 0x8b, 0x85, 0x31, 0x0b, 0x87, 0x64, 0xd5, 0x4d, - 0xec, 0xc9, 0xf9, 0x9b, 0xa1, 0x52, 0xe9, 0x9f, 0xc7, 0x20, 0x4b, 0x6d, 0x5a, 0xc7, 0x9e, 0x1a, - 0x19, 0xc3, 0xd8, 0xbd, 0x8f, 0xe1, 0x43, 0x00, 0x8c, 0xc6, 0xd5, 0xdf, 0xc4, 0x3c, 0xb2, 0xb2, - 0x54, 0xd2, 0xd4, 0xdf, 0xc4, 0xe8, 0xbc, 0xef, 0xf0, 0xc4, 0xe1, 0x0e, 0x17, 0x59, 0x37, 0x77, - 0xfb, 0x09, 0x48, 0xd3, 0x7f, 0xd7, 0x74, 0xdb, 0xe5, 0x89, 0x74, 0xca, 0xec, 0x76, 0xb6, 0x6e, - 0xbb, 0xa5, 0x37, 0x20, 0xbd, 0x75, 0x9b, 0xdd, 0x8d, 0x3c, 0x00, 0x59, 0xc7, 0xb2, 0xf8, 0x9e, - 0xcc, 0x72, 0xa1, 0x0c, 0x11, 0xd0, 0x2d, 0x48, 0xdc, 0x07, 0xc4, 0x83, 0xfb, 0x80, 0xe0, 0x42, - 0x23, 0x31, 0xd6, 0x85, 0xc6, 0x93, 0xbf, 0x19, 0x83, 0x5c, 0x68, 0x7d, 0x40, 0xcf, 0xc1, 0xb1, - 0xea, 0xda, 0xe6, 0xca, 0x75, 0x65, 0xb5, 0xa6, 0x5c, 0x5e, 0xab, 0x5c, 0x09, 0xbe, 0x5e, 0x9a, - 0x3f, 0x7e, 0xe7, 0xee, 0x12, 0x0a, 0xe9, 0x6e, 0x9b, 0xf4, 0x9e, 0x1e, 0x9d, 0x81, 0xb9, 0x28, - 0xa4, 0x52, 0x6d, 0xd6, 0x37, 0xb6, 0xa4, 0xd8, 0xfc, 0xb1, 0x3b, 0x77, 0x97, 0x66, 0x42, 0x88, - 0xca, 0x8e, 0x8b, 0x4d, 0xaf, 0x1f, 0xb0, 0xb2, 0xb9, 0xbe, 0xbe, 0xba, 0x25, 0xc5, 0xfb, 0x00, - 0x7c, 0xc1, 0x7e, 0x02, 0x66, 0xa2, 0x80, 0x8d, 0xd5, 0x35, 0x29, 0x31, 0x8f, 0xee, 0xdc, 0x5d, - 0x2a, 0x84, 0xb4, 0x37, 0x74, 0x63, 0x3e, 0xf3, 0xb1, 0xcf, 0x2e, 0x4c, 0xfc, 0xe2, 0x2f, 0x2c, - 0xc4, 0x48, 0xcf, 0xa6, 0x22, 0x6b, 0x04, 0x7a, 0x1a, 0x4e, 0x34, 0x57, 0xaf, 0x6c, 0xd4, 0x6b, - 0xca, 0x7a, 0xf3, 0x8a, 0xb8, 0xe9, 0x16, 0xbd, 0x9b, 0xbe, 0x73, 0x77, 0x29, 0xc7, 0xbb, 0x34, - 0x4c, 0xbb, 0x21, 0xd7, 0x6f, 0x6c, 0x6e, 0xd5, 0xa5, 0x18, 0xd3, 0x6e, 0x38, 0xf8, 0xa6, 0xe5, - 0xb1, 0xff, 0xe7, 0xf6, 0x2c, 0x9c, 0x1c, 0xa0, 0xed, 0x77, 0x6c, 0xe6, 0xce, 0xdd, 0xa5, 0xa9, - 0x86, 0x83, 0xd9, 0xfc, 0xa1, 0x88, 0x65, 0x28, 0xf6, 0x23, 0x36, 0x1b, 0x9b, 0xcd, 0xca, 0x9a, - 0xb4, 0x34, 0x2f, 0xdd, 0xb9, 0xbb, 0x94, 0x17, 0x8b, 0x21, 0xd1, 0x0f, 0x7a, 0xf6, 0x41, 0x9e, - 0x78, 0x7e, 0x72, 0x19, 0x1e, 0xe5, 0x77, 0x80, 0xae, 0xa7, 0xee, 0xeb, 0x66, 0xdb, 0xbf, 0xbc, - 0xe5, 0x65, 0x7e, 0xf2, 0x39, 0xce, 0xef, 0x19, 0x85, 0x74, 0xc4, 0x15, 0xee, 0xd0, 0xa7, 0x97, - 0xf3, 0x23, 0x1e, 0xea, 0x8d, 0x3e, 0x3a, 0x0d, 0xbf, 0x1e, 0x9e, 0x1f, 0x71, 0x09, 0x3d, 0x7f, - 0xe8, 0xe1, 0xae, 0xf4, 0xf1, 0x18, 0x14, 0xae, 0xea, 0xae, 0x67, 0x39, 0xba, 0xa6, 0x1a, 0xf4, - 0x9b, 0xa5, 0xf3, 0xe3, 0xae, 0xad, 0x3d, 0x53, 0xfd, 0x25, 0x48, 0xdd, 0x54, 0x0d, 0xb6, 0xa8, - 0x85, 0x9f, 0x05, 0xf4, 0xba, 0x2f, 0x58, 0xda, 0x04, 0x01, 0x83, 0x95, 0xbe, 0x10, 0x87, 0x69, - 0x3a, 0x19, 0x5c, 0xf6, 0xef, 0xb8, 0xc8, 0x19, 0xab, 0x01, 0x49, 0x47, 0xf5, 0xf8, 0xa5, 0x61, - 0xf5, 0x47, 0xf8, 0x3d, 0xf0, 0xe3, 0xa3, 0x6f, 0x73, 0x97, 0xfb, 0xaf, 0x8a, 0x29, 0x13, 0x7a, - 0x05, 0x32, 0x1d, 0xf5, 0xb6, 0x42, 0x59, 0xe3, 0xf7, 0x81, 0x35, 0xdd, 0x51, 0x6f, 0x13, 0x5b, - 0x51, 0x0b, 0xa6, 0x09, 0xb1, 0xb6, 0xa7, 0x9a, 0x6d, 0xcc, 0xf8, 0x13, 0xf7, 0x81, 0x7f, 0xaa, - 0xa3, 0xde, 0x5e, 0xa1, 0x9c, 0xa4, 0x95, 0x72, 0xe6, 0x93, 0x6f, 0x2f, 0x4e, 0xd0, 0x6b, 0xf6, - 0x5f, 0x8b, 0x01, 0x04, 0xee, 0x42, 0x7f, 0x12, 0x24, 0xcd, 0x2f, 0xd1, 0xe6, 0x5d, 0x3e, 0x80, - 0xa7, 0x86, 0x0d, 0x44, 0x8f, 0xb3, 0xd9, 0xc6, 0xfc, 0xf5, 0x77, 0x17, 0x63, 0xf2, 0xb4, 0xd6, - 0x33, 0x0e, 0x75, 0xc8, 0x75, 0xed, 0x96, 0xea, 0x61, 0x85, 0x1e, 0xe2, 0xe2, 0x47, 0xd8, 0xe4, - 0x81, 0x01, 0x49, 0x55, 0xc8, 0xfa, 0x2f, 0xc4, 0x20, 0x57, 0x0b, 0x3d, 0xe4, 0x2b, 0x42, 0xba, - 0x63, 0x99, 0xfa, 0x3e, 0x0f, 0xbb, 0xac, 0x2c, 0x8a, 0x68, 0x1e, 0x32, 0xec, 0x6b, 0x4d, 0xef, - 0x40, 0xdc, 0x78, 0x8a, 0x32, 0x41, 0xdd, 0xc2, 0x3b, 0xae, 0x2e, 0x7c, 0x2d, 0x8b, 0x22, 0x39, - 0xba, 0xb8, 0x58, 0xeb, 0x3a, 0xba, 0x77, 0xa0, 0x68, 0x96, 0xe9, 0xa9, 0x9a, 0xc7, 0xbf, 0xfb, - 0x9b, 0x16, 0xf2, 0x15, 0x26, 0x26, 0x24, 0x2d, 0xec, 0xa9, 0xba, 0xe1, 0x16, 0xd9, 0x83, 0x30, - 0x51, 0x0c, 0x99, 0xfb, 0xfb, 0xe9, 0xf0, 0x15, 0xd5, 0x0a, 0x48, 0x96, 0x8d, 0x9d, 0x48, 0x4a, - 0xc9, 0x22, 0xb4, 0xf8, 0x1b, 0x5f, 0x7a, 0x66, 0x8e, 0xbb, 0x9b, 0x27, 0x95, 0xec, 0xc5, 0x56, - 0x79, 0x5a, 0x20, 0x44, 0xae, 0xf9, 0x1a, 0x19, 0x30, 0x71, 0xde, 0xb3, 0xbb, 0x3b, 0xc1, 0xb5, - 0xd6, 0x5c, 0x9f, 0x5f, 0x2b, 0xe6, 0x41, 0xb5, 0xf8, 0xb5, 0x80, 0x3a, 0xb8, 0x4b, 0xba, 0x8e, - 0x0f, 0xc8, 0x68, 0x71, 0x9e, 0x06, 0xa5, 0x21, 0x29, 0xe2, 0x1b, 0xaa, 0x6e, 0x88, 0x8f, 0xd0, - 0x65, 0x5e, 0x42, 0x65, 0x48, 0xb9, 0x9e, 0xea, 0x75, 0x5d, 0xfe, 0xcf, 0xe2, 0x4a, 0xc3, 0x22, - 0xa3, 0x6a, 0x99, 0xad, 0x26, 0xd5, 0x94, 0x39, 0x02, 0x6d, 0x41, 0xca, 0xb3, 0xf6, 0xb1, 0xc9, - 0x9d, 0x74, 0xa4, 0xa8, 0x1e, 0xf0, 0x2c, 0x8a, 0x71, 0xa1, 0x36, 0x48, 0x2d, 0x6c, 0xe0, 0x36, - 0x4b, 0x88, 0xf6, 0x54, 0x72, 0x6e, 0x48, 0xdd, 0x87, 0x59, 0x33, 0xed, 0xb3, 0x36, 0x29, 0x29, - 0xba, 0x1e, 0x7d, 0xcc, 0xcc, 0xfe, 0xb3, 0xe2, 0x23, 0xc3, 0xfa, 0x1f, 0x8a, 0x4c, 0x71, 0x99, - 0x10, 0x7e, 0x22, 0xfd, 0x04, 0x48, 0x5d, 0x73, 0xc7, 0x32, 0xe9, 0xa7, 0xa2, 0x3c, 0x19, 0xcf, - 0xd0, 0xf4, 0x66, 0xda, 0x97, 0x5f, 0x65, 0x59, 0xf9, 0x75, 0x28, 0x04, 0xaa, 0x74, 0xee, 0x64, - 0x8f, 0x30, 0x77, 0xa6, 0x7c, 0x2c, 0xa9, 0x45, 0x57, 0x01, 0x82, 0x89, 0x49, 0xaf, 0x07, 0x72, - 0xc3, 0xc7, 0x30, 0x98, 0xdd, 0xe2, 0x98, 0x15, 0x60, 0x91, 0x01, 0xb3, 0x1d, 0xdd, 0x54, 0x5c, - 0x6c, 0xec, 0x2a, 0xdc, 0x55, 0x84, 0x32, 0x77, 0x1f, 0x86, 0x76, 0xa6, 0xa3, 0x9b, 0x4d, 0x6c, - 0xec, 0xd6, 0x7c, 0x5a, 0x54, 0x25, 0x93, 0x91, 0xb5, 0xe4, 0xcf, 0x97, 0xfc, 0x88, 0xf9, 0x52, - 0x70, 0x19, 0x87, 0x98, 0x2e, 0x15, 0x98, 0x76, 0xb0, 0xa1, 0x1e, 0x84, 0xae, 0x22, 0xa6, 0x46, - 0x51, 0x70, 0x80, 0xa0, 0x78, 0x3c, 0xa0, 0xd8, 0x31, 0x5c, 0x7a, 0x4f, 0xcb, 0x6e, 0x33, 0xa6, - 0xb8, 0xb8, 0x6a, 0xb8, 0xd7, 0xf1, 0x41, 0x39, 0xff, 0xb1, 0xb7, 0x17, 0x27, 0xf8, 0xd4, 0x9f, - 0x28, 0x35, 0xe8, 0x8d, 0x3a, 0xe7, 0xc0, 0x2e, 0x3a, 0x0f, 0x59, 0x55, 0x14, 0xe8, 0x3d, 0xc7, - 0x61, 0x26, 0x04, 0xaa, 0x6c, 0x31, 0x79, 0xeb, 0x77, 0x96, 0x62, 0xa5, 0x5f, 0x88, 0x41, 0xaa, - 0x76, 0xa3, 0xa1, 0xea, 0x0e, 0xaa, 0xc3, 0x4c, 0x10, 0xff, 0xe3, 0x2e, 0x25, 0xc1, 0x94, 0x11, - 0x3d, 0xab, 0x0f, 0x3b, 0xe4, 0x1e, 0x4a, 0xd3, 0x7b, 0xfc, 0xed, 0xe9, 0x78, 0x1d, 0xd2, 0xcc, - 0x4a, 0x17, 0x95, 0x61, 0xd2, 0x26, 0x3f, 0xf8, 0x03, 0x84, 0x85, 0xa1, 0xf3, 0x86, 0xea, 0xfb, - 0x17, 0x9e, 0x04, 0x52, 0xfa, 0x83, 0x18, 0x40, 0xed, 0xc6, 0x8d, 0x2d, 0x47, 0xb7, 0x0d, 0xec, - 0xdd, 0xaf, 0x1e, 0xaf, 0xc1, 0xb1, 0xd0, 0x49, 0xca, 0xd1, 0xc6, 0xee, 0xf5, 0x6c, 0x70, 0x96, - 0x72, 0xb4, 0x81, 0x6c, 0x2d, 0xd7, 0xf3, 0xd9, 0x12, 0x63, 0xb3, 0xd5, 0x5c, 0x6f, 0xb0, 0x1b, - 0x9b, 0x90, 0x0b, 0xba, 0xef, 0xa2, 0x1a, 0x64, 0x3c, 0xfe, 0x9b, 0x7b, 0xb3, 0x34, 0xdc, 0x9b, - 0x02, 0xc6, 0x3d, 0xea, 0x23, 0x4b, 0xff, 0x8f, 0x38, 0x35, 0x98, 0x60, 0x7f, 0xac, 0xc2, 0x88, - 0x6c, 0x15, 0x7c, 0x29, 0xbf, 0x1f, 0x09, 0x10, 0xe7, 0xea, 0xf1, 0xea, 0x47, 0xe3, 0x30, 0xbb, - 0x2d, 0x16, 0xc7, 0x3f, 0xb6, 0x9e, 0x68, 0x40, 0x1a, 0x9b, 0x9e, 0xa3, 0x53, 0x57, 0x90, 0xb1, - 0x7e, 0x76, 0xd8, 0x58, 0x0f, 0xe8, 0x0b, 0xfd, 0x17, 0x4b, 0xe2, 0x1a, 0x9e, 0xd3, 0xf4, 0x78, - 0xe1, 0x3f, 0xc4, 0xa1, 0x38, 0x0c, 0x89, 0x4e, 0xc1, 0xb4, 0xe6, 0x60, 0x2a, 0x50, 0x22, 0x77, - 0x81, 0x05, 0x21, 0xe6, 0x7b, 0xd4, 0x3a, 0x90, 0x7c, 0x8f, 0x04, 0x16, 0x51, 0x3d, 0x72, 0x82, - 0x57, 0x08, 0xc0, 0x74, 0x97, 0xc2, 0x30, 0xad, 0x9b, 0xba, 0xa7, 0xab, 0x86, 0xb2, 0xa3, 0x1a, - 0xaa, 0xa9, 0xdd, 0x4b, 0x22, 0xdc, 0xbf, 0xaf, 0x14, 0x38, 0x69, 0x95, 0x71, 0xa2, 0x1b, 0x90, - 0x16, 0xf4, 0xc9, 0xfb, 0x40, 0x2f, 0xc8, 0x42, 0x49, 0xdf, 0x6f, 0xc7, 0x61, 0x46, 0xc6, 0xad, - 0x1f, 0x2e, 0xb7, 0xfe, 0x28, 0x00, 0x9b, 0x70, 0x64, 0x1d, 0xbc, 0x07, 0xcf, 0xf6, 0x4f, 0xe0, - 0x2c, 0xe3, 0xab, 0xb9, 0x5e, 0xc8, 0xb7, 0x5f, 0x8b, 0x43, 0x3e, 0xec, 0xdb, 0x1f, 0x82, 0x7d, - 0x01, 0xad, 0x06, 0xab, 0x41, 0x92, 0xff, 0x73, 0xd8, 0x21, 0xab, 0x41, 0x5f, 0xd4, 0x1d, 0xbe, - 0x0c, 0x7c, 0x23, 0x01, 0xa9, 0x86, 0xea, 0xa8, 0x1d, 0x17, 0x5d, 0xeb, 0xcb, 0x37, 0xc5, 0xa5, - 0x60, 0xdf, 0xbf, 0x00, 0xe7, 0x77, 0x10, 0x2c, 0xe4, 0x3e, 0x39, 0x20, 0xdd, 0x7c, 0x0c, 0x0a, - 0xe4, 0x44, 0x1b, 0x7a, 0x7f, 0x20, 0x4e, 0x9f, 0x8a, 0x92, 0x23, 0x69, 0xf0, 0xf0, 0x0a, 0x2d, - 0x42, 0x8e, 0xa8, 0x05, 0x0b, 0x1d, 0xd1, 0x81, 0x8e, 0x7a, 0xbb, 0xce, 0x24, 0xe8, 0x19, 0x40, - 0x7b, 0xfe, 0x1d, 0x83, 0x12, 0xb8, 0x80, 0xe8, 0xcd, 0x04, 0x35, 0x42, 0xfd, 0x21, 0x00, 0x62, - 0x85, 0xc2, 0xde, 0x49, 0x63, 0x47, 0xb2, 0x2c, 0x91, 0xd4, 0xe8, 0x7b, 0x69, 0x3f, 0xc1, 0x52, - 0xd7, 0x9e, 0xc3, 0x2e, 0x3f, 0x35, 0xac, 0x1d, 0x2d, 0x52, 0x7f, 0xef, 0xdd, 0xc5, 0xf9, 0x03, - 0xb5, 0x63, 0x94, 0x4b, 0x03, 0x28, 0x4b, 0x34, 0x95, 0x8d, 0x1e, 0x92, 0x87, 0x25, 0xce, 0xe9, - 0x0f, 0x24, 0x71, 0x0e, 0xcd, 0x97, 0xcf, 0xc6, 0x00, 0x05, 0x15, 0x32, 0x76, 0x6d, 0x72, 0xe6, - 0x23, 0x27, 0x82, 0x90, 0x15, 0xb1, 0xc3, 0x4f, 0x04, 0x01, 0x5e, 0x9c, 0x08, 0x42, 0xf3, 0xef, - 0x62, 0xb0, 0x9c, 0xc6, 0x79, 0xc4, 0x0c, 0x78, 0x7d, 0x71, 0x79, 0xc5, 0xd2, 0x05, 0xba, 0x6f, - 0xc5, 0x9c, 0x28, 0xfd, 0x76, 0x0c, 0x4e, 0xf6, 0xc5, 0xae, 0x6f, 0xec, 0x9f, 0x02, 0xe4, 0x84, - 0x2a, 0xf9, 0xff, 0x14, 0x64, 0x46, 0x1f, 0x79, 0x2a, 0xcc, 0x38, 0x7d, 0x2b, 0xf3, 0x07, 0xb5, - 0x23, 0xb0, 0xd7, 0x1a, 0xff, 0x69, 0x0c, 0xe6, 0xc2, 0xc6, 0xf8, 0xdd, 0xda, 0x80, 0x7c, 0xd8, - 0x16, 0xde, 0xa1, 0x47, 0xc7, 0xe9, 0x10, 0xef, 0x4b, 0x04, 0x8f, 0x5e, 0x0e, 0x96, 0x09, 0x76, - 0x93, 0xf6, 0xdc, 0xd8, 0xbe, 0x11, 0x36, 0xf5, 0x2e, 0x17, 0x49, 0x91, 0x33, 0x25, 0x1b, 0x96, - 0x65, 0xa0, 0x3f, 0x0d, 0x33, 0xa6, 0xe5, 0x29, 0x64, 0x4e, 0xe1, 0x96, 0xc2, 0x8f, 0xf5, 0x6c, - 0xad, 0x7d, 0xf9, 0x68, 0x2e, 0xfb, 0xce, 0xbb, 0x8b, 0xfd, 0x54, 0x3d, 0x7e, 0x9c, 0x36, 0x2d, - 0xaf, 0x4a, 0xeb, 0xb7, 0xd8, 0xa1, 0xdf, 0x81, 0xa9, 0x68, 0xd3, 0x6c, 0x6d, 0x5e, 0x3f, 0x72, - 0xd3, 0x53, 0x87, 0x35, 0x9b, 0xdf, 0x09, 0xb5, 0xc9, 0x5e, 0xf8, 0xfa, 0xde, 0xdb, 0x8b, 0xb1, - 0x27, 0xbf, 0x1c, 0x03, 0x08, 0xee, 0x37, 0xd0, 0xd3, 0x70, 0xa2, 0xba, 0xb9, 0x51, 0x53, 0x9a, - 0x5b, 0x95, 0xad, 0xed, 0x66, 0xf4, 0xb5, 0x70, 0x71, 0x61, 0xee, 0xda, 0x58, 0xd3, 0x77, 0x75, - 0xdc, 0x42, 0x8f, 0xc3, 0x5c, 0x54, 0x9b, 0x94, 0xea, 0x35, 0x29, 0x36, 0x9f, 0xbf, 0x73, 0x77, - 0x29, 0xc3, 0x72, 0x31, 0xdc, 0x42, 0xa7, 0xe1, 0x58, 0xbf, 0xde, 0xea, 0xc6, 0x15, 0x29, 0x3e, - 0x3f, 0x75, 0xe7, 0xee, 0x52, 0xd6, 0x4f, 0xda, 0x50, 0x09, 0x50, 0x58, 0x93, 0xf3, 0x25, 0xe6, - 0xe1, 0xce, 0xdd, 0xa5, 0x14, 0x73, 0xdb, 0x7c, 0xf2, 0x63, 0x9f, 0x5d, 0x98, 0xa8, 0x5e, 0x1e, - 0x7a, 0x25, 0xfe, 0xf4, 0xa1, 0x1e, 0xbb, 0xed, 0x5f, 0x73, 0x47, 0xee, 0xc1, 0xff, 0x7f, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x1b, 0xa3, 0x2e, 0x16, 0x25, 0x67, 0x00, 0x00, + 0x79, 0xd7, 0xf4, 0x63, 0xfa, 0xf1, 0x75, 0x4f, 0x77, 0x4d, 0xce, 0xec, 0x6e, 0xef, 0xdc, 0xdd, + 0xcc, 0x5c, 0xdf, 0x63, 0xf7, 0xf6, 0xee, 0x66, 0x6f, 0xf7, 0x6e, 0x77, 0x6f, 0x7b, 0x2d, 0x1d, + 0xdd, 0xd3, 0xbd, 0xb3, 0xb3, 0x3b, 0x8f, 0xbe, 0xea, 0x99, 0xbd, 0x87, 0x31, 0x15, 0x35, 0xd5, + 0x39, 0x3d, 0x75, 0x53, 0x5d, 0x55, 0xae, 0xaa, 0xde, 0xdd, 0xb9, 0x30, 0xc4, 0x29, 0xc4, 0x43, + 0x5a, 0x02, 0x90, 0x31, 0x81, 0x65, 0x59, 0x2b, 0xee, 0x2c, 0x83, 0x8c, 0x10, 0x60, 0x4b, 0x42, + 0x60, 0x1c, 0x60, 0x01, 0x01, 0x08, 0xfd, 0x41, 0xc8, 0xfe, 0x03, 0xdb, 0x60, 0x0e, 0x71, 0x52, + 0x80, 0x10, 0x02, 0x0b, 0x73, 0x44, 0x40, 0x28, 0x4c, 0x10, 0xf9, 0xaa, 0xaa, 0x7e, 0x4d, 0xf7, + 0x2c, 0x7b, 0xb2, 0x23, 0xf4, 0xd7, 0x74, 0x7e, 0xf9, 0xfd, 0x7e, 0xf9, 0xe5, 0x97, 0x5f, 0x66, + 0x7e, 0x99, 0x55, 0x35, 0xf0, 0xcf, 0xae, 0xc0, 0x62, 0xcb, 0xb2, 0x5a, 0x06, 0x3e, 0x6b, 0x3b, + 0x96, 0x67, 0xed, 0x74, 0x76, 0xcf, 0x36, 0xb1, 0xab, 0x39, 0xba, 0xed, 0x59, 0xce, 0x12, 0x95, + 0xa1, 0x3c, 0xd3, 0x58, 0x12, 0x1a, 0xc5, 0x75, 0x98, 0xbe, 0xaa, 0x1b, 0xb8, 0xea, 0x2b, 0x36, + 0xb0, 0x87, 0x5e, 0x84, 0xf8, 0xae, 0x6e, 0xe0, 0x42, 0x64, 0x31, 0x76, 0x3a, 0x73, 0xfe, 0xf1, + 0xa5, 0x1e, 0xd0, 0x52, 0x37, 0xa2, 0x4e, 0xc4, 0x32, 0x45, 0x14, 0xbf, 0x1d, 0x87, 0x99, 0x01, + 0xb5, 0x08, 0x41, 0xdc, 0x54, 0xdb, 0x84, 0x31, 0x72, 0x3a, 0x2d, 0xd3, 0xdf, 0xa8, 0x00, 0x49, + 0x5b, 0xd5, 0xf6, 0xd5, 0x16, 0x2e, 0x44, 0xa9, 0x58, 0x14, 0xd1, 0x3c, 0x40, 0x13, 0xdb, 0xd8, + 0x6c, 0x62, 0x53, 0x3b, 0x28, 0xc4, 0x16, 0x63, 0xa7, 0xd3, 0x72, 0x48, 0x82, 0x9e, 0x86, 0x69, + 0xbb, 0xb3, 0x63, 0xe8, 0x9a, 0x12, 0x52, 0x83, 0xc5, 0xd8, 0xe9, 0x49, 0x59, 0x62, 0x15, 0xd5, + 0x40, 0xf9, 0x14, 0xe4, 0x6f, 0x63, 0x75, 0x3f, 0xac, 0x9a, 0xa1, 0xaa, 0x39, 0x22, 0x0e, 0x29, + 0x2e, 0x43, 0xb6, 0x8d, 0x5d, 0x57, 0x6d, 0x61, 0xc5, 0x3b, 0xb0, 0x71, 0x21, 0x4e, 0x7b, 0xbf, + 0xd8, 0xd7, 0xfb, 0xde, 0x9e, 0x67, 0x38, 0x6a, 0xeb, 0xc0, 0xc6, 0xa8, 0x0c, 0x69, 0x6c, 0x76, + 0xda, 0x8c, 0x61, 0x72, 0x88, 0xff, 0x6a, 0x66, 0xa7, 0xdd, 0xcb, 0x92, 0x22, 0x30, 0x4e, 0x91, + 0x74, 0xb1, 0x73, 0x4b, 0xd7, 0x70, 0x21, 0x41, 0x09, 0x4e, 0xf5, 0x11, 0x34, 0x58, 0x7d, 0x2f, + 0x87, 0xc0, 0xa1, 0x65, 0x48, 0xe3, 0x3b, 0x1e, 0x36, 0x5d, 0xdd, 0x32, 0x0b, 0x49, 0x4a, 0xf2, + 0xc4, 0x80, 0x51, 0xc4, 0x46, 0xb3, 0x97, 0x22, 0xc0, 0xa1, 0x8b, 0x90, 0xb4, 0x6c, 0x4f, 0xb7, + 0x4c, 0xb7, 0x90, 0x5a, 0x8c, 0x9c, 0xce, 0x9c, 0x7f, 0x78, 0x60, 0x20, 0x6c, 0x32, 0x1d, 0x59, + 0x28, 0xa3, 0x55, 0x90, 0x5c, 0xab, 0xe3, 0x68, 0x58, 0xd1, 0xac, 0x26, 0x56, 0x74, 0x73, 0xd7, + 0x2a, 0xa4, 0x29, 0xc1, 0x42, 0x7f, 0x47, 0xa8, 0xe2, 0xb2, 0xd5, 0xc4, 0xab, 0xe6, 0xae, 0x25, + 0xe7, 0xdc, 0xae, 0x32, 0x3a, 0x0e, 0x09, 0xf7, 0xc0, 0xf4, 0xd4, 0x3b, 0x85, 0x2c, 0x8d, 0x10, + 0x5e, 0x2a, 0xfe, 0x6a, 0x02, 0xf2, 0xe3, 0x84, 0xd8, 0x15, 0x98, 0xdc, 0x25, 0xbd, 0x2c, 0x44, + 0x8f, 0xe2, 0x03, 0x86, 0xe9, 0x76, 0x62, 0xe2, 0x3e, 0x9d, 0x58, 0x86, 0x8c, 0x89, 0x5d, 0x0f, + 0x37, 0x59, 0x44, 0xc4, 0xc6, 0x8c, 0x29, 0x60, 0xa0, 0xfe, 0x90, 0x8a, 0xdf, 0x57, 0x48, 0xbd, + 0x0a, 0x79, 0xdf, 0x24, 0xc5, 0x51, 0xcd, 0x96, 0x88, 0xcd, 0xb3, 0xa3, 0x2c, 0x59, 0xaa, 0x09, + 0x9c, 0x4c, 0x60, 0x72, 0x0e, 0x77, 0x95, 0x51, 0x15, 0xc0, 0x32, 0xb1, 0xb5, 0xab, 0x34, 0xb1, + 0x66, 0x14, 0x52, 0x43, 0xbc, 0xb4, 0x49, 0x54, 0xfa, 0xbc, 0x64, 0x31, 0xa9, 0x66, 0xa0, 0xcb, + 0x41, 0xa8, 0x25, 0x87, 0x44, 0xca, 0x3a, 0x9b, 0x64, 0x7d, 0xd1, 0xb6, 0x0d, 0x39, 0x07, 0x93, + 0xb8, 0xc7, 0x4d, 0xde, 0xb3, 0x34, 0x35, 0x62, 0x69, 0x64, 0xcf, 0x64, 0x0e, 0x63, 0x1d, 0x9b, + 0x72, 0xc2, 0x45, 0xf4, 0x18, 0xf8, 0x02, 0x85, 0x86, 0x15, 0xd0, 0x55, 0x28, 0x2b, 0x84, 0x1b, + 0x6a, 0x1b, 0xcf, 0xbd, 0x09, 0xb9, 0x6e, 0xf7, 0xa0, 0x59, 0x98, 0x74, 0x3d, 0xd5, 0xf1, 0x68, + 0x14, 0x4e, 0xca, 0xac, 0x80, 0x24, 0x88, 0x61, 0xb3, 0x49, 0x57, 0xb9, 0x49, 0x99, 0xfc, 0x44, + 0x7f, 0x2c, 0xe8, 0x70, 0x8c, 0x76, 0xf8, 0xc9, 0xfe, 0x11, 0xed, 0x62, 0xee, 0xed, 0xf7, 0xdc, + 0x25, 0x98, 0xea, 0xea, 0xc0, 0xb8, 0x4d, 0x17, 0x7f, 0x0a, 0x8e, 0x0d, 0xa4, 0x46, 0xaf, 0xc2, + 0x6c, 0xc7, 0xd4, 0x4d, 0x0f, 0x3b, 0xb6, 0x83, 0x49, 0xc4, 0xb2, 0xa6, 0x0a, 0xff, 0x39, 0x39, + 0x24, 0xe6, 0xb6, 0xc3, 0xda, 0x8c, 0x45, 0x9e, 0xe9, 0xf4, 0x0b, 0xcf, 0xa4, 0x53, 0xdf, 0x49, + 0x4a, 0x6f, 0xbd, 0xf5, 0xd6, 0x5b, 0xd1, 0xe2, 0x3f, 0x49, 0xc0, 0xec, 0xa0, 0x39, 0x33, 0x70, + 0xfa, 0x1e, 0x87, 0x84, 0xd9, 0x69, 0xef, 0x60, 0x87, 0x3a, 0x69, 0x52, 0xe6, 0x25, 0x54, 0x86, + 0x49, 0x43, 0xdd, 0xc1, 0x46, 0x21, 0xbe, 0x18, 0x39, 0x9d, 0x3b, 0xff, 0xf4, 0x58, 0xb3, 0x72, + 0x69, 0x8d, 0x40, 0x64, 0x86, 0x44, 0x1f, 0x86, 0x38, 0x5f, 0xa2, 0x09, 0xc3, 0x99, 0xf1, 0x18, + 0xc8, 0x5c, 0x92, 0x29, 0x0e, 0x3d, 0x04, 0x69, 0xf2, 0x97, 0xc5, 0x46, 0x82, 0xda, 0x9c, 0x22, + 0x02, 0x12, 0x17, 0x68, 0x0e, 0x52, 0x74, 0x9a, 0x34, 0xb1, 0xd8, 0xda, 0xfc, 0x32, 0x09, 0xac, + 0x26, 0xde, 0x55, 0x3b, 0x86, 0xa7, 0xdc, 0x52, 0x8d, 0x0e, 0xa6, 0x01, 0x9f, 0x96, 0xb3, 0x5c, + 0x78, 0x93, 0xc8, 0xd0, 0x02, 0x64, 0xd8, 0xac, 0xd2, 0xcd, 0x26, 0xbe, 0x43, 0x57, 0xcf, 0x49, + 0x99, 0x4d, 0xb4, 0x55, 0x22, 0x21, 0xcd, 0xbf, 0xe1, 0x5a, 0xa6, 0x08, 0x4d, 0xda, 0x04, 0x11, + 0xd0, 0xe6, 0x2f, 0xf5, 0x2e, 0xdc, 0x8f, 0x0c, 0xee, 0x5e, 0xdf, 0x5c, 0x3a, 0x05, 0x79, 0xaa, + 0xf1, 0x3c, 0x1f, 0x7a, 0xd5, 0x28, 0x4c, 0x2f, 0x46, 0x4e, 0xa7, 0xe4, 0x1c, 0x13, 0x6f, 0x72, + 0x69, 0xf1, 0x2b, 0x51, 0x88, 0xd3, 0x85, 0x25, 0x0f, 0x99, 0xad, 0xd7, 0xea, 0x35, 0xa5, 0xba, + 0xb9, 0x5d, 0x59, 0xab, 0x49, 0x11, 0x94, 0x03, 0xa0, 0x82, 0xab, 0x6b, 0x9b, 0xe5, 0x2d, 0x29, + 0xea, 0x97, 0x57, 0x37, 0xb6, 0x2e, 0xbe, 0x20, 0xc5, 0x7c, 0xc0, 0x36, 0x13, 0xc4, 0xc3, 0x0a, + 0xcf, 0x9f, 0x97, 0x26, 0x91, 0x04, 0x59, 0x46, 0xb0, 0xfa, 0x6a, 0xad, 0x7a, 0xf1, 0x05, 0x29, + 0xd1, 0x2d, 0x79, 0xfe, 0xbc, 0x94, 0x44, 0x53, 0x90, 0xa6, 0x92, 0xca, 0xe6, 0xe6, 0x9a, 0x94, + 0xf2, 0x39, 0x1b, 0x5b, 0xf2, 0xea, 0xc6, 0x8a, 0x94, 0xf6, 0x39, 0x57, 0xe4, 0xcd, 0xed, 0xba, + 0x04, 0x3e, 0xc3, 0x7a, 0xad, 0xd1, 0x28, 0xaf, 0xd4, 0xa4, 0x8c, 0xaf, 0x51, 0x79, 0x6d, 0xab, + 0xd6, 0x90, 0xb2, 0x5d, 0x66, 0x3d, 0x7f, 0x5e, 0x9a, 0xf2, 0x9b, 0xa8, 0x6d, 0x6c, 0xaf, 0x4b, + 0x39, 0x34, 0x0d, 0x53, 0xac, 0x09, 0x61, 0x44, 0xbe, 0x47, 0x74, 0xf1, 0x05, 0x49, 0x0a, 0x0c, + 0x61, 0x2c, 0xd3, 0x5d, 0x82, 0x8b, 0x2f, 0x48, 0xa8, 0xb8, 0x0c, 0x93, 0x34, 0x0c, 0x11, 0x82, + 0xdc, 0x5a, 0xb9, 0x52, 0x5b, 0x53, 0x36, 0xeb, 0x5b, 0xab, 0x9b, 0x1b, 0xe5, 0x35, 0x29, 0x12, + 0xc8, 0xe4, 0xda, 0xcb, 0xdb, 0xab, 0x72, 0xad, 0x2a, 0x45, 0xc3, 0xb2, 0x7a, 0xad, 0xbc, 0x55, + 0xab, 0x4a, 0xb1, 0xa2, 0x06, 0xb3, 0x83, 0x16, 0xd4, 0x81, 0x53, 0x28, 0x14, 0x0b, 0xd1, 0x21, + 0xb1, 0x40, 0xb9, 0x7a, 0x63, 0xa1, 0xf8, 0xad, 0x28, 0xcc, 0x0c, 0xd8, 0x54, 0x06, 0x36, 0xf2, + 0x12, 0x4c, 0xb2, 0x58, 0x66, 0xdb, 0xec, 0x53, 0x03, 0x77, 0x27, 0x1a, 0xd9, 0x7d, 0x5b, 0x2d, + 0xc5, 0x85, 0x53, 0x8d, 0xd8, 0x90, 0x54, 0x83, 0x50, 0xf4, 0x05, 0xec, 0x4f, 0xf4, 0x2d, 0xfe, + 0x6c, 0x7f, 0xbc, 0x38, 0xce, 0xfe, 0x48, 0x65, 0x47, 0xdb, 0x04, 0x26, 0x07, 0x6c, 0x02, 0x57, + 0x60, 0xba, 0x8f, 0x68, 0xec, 0xc5, 0xf8, 0xa3, 0x11, 0x28, 0x0c, 0x73, 0xce, 0x88, 0x25, 0x31, + 0xda, 0xb5, 0x24, 0x5e, 0xe9, 0xf5, 0xe0, 0xa3, 0xc3, 0x07, 0xa1, 0x6f, 0xac, 0x3f, 0x17, 0x81, + 0xe3, 0x83, 0x53, 0xca, 0x81, 0x36, 0x7c, 0x18, 0x12, 0x6d, 0xec, 0xed, 0x59, 0x22, 0xad, 0x7a, + 0x72, 0xc0, 0x66, 0x4d, 0xaa, 0x7b, 0x07, 0x9b, 0xa3, 0xc2, 0xbb, 0x7d, 0x6c, 0x58, 0x5e, 0xc8, + 0xac, 0xe9, 0xb3, 0xf4, 0xe3, 0x51, 0x38, 0x36, 0x90, 0x7c, 0xa0, 0xa1, 0x8f, 0x00, 0xe8, 0xa6, + 0xdd, 0xf1, 0x58, 0xea, 0xc4, 0x56, 0xe2, 0x34, 0x95, 0xd0, 0xc5, 0x8b, 0xac, 0xb2, 0x1d, 0xcf, + 0xaf, 0x8f, 0xd1, 0x7a, 0x60, 0x22, 0xaa, 0xf0, 0x62, 0x60, 0x68, 0x9c, 0x1a, 0x3a, 0x3f, 0xa4, + 0xa7, 0x7d, 0x81, 0xf9, 0x1c, 0x48, 0x9a, 0xa1, 0x63, 0xd3, 0x53, 0x5c, 0xcf, 0xc1, 0x6a, 0x5b, + 0x37, 0x5b, 0x74, 0xab, 0x49, 0x95, 0x26, 0x77, 0x55, 0xc3, 0xc5, 0x72, 0x9e, 0x55, 0x37, 0x44, + 0x2d, 0x41, 0xd0, 0x00, 0x72, 0x42, 0x88, 0x44, 0x17, 0x82, 0x55, 0xfb, 0x88, 0xe2, 0x4f, 0xa7, + 0x21, 0x13, 0x4a, 0xc0, 0xd1, 0xa3, 0x90, 0x7d, 0x43, 0xbd, 0xa5, 0x2a, 0xe2, 0x50, 0xc5, 0x3c, + 0x91, 0x21, 0xb2, 0x3a, 0x3f, 0x58, 0x3d, 0x07, 0xb3, 0x54, 0xc5, 0xea, 0x78, 0xd8, 0x51, 0x34, + 0x43, 0x75, 0x5d, 0xea, 0xb4, 0x14, 0x55, 0x45, 0xa4, 0x6e, 0x93, 0x54, 0x2d, 0x8b, 0x1a, 0x74, + 0x01, 0x66, 0x28, 0xa2, 0xdd, 0x31, 0x3c, 0xdd, 0x36, 0xb0, 0x42, 0x8e, 0x79, 0x2e, 0xdd, 0x72, + 0x7c, 0xcb, 0xa6, 0x89, 0xc6, 0x3a, 0x57, 0x20, 0x16, 0xb9, 0xa8, 0x0a, 0x8f, 0x50, 0x58, 0x0b, + 0x9b, 0xd8, 0x51, 0x3d, 0xac, 0xe0, 0x9f, 0xec, 0xa8, 0x86, 0xab, 0xa8, 0x66, 0x53, 0xd9, 0x53, + 0xdd, 0xbd, 0xc2, 0x2c, 0x21, 0xa8, 0x44, 0x0b, 0x11, 0xf9, 0x24, 0x51, 0x5c, 0xe1, 0x7a, 0x35, + 0xaa, 0x56, 0x36, 0x9b, 0xd7, 0x54, 0x77, 0x0f, 0x95, 0xe0, 0x38, 0x65, 0x71, 0x3d, 0x47, 0x37, + 0x5b, 0x8a, 0xb6, 0x87, 0xb5, 0x7d, 0xa5, 0xe3, 0xed, 0xbe, 0x58, 0x78, 0x28, 0xdc, 0x3e, 0xb5, + 0xb0, 0x41, 0x75, 0x96, 0x89, 0xca, 0xb6, 0xb7, 0xfb, 0x22, 0x6a, 0x40, 0x96, 0x0c, 0x46, 0x5b, + 0x7f, 0x13, 0x2b, 0xbb, 0x96, 0x43, 0xf7, 0xd0, 0xdc, 0x80, 0xa5, 0x29, 0xe4, 0xc1, 0xa5, 0x4d, + 0x0e, 0x58, 0xb7, 0x9a, 0xb8, 0x34, 0xd9, 0xa8, 0xd7, 0x6a, 0x55, 0x39, 0x23, 0x58, 0xae, 0x5a, + 0x0e, 0x09, 0xa8, 0x96, 0xe5, 0x3b, 0x38, 0xc3, 0x02, 0xaa, 0x65, 0x09, 0xf7, 0x5e, 0x80, 0x19, + 0x4d, 0x63, 0x7d, 0xd6, 0x35, 0x85, 0x1f, 0xc6, 0xdc, 0x82, 0xd4, 0xe5, 0x2c, 0x4d, 0x5b, 0x61, + 0x0a, 0x3c, 0xc6, 0x5d, 0x74, 0x19, 0x8e, 0x05, 0xce, 0x0a, 0x03, 0xa7, 0xfb, 0x7a, 0xd9, 0x0b, + 0xbd, 0x00, 0x33, 0xf6, 0x41, 0x3f, 0x10, 0x75, 0xb5, 0x68, 0x1f, 0xf4, 0xc2, 0x2e, 0xc1, 0xac, + 0xbd, 0x67, 0xf7, 0xe3, 0xce, 0x84, 0x71, 0xc8, 0xde, 0xb3, 0x7b, 0x81, 0x4f, 0xd0, 0x93, 0xb9, + 0x83, 0x35, 0xd5, 0xc3, 0xcd, 0xc2, 0x89, 0xb0, 0x7a, 0xa8, 0x02, 0x2d, 0x81, 0xa4, 0x69, 0x0a, + 0x36, 0xd5, 0x1d, 0x03, 0x2b, 0xaa, 0x83, 0x4d, 0xd5, 0x2d, 0x2c, 0x50, 0xe5, 0xb8, 0xe7, 0x74, + 0xb0, 0x9c, 0xd3, 0xb4, 0x1a, 0xad, 0x2c, 0xd3, 0x3a, 0x74, 0x06, 0xa6, 0xad, 0x9d, 0x37, 0x34, + 0x16, 0x91, 0x8a, 0xed, 0xe0, 0x5d, 0xfd, 0x4e, 0xe1, 0x71, 0xea, 0xde, 0x3c, 0xa9, 0xa0, 0xf1, + 0x58, 0xa7, 0x62, 0xf4, 0x14, 0x48, 0x9a, 0xbb, 0xa7, 0x3a, 0x36, 0x5d, 0x92, 0x5d, 0x5b, 0xd5, + 0x70, 0xe1, 0x09, 0xa6, 0xca, 0xe4, 0x1b, 0x42, 0x4c, 0x66, 0x84, 0x7b, 0x5b, 0xdf, 0xf5, 0x04, + 0xe3, 0x29, 0x36, 0x23, 0xa8, 0x8c, 0xb3, 0x9d, 0x06, 0x89, 0x78, 0xa2, 0xab, 0xe1, 0xd3, 0x54, + 0x2d, 0x67, 0xef, 0xd9, 0xe1, 0x76, 0x1f, 0x83, 0x29, 0xa2, 0x19, 0x34, 0xfa, 0x14, 0x4b, 0xdc, + 0xec, 0xbd, 0x50, 0x8b, 0x2f, 0xc0, 0x71, 0xa2, 0xd4, 0xc6, 0x9e, 0xda, 0x54, 0x3d, 0x35, 0xa4, + 0xfd, 0x0c, 0xd5, 0x26, 0x6e, 0x5f, 0xe7, 0x95, 0x5d, 0x76, 0x3a, 0x9d, 0x9d, 0x03, 0x3f, 0xb0, + 0x9e, 0x65, 0x76, 0x12, 0x99, 0x08, 0xad, 0x0f, 0x2c, 0x39, 0x2f, 0x96, 0x20, 0x1b, 0x8e, 0x7b, + 0x94, 0x06, 0x16, 0xf9, 0x52, 0x84, 0x24, 0x41, 0xcb, 0x9b, 0x55, 0x92, 0xbe, 0xbc, 0x5e, 0x93, + 0xa2, 0x24, 0x8d, 0x5a, 0x5b, 0xdd, 0xaa, 0x29, 0xf2, 0xf6, 0xc6, 0xd6, 0xea, 0x7a, 0x4d, 0x8a, + 0x85, 0x12, 0xfb, 0xeb, 0xf1, 0xd4, 0x93, 0xd2, 0x29, 0x92, 0x35, 0xe4, 0xba, 0x4f, 0x6a, 0xe8, + 0xc7, 0xe0, 0x84, 0xb8, 0x56, 0x71, 0xb1, 0xa7, 0xdc, 0xd6, 0x1d, 0x3a, 0x21, 0xdb, 0x2a, 0xdb, + 0x1c, 0xfd, 0xf8, 0x99, 0xe5, 0x5a, 0x0d, 0xec, 0xbd, 0xa2, 0x3b, 0x64, 0xba, 0xb5, 0x55, 0x0f, + 0xad, 0xc1, 0x82, 0x69, 0x29, 0xae, 0xa7, 0x9a, 0x4d, 0xd5, 0x69, 0x2a, 0xc1, 0x85, 0x96, 0xa2, + 0x6a, 0x1a, 0x76, 0x5d, 0x8b, 0x6d, 0x84, 0x3e, 0xcb, 0xc3, 0xa6, 0xd5, 0xe0, 0xca, 0xc1, 0x0e, + 0x51, 0xe6, 0xaa, 0x3d, 0xe1, 0x1b, 0x1b, 0x16, 0xbe, 0x0f, 0x41, 0xba, 0xad, 0xda, 0x0a, 0x36, + 0x3d, 0xe7, 0x80, 0xe6, 0xe7, 0x29, 0x39, 0xd5, 0x56, 0xed, 0x1a, 0x29, 0xff, 0x50, 0x8e, 0x49, + 0xd7, 0xe3, 0xa9, 0xb8, 0x34, 0x79, 0x3d, 0x9e, 0x9a, 0x94, 0x12, 0xd7, 0xe3, 0xa9, 0x84, 0x94, + 0xbc, 0x1e, 0x4f, 0xa5, 0xa4, 0xf4, 0xf5, 0x78, 0x2a, 0x2d, 0x41, 0xf1, 0xbd, 0x18, 0x64, 0xc3, + 0x19, 0x3c, 0x39, 0x10, 0x69, 0x74, 0x0f, 0x8b, 0xd0, 0x55, 0xee, 0xb1, 0x43, 0xf3, 0xfd, 0xa5, + 0x65, 0xb2, 0xb9, 0x95, 0x12, 0x2c, 0x5d, 0x96, 0x19, 0x92, 0x24, 0x16, 0x24, 0xfc, 0x30, 0x4b, + 0x4f, 0x52, 0x32, 0x2f, 0xa1, 0x15, 0x48, 0xbc, 0xe1, 0x52, 0xee, 0x04, 0xe5, 0x7e, 0xfc, 0x70, + 0xee, 0xeb, 0x0d, 0x4a, 0x9e, 0xbe, 0xde, 0x50, 0x36, 0x36, 0xe5, 0xf5, 0xf2, 0x9a, 0xcc, 0xe1, + 0xe8, 0x24, 0xc4, 0x0d, 0xf5, 0xcd, 0x83, 0xee, 0x6d, 0x90, 0x8a, 0xc6, 0x1d, 0x96, 0x93, 0x10, + 0xbf, 0x8d, 0xd5, 0xfd, 0xee, 0xcd, 0x87, 0x8a, 0x3e, 0xc0, 0xe9, 0x71, 0x16, 0x26, 0xa9, 0xbf, + 0x10, 0x00, 0xf7, 0x98, 0x34, 0x81, 0x52, 0x10, 0x5f, 0xde, 0x94, 0xc9, 0x14, 0x91, 0x20, 0xcb, + 0xa4, 0x4a, 0x7d, 0xb5, 0xb6, 0x5c, 0x93, 0xa2, 0xc5, 0x0b, 0x90, 0x60, 0x4e, 0x20, 0xd3, 0xc7, + 0x77, 0x83, 0x34, 0xc1, 0x8b, 0x9c, 0x23, 0x22, 0x6a, 0xb7, 0xd7, 0x2b, 0x35, 0x59, 0x8a, 0xf6, + 0x0d, 0x7e, 0xd1, 0x85, 0x6c, 0x38, 0x33, 0xff, 0xe1, 0x1c, 0xcf, 0xbf, 0x1a, 0x81, 0x4c, 0x28, + 0xd3, 0x26, 0x29, 0x92, 0x6a, 0x18, 0xd6, 0x6d, 0x45, 0x35, 0x74, 0xd5, 0xe5, 0xa1, 0x01, 0x54, + 0x54, 0x26, 0x92, 0x71, 0x87, 0xee, 0x87, 0x34, 0x69, 0x26, 0xa5, 0x44, 0xf1, 0x33, 0x11, 0x90, + 0x7a, 0x53, 0xdd, 0x1e, 0x33, 0x23, 0x7f, 0x98, 0x66, 0x16, 0x3f, 0x1d, 0x81, 0x5c, 0x77, 0x7e, + 0xdb, 0x63, 0xde, 0xa3, 0x7f, 0xa8, 0xe6, 0x7d, 0x33, 0x0a, 0x53, 0x5d, 0x59, 0xed, 0xb8, 0xd6, + 0xfd, 0x24, 0x4c, 0xeb, 0x4d, 0xdc, 0xb6, 0x2d, 0x0f, 0x9b, 0xda, 0x81, 0x62, 0xe0, 0x5b, 0xd8, + 0x28, 0x14, 0xe9, 0xa2, 0x71, 0xf6, 0xf0, 0xbc, 0x79, 0x69, 0x35, 0xc0, 0xad, 0x11, 0x58, 0x69, + 0x66, 0xb5, 0x5a, 0x5b, 0xaf, 0x6f, 0x6e, 0xd5, 0x36, 0x96, 0x5f, 0x53, 0xb6, 0x37, 0x6e, 0x6c, + 0x6c, 0xbe, 0xb2, 0x21, 0x4b, 0x7a, 0x8f, 0xda, 0x07, 0x38, 0xed, 0xeb, 0x20, 0xf5, 0x1a, 0x85, + 0x4e, 0xc0, 0x20, 0xb3, 0xa4, 0x09, 0x34, 0x03, 0xf9, 0x8d, 0x4d, 0xa5, 0xb1, 0x5a, 0xad, 0x29, + 0xb5, 0xab, 0x57, 0x6b, 0xcb, 0x5b, 0x0d, 0x76, 0x13, 0xe2, 0x6b, 0x6f, 0x75, 0x4d, 0xf0, 0xe2, + 0xa7, 0x62, 0x30, 0x33, 0xc0, 0x12, 0x54, 0xe6, 0x67, 0x18, 0x76, 0xac, 0x7a, 0x76, 0x1c, 0xeb, + 0x97, 0x48, 0x16, 0x51, 0x57, 0x1d, 0x8f, 0x1f, 0x79, 0x9e, 0x02, 0xe2, 0x25, 0xd3, 0xd3, 0x77, + 0x75, 0xec, 0xf0, 0x1b, 0x26, 0x76, 0xb0, 0xc9, 0x07, 0x72, 0x76, 0xc9, 0xf4, 0x0c, 0x20, 0xdb, + 0x72, 0x75, 0x4f, 0xbf, 0x85, 0x15, 0xdd, 0x14, 0xd7, 0x51, 0xe4, 0xa0, 0x13, 0x97, 0x25, 0x51, + 0xb3, 0x6a, 0x7a, 0xbe, 0xb6, 0x89, 0x5b, 0x6a, 0x8f, 0x36, 0x59, 0xcc, 0x63, 0xb2, 0x24, 0x6a, + 0x7c, 0xed, 0x47, 0x21, 0xdb, 0xb4, 0x3a, 0x24, 0xfb, 0x63, 0x7a, 0x64, 0xef, 0x88, 0xc8, 0x19, + 0x26, 0xf3, 0x55, 0x78, 0x5e, 0x1f, 0xdc, 0x83, 0x65, 0xe5, 0x0c, 0x93, 0x31, 0x95, 0x53, 0x90, + 0x57, 0x5b, 0x2d, 0x87, 0x90, 0x0b, 0x22, 0x76, 0x52, 0xc9, 0xf9, 0x62, 0xaa, 0x38, 0x77, 0x1d, + 0x52, 0xc2, 0x0f, 0x64, 0xf3, 0x26, 0x9e, 0x50, 0x6c, 0x76, 0xfc, 0x8e, 0x9e, 0x4e, 0xcb, 0x29, + 0x53, 0x54, 0x3e, 0x0a, 0x59, 0xdd, 0x55, 0x82, 0x6b, 0xfd, 0xe8, 0x62, 0xf4, 0x74, 0x4a, 0xce, + 0xe8, 0xae, 0x7f, 0x25, 0x5a, 0xfc, 0x5c, 0x14, 0x72, 0xdd, 0x8f, 0x25, 0x50, 0x15, 0x52, 0x86, + 0xa5, 0xa9, 0x34, 0xb4, 0xd8, 0x33, 0xb1, 0xd3, 0x23, 0x9e, 0x64, 0x2c, 0xad, 0x71, 0x7d, 0xd9, + 0x47, 0xce, 0xfd, 0xeb, 0x08, 0xa4, 0x84, 0x18, 0x1d, 0x87, 0xb8, 0xad, 0x7a, 0x7b, 0x94, 0x6e, + 0xb2, 0x12, 0x95, 0x22, 0x32, 0x2d, 0x13, 0xb9, 0x6b, 0xab, 0x26, 0x0d, 0x01, 0x2e, 0x27, 0x65, + 0x32, 0xae, 0x06, 0x56, 0x9b, 0xf4, 0x18, 0x64, 0xb5, 0xdb, 0xd8, 0xf4, 0x5c, 0x31, 0xae, 0x5c, + 0xbe, 0xcc, 0xc5, 0xe8, 0x69, 0x98, 0xf6, 0x1c, 0x55, 0x37, 0xba, 0x74, 0xe3, 0x54, 0x57, 0x12, + 0x15, 0xbe, 0x72, 0x09, 0x4e, 0x0a, 0xde, 0x26, 0xf6, 0x54, 0x6d, 0x0f, 0x37, 0x03, 0x50, 0x82, + 0x5e, 0x77, 0x9c, 0xe0, 0x0a, 0x55, 0x5e, 0x2f, 0xb0, 0xc5, 0xdf, 0x88, 0xc0, 0xb4, 0x38, 0xb8, + 0x35, 0x7d, 0x67, 0xad, 0x03, 0xa8, 0xa6, 0x69, 0x79, 0x61, 0x77, 0xf5, 0x87, 0x72, 0x1f, 0x6e, + 0xa9, 0xec, 0x83, 0xe4, 0x10, 0xc1, 0x5c, 0x1b, 0x20, 0xa8, 0x19, 0xea, 0xb6, 0x05, 0xc8, 0xf0, + 0x67, 0x4e, 0xf4, 0xc1, 0x25, 0x3b, 0xea, 0x03, 0x13, 0x91, 0x13, 0x1e, 0x9a, 0x85, 0xc9, 0x1d, + 0xdc, 0xd2, 0x4d, 0x7e, 0x93, 0xcc, 0x0a, 0xe2, 0x42, 0x26, 0xee, 0x5f, 0xc8, 0x54, 0xfe, 0x14, + 0xcc, 0x68, 0x56, 0xbb, 0xd7, 0xdc, 0x8a, 0xd4, 0x73, 0xdd, 0xe0, 0x5e, 0x8b, 0xbc, 0xfe, 0x2c, + 0x57, 0x6a, 0x59, 0x86, 0x6a, 0xb6, 0x96, 0x2c, 0xa7, 0x15, 0x3c, 0x78, 0x25, 0x19, 0x8f, 0x1b, + 0x7a, 0xfc, 0x6a, 0xef, 0xfc, 0xef, 0x48, 0xe4, 0x17, 0xa2, 0xb1, 0x95, 0x7a, 0xe5, 0xf3, 0xd1, + 0xb9, 0x15, 0x06, 0xac, 0x0b, 0x67, 0xc8, 0x78, 0xd7, 0xc0, 0x1a, 0xe9, 0x20, 0x7c, 0xf7, 0x69, + 0x98, 0x6d, 0x59, 0x2d, 0x8b, 0x32, 0x9d, 0x25, 0xbf, 0xf8, 0x93, 0xdb, 0xb4, 0x2f, 0x9d, 0x1b, + 0xf9, 0x98, 0xb7, 0xb4, 0x01, 0x33, 0x5c, 0x59, 0xa1, 0x8f, 0x8e, 0xd8, 0xc1, 0x06, 0x1d, 0x7a, + 0xab, 0x56, 0xf8, 0x95, 0x6f, 0xd3, 0xed, 0x5b, 0x9e, 0xe6, 0x50, 0x52, 0xc7, 0xce, 0x3e, 0x25, + 0x19, 0x8e, 0x75, 0xf1, 0xb1, 0x49, 0x8a, 0x9d, 0x11, 0x8c, 0xff, 0x9c, 0x33, 0xce, 0x84, 0x18, + 0x1b, 0x1c, 0x5a, 0x5a, 0x86, 0xa9, 0xa3, 0x70, 0xfd, 0x0b, 0xce, 0x95, 0xc5, 0x61, 0x92, 0x15, + 0xc8, 0x53, 0x12, 0xad, 0xe3, 0x7a, 0x56, 0x9b, 0xae, 0x80, 0x87, 0xd3, 0xfc, 0xcb, 0x6f, 0xb3, + 0x59, 0x93, 0x23, 0xb0, 0x65, 0x1f, 0x55, 0x2a, 0x01, 0x7d, 0x5a, 0xd6, 0xc4, 0x9a, 0x31, 0x82, + 0xe1, 0x6b, 0xdc, 0x10, 0x5f, 0xbf, 0x74, 0x13, 0x66, 0xc9, 0x6f, 0xba, 0x40, 0x85, 0x2d, 0x19, + 0x7d, 0x05, 0x57, 0xf8, 0x8d, 0x8f, 0xb2, 0x89, 0x39, 0xe3, 0x13, 0x84, 0x6c, 0x0a, 0x8d, 0x62, + 0x0b, 0x7b, 0x1e, 0x76, 0x5c, 0x45, 0x35, 0x06, 0x99, 0x17, 0xba, 0xc3, 0x28, 0xfc, 0xdc, 0xf7, + 0xba, 0x47, 0x71, 0x85, 0x21, 0xcb, 0x86, 0x51, 0xda, 0x86, 0x13, 0x03, 0xa2, 0x62, 0x0c, 0xce, + 0x4f, 0x71, 0xce, 0xd9, 0xbe, 0xc8, 0x20, 0xb4, 0x75, 0x10, 0x72, 0x7f, 0x2c, 0xc7, 0xe0, 0xfc, + 0x79, 0xce, 0x89, 0x38, 0x56, 0x0c, 0x29, 0x61, 0xbc, 0x0e, 0xd3, 0xb7, 0xb0, 0xb3, 0x63, 0xb9, + 0xfc, 0xde, 0x68, 0x0c, 0xba, 0x4f, 0x73, 0xba, 0x3c, 0x07, 0xd2, 0x8b, 0x24, 0xc2, 0x75, 0x19, + 0x52, 0xbb, 0xaa, 0x86, 0xc7, 0xa0, 0xb8, 0xc7, 0x29, 0x92, 0x44, 0x9f, 0x40, 0xcb, 0x90, 0x6d, + 0x59, 0x7c, 0x8f, 0x1a, 0x0d, 0xff, 0x0c, 0x87, 0x67, 0x04, 0x86, 0x53, 0xd8, 0x96, 0xdd, 0x31, + 0xc8, 0x06, 0x36, 0x9a, 0xe2, 0xaf, 0x09, 0x0a, 0x81, 0xe1, 0x14, 0x47, 0x70, 0xeb, 0xdb, 0x82, + 0xc2, 0x0d, 0xf9, 0xf3, 0x25, 0xc8, 0x58, 0xa6, 0x71, 0x60, 0x99, 0xe3, 0x18, 0xf1, 0x0e, 0x67, + 0x00, 0x0e, 0x21, 0x04, 0x57, 0x20, 0x3d, 0xee, 0x40, 0xfc, 0xf5, 0xef, 0x89, 0xe9, 0x21, 0x46, + 0x60, 0x05, 0xf2, 0x62, 0x81, 0xd2, 0x2d, 0x73, 0x0c, 0x8a, 0xbf, 0xc1, 0x29, 0x72, 0x21, 0x18, + 0xef, 0x86, 0x87, 0x5d, 0xaf, 0x85, 0xc7, 0x21, 0xf9, 0x9c, 0xe8, 0x06, 0x87, 0x70, 0x57, 0xee, + 0x60, 0x53, 0xdb, 0x1b, 0x8f, 0xe1, 0x97, 0x84, 0x2b, 0x05, 0x86, 0x50, 0x2c, 0xc3, 0x54, 0x5b, + 0x75, 0xdc, 0x3d, 0xd5, 0x18, 0x6b, 0x38, 0xfe, 0x26, 0xe7, 0xc8, 0xfa, 0x20, 0xee, 0x91, 0x8e, + 0x79, 0x14, 0x9a, 0xcf, 0x0b, 0x8f, 0x84, 0x60, 0x7c, 0xea, 0xb9, 0x1e, 0xbd, 0x64, 0x3b, 0x0a, + 0xdb, 0xdf, 0x12, 0x53, 0x8f, 0x61, 0xd7, 0xc3, 0x8c, 0x57, 0x20, 0xed, 0xea, 0x6f, 0x8e, 0x45, + 0xf3, 0x05, 0x31, 0xd2, 0x14, 0x40, 0xc0, 0xaf, 0xc1, 0xc9, 0x81, 0xdb, 0xc4, 0x18, 0x64, 0x7f, + 0x9b, 0x93, 0x1d, 0x1f, 0xb0, 0x55, 0xf0, 0x25, 0xe1, 0xa8, 0x94, 0x7f, 0x47, 0x2c, 0x09, 0xb8, + 0x87, 0xab, 0x4e, 0x4e, 0x0d, 0xae, 0xba, 0x7b, 0x34, 0xaf, 0xfd, 0x5d, 0xe1, 0x35, 0x86, 0xed, + 0xf2, 0xda, 0x16, 0x1c, 0xe7, 0x8c, 0x47, 0x1b, 0xd7, 0x5f, 0x16, 0x0b, 0x2b, 0x43, 0x6f, 0x77, + 0x8f, 0xee, 0x8f, 0xc3, 0x9c, 0xef, 0x4e, 0x91, 0x9e, 0xba, 0x4a, 0x5b, 0xb5, 0xc7, 0x60, 0xfe, + 0x15, 0xce, 0x2c, 0x56, 0x7c, 0x3f, 0xbf, 0x75, 0xd7, 0x55, 0x9b, 0x90, 0xbf, 0x0a, 0x05, 0x41, + 0xde, 0x31, 0x1d, 0xac, 0x59, 0x2d, 0x53, 0x7f, 0x13, 0x37, 0xc7, 0xa0, 0xfe, 0x62, 0xcf, 0x50, + 0x6d, 0x87, 0xe0, 0x84, 0x79, 0x15, 0x24, 0x3f, 0x57, 0x51, 0xf4, 0xb6, 0x6d, 0x39, 0xde, 0x08, + 0xc6, 0x2f, 0x89, 0x91, 0xf2, 0x71, 0xab, 0x14, 0x56, 0xaa, 0x01, 0x7b, 0xf2, 0x3c, 0x6e, 0x48, + 0x7e, 0x99, 0x13, 0x4d, 0x05, 0x28, 0xbe, 0x70, 0x68, 0x56, 0xdb, 0x56, 0x9d, 0x71, 0xd6, 0xbf, + 0xbf, 0x27, 0x16, 0x0e, 0x0e, 0xe1, 0x0b, 0x07, 0xc9, 0xe8, 0xc8, 0x6e, 0x3f, 0x06, 0xc3, 0x57, + 0xc4, 0xc2, 0x21, 0x30, 0x9c, 0x42, 0x24, 0x0c, 0x63, 0x50, 0xfc, 0x7d, 0x41, 0x21, 0x30, 0x84, + 0xe2, 0xe5, 0x60, 0xa3, 0x75, 0x70, 0x4b, 0x77, 0x3d, 0x87, 0x25, 0xc5, 0x87, 0x53, 0xfd, 0x83, + 0xef, 0x75, 0x27, 0x61, 0x72, 0x08, 0x4a, 0x56, 0x22, 0x7e, 0xed, 0x4a, 0xcf, 0x4c, 0xa3, 0x0d, + 0xfb, 0x55, 0xb1, 0x12, 0x85, 0x60, 0xc4, 0xb6, 0x50, 0x86, 0x48, 0xdc, 0xae, 0x91, 0x93, 0xc2, + 0x18, 0x74, 0xff, 0xb0, 0xc7, 0xb8, 0x86, 0xc0, 0x12, 0xce, 0x50, 0xfe, 0xd3, 0x31, 0xf7, 0xf1, + 0xc1, 0x58, 0xd1, 0xf9, 0x6b, 0x3d, 0xf9, 0xcf, 0x36, 0x43, 0xb2, 0x35, 0x24, 0xdf, 0x93, 0x4f, + 0xa1, 0x51, 0xef, 0x19, 0x15, 0x3e, 0xf2, 0x3e, 0xef, 0x6f, 0x77, 0x3a, 0x55, 0x5a, 0x23, 0x41, + 0xde, 0x9d, 0xf4, 0x8c, 0x26, 0xfb, 0xe8, 0xfb, 0x7e, 0x9c, 0x77, 0xe5, 0x3c, 0xa5, 0xab, 0x30, + 0xd5, 0x95, 0xf0, 0x8c, 0xa6, 0xfa, 0xd3, 0x9c, 0x2a, 0x1b, 0xce, 0x77, 0x4a, 0x17, 0x20, 0x4e, + 0x92, 0x97, 0xd1, 0xf0, 0x3f, 0xc3, 0xe1, 0x54, 0xbd, 0xf4, 0x21, 0x48, 0x89, 0xa4, 0x65, 0x34, + 0xf4, 0xcf, 0x72, 0xa8, 0x0f, 0x21, 0x70, 0x91, 0xb0, 0x8c, 0x86, 0xff, 0x39, 0x01, 0x17, 0x10, + 0x02, 0x1f, 0xdf, 0x85, 0x5f, 0xfd, 0xf3, 0x71, 0xbe, 0xe9, 0x08, 0xdf, 0x5d, 0x81, 0x24, 0xcf, + 0x54, 0x46, 0xa3, 0x3f, 0xce, 0x1b, 0x17, 0x88, 0xd2, 0x25, 0x98, 0x1c, 0xd3, 0xe1, 0x7f, 0x81, + 0x43, 0x99, 0x7e, 0x69, 0x19, 0x32, 0xa1, 0xec, 0x64, 0x34, 0xfc, 0x2f, 0x72, 0x78, 0x18, 0x45, + 0x4c, 0xe7, 0xd9, 0xc9, 0x68, 0x82, 0xbf, 0x24, 0x4c, 0xe7, 0x08, 0xe2, 0x36, 0x91, 0x98, 0x8c, + 0x46, 0x7f, 0x42, 0x78, 0x5d, 0x40, 0x4a, 0x2f, 0x41, 0xda, 0xdf, 0x6c, 0x46, 0xe3, 0x7f, 0x9a, + 0xe3, 0x03, 0x0c, 0xf1, 0x40, 0x68, 0xb3, 0x1b, 0x4d, 0xf1, 0x97, 0x85, 0x07, 0x42, 0x28, 0x32, + 0x8d, 0x7a, 0x13, 0x98, 0xd1, 0x4c, 0x3f, 0x23, 0xa6, 0x51, 0x4f, 0xfe, 0x42, 0x46, 0x93, 0xae, + 0xf9, 0xa3, 0x29, 0xfe, 0x8a, 0x18, 0x4d, 0xaa, 0x4f, 0xcc, 0xe8, 0xcd, 0x08, 0x46, 0x73, 0xfc, + 0xac, 0x30, 0xa3, 0x27, 0x21, 0x28, 0xd5, 0x01, 0xf5, 0x67, 0x03, 0xa3, 0xf9, 0x3e, 0xc9, 0xf9, + 0xa6, 0xfb, 0x92, 0x81, 0xd2, 0x2b, 0x70, 0x7c, 0x70, 0x26, 0x30, 0x9a, 0xf5, 0xe7, 0xde, 0xef, + 0x39, 0xbb, 0x85, 0x13, 0x81, 0xd2, 0x56, 0xb0, 0xa5, 0x84, 0xb3, 0x80, 0xd1, 0xb4, 0x9f, 0x7a, + 0xbf, 0x7b, 0xe1, 0x0e, 0x27, 0x01, 0xa5, 0x32, 0x40, 0xb0, 0x01, 0x8f, 0xe6, 0xfa, 0x34, 0xe7, + 0x0a, 0x81, 0xc8, 0xd4, 0xe0, 0xfb, 0xef, 0x68, 0xfc, 0x3d, 0x31, 0x35, 0x38, 0x82, 0x4c, 0x0d, + 0xb1, 0xf5, 0x8e, 0x46, 0x7f, 0x46, 0x4c, 0x0d, 0x01, 0x21, 0x91, 0x1d, 0xda, 0xdd, 0x46, 0x33, + 0xbc, 0x23, 0x22, 0x3b, 0x84, 0x2a, 0x6d, 0xc0, 0x74, 0xdf, 0x86, 0x38, 0x9a, 0xea, 0x17, 0x38, + 0x95, 0xd4, 0xbb, 0x1f, 0x86, 0x37, 0x2f, 0xbe, 0x19, 0x8e, 0x66, 0xfb, 0x6c, 0xcf, 0xe6, 0xc5, + 0xf7, 0xc2, 0xd2, 0x15, 0x48, 0x99, 0x1d, 0xc3, 0x20, 0x93, 0x07, 0x1d, 0xfe, 0x6e, 0x60, 0xe1, + 0xbf, 0xfc, 0x80, 0x7b, 0x47, 0x00, 0x4a, 0x17, 0x60, 0x12, 0xb7, 0x77, 0x70, 0x73, 0x14, 0xf2, + 0xbb, 0x3f, 0x10, 0x0b, 0x26, 0xd1, 0x2e, 0xbd, 0x04, 0xc0, 0xae, 0x46, 0xe8, 0xc3, 0xc0, 0x11, + 0xd8, 0xff, 0xfa, 0x03, 0xfe, 0x32, 0x4e, 0x00, 0x09, 0x08, 0xd8, 0xab, 0x3d, 0x87, 0x13, 0x7c, + 0xaf, 0x9b, 0x80, 0x8e, 0xc8, 0x65, 0x48, 0xbe, 0xe1, 0x5a, 0xa6, 0xa7, 0xb6, 0x46, 0xa1, 0xff, + 0x1b, 0x47, 0x0b, 0x7d, 0xe2, 0xb0, 0xb6, 0xe5, 0x60, 0x4f, 0x6d, 0xb9, 0xa3, 0xb0, 0xff, 0x9d, + 0x63, 0x7d, 0x00, 0x01, 0x6b, 0xaa, 0xeb, 0x8d, 0xd3, 0xef, 0xdf, 0x13, 0x60, 0x01, 0x20, 0x46, + 0x93, 0xdf, 0xfb, 0xf8, 0x60, 0x14, 0xf6, 0xfb, 0xc2, 0x68, 0xae, 0x5f, 0xfa, 0x10, 0xa4, 0xc9, + 0x4f, 0xf6, 0x86, 0xdd, 0x08, 0xf0, 0xff, 0xe0, 0xe0, 0x00, 0x41, 0x5a, 0x76, 0xbd, 0xa6, 0xa7, + 0x8f, 0x76, 0xf6, 0xef, 0xf3, 0x91, 0x16, 0xfa, 0xa5, 0x32, 0x64, 0x5c, 0xaf, 0xd9, 0xec, 0xf0, + 0xfc, 0x74, 0x04, 0xfc, 0x7f, 0xfe, 0xc0, 0xbf, 0xb2, 0xf0, 0x31, 0x64, 0xb4, 0x6f, 0xef, 0x7b, + 0xb6, 0x45, 0x1f, 0x78, 0x8c, 0x62, 0x78, 0x9f, 0x33, 0x84, 0x20, 0xa5, 0x65, 0xc8, 0x92, 0xbe, + 0x38, 0xd8, 0xc6, 0xf4, 0xe9, 0xd4, 0x08, 0x8a, 0xff, 0xc5, 0x1d, 0xd0, 0x05, 0xaa, 0xfc, 0xc4, + 0xd7, 0xde, 0x9b, 0x8f, 0x7c, 0xe3, 0xbd, 0xf9, 0xc8, 0x37, 0xdf, 0x9b, 0x8f, 0x7c, 0xe2, 0x5b, + 0xf3, 0x13, 0xdf, 0xf8, 0xd6, 0xfc, 0xc4, 0x6f, 0x7f, 0x6b, 0x7e, 0x62, 0xf0, 0x2d, 0x31, 0xac, + 0x58, 0x2b, 0x16, 0xbb, 0x1f, 0x7e, 0xbd, 0xd8, 0xd2, 0xbd, 0xbd, 0xce, 0xce, 0x92, 0x66, 0xb5, + 0xe9, 0x35, 0x6e, 0x70, 0x5b, 0xeb, 0x1f, 0x72, 0xe0, 0x23, 0x51, 0x72, 0x60, 0xee, 0xbe, 0xcb, + 0x55, 0xcd, 0x83, 0x21, 0xdf, 0xea, 0xcc, 0x0d, 0xbc, 0x18, 0x2e, 0x5e, 0x83, 0x58, 0xd9, 0x3c, + 0x40, 0x27, 0xd9, 0x9a, 0xa7, 0x74, 0x1c, 0x83, 0xbf, 0xf9, 0x95, 0x24, 0xe5, 0x6d, 0xc7, 0x40, + 0xb3, 0xc1, 0xeb, 0x99, 0x91, 0xd3, 0x59, 0xfe, 0xce, 0x65, 0x49, 0xfa, 0xe4, 0xdb, 0x0b, 0x13, + 0xbf, 0xfc, 0xf6, 0xc2, 0xc4, 0xf7, 0xdf, 0x59, 0x98, 0x78, 0xeb, 0x77, 0x17, 0x27, 0x2a, 0xfb, + 0xbd, 0xbd, 0xfd, 0xea, 0xc8, 0x1e, 0xa7, 0xca, 0xe6, 0x01, 0xed, 0x70, 0x3d, 0xf2, 0xfa, 0x24, + 0xbd, 0xf4, 0x16, 0x97, 0xdc, 0xf3, 0xbd, 0x97, 0xdc, 0xaf, 0x60, 0xc3, 0xb8, 0x61, 0x5a, 0xb7, + 0xcd, 0x2d, 0xa2, 0xb6, 0x93, 0x60, 0xaf, 0x14, 0xc3, 0xcf, 0x44, 0x61, 0xbe, 0xef, 0x3e, 0x9b, + 0x47, 0xc1, 0xb0, 0x8f, 0x96, 0x4a, 0x90, 0xaa, 0x8a, 0xe0, 0x2a, 0x40, 0xd2, 0xc5, 0x9a, 0x65, + 0x36, 0x5d, 0xda, 0xed, 0x98, 0x2c, 0x8a, 0xa4, 0xdb, 0xa6, 0x6a, 0x5a, 0x2e, 0x7f, 0x53, 0x92, + 0x15, 0x2a, 0x3f, 0x1f, 0x39, 0xda, 0x98, 0x4e, 0x89, 0x96, 0x44, 0x37, 0xcf, 0x8d, 0xbc, 0xf6, + 0xdf, 0x27, 0xbd, 0xf4, 0x3b, 0xd1, 0x75, 0xf5, 0x3f, 0xae, 0x57, 0x7e, 0x36, 0x0a, 0x0b, 0xbd, + 0x5e, 0x21, 0x53, 0xcb, 0xf5, 0xd4, 0xb6, 0x3d, 0xcc, 0x2d, 0x57, 0x20, 0xbd, 0x25, 0x74, 0x8e, + 0xec, 0x97, 0x7b, 0x47, 0xf4, 0x4b, 0xce, 0x6f, 0x4a, 0x38, 0xe6, 0xfc, 0x98, 0x8e, 0xf1, 0xfb, + 0x71, 0x5f, 0x9e, 0xf9, 0x3f, 0x09, 0x38, 0xa9, 0x59, 0x6e, 0xdb, 0x72, 0x15, 0x36, 0x15, 0x58, + 0x81, 0xfb, 0x24, 0x1b, 0xae, 0x1a, 0xfd, 0xa0, 0xa4, 0x78, 0x03, 0x66, 0x56, 0xc9, 0x72, 0x41, + 0x8e, 0x41, 0xc1, 0x23, 0x9e, 0x81, 0x2f, 0x93, 0x2e, 0x76, 0x65, 0xfc, 0xfc, 0x11, 0x53, 0x58, + 0x54, 0xfc, 0x48, 0x04, 0xa4, 0x86, 0xa6, 0x1a, 0xaa, 0xf3, 0xff, 0x4b, 0x85, 0x2e, 0x01, 0xd0, + 0x8f, 0x90, 0x82, 0xaf, 0x86, 0x72, 0xe7, 0x0b, 0x4b, 0xe1, 0xce, 0x2d, 0xb1, 0x96, 0xe8, 0x27, + 0x09, 0x69, 0xaa, 0x4b, 0x7e, 0x9e, 0x79, 0x15, 0x20, 0xa8, 0x40, 0x0f, 0xc1, 0x89, 0xc6, 0x72, + 0x79, 0xad, 0x2c, 0x2b, 0xec, 0xed, 0xf6, 0x8d, 0x46, 0xbd, 0xb6, 0xbc, 0x7a, 0x75, 0xb5, 0x56, + 0x95, 0x26, 0xd0, 0x71, 0x40, 0xe1, 0x4a, 0xff, 0xc5, 0x94, 0x63, 0x30, 0x1d, 0x96, 0xb3, 0x57, + 0xe4, 0xa3, 0x24, 0x55, 0xd4, 0xdb, 0xb6, 0x81, 0xe9, 0xb3, 0x3f, 0x45, 0x17, 0x5e, 0x1b, 0x9d, + 0x85, 0xfc, 0xab, 0x7f, 0xc3, 0x5e, 0x9b, 0x9e, 0x09, 0xe0, 0xbe, 0xcf, 0x4b, 0x6b, 0x30, 0xad, + 0x6a, 0x1a, 0xb6, 0xbb, 0x28, 0x47, 0xac, 0xd5, 0x84, 0x90, 0x3e, 0xcd, 0xe4, 0xc8, 0x80, 0xed, + 0x12, 0x24, 0x5c, 0xda, 0xfb, 0x51, 0x14, 0x5f, 0xe7, 0x14, 0x5c, 0xbd, 0x64, 0xc2, 0x34, 0x49, + 0xfd, 0x54, 0x07, 0x87, 0xcc, 0x38, 0xfc, 0xa2, 0xe1, 0x1f, 0x7d, 0xe9, 0x39, 0xfa, 0x6c, 0xf3, + 0xd1, 0xee, 0x61, 0x19, 0x10, 0x4e, 0xb2, 0xc4, 0xb9, 0x03, 0x43, 0x31, 0xe4, 0x44, 0x7b, 0xdc, + 0xe0, 0xc3, 0x1b, 0xfb, 0xc7, 0xbc, 0xb1, 0xf9, 0x41, 0x31, 0x10, 0x6a, 0x69, 0x8a, 0xb3, 0xb2, + 0x8a, 0x4a, 0x6d, 0xd8, 0x9c, 0x7e, 0xfd, 0xe9, 0xd0, 0xf6, 0xc4, 0x28, 0xf9, 0x9f, 0x67, 0x29, + 0xf3, 0x95, 0x70, 0x33, 0xfe, 0xdc, 0xfb, 0xad, 0x18, 0xcc, 0x73, 0xe5, 0x1d, 0xd5, 0xc5, 0x67, + 0x6f, 0x9d, 0xdb, 0xc1, 0x9e, 0x7a, 0xee, 0xac, 0x66, 0xe9, 0x62, 0xad, 0x9e, 0xe1, 0xd3, 0x91, + 0xd4, 0x2f, 0xf1, 0xfa, 0xc1, 0x1b, 0xd7, 0xdc, 0xf0, 0x69, 0x5c, 0xdc, 0x86, 0xf8, 0xb2, 0xa5, + 0x9b, 0x64, 0xa9, 0x6a, 0x62, 0xd3, 0x6a, 0xf3, 0xd9, 0xc3, 0x0a, 0xe8, 0x1c, 0x24, 0xd4, 0xb6, + 0xd5, 0x31, 0x3d, 0x36, 0x73, 0x2a, 0x27, 0xbf, 0xf6, 0xee, 0xc2, 0xc4, 0xbf, 0x7d, 0x77, 0x21, + 0xb6, 0x6a, 0x7a, 0xbf, 0xf9, 0xe5, 0x67, 0x81, 0x53, 0xad, 0x9a, 0x9e, 0xcc, 0x15, 0x4b, 0xf1, + 0xef, 0xbc, 0xbd, 0x10, 0x29, 0xbe, 0x0a, 0xc9, 0x2a, 0xd6, 0xee, 0x87, 0xb9, 0x8a, 0xb5, 0x10, + 0x73, 0x15, 0x6b, 0x3d, 0xcc, 0x97, 0x20, 0xb5, 0x6a, 0x7a, 0xec, 0x4d, 0xf4, 0xa7, 0x21, 0xa6, + 0x9b, 0xec, 0xe5, 0xc6, 0x43, 0x6d, 0x23, 0x5a, 0x04, 0x58, 0xc5, 0x9a, 0x0f, 0x6c, 0x62, 0xad, + 0x17, 0xd8, 0xdf, 0x34, 0xd1, 0xaa, 0x54, 0x7f, 0xfb, 0x3f, 0xce, 0x4f, 0xbc, 0xf5, 0xde, 0xfc, + 0xc4, 0xd0, 0x21, 0x2e, 0x0e, 0x1d, 0x62, 0xb7, 0xb9, 0xcf, 0x56, 0x64, 0x7f, 0x64, 0x3f, 0x1f, + 0x87, 0x47, 0xe8, 0x07, 0x4a, 0x4e, 0x5b, 0x37, 0xbd, 0xb3, 0x9a, 0x73, 0x60, 0x7b, 0x34, 0x65, + 0xb1, 0x76, 0xf9, 0xc0, 0x4e, 0x07, 0xd5, 0x4b, 0xac, 0x7a, 0x48, 0x3e, 0xb2, 0x0b, 0x93, 0x75, + 0x82, 0x23, 0x2e, 0xf6, 0x2c, 0x4f, 0x35, 0xf8, 0xfe, 0xc3, 0x0a, 0x44, 0xca, 0x3e, 0x6a, 0x8a, + 0x32, 0xa9, 0x2e, 0xbe, 0x67, 0x32, 0xb0, 0xba, 0xcb, 0xde, 0x0d, 0x8f, 0xd1, 0x34, 0x25, 0x45, + 0x04, 0xf4, 0x35, 0xf0, 0x59, 0x98, 0x54, 0x3b, 0xec, 0x25, 0x86, 0x18, 0xc9, 0x5f, 0x68, 0xa1, + 0x78, 0x03, 0x92, 0xfc, 0x51, 0x2a, 0x92, 0x20, 0xb6, 0x8f, 0x0f, 0x68, 0x3b, 0x59, 0x99, 0xfc, + 0x44, 0x4b, 0x30, 0x49, 0x8d, 0xe7, 0x1f, 0xbd, 0x14, 0x96, 0xfa, 0xac, 0x5f, 0xa2, 0x46, 0xca, + 0x4c, 0xad, 0x78, 0x1d, 0x52, 0x55, 0xab, 0xad, 0x9b, 0x56, 0x37, 0x5b, 0x9a, 0xb1, 0x51, 0x9b, + 0xed, 0x0e, 0x8f, 0x0a, 0x99, 0x15, 0xd0, 0x71, 0x48, 0xb0, 0x6f, 0x05, 0xf8, 0x8b, 0x18, 0xbc, + 0x54, 0x5c, 0x86, 0x24, 0xe5, 0xde, 0xb4, 0xc9, 0xe2, 0xef, 0xbf, 0x96, 0x99, 0xe6, 0x5f, 0x8e, + 0x71, 0xfa, 0x68, 0x60, 0x2c, 0x82, 0x78, 0x53, 0xf5, 0x54, 0xde, 0x6f, 0xfa, 0xbb, 0xf8, 0x61, + 0x48, 0x71, 0x12, 0x17, 0x9d, 0x87, 0x98, 0x65, 0xbb, 0xfc, 0x55, 0x8a, 0xb9, 0x61, 0x5d, 0xd9, + 0xb4, 0x2b, 0x71, 0x12, 0x33, 0x32, 0x51, 0xae, 0xc8, 0x43, 0xc3, 0xe2, 0xc5, 0x50, 0x58, 0x84, + 0x86, 0x3c, 0xf4, 0x93, 0x0d, 0x69, 0x5f, 0x38, 0xf8, 0xc1, 0xf2, 0x4e, 0x14, 0xe6, 0x43, 0xb5, + 0xb7, 0xb0, 0xe3, 0xea, 0x96, 0xc9, 0x22, 0x8a, 0x47, 0x0b, 0x0a, 0x19, 0xc9, 0xeb, 0x87, 0x84, + 0xcb, 0x87, 0x20, 0x56, 0xb6, 0x6d, 0x34, 0x07, 0x29, 0x5a, 0xd6, 0x2c, 0x16, 0x2f, 0x71, 0xd9, + 0x2f, 0x93, 0x3a, 0xd7, 0xda, 0xf5, 0x6e, 0xab, 0x8e, 0xff, 0x39, 0x9d, 0x28, 0x17, 0x2f, 0x43, + 0x7a, 0xd9, 0x32, 0x5d, 0x6c, 0xba, 0x1d, 0x9a, 0xd9, 0xec, 0x18, 0x96, 0xb6, 0xcf, 0x19, 0x58, + 0x81, 0x38, 0x5c, 0xb5, 0x6d, 0x8a, 0x8c, 0xcb, 0xe4, 0x27, 0x9b, 0xb3, 0x95, 0xc6, 0x50, 0x17, + 0x5d, 0x3e, 0xba, 0x8b, 0x78, 0x27, 0x7d, 0x1f, 0xfd, 0x41, 0x04, 0x1e, 0xee, 0x9f, 0x50, 0xfb, + 0xf8, 0xc0, 0x3d, 0xea, 0x7c, 0x7a, 0x15, 0xd2, 0x75, 0xfa, 0x4d, 0xfb, 0x0d, 0x7c, 0x80, 0xe6, + 0x20, 0x89, 0x9b, 0xe7, 0x2f, 0x5c, 0x38, 0x77, 0x99, 0x45, 0xfb, 0xb5, 0x09, 0x59, 0x08, 0xd0, + 0x3c, 0xa4, 0x5d, 0xac, 0xd9, 0xe7, 0x2f, 0x5c, 0xdc, 0x3f, 0xc7, 0xc2, 0xeb, 0xda, 0x84, 0x1c, + 0x88, 0x4a, 0x29, 0xd2, 0xeb, 0xef, 0xbc, 0xb3, 0x10, 0xa9, 0x4c, 0x42, 0xcc, 0xed, 0xb4, 0x3f, + 0xd0, 0x18, 0xf9, 0xd4, 0x24, 0x2c, 0x86, 0x91, 0x34, 0xff, 0xbb, 0xa5, 0x1a, 0x7a, 0x53, 0x0d, + 0xfe, 0x1b, 0x81, 0x14, 0xf2, 0x01, 0xd5, 0x18, 0xb2, 0x53, 0x1c, 0xea, 0xc9, 0xe2, 0x17, 0x23, + 0x90, 0xbd, 0x29, 0x98, 0x1b, 0xd8, 0x43, 0x57, 0x00, 0xfc, 0x96, 0xc4, 0xb4, 0x79, 0x68, 0xa9, + 0xb7, 0xad, 0x25, 0x1f, 0x23, 0x87, 0xd4, 0xd1, 0x25, 0x1a, 0x88, 0xb6, 0xe5, 0xf2, 0x4f, 0xac, + 0x46, 0x40, 0x7d, 0x65, 0xf4, 0x0c, 0x20, 0xba, 0xc2, 0x29, 0xb7, 0x2c, 0x4f, 0x37, 0x5b, 0x8a, + 0x6d, 0xdd, 0xe6, 0x1f, 0xae, 0xc6, 0x64, 0x89, 0xd6, 0xdc, 0xa4, 0x15, 0x75, 0x22, 0x27, 0x46, + 0xa7, 0x7d, 0x16, 0x92, 0xac, 0xab, 0xcd, 0xa6, 0x83, 0x5d, 0x97, 0x2f, 0x62, 0xa2, 0x88, 0xae, + 0x40, 0xd2, 0xee, 0xec, 0x28, 0x62, 0xc5, 0xc8, 0x9c, 0x7f, 0x78, 0xd0, 0xfc, 0x17, 0xf1, 0xc1, + 0x57, 0x80, 0x84, 0xdd, 0xd9, 0x21, 0xd1, 0xf2, 0x28, 0x64, 0x07, 0x18, 0x93, 0xb9, 0x15, 0xd8, + 0x41, 0xff, 0x95, 0x02, 0xef, 0x81, 0x62, 0x3b, 0xba, 0xe5, 0xe8, 0xde, 0x01, 0x7d, 0x1f, 0x2a, + 0x26, 0x4b, 0xa2, 0xa2, 0xce, 0xe5, 0xc5, 0x7d, 0xc8, 0x37, 0x68, 0x12, 0x17, 0x58, 0x7e, 0x21, + 0xb0, 0x2f, 0x32, 0xda, 0xbe, 0xa1, 0x96, 0x45, 0xfb, 0x2c, 0xab, 0xbc, 0x3c, 0x34, 0x3a, 0x2f, + 0x1d, 0x3d, 0x3a, 0xbb, 0x77, 0xbb, 0xdf, 0x3b, 0xd9, 0x35, 0x39, 0x59, 0x70, 0x86, 0x97, 0xaf, + 0x71, 0x03, 0x73, 0xd4, 0x19, 0x6d, 0xee, 0xf0, 0x4d, 0x75, 0x6e, 0xc4, 0x32, 0x3a, 0x37, 0x72, + 0x0a, 0x15, 0x2f, 0xc3, 0x54, 0x5d, 0x75, 0xbc, 0x06, 0xf6, 0xae, 0x61, 0xb5, 0x89, 0x9d, 0xee, + 0x5d, 0x77, 0x4a, 0xec, 0xba, 0x08, 0xe2, 0x74, 0x6b, 0x65, 0xbb, 0x0e, 0xfd, 0x5d, 0xdc, 0x83, + 0x38, 0x7d, 0x27, 0xd2, 0xdf, 0x91, 0x39, 0x82, 0xed, 0xc8, 0x64, 0x2d, 0x3d, 0xf0, 0xb0, 0x2b, + 0x2e, 0x0d, 0x68, 0x01, 0xbd, 0x20, 0xf6, 0xd5, 0xd8, 0xe1, 0xfb, 0x2a, 0x0f, 0x44, 0xbe, 0xbb, + 0x1a, 0x90, 0xac, 0x90, 0xa5, 0x78, 0xb5, 0xea, 0x1b, 0x12, 0x09, 0x0c, 0x41, 0xeb, 0x90, 0xb7, + 0x55, 0xc7, 0xa3, 0x9f, 0x87, 0xec, 0xd1, 0x5e, 0xf0, 0x58, 0x5f, 0xe8, 0x9f, 0x79, 0x5d, 0x9d, + 0xe5, 0xad, 0x4c, 0xd9, 0x61, 0x61, 0xf1, 0x3f, 0xc5, 0x21, 0xc1, 0x9d, 0xf1, 0x21, 0x48, 0x72, + 0xb7, 0xf2, 0xe8, 0x7c, 0x64, 0xa9, 0x7f, 0x63, 0x5a, 0xf2, 0x37, 0x10, 0xce, 0x27, 0x30, 0xe8, + 0x49, 0x48, 0x69, 0x7b, 0xaa, 0x6e, 0x2a, 0x7a, 0x93, 0x27, 0x84, 0x99, 0xf7, 0xde, 0x5d, 0x48, + 0x2e, 0x13, 0xd9, 0x6a, 0x55, 0x4e, 0xd2, 0xca, 0xd5, 0x26, 0xc9, 0x04, 0xf6, 0xb0, 0xde, 0xda, + 0xf3, 0xf8, 0x0c, 0xe3, 0x25, 0xf4, 0x22, 0xc4, 0x49, 0x40, 0xf0, 0x8f, 0x07, 0xe7, 0xfa, 0x32, + 0x7c, 0xff, 0x08, 0x5d, 0x49, 0x91, 0x86, 0x3f, 0xf1, 0x1f, 0x16, 0x22, 0x32, 0x45, 0xa0, 0x65, + 0x98, 0x32, 0x54, 0xd7, 0x53, 0xe8, 0x0e, 0x46, 0x9a, 0x9f, 0xa4, 0x14, 0x27, 0xfb, 0x1d, 0xc2, + 0x1d, 0xcb, 0x4d, 0xcf, 0x10, 0x14, 0x13, 0x35, 0xd1, 0x69, 0x90, 0x28, 0x89, 0x66, 0xb5, 0xdb, + 0xba, 0xc7, 0x72, 0xab, 0x04, 0xf5, 0x7b, 0x8e, 0xc8, 0x97, 0xa9, 0x98, 0x66, 0x58, 0x0f, 0x41, + 0x9a, 0x7e, 0xae, 0x44, 0x55, 0xd8, 0x8b, 0xb8, 0x29, 0x22, 0xa0, 0x95, 0xa7, 0x20, 0x1f, 0xac, + 0x8f, 0x4c, 0x25, 0xc5, 0x58, 0x02, 0x31, 0x55, 0x7c, 0x0e, 0x66, 0x4d, 0x7c, 0x87, 0xbe, 0x1a, + 0xdc, 0xa5, 0x9d, 0xa6, 0xda, 0x88, 0xd4, 0xdd, 0xec, 0x46, 0x3c, 0x01, 0x39, 0x4d, 0x38, 0x9f, + 0xe9, 0x02, 0xd5, 0x9d, 0xf2, 0xa5, 0x54, 0xed, 0x24, 0xa4, 0x54, 0xdb, 0x66, 0x0a, 0x19, 0xbe, + 0x3e, 0xda, 0x36, 0xad, 0x3a, 0x03, 0xd3, 0xb4, 0x8f, 0x0e, 0x76, 0x3b, 0x86, 0xc7, 0x49, 0xb2, + 0x54, 0x27, 0x4f, 0x2a, 0x64, 0x26, 0xa7, 0xba, 0x8f, 0xc1, 0x14, 0xbe, 0xa5, 0x37, 0xb1, 0xa9, + 0x61, 0xa6, 0x37, 0x45, 0xf5, 0xb2, 0x42, 0x48, 0x95, 0x9e, 0x02, 0x7f, 0xdd, 0x53, 0xc4, 0x9a, + 0x9c, 0x63, 0x7c, 0x42, 0x5e, 0x66, 0xe2, 0x62, 0x01, 0xe2, 0x55, 0xd5, 0x53, 0x49, 0x82, 0xe1, + 0xdd, 0x61, 0x1b, 0x4d, 0x56, 0x26, 0x3f, 0x8b, 0xdf, 0x89, 0x42, 0xfc, 0xa6, 0xe5, 0x61, 0xf4, + 0x7c, 0x28, 0x01, 0xcc, 0x0d, 0x8a, 0xe7, 0x86, 0xde, 0x32, 0x71, 0x73, 0xdd, 0x6d, 0x85, 0xfe, + 0xb7, 0x40, 0x10, 0x4e, 0xd1, 0xae, 0x70, 0x9a, 0x85, 0x49, 0xc7, 0xea, 0x98, 0x4d, 0xf1, 0x0e, + 0x2b, 0x2d, 0xa0, 0x1a, 0xa4, 0xfc, 0x28, 0x89, 0x8f, 0x8a, 0x92, 0x3c, 0x89, 0x12, 0x12, 0xc3, + 0x5c, 0x20, 0x27, 0x77, 0x78, 0xb0, 0x54, 0x20, 0xed, 0x2f, 0x5e, 0x3c, 0xda, 0xc6, 0x0b, 0xd8, + 0x00, 0x46, 0x36, 0x13, 0x7f, 0xec, 0x7d, 0xe7, 0xb1, 0x88, 0x93, 0xfc, 0x0a, 0xee, 0xbd, 0xae, + 0xb0, 0xe2, 0xff, 0xe7, 0x20, 0x49, 0xfb, 0x15, 0x84, 0x15, 0xfb, 0x5f, 0x07, 0x0f, 0x43, 0xda, + 0xd5, 0x5b, 0xa6, 0xea, 0x75, 0x1c, 0xcc, 0x23, 0x2f, 0x10, 0x14, 0xbf, 0x1a, 0x81, 0x04, 0x8b, + 0xe4, 0x90, 0xdf, 0x22, 0x83, 0xfd, 0x16, 0x1d, 0xe6, 0xb7, 0xd8, 0xfd, 0xfb, 0xad, 0x0c, 0xe0, + 0x1b, 0xe3, 0xf2, 0xcf, 0xcf, 0x07, 0x64, 0x0c, 0xcc, 0xc4, 0x86, 0xde, 0xe2, 0x13, 0x35, 0x04, + 0x2a, 0xfe, 0xfb, 0x08, 0x49, 0x62, 0x79, 0x3d, 0x2a, 0xc3, 0x94, 0xb0, 0x4b, 0xd9, 0x35, 0xd4, + 0x16, 0x8f, 0x9d, 0x47, 0x86, 0x1a, 0x77, 0xd5, 0x50, 0x5b, 0x72, 0x86, 0xdb, 0x43, 0x0a, 0x83, + 0xc7, 0x21, 0x3a, 0x64, 0x1c, 0xba, 0x06, 0x3e, 0x76, 0x7f, 0x03, 0xdf, 0x35, 0x44, 0xf1, 0xde, + 0x21, 0xfa, 0x52, 0x94, 0x1e, 0x66, 0x6c, 0xcb, 0x55, 0x8d, 0x1f, 0xc6, 0x8c, 0x78, 0x08, 0xd2, + 0xb6, 0x65, 0x28, 0xac, 0x86, 0xbd, 0xdb, 0x9d, 0xb2, 0x2d, 0x43, 0xee, 0x1b, 0xf6, 0xc9, 0x07, + 0x34, 0x5d, 0x12, 0x0f, 0xc0, 0x6b, 0xc9, 0x5e, 0xaf, 0x39, 0x90, 0x65, 0xae, 0xe0, 0x7b, 0xd9, + 0x73, 0xc4, 0x07, 0x74, 0x73, 0x8c, 0xf4, 0xef, 0xbd, 0xcc, 0x6c, 0xa6, 0x29, 0x73, 0x3d, 0x82, + 0x60, 0x4b, 0xff, 0xa0, 0x53, 0x70, 0x38, 0x2c, 0x65, 0xae, 0x57, 0xfc, 0xab, 0x11, 0x80, 0x35, + 0xe2, 0x59, 0xda, 0x5f, 0xb2, 0x0b, 0xb9, 0xd4, 0x04, 0xa5, 0xab, 0xe5, 0xf9, 0x61, 0x83, 0xc6, + 0xdb, 0xcf, 0xba, 0x61, 0xbb, 0x97, 0x61, 0x2a, 0x08, 0x46, 0x17, 0x0b, 0x63, 0xe6, 0x0f, 0xc9, + 0xaa, 0x1b, 0xd8, 0x93, 0xb3, 0xb7, 0x42, 0xa5, 0xe2, 0x3f, 0x8d, 0x40, 0x9a, 0xda, 0xb4, 0x8e, + 0x3d, 0xb5, 0x6b, 0x0c, 0x23, 0xf7, 0x3f, 0x86, 0x8f, 0x00, 0x30, 0x1a, 0x57, 0x7f, 0x13, 0xf3, + 0xc8, 0x4a, 0x53, 0x49, 0x43, 0x7f, 0x13, 0xa3, 0x8b, 0xbe, 0xc3, 0x63, 0x87, 0x3b, 0x5c, 0x64, + 0xdd, 0xdc, 0xed, 0x27, 0x20, 0x49, 0xff, 0x5d, 0xd3, 0x1d, 0x97, 0x27, 0xd2, 0x09, 0xb3, 0xd3, + 0xde, 0xba, 0xe3, 0x16, 0xdf, 0x80, 0xe4, 0xd6, 0x1d, 0x76, 0x37, 0xf2, 0x10, 0xa4, 0x1d, 0xcb, + 0xe2, 0x7b, 0x32, 0xcb, 0x85, 0x52, 0x44, 0x40, 0xb7, 0x20, 0x71, 0x1f, 0x10, 0x0d, 0xee, 0x03, + 0x82, 0x0b, 0x8d, 0xd8, 0x58, 0x17, 0x1a, 0x67, 0x7e, 0x2b, 0x02, 0x99, 0xd0, 0xfa, 0x80, 0xce, + 0xc1, 0xb1, 0xca, 0xda, 0xe6, 0xf2, 0x0d, 0x65, 0xb5, 0xaa, 0x5c, 0x5d, 0x2b, 0xaf, 0x04, 0x5f, + 0x2f, 0xcd, 0x1d, 0xbf, 0x7b, 0x6f, 0x11, 0x85, 0x74, 0xb7, 0x4d, 0x7a, 0x4f, 0x8f, 0xce, 0xc2, + 0x6c, 0x37, 0xa4, 0x5c, 0x69, 0xd4, 0x36, 0xb6, 0xa4, 0xc8, 0xdc, 0xb1, 0xbb, 0xf7, 0x16, 0xa7, + 0x43, 0x88, 0xf2, 0x8e, 0x8b, 0x4d, 0xaf, 0x1f, 0xb0, 0xbc, 0xb9, 0xbe, 0xbe, 0xba, 0x25, 0x45, + 0xfb, 0x00, 0x7c, 0xc1, 0x7e, 0x0a, 0xa6, 0xbb, 0x01, 0x1b, 0xab, 0x6b, 0x52, 0x6c, 0x0e, 0xdd, + 0xbd, 0xb7, 0x98, 0x0b, 0x69, 0x6f, 0xe8, 0xc6, 0x5c, 0xea, 0x63, 0x9f, 0x9d, 0x9f, 0xf8, 0xa5, + 0x5f, 0x9c, 0x8f, 0x90, 0x9e, 0x4d, 0x75, 0xad, 0x11, 0xe8, 0x19, 0x38, 0xd1, 0x58, 0x5d, 0xd9, + 0xa8, 0x55, 0x95, 0xf5, 0xc6, 0x8a, 0xb8, 0xe9, 0x16, 0xbd, 0xcb, 0xdf, 0xbd, 0xb7, 0x98, 0xe1, + 0x5d, 0x1a, 0xa6, 0x5d, 0x97, 0x6b, 0x37, 0x37, 0xb7, 0x6a, 0x52, 0x84, 0x69, 0xd7, 0x1d, 0x7c, + 0xcb, 0xf2, 0xd8, 0xff, 0x73, 0x7b, 0x0e, 0x4e, 0x0e, 0xd0, 0xf6, 0x3b, 0x36, 0x7d, 0xf7, 0xde, + 0xe2, 0x54, 0xdd, 0xc1, 0x6c, 0xfe, 0x50, 0xc4, 0x12, 0x14, 0xfa, 0x11, 0x9b, 0xf5, 0xcd, 0x46, + 0x79, 0x4d, 0x5a, 0x9c, 0x93, 0xee, 0xde, 0x5b, 0xcc, 0x8a, 0xc5, 0x90, 0xe8, 0x07, 0x3d, 0xfb, + 0x20, 0x4f, 0x3c, 0xbf, 0xbe, 0x04, 0x8f, 0xf3, 0x3b, 0x40, 0xd7, 0x53, 0xf7, 0x75, 0xb3, 0xe5, + 0x5f, 0xde, 0xf2, 0x32, 0x3f, 0xf9, 0x1c, 0xe7, 0xf7, 0x8c, 0x42, 0x3a, 0xe2, 0x0a, 0x77, 0xe8, + 0xd3, 0xcb, 0xb9, 0x11, 0x0f, 0xf5, 0x46, 0x1f, 0x9d, 0x86, 0x5f, 0x0f, 0xcf, 0x8d, 0xb8, 0x84, + 0x9e, 0x3b, 0xf4, 0x70, 0x57, 0xfc, 0x78, 0x04, 0x72, 0xd7, 0x74, 0xd7, 0xb3, 0x1c, 0x5d, 0x53, + 0x0d, 0xfa, 0xcd, 0xd2, 0xc5, 0x71, 0xd7, 0xd6, 0x9e, 0xa9, 0xfe, 0x12, 0x24, 0x6e, 0xa9, 0x06, + 0x5b, 0xd4, 0xc2, 0xcf, 0x02, 0x7a, 0xdd, 0x17, 0x2c, 0x6d, 0x82, 0x80, 0xc1, 0x8a, 0x5f, 0x88, + 0x42, 0x9e, 0x4e, 0x06, 0x97, 0xfd, 0x3b, 0x2e, 0x72, 0xc6, 0xaa, 0x43, 0xdc, 0x51, 0x3d, 0x7e, + 0x69, 0x58, 0xf9, 0x31, 0x7e, 0x0f, 0xfc, 0xe4, 0xe8, 0xdb, 0xdc, 0xa5, 0xfe, 0xab, 0x62, 0xca, + 0x84, 0x5e, 0x81, 0x54, 0x5b, 0xbd, 0xa3, 0x50, 0xd6, 0xe8, 0x03, 0x60, 0x4d, 0xb6, 0xd5, 0x3b, + 0xc4, 0x56, 0xd4, 0x84, 0x3c, 0x21, 0xd6, 0xf6, 0x54, 0xb3, 0x85, 0x19, 0x7f, 0xec, 0x01, 0xf0, + 0x4f, 0xb5, 0xd5, 0x3b, 0xcb, 0x94, 0x93, 0xb4, 0x52, 0x4a, 0x7d, 0xf2, 0xed, 0x85, 0x09, 0x7a, + 0xcd, 0xfe, 0x6b, 0x11, 0x80, 0xc0, 0x5d, 0xe8, 0x8f, 0x83, 0xa4, 0xf9, 0x25, 0xda, 0xbc, 0xcb, + 0x07, 0xf0, 0xd4, 0xb0, 0x81, 0xe8, 0x71, 0x36, 0xdb, 0x98, 0xbf, 0xf1, 0xee, 0x42, 0x44, 0xce, + 0x6b, 0x3d, 0xe3, 0x50, 0x83, 0x4c, 0xc7, 0x6e, 0xaa, 0x1e, 0x56, 0xe8, 0x21, 0x2e, 0x7a, 0x84, + 0x4d, 0x1e, 0x18, 0x90, 0x54, 0x85, 0xac, 0xff, 0x42, 0x04, 0x32, 0xd5, 0xd0, 0x43, 0xbe, 0x02, + 0x24, 0xdb, 0x96, 0xa9, 0xef, 0xf3, 0xb0, 0x4b, 0xcb, 0xa2, 0x88, 0xe6, 0x20, 0xc5, 0xbe, 0xd6, + 0xf4, 0x0e, 0xc4, 0x8d, 0xa7, 0x28, 0x13, 0xd4, 0x6d, 0xbc, 0xe3, 0xea, 0xc2, 0xd7, 0xb2, 0x28, + 0x92, 0xa3, 0x8b, 0x8b, 0xb5, 0x8e, 0xa3, 0x7b, 0x07, 0x8a, 0x66, 0x99, 0x9e, 0xaa, 0x79, 0xfc, + 0xbb, 0xbf, 0xbc, 0x90, 0x2f, 0x33, 0x31, 0x21, 0x69, 0x62, 0x4f, 0xd5, 0x0d, 0xb7, 0xc0, 0x1e, + 0x84, 0x89, 0x62, 0xc8, 0xdc, 0x2f, 0xa6, 0xc2, 0x57, 0x54, 0xcb, 0x20, 0x59, 0x36, 0x76, 0xba, + 0x52, 0x4a, 0x16, 0xa1, 0x85, 0xdf, 0xfc, 0xf2, 0xb3, 0xb3, 0xdc, 0xdd, 0x3c, 0xa9, 0x64, 0x2f, + 0xb6, 0xca, 0x79, 0x81, 0x10, 0xb9, 0xe6, 0x6b, 0x64, 0xc0, 0xc4, 0x79, 0xcf, 0xee, 0xec, 0x04, + 0xd7, 0x5a, 0xb3, 0x7d, 0x7e, 0x2d, 0x9b, 0x07, 0x95, 0xc2, 0xd7, 0x03, 0xea, 0xe0, 0x2e, 0xe9, + 0x06, 0x3e, 0x20, 0xa3, 0xc5, 0x79, 0xea, 0x94, 0x86, 0xa4, 0x88, 0x6f, 0xa8, 0xba, 0x21, 0x3e, + 0x42, 0x97, 0x79, 0x09, 0x95, 0x20, 0xe1, 0x7a, 0xaa, 0xd7, 0x71, 0xf9, 0x3f, 0x8b, 0x2b, 0x0e, + 0x8b, 0x8c, 0x8a, 0x65, 0x36, 0x1b, 0x54, 0x53, 0xe6, 0x08, 0xb4, 0x05, 0x09, 0xcf, 0xda, 0xc7, + 0x26, 0x77, 0xd2, 0x91, 0xa2, 0x7a, 0xc0, 0xb3, 0x28, 0xc6, 0x85, 0x5a, 0x20, 0x35, 0xb1, 0x81, + 0x5b, 0x2c, 0x21, 0xda, 0x53, 0xc9, 0xb9, 0x21, 0xf1, 0x00, 0x66, 0x4d, 0xde, 0x67, 0x6d, 0x50, + 0x52, 0x74, 0xa3, 0xfb, 0x31, 0x33, 0xfb, 0xcf, 0x8a, 0x8f, 0x0d, 0xeb, 0x7f, 0x28, 0x32, 0xc5, + 0x65, 0x42, 0xf8, 0x89, 0xf4, 0x53, 0x20, 0x75, 0xcc, 0x1d, 0xcb, 0xa4, 0x9f, 0x8a, 0xf2, 0x64, + 0x3c, 0x45, 0xd3, 0x9b, 0xbc, 0x2f, 0xbf, 0xc6, 0xb2, 0xf2, 0x1b, 0x90, 0x0b, 0x54, 0xe9, 0xdc, + 0x49, 0x1f, 0x61, 0xee, 0x4c, 0xf9, 0x58, 0x52, 0x8b, 0xae, 0x01, 0x04, 0x13, 0x93, 0x5e, 0x0f, + 0x64, 0x86, 0x8f, 0x61, 0x30, 0xbb, 0xc5, 0x31, 0x2b, 0xc0, 0x22, 0x03, 0x66, 0xda, 0xba, 0xa9, + 0xb8, 0xd8, 0xd8, 0x55, 0xb8, 0xab, 0x08, 0x65, 0xe6, 0x01, 0x0c, 0xed, 0x74, 0x5b, 0x37, 0x1b, + 0xd8, 0xd8, 0xad, 0xfa, 0xb4, 0xa8, 0x42, 0x26, 0x23, 0x6b, 0xc9, 0x9f, 0x2f, 0xd9, 0x11, 0xf3, + 0x25, 0xe7, 0x32, 0x0e, 0x31, 0x5d, 0xca, 0x90, 0x77, 0xb0, 0xa1, 0x1e, 0x84, 0xae, 0x22, 0xa6, + 0x46, 0x51, 0x70, 0x80, 0xa0, 0x58, 0x01, 0xa4, 0xed, 0xa9, 0x86, 0x81, 0xd9, 0x47, 0x33, 0xa1, + 0x0b, 0x8d, 0xc3, 0x58, 0xa6, 0x03, 0x8c, 0x20, 0x3a, 0x01, 0xc9, 0x1d, 0xc3, 0xa5, 0x17, 0xbd, + 0x79, 0x9a, 0x97, 0x26, 0x76, 0x0c, 0xf7, 0x06, 0x3e, 0x28, 0x65, 0x3f, 0xf6, 0xf6, 0xc2, 0x04, + 0x5f, 0x34, 0x26, 0x8a, 0x75, 0x7a, 0x17, 0xcf, 0x41, 0xd8, 0x45, 0x17, 0x21, 0xad, 0x8a, 0x02, + 0xbd, 0x21, 0x39, 0xac, 0xd9, 0x40, 0x95, 0x2d, 0x43, 0x6f, 0xfd, 0xee, 0x62, 0xa4, 0xf8, 0x8b, + 0x11, 0x48, 0x54, 0x6f, 0xd6, 0x55, 0xdd, 0x41, 0x35, 0x98, 0x0e, 0x66, 0xce, 0xb8, 0x8b, 0x50, + 0x30, 0xd9, 0x44, 0x57, 0x6a, 0xc3, 0x8e, 0xc7, 0x87, 0xd2, 0xf4, 0x1e, 0x9c, 0x7b, 0x3a, 0x5e, + 0x83, 0x24, 0xb3, 0xd2, 0x45, 0x25, 0x98, 0xb4, 0xc9, 0x0f, 0xfe, 0xe8, 0x61, 0x7e, 0xe8, 0x8c, + 0xa3, 0xfa, 0xfe, 0x55, 0x29, 0x81, 0x14, 0xff, 0x20, 0x02, 0x50, 0xbd, 0x79, 0x73, 0xcb, 0xd1, + 0x6d, 0x03, 0x7b, 0x0f, 0xaa, 0xc7, 0x6b, 0x70, 0x2c, 0x74, 0x06, 0x73, 0xb4, 0xb1, 0x7b, 0x3d, + 0x13, 0x9c, 0xc2, 0x1c, 0x6d, 0x20, 0x5b, 0xd3, 0xf5, 0x7c, 0xb6, 0xd8, 0xd8, 0x6c, 0x55, 0xd7, + 0x1b, 0xec, 0xc6, 0x06, 0x64, 0x82, 0xee, 0xbb, 0xa8, 0x0a, 0x29, 0x8f, 0xff, 0xe6, 0xde, 0x2c, + 0x0e, 0xf7, 0xa6, 0x80, 0x71, 0x8f, 0xfa, 0xc8, 0xe2, 0xff, 0x25, 0x4e, 0x0d, 0xa6, 0xe6, 0x1f, + 0xa9, 0x30, 0x22, 0x9b, 0x0c, 0xdf, 0x04, 0x1e, 0x44, 0xea, 0xc4, 0xb9, 0x7a, 0xbc, 0xfa, 0xd1, + 0x28, 0xcc, 0x6c, 0x8b, 0x65, 0xf5, 0x8f, 0xac, 0x27, 0xea, 0x90, 0xc4, 0xa6, 0xe7, 0xe8, 0xd4, + 0x15, 0x64, 0xac, 0x9f, 0x1b, 0x36, 0xd6, 0x03, 0xfa, 0x42, 0xff, 0x39, 0x93, 0xb8, 0xc0, 0xe7, + 0x34, 0x3d, 0x5e, 0xf8, 0x77, 0x51, 0x28, 0x0c, 0x43, 0xa2, 0x53, 0x90, 0xd7, 0x1c, 0x4c, 0x05, + 0x4a, 0xd7, 0x2d, 0x62, 0x4e, 0x88, 0xf9, 0xee, 0xb6, 0x0e, 0x24, 0x53, 0x24, 0x81, 0x45, 0x54, + 0x8f, 0x9c, 0x1a, 0xe6, 0x02, 0x30, 0xdd, 0xdf, 0x30, 0xe4, 0x75, 0x53, 0xf7, 0x74, 0xd5, 0x50, + 0x76, 0x54, 0x43, 0x35, 0xb5, 0xfb, 0x49, 0xa1, 0xfb, 0x77, 0xa4, 0x1c, 0x27, 0xad, 0x30, 0x4e, + 0x74, 0x13, 0x92, 0x82, 0x3e, 0xfe, 0x00, 0xe8, 0x05, 0x59, 0x28, 0x5d, 0xfc, 0x9d, 0x28, 0x4c, + 0xcb, 0xb8, 0xf9, 0xa3, 0xe5, 0xd6, 0x1f, 0x07, 0x60, 0x13, 0x8e, 0xac, 0x83, 0xf7, 0xe1, 0xd9, + 0xfe, 0x09, 0x9c, 0x66, 0x7c, 0x55, 0xd7, 0x0b, 0xf9, 0xf6, 0xeb, 0x51, 0xc8, 0x86, 0x7d, 0xfb, + 0x23, 0xb0, 0x2f, 0xa0, 0xd5, 0x60, 0x35, 0x88, 0xf3, 0x7f, 0x2b, 0x3b, 0x64, 0x35, 0xe8, 0x8b, + 0xba, 0xc3, 0x97, 0x81, 0x6f, 0xc6, 0x20, 0x51, 0x57, 0x1d, 0xb5, 0xed, 0xa2, 0xeb, 0x7d, 0x99, + 0xaa, 0xb8, 0x4e, 0xec, 0xfb, 0xe7, 0xe1, 0xfc, 0xf6, 0x82, 0x85, 0xdc, 0x27, 0x07, 0x24, 0xaa, + 0x4f, 0x40, 0x8e, 0x9c, 0x85, 0x43, 0x6f, 0x1e, 0x44, 0xe9, 0xf3, 0x54, 0x72, 0x98, 0x0d, 0x1e, + 0x7b, 0xa1, 0x05, 0xc8, 0x10, 0xb5, 0x60, 0xa1, 0x23, 0x3a, 0xd0, 0x56, 0xef, 0xd4, 0x98, 0x04, + 0x3d, 0x0b, 0x68, 0xcf, 0xbf, 0x9d, 0x50, 0x02, 0x17, 0x10, 0xbd, 0xe9, 0xa0, 0x46, 0xa8, 0x3f, + 0x02, 0x40, 0xac, 0x50, 0xd8, 0xdb, 0x6c, 0xec, 0x30, 0x97, 0x26, 0x92, 0x2a, 0x7d, 0xa3, 0xed, + 0xa7, 0x58, 0xd2, 0xdb, 0x73, 0x4c, 0xe6, 0xe7, 0x8d, 0xb5, 0xa3, 0x45, 0xea, 0xef, 0xbf, 0xbb, + 0x30, 0x77, 0xa0, 0xb6, 0x8d, 0x52, 0x71, 0x00, 0x65, 0x91, 0x26, 0xc1, 0xdd, 0xc7, 0xeb, 0x61, + 0x29, 0x77, 0xf2, 0x03, 0x49, 0xb9, 0x43, 0xf3, 0xe5, 0xb3, 0x11, 0x40, 0x41, 0x85, 0x8c, 0x5d, + 0x9b, 0x9c, 0x16, 0xc9, 0x59, 0x22, 0x64, 0x45, 0xe4, 0xf0, 0xb3, 0x44, 0x80, 0x17, 0x67, 0x89, + 0xd0, 0xfc, 0xbb, 0x1c, 0x2c, 0xa7, 0x51, 0x1e, 0x31, 0x03, 0x5e, 0x7c, 0x5c, 0x5a, 0xb6, 0x74, + 0x81, 0xee, 0x5b, 0x31, 0x27, 0x8a, 0xbf, 0x13, 0x81, 0x93, 0x7d, 0xb1, 0xeb, 0x1b, 0xfb, 0x27, + 0x00, 0x39, 0xa1, 0x4a, 0xfe, 0xdf, 0x08, 0x99, 0xd1, 0x47, 0x9e, 0x0a, 0xd3, 0x4e, 0xdf, 0xca, + 0xfc, 0x41, 0xed, 0x08, 0xec, 0x85, 0xc8, 0x5f, 0x8f, 0xc0, 0x6c, 0xd8, 0x18, 0xbf, 0x5b, 0x1b, + 0x90, 0x0d, 0xdb, 0xc2, 0x3b, 0xf4, 0xf8, 0x38, 0x1d, 0xe2, 0x7d, 0xe9, 0xc2, 0xa3, 0x97, 0x83, + 0x65, 0x82, 0xdd, 0xc1, 0x9d, 0x1b, 0xdb, 0x37, 0xc2, 0xa6, 0xde, 0xe5, 0x22, 0x2e, 0x72, 0xa6, + 0x78, 0xdd, 0xb2, 0x0c, 0xf4, 0x27, 0x61, 0xda, 0xb4, 0x3c, 0x85, 0xcc, 0x29, 0xdc, 0x54, 0xf8, + 0x85, 0x00, 0x5b, 0x6b, 0x5f, 0x3e, 0x9a, 0xcb, 0xbe, 0xfb, 0xee, 0x42, 0x3f, 0x55, 0x8f, 0x1f, + 0xf3, 0xa6, 0xe5, 0x55, 0x68, 0xfd, 0x16, 0xbb, 0x2e, 0x70, 0x60, 0xaa, 0xbb, 0x69, 0xb6, 0x36, + 0xaf, 0x1f, 0xb9, 0xe9, 0xa9, 0xc3, 0x9a, 0xcd, 0xee, 0x84, 0xda, 0x64, 0xaf, 0x8a, 0x7d, 0xff, + 0xed, 0x85, 0xc8, 0x99, 0xaf, 0x44, 0x00, 0x82, 0x9b, 0x11, 0xf4, 0x0c, 0x9c, 0xa8, 0x6c, 0x6e, + 0x54, 0x95, 0xc6, 0x56, 0x79, 0x6b, 0xbb, 0xd1, 0xfd, 0x42, 0xb9, 0xb8, 0x6a, 0x77, 0x6d, 0xac, + 0xe9, 0xbb, 0x3a, 0x6e, 0xa2, 0x27, 0x61, 0xb6, 0x5b, 0x9b, 0x94, 0x6a, 0x55, 0x29, 0x32, 0x97, + 0xbd, 0x7b, 0x6f, 0x31, 0xc5, 0x72, 0x31, 0xdc, 0x44, 0xa7, 0xe1, 0x58, 0xbf, 0xde, 0xea, 0xc6, + 0x8a, 0x14, 0x9d, 0x9b, 0xba, 0x7b, 0x6f, 0x31, 0xed, 0x27, 0x6d, 0xa8, 0x08, 0x28, 0xac, 0xc9, + 0xf9, 0x62, 0x73, 0x70, 0xf7, 0xde, 0x62, 0x82, 0xb9, 0x6d, 0x2e, 0xfe, 0xb1, 0xcf, 0xce, 0x4f, + 0x54, 0xae, 0x0e, 0xbd, 0x4c, 0x7f, 0xe6, 0x50, 0x8f, 0xdd, 0xf1, 0x2f, 0xc8, 0xbb, 0x6e, 0xd0, + 0xff, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x93, 0x68, 0x7e, 0x9b, 0x5f, 0x67, 0x00, 0x00, } r := bytes.NewReader(gzipped) gzipr, err := compress_gzip.NewReader(r) @@ -2232,10 +2236,17 @@ func (m *Validator) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.RelayerBlsKey) > 0 { - i -= len(m.RelayerBlsKey) - copy(dAtA[i:], m.RelayerBlsKey) - i = encodeVarintStaking(dAtA, i, uint64(len(m.RelayerBlsKey))) + if len(m.BlsKey) > 0 { + i -= len(m.BlsKey) + copy(dAtA[i:], m.BlsKey) + i = encodeVarintStaking(dAtA, i, uint64(len(m.BlsKey))) + i-- + dAtA[i] = 0x7a + } + if len(m.ChallengerAddress) > 0 { + i -= len(m.ChallengerAddress) + copy(dAtA[i:], m.ChallengerAddress) + i = encodeVarintStaking(dAtA, i, uint64(len(m.ChallengerAddress))) i-- dAtA[i] = 0x72 } @@ -3185,7 +3196,11 @@ func (m *Validator) Size() (n int) { if l > 0 { n += 1 + l + sovStaking(uint64(l)) } - l = len(m.RelayerBlsKey) + l = len(m.ChallengerAddress) + if l > 0 { + n += 1 + l + sovStaking(uint64(l)) + } + l = len(m.BlsKey) if l > 0 { n += 1 + l + sovStaking(uint64(l)) } @@ -4505,7 +4520,39 @@ func (m *Validator) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 14: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RelayerBlsKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChallengerAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthStaking + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthStaking + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChallengerAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlsKey", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -4532,9 +4579,9 @@ func (m *Validator) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RelayerBlsKey = append(m.RelayerBlsKey[:0], dAtA[iNdEx:postIndex]...) - if m.RelayerBlsKey == nil { - m.RelayerBlsKey = []byte{} + m.BlsKey = append(m.BlsKey[:0], dAtA[iNdEx:postIndex]...) + if m.BlsKey == nil { + m.BlsKey = []byte{} } iNdEx = postIndex default: diff --git a/x/staking/types/tx.pb.go b/x/staking/types/tx.pb.go index 49c03f0b96..20b4482668 100644 --- a/x/staking/types/tx.pb.go +++ b/x/staking/types/tx.pb.go @@ -48,7 +48,8 @@ type MsgCreateValidator struct { Value types1.Coin `protobuf:"bytes,7,opt,name=value,proto3" json:"value"` From string `protobuf:"bytes,8,opt,name=from,proto3" json:"from,omitempty"` RelayerAddress string `protobuf:"bytes,9,opt,name=relayer_address,json=relayerAddress,proto3" json:"relayer_address,omitempty"` - RelayerBlsKey string `protobuf:"bytes,10,opt,name=relayer_bls_key,json=relayerBlsKey,proto3" json:"relayer_bls_key,omitempty"` + ChallengerAddress string `protobuf:"bytes,10,opt,name=challenger_address,json=challengerAddress,proto3" json:"challenger_address,omitempty"` + BlsKey string `protobuf:"bytes,11,opt,name=bls_key,json=blsKey,proto3" json:"bls_key,omitempty"` } func (m *MsgCreateValidator) Reset() { *m = MsgCreateValidator{} } @@ -132,7 +133,8 @@ type MsgEditValidator struct { CommissionRate *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=commission_rate,json=commissionRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"commission_rate,omitempty"` MinSelfDelegation *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,4,opt,name=min_self_delegation,json=minSelfDelegation,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"min_self_delegation,omitempty"` RelayerAddress string `protobuf:"bytes,5,opt,name=relayer_address,json=relayerAddress,proto3" json:"relayer_address,omitempty"` - RelayerBlsKey string `protobuf:"bytes,6,opt,name=relayer_bls_key,json=relayerBlsKey,proto3" json:"relayer_bls_key,omitempty"` + ChallengerAddress string `protobuf:"bytes,6,opt,name=challenger_address,json=challengerAddress,proto3" json:"challenger_address,omitempty"` + BlsKey string `protobuf:"bytes,7,opt,name=bls_key,json=blsKey,proto3" json:"bls_key,omitempty"` } func (m *MsgEditValidator) Reset() { *m = MsgEditValidator{} } @@ -656,70 +658,71 @@ func init() { func init() { proto.RegisterFile("cosmos/staking/v1beta1/tx.proto", fileDescriptor_0926ef28816b35ab) } var fileDescriptor_0926ef28816b35ab = []byte{ - // 995 bytes of a gzipped FileDescriptorProto + // 1016 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x57, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xf6, 0x26, 0xb6, 0x49, 0x5f, 0x94, 0xb8, 0xd9, 0x24, 0xe0, 0xac, 0x2a, 0xbb, 0x72, 0x4b, - 0x1a, 0x95, 0x66, 0x4d, 0x03, 0x08, 0x54, 0xf5, 0x12, 0xd7, 0xad, 0xa8, 0x82, 0x25, 0xb4, 0xa1, - 0x1c, 0x10, 0x92, 0xb5, 0x3f, 0xc6, 0x9b, 0x95, 0x77, 0x67, 0xdc, 0x9d, 0x71, 0x54, 0x5f, 0x39, - 0x71, 0xa3, 0x7f, 0x42, 0xcf, 0x88, 0x03, 0x87, 0xfe, 0x11, 0x15, 0xe2, 0x50, 0xf5, 0x02, 0xe2, - 0x50, 0x50, 0x72, 0x80, 0x23, 0xe2, 0x0f, 0x40, 0x68, 0x67, 0x67, 0xc7, 0x8e, 0x7f, 0x6c, 0x36, - 0x90, 0x1e, 0x50, 0x4f, 0x5e, 0xcd, 0x7c, 0xef, 0x9b, 0x99, 0xef, 0x7d, 0xef, 0xcd, 0x18, 0xaa, - 0x36, 0xa1, 0x01, 0xa1, 0x75, 0xca, 0xcc, 0xae, 0x87, 0xdd, 0xfa, 0xe1, 0x4d, 0x0b, 0x31, 0xf3, - 0x66, 0x9d, 0x3d, 0xd2, 0x7b, 0x21, 0x61, 0x44, 0x7d, 0x33, 0x06, 0xe8, 0x02, 0xa0, 0x0b, 0x80, - 0xb6, 0xe1, 0x12, 0xe2, 0xfa, 0xa8, 0xce, 0x51, 0x56, 0xbf, 0x53, 0x37, 0xf1, 0x20, 0x0e, 0xd1, - 0xaa, 0xe3, 0x53, 0xcc, 0x0b, 0x10, 0x65, 0x66, 0xd0, 0x13, 0x80, 0x35, 0x97, 0xb8, 0x84, 0x7f, - 0xd6, 0xa3, 0x2f, 0x31, 0xba, 0x11, 0xaf, 0xd4, 0x8e, 0x27, 0xc4, 0xb2, 0xf1, 0x54, 0x45, 0xec, - 0xd2, 0x32, 0x29, 0x92, 0x5b, 0xb4, 0x89, 0x87, 0xc5, 0xfc, 0xd5, 0x19, 0xa7, 0x48, 0x36, 0x1d, - 0xa3, 0xde, 0x12, 0xa8, 0x80, 0x46, 0x88, 0xe8, 0x27, 0x9e, 0xa8, 0xfd, 0x54, 0x00, 0xb5, 0x45, - 0xdd, 0x3b, 0x21, 0x32, 0x19, 0xfa, 0xdc, 0xf4, 0x3d, 0xc7, 0x64, 0x24, 0x54, 0xf7, 0x60, 0xd1, - 0x41, 0xd4, 0x0e, 0xbd, 0x1e, 0xf3, 0x08, 0x2e, 0x2b, 0x97, 0x95, 0xad, 0xc5, 0x9d, 0x2b, 0xfa, - 0x74, 0x41, 0xf4, 0xe6, 0x10, 0xda, 0xc8, 0x3f, 0x7b, 0x59, 0xcd, 0x19, 0xa3, 0xd1, 0x6a, 0x0b, - 0xc0, 0x26, 0x41, 0xe0, 0x51, 0x1a, 0x71, 0xcd, 0x71, 0xae, 0x6b, 0xb3, 0xb8, 0xee, 0x48, 0xa4, - 0x61, 0x32, 0x44, 0x05, 0xdf, 0x08, 0x81, 0xea, 0xc3, 0x6a, 0xe0, 0xe1, 0x36, 0x45, 0x7e, 0xa7, - 0xed, 0x20, 0x1f, 0xb9, 0x26, 0xdf, 0xe3, 0xfc, 0x65, 0x65, 0xeb, 0x42, 0xe3, 0x76, 0x04, 0xff, - 0xe5, 0x65, 0x75, 0xd3, 0xf5, 0xd8, 0x41, 0xdf, 0xd2, 0x6d, 0x12, 0x08, 0x3d, 0xc5, 0xcf, 0x36, - 0x75, 0xba, 0x75, 0x36, 0xe8, 0x21, 0xaa, 0xdf, 0xc7, 0xec, 0xc5, 0xd3, 0x6d, 0x10, 0x1b, 0xb9, - 0x8f, 0x99, 0xb1, 0x12, 0x78, 0x78, 0x1f, 0xf9, 0x9d, 0xa6, 0xa4, 0x55, 0xef, 0xc2, 0x8a, 0x58, - 0x84, 0x84, 0x6d, 0xd3, 0x71, 0x42, 0x44, 0x69, 0x39, 0xcf, 0xd7, 0x2a, 0xbf, 0x78, 0xba, 0xbd, - 0x26, 0xa2, 0x77, 0xe3, 0x99, 0x7d, 0x16, 0x7a, 0xd8, 0x35, 0x2e, 0xca, 0x10, 0x31, 0x1e, 0xd1, - 0x1c, 0x26, 0xea, 0x4a, 0x9a, 0xc2, 0x69, 0x34, 0x32, 0x24, 0xa1, 0xb9, 0x07, 0xc5, 0x5e, 0xdf, - 0xea, 0xa2, 0x41, 0xb9, 0xc8, 0x65, 0x5c, 0xd3, 0x63, 0xc3, 0xe9, 0x89, 0xe1, 0xf4, 0x5d, 0x3c, - 0x68, 0x94, 0x7f, 0x18, 0x32, 0xda, 0xe1, 0xa0, 0xc7, 0x88, 0xfe, 0x69, 0xdf, 0xda, 0x43, 0x03, - 0x43, 0x44, 0xab, 0x1f, 0x40, 0xe1, 0xd0, 0xf4, 0xfb, 0xa8, 0xfc, 0x06, 0xa7, 0xd9, 0x48, 0xb2, - 0x11, 0xb9, 0x6c, 0x24, 0x15, 0x5e, 0x92, 0xcf, 0x18, 0xad, 0xde, 0x80, 0x7c, 0x27, 0x24, 0x41, - 0x79, 0xe1, 0x94, 0x8d, 0x73, 0x94, 0xba, 0x0b, 0xa5, 0x10, 0xf9, 0xe6, 0x00, 0x0d, 0x4f, 0x7c, - 0xe1, 0x94, 0xc0, 0x65, 0x11, 0x90, 0x9c, 0x77, 0x73, 0x48, 0x61, 0xf9, 0xb4, 0x1d, 0x1d, 0x1c, - 0x22, 0x0a, 0x63, 0x49, 0x0c, 0x37, 0x7c, 0xba, 0x87, 0x06, 0xb7, 0x56, 0xbe, 0x7e, 0x52, 0xcd, - 0xfd, 0xf1, 0xa4, 0x9a, 0xfb, 0xea, 0xf7, 0xef, 0xaf, 0xf3, 0xd5, 0x6b, 0x97, 0x40, 0x9b, 0x34, - 0xb6, 0x81, 0x68, 0x8f, 0x60, 0x8a, 0x6a, 0x7f, 0xcf, 0xc3, 0xc5, 0x16, 0x75, 0xef, 0x3a, 0x1e, - 0x7b, 0x45, 0xae, 0x9f, 0x9a, 0xf1, 0xb9, 0x33, 0x67, 0xdc, 0x84, 0xd2, 0xd0, 0xfb, 0xed, 0xd0, - 0x64, 0x48, 0x38, 0xfd, 0xa3, 0x8c, 0x2e, 0x6f, 0x22, 0x7b, 0xc4, 0xe5, 0x4d, 0x64, 0x1b, 0xcb, - 0xf6, 0x89, 0x1a, 0x53, 0x0f, 0xa6, 0x17, 0x54, 0xfe, 0x4c, 0xcb, 0x64, 0x2a, 0xa6, 0x29, 0x8e, - 0x28, 0xfc, 0x77, 0x47, 0x14, 0xa7, 0x39, 0xa2, 0x32, 0xea, 0x88, 0xc9, 0x4c, 0xd4, 0x34, 0x28, - 0x8f, 0xe7, 0x5f, 0x9a, 0xe3, 0x4f, 0x05, 0x16, 0x5b, 0xd4, 0x15, 0x1b, 0x47, 0xd3, 0x7b, 0x80, - 0x72, 0x3e, 0x3d, 0xe0, 0xec, 0x8e, 0xf8, 0x10, 0x8a, 0x66, 0x40, 0xfa, 0x98, 0x71, 0x23, 0x64, - 0x28, 0x5e, 0x01, 0xbf, 0xa5, 0x49, 0x39, 0x26, 0x4e, 0x53, 0x5b, 0x87, 0xd5, 0x91, 0x13, 0x4b, - 0x25, 0x7e, 0x9c, 0xe3, 0xd7, 0x43, 0x03, 0xb9, 0x1e, 0x36, 0x90, 0x73, 0xce, 0x82, 0x7c, 0x02, - 0xeb, 0x43, 0x41, 0x68, 0x68, 0x67, 0x16, 0x65, 0x55, 0x86, 0xed, 0x87, 0xf6, 0x54, 0x36, 0x87, - 0x32, 0xc9, 0x36, 0x9f, 0x99, 0xad, 0x49, 0xd9, 0xa4, 0xca, 0xf9, 0xf3, 0x53, 0xb9, 0xcb, 0x7b, - 0xd2, 0x98, 0x9a, 0x89, 0xd8, 0x6a, 0x8b, 0x97, 0x7a, 0xcf, 0x47, 0x51, 0xad, 0xb4, 0xa3, 0x97, - 0x83, 0x68, 0x41, 0xda, 0x44, 0x97, 0xff, 0x2c, 0x79, 0x56, 0x34, 0x16, 0xa2, 0xc5, 0x1f, 0xff, - 0x5a, 0x55, 0x78, 0x59, 0x8b, 0xe0, 0x68, 0xba, 0xf6, 0x97, 0x02, 0x4b, 0x2d, 0xea, 0x3e, 0xc0, - 0xce, 0x6b, 0xe4, 0xe3, 0x0e, 0xac, 0x9f, 0x38, 0xf3, 0xab, 0x12, 0xf7, 0xdb, 0x39, 0xb8, 0x14, - 0x5d, 0x2f, 0x26, 0xb6, 0x91, 0xff, 0x00, 0x5b, 0x04, 0x3b, 0x1e, 0x76, 0x4f, 0x7b, 0x37, 0xfc, - 0xef, 0xb4, 0x56, 0xaf, 0x41, 0xc9, 0x8e, 0xae, 0xd0, 0x48, 0xb4, 0x03, 0xe4, 0xb9, 0x07, 0x71, - 0x3d, 0xcc, 0x1b, 0xcb, 0xc9, 0xf0, 0xc7, 0x7c, 0x34, 0x35, 0x29, 0x9b, 0x70, 0x35, 0x4d, 0xab, - 0x24, 0x47, 0x3b, 0xdf, 0x15, 0x60, 0xbe, 0x45, 0x5d, 0xf5, 0x21, 0x94, 0xc6, 0x1f, 0xa4, 0xd7, - 0x67, 0xdd, 0xc2, 0x93, 0x77, 0xbc, 0xb6, 0x93, 0x1d, 0x2b, 0xed, 0xd1, 0x85, 0xa5, 0x93, 0x6f, - 0x81, 0xad, 0x14, 0x92, 0x13, 0x48, 0xed, 0xdd, 0xac, 0x48, 0xb9, 0xd8, 0x97, 0xb0, 0x20, 0xef, - 0x96, 0x2b, 0x29, 0xd1, 0x09, 0x48, 0x7b, 0x27, 0x03, 0x48, 0xb2, 0x3f, 0x84, 0xd2, 0x78, 0xbf, - 0x4e, 0x53, 0x6f, 0x0c, 0x9b, 0xaa, 0xde, 0xac, 0xce, 0x65, 0x01, 0x8c, 0xb4, 0x99, 0xb7, 0x53, - 0x18, 0x86, 0x30, 0x6d, 0x3b, 0x13, 0x4c, 0xae, 0xf1, 0x8d, 0x02, 0x1b, 0xb3, 0xcb, 0xed, 0xfd, - 0xb4, 0x9c, 0xcf, 0x8a, 0xd2, 0x6e, 0xff, 0x9b, 0xa8, 0x64, 0x47, 0x8d, 0x7b, 0xcf, 0x8e, 0x2a, - 0xca, 0xf3, 0xa3, 0x8a, 0xf2, 0xdb, 0x51, 0x45, 0x79, 0x7c, 0x5c, 0xc9, 0x3d, 0x3f, 0xae, 0xe4, - 0x7e, 0x3e, 0xae, 0xe4, 0xbe, 0xb8, 0x91, 0xfa, 0x60, 0x7a, 0x24, 0xff, 0xac, 0xf1, 0xa7, 0x93, - 0x55, 0xe4, 0x9d, 0xe7, 0xbd, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xb6, 0xcb, 0x18, 0x6c, 0x91, - 0x0e, 0x00, 0x00, + 0x14, 0xf6, 0x26, 0x8e, 0x93, 0xbe, 0xa8, 0x71, 0xb3, 0x49, 0xa8, 0xb3, 0xaa, 0xec, 0xca, 0x2d, + 0x6d, 0x54, 0x9a, 0x35, 0x0d, 0x20, 0x50, 0xd5, 0x4b, 0x5c, 0xb7, 0x50, 0x05, 0x4b, 0x68, 0x43, + 0x39, 0x20, 0x24, 0x6b, 0x76, 0x77, 0xbc, 0x5e, 0x79, 0x77, 0xc6, 0xdd, 0x19, 0x47, 0xf5, 0x95, + 0x13, 0x37, 0xca, 0x7f, 0xd0, 0x33, 0xe2, 0xc0, 0xa1, 0x07, 0xfe, 0x84, 0x0a, 0x71, 0xa8, 0x7a, + 0x42, 0x1c, 0x0a, 0x4a, 0x0e, 0x70, 0x44, 0xfc, 0x05, 0x68, 0x77, 0x67, 0xc7, 0xbf, 0xed, 0x0d, + 0xa4, 0x07, 0xc4, 0xc9, 0xab, 0x99, 0xef, 0x7d, 0x33, 0xf3, 0xcd, 0xf7, 0xde, 0x3c, 0x43, 0xc9, + 0xa2, 0xcc, 0xa7, 0xac, 0xc2, 0x38, 0x6a, 0xbb, 0xc4, 0xa9, 0x1c, 0xdd, 0x32, 0x31, 0x47, 0xb7, + 0x2a, 0xfc, 0xb1, 0xde, 0x09, 0x28, 0xa7, 0xea, 0x1b, 0x31, 0x40, 0x17, 0x00, 0x5d, 0x00, 0xb4, + 0x6d, 0x87, 0x52, 0xc7, 0xc3, 0x95, 0x08, 0x65, 0x76, 0x9b, 0x15, 0x44, 0x7a, 0x71, 0x88, 0x56, + 0x1a, 0x9d, 0xe2, 0xae, 0x8f, 0x19, 0x47, 0x7e, 0x47, 0x00, 0x36, 0x1d, 0xea, 0xd0, 0xe8, 0xb3, + 0x12, 0x7e, 0x89, 0xd1, 0xed, 0x78, 0xa5, 0x46, 0x3c, 0x21, 0x96, 0x8d, 0xa7, 0x8a, 0x62, 0x97, + 0x26, 0x62, 0x58, 0x6e, 0xd1, 0xa2, 0x2e, 0x11, 0xf3, 0x57, 0xa7, 0x9c, 0x22, 0xd9, 0x74, 0x8c, + 0xba, 0x28, 0x50, 0x3e, 0x0b, 0x11, 0xe1, 0x4f, 0x3c, 0x51, 0xfe, 0x26, 0x07, 0x6a, 0x9d, 0x39, + 0x77, 0x03, 0x8c, 0x38, 0xfe, 0x0c, 0x79, 0xae, 0x8d, 0x38, 0x0d, 0xd4, 0x03, 0x58, 0xb5, 0x31, + 0xb3, 0x02, 0xb7, 0xc3, 0x5d, 0x4a, 0x0a, 0xca, 0x65, 0x65, 0x67, 0x75, 0xef, 0x8a, 0x3e, 0x59, + 0x10, 0xbd, 0xd6, 0x87, 0x56, 0xb3, 0xcf, 0x5f, 0x95, 0x32, 0xc6, 0x60, 0xb4, 0x5a, 0x07, 0xb0, + 0xa8, 0xef, 0xbb, 0x8c, 0x85, 0x5c, 0x0b, 0x11, 0xd7, 0xf5, 0x69, 0x5c, 0x77, 0x25, 0xd2, 0x40, + 0x1c, 0x33, 0xc1, 0x37, 0x40, 0xa0, 0x7a, 0xb0, 0xe1, 0xbb, 0xa4, 0xc1, 0xb0, 0xd7, 0x6c, 0xd8, + 0xd8, 0xc3, 0x0e, 0x8a, 0xf6, 0xb8, 0x78, 0x59, 0xd9, 0x39, 0x57, 0xbd, 0x13, 0xc2, 0x7f, 0x79, + 0x55, 0xba, 0xe6, 0xb8, 0xbc, 0xd5, 0x35, 0x75, 0x8b, 0xfa, 0x42, 0x4f, 0xf1, 0xb3, 0xcb, 0xec, + 0x76, 0x85, 0xf7, 0x3a, 0x98, 0xe9, 0x0f, 0x08, 0x7f, 0xf9, 0x6c, 0x17, 0xc4, 0x46, 0x1e, 0x10, + 0x6e, 0xac, 0xfb, 0x2e, 0x39, 0xc4, 0x5e, 0xb3, 0x26, 0x69, 0xd5, 0x7b, 0xb0, 0x2e, 0x16, 0xa1, + 0x41, 0x03, 0xd9, 0x76, 0x80, 0x19, 0x2b, 0x64, 0xa3, 0xb5, 0x0a, 0x2f, 0x9f, 0xed, 0x6e, 0x8a, + 0xe8, 0xfd, 0x78, 0xe6, 0x90, 0x07, 0x2e, 0x71, 0x8c, 0x0b, 0x32, 0x44, 0x8c, 0x87, 0x34, 0x47, + 0x89, 0xba, 0x92, 0x66, 0x69, 0x1e, 0x8d, 0x0c, 0x49, 0x68, 0xee, 0x43, 0xae, 0xd3, 0x35, 0xdb, + 0xb8, 0x57, 0xc8, 0x45, 0x32, 0x6e, 0xea, 0xb1, 0xe1, 0xf4, 0xc4, 0x70, 0xfa, 0x3e, 0xe9, 0x55, + 0x0b, 0x3f, 0xf6, 0x19, 0xad, 0xa0, 0xd7, 0xe1, 0x54, 0xff, 0xa4, 0x6b, 0x1e, 0xe0, 0x9e, 0x21, + 0xa2, 0xd5, 0xf7, 0x60, 0xe9, 0x08, 0x79, 0x5d, 0x5c, 0x58, 0x8e, 0x68, 0xb6, 0x93, 0xdb, 0x08, + 0x5d, 0x36, 0x70, 0x15, 0x6e, 0x72, 0x9f, 0x31, 0x5a, 0xbd, 0x09, 0xd9, 0x66, 0x40, 0xfd, 0xc2, + 0xca, 0x9c, 0x8d, 0x47, 0x28, 0x75, 0x1f, 0xf2, 0x01, 0xf6, 0x50, 0x0f, 0xf7, 0x4f, 0x7c, 0x6e, + 0x4e, 0xe0, 0x9a, 0x08, 0x48, 0xce, 0xfb, 0x21, 0xa8, 0x56, 0x0b, 0x79, 0x1e, 0x26, 0xce, 0x00, + 0x0b, 0xcc, 0x61, 0x59, 0xef, 0xc7, 0x24, 0x44, 0x17, 0x61, 0xd9, 0xf4, 0x58, 0x23, 0x54, 0x6e, + 0x35, 0x8c, 0x36, 0x72, 0xa6, 0xc7, 0x0e, 0x70, 0xef, 0xf6, 0xfa, 0x57, 0x4f, 0x4b, 0x99, 0x3f, + 0x9e, 0x96, 0x32, 0x5f, 0xfe, 0xfe, 0xfd, 0x8d, 0x68, 0xdf, 0xe5, 0x4b, 0xa0, 0x8d, 0xa7, 0x84, + 0x81, 0x59, 0x87, 0x12, 0x86, 0xcb, 0x3f, 0x64, 0xe1, 0x42, 0x9d, 0x39, 0xf7, 0x6c, 0x97, 0xbf, + 0xa6, 0x7c, 0x99, 0xe8, 0x95, 0x85, 0x53, 0x7b, 0x05, 0x41, 0xbe, 0x9f, 0x35, 0x8d, 0x00, 0x71, + 0x2c, 0x72, 0xe4, 0x83, 0x94, 0xf9, 0x51, 0xc3, 0xd6, 0x40, 0x7e, 0xd4, 0xb0, 0x65, 0xac, 0x59, + 0x43, 0xd9, 0xa9, 0xb6, 0x26, 0xa7, 0x62, 0xf6, 0x54, 0xcb, 0xa4, 0x4a, 0xc3, 0x09, 0x5e, 0x5a, + 0x3a, 0x13, 0x2f, 0xe5, 0xfe, 0x95, 0x97, 0x96, 0x87, 0xbc, 0x54, 0x1c, 0xf4, 0xd2, 0xf8, 0x1d, + 0x96, 0x35, 0x28, 0x8c, 0x3a, 0x47, 0xda, 0xea, 0x4f, 0x05, 0x56, 0xeb, 0xcc, 0x11, 0x47, 0xc6, + 0x93, 0xeb, 0x8e, 0x72, 0x36, 0x75, 0xe7, 0xf4, 0x5e, 0x7a, 0x1f, 0x72, 0xc8, 0xa7, 0x5d, 0xc2, + 0x23, 0x0b, 0xa5, 0x28, 0x18, 0x02, 0x7e, 0x5b, 0x93, 0x72, 0x8c, 0x9d, 0xa6, 0xbc, 0x05, 0x1b, + 0x03, 0x27, 0x96, 0x4a, 0xfc, 0xb4, 0x10, 0x3d, 0x49, 0x55, 0xec, 0xb8, 0xc4, 0xc0, 0xf6, 0x19, + 0x0b, 0xf2, 0x31, 0x6c, 0xf5, 0x05, 0x61, 0x81, 0x95, 0x5a, 0x94, 0x0d, 0x19, 0x76, 0x18, 0x58, + 0x13, 0xd9, 0x6c, 0xc6, 0x25, 0xdb, 0x62, 0x6a, 0xb6, 0x1a, 0xe3, 0xe3, 0x2a, 0x67, 0xcf, 0x4e, + 0xe5, 0x76, 0x54, 0xcd, 0x46, 0xd4, 0x4c, 0xc4, 0x56, 0xeb, 0x51, 0x91, 0xe8, 0x78, 0x38, 0xcc, + 0xb2, 0x46, 0xd8, 0xad, 0x88, 0xe2, 0xa5, 0x8d, 0xbd, 0x2c, 0x9f, 0x26, 0xad, 0x4c, 0x75, 0x25, + 0x5c, 0xfc, 0xc9, 0xaf, 0x25, 0x25, 0x2a, 0x08, 0x22, 0x38, 0x9c, 0x2e, 0xff, 0xa5, 0xc0, 0xf9, + 0x3a, 0x73, 0x1e, 0x12, 0xfb, 0x7f, 0xe4, 0xe3, 0x26, 0x6c, 0x0d, 0x9d, 0xf9, 0x75, 0x89, 0xfb, + 0xed, 0x02, 0x5c, 0x0a, 0x1f, 0x26, 0x44, 0x2c, 0xec, 0x3d, 0x24, 0x26, 0x25, 0xb6, 0x4b, 0x9c, + 0x79, 0xbd, 0xca, 0x7f, 0x4e, 0x6b, 0xf5, 0x3a, 0xe4, 0xad, 0xf0, 0xf1, 0x0d, 0x45, 0x6b, 0x61, + 0xd7, 0x69, 0xc5, 0xf9, 0xb0, 0x68, 0xac, 0x25, 0xc3, 0x1f, 0x45, 0xa3, 0x33, 0x2f, 0xe5, 0x1a, + 0x5c, 0x9d, 0xa5, 0x55, 0x72, 0x47, 0x7b, 0xdf, 0x2d, 0xc1, 0x62, 0x9d, 0x39, 0xea, 0x23, 0xc8, + 0x8f, 0x36, 0xc1, 0x37, 0xa6, 0xbd, 0xdf, 0xe3, 0xdd, 0x81, 0xb6, 0x97, 0x1e, 0x2b, 0xed, 0xd1, + 0x86, 0xf3, 0xc3, 0x5d, 0xc4, 0xce, 0x0c, 0x92, 0x21, 0xa4, 0xf6, 0x76, 0x5a, 0xa4, 0x5c, 0xec, + 0x0b, 0x58, 0x91, 0x6f, 0xcb, 0x95, 0x19, 0xd1, 0x09, 0x48, 0x7b, 0x2b, 0x05, 0x48, 0xb2, 0x3f, + 0x82, 0xfc, 0x68, 0xbd, 0x9e, 0xa5, 0xde, 0x08, 0x76, 0xa6, 0x7a, 0xd3, 0x2a, 0x97, 0x09, 0x30, + 0x50, 0x66, 0xde, 0x9c, 0xc1, 0xd0, 0x87, 0x69, 0xbb, 0xa9, 0x60, 0x72, 0x8d, 0xaf, 0x15, 0xd8, + 0x9e, 0x9e, 0x6e, 0xef, 0xce, 0xba, 0xf3, 0x69, 0x51, 0xda, 0x9d, 0x7f, 0x12, 0x95, 0xec, 0xa8, + 0x7a, 0xff, 0xf9, 0x71, 0x51, 0x79, 0x71, 0x5c, 0x54, 0x7e, 0x3b, 0x2e, 0x2a, 0x4f, 0x4e, 0x8a, + 0x99, 0x17, 0x27, 0xc5, 0xcc, 0xcf, 0x27, 0xc5, 0xcc, 0xe7, 0x37, 0x67, 0xb6, 0x5a, 0x8f, 0xe5, + 0x1f, 0xc4, 0xa8, 0xe9, 0x32, 0x73, 0x51, 0xe5, 0x79, 0xe7, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x4d, 0xb0, 0x55, 0x06, 0x05, 0x0f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1026,10 +1029,17 @@ func (m *MsgCreateValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.RelayerBlsKey) > 0 { - i -= len(m.RelayerBlsKey) - copy(dAtA[i:], m.RelayerBlsKey) - i = encodeVarintTx(dAtA, i, uint64(len(m.RelayerBlsKey))) + if len(m.BlsKey) > 0 { + i -= len(m.BlsKey) + copy(dAtA[i:], m.BlsKey) + i = encodeVarintTx(dAtA, i, uint64(len(m.BlsKey))) + i-- + dAtA[i] = 0x5a + } + if len(m.ChallengerAddress) > 0 { + i -= len(m.ChallengerAddress) + copy(dAtA[i:], m.ChallengerAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChallengerAddress))) i-- dAtA[i] = 0x52 } @@ -1159,10 +1169,17 @@ func (m *MsgEditValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.RelayerBlsKey) > 0 { - i -= len(m.RelayerBlsKey) - copy(dAtA[i:], m.RelayerBlsKey) - i = encodeVarintTx(dAtA, i, uint64(len(m.RelayerBlsKey))) + if len(m.BlsKey) > 0 { + i -= len(m.BlsKey) + copy(dAtA[i:], m.BlsKey) + i = encodeVarintTx(dAtA, i, uint64(len(m.BlsKey))) + i-- + dAtA[i] = 0x3a + } + if len(m.ChallengerAddress) > 0 { + i -= len(m.ChallengerAddress) + copy(dAtA[i:], m.ChallengerAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChallengerAddress))) i-- dAtA[i] = 0x32 } @@ -1593,7 +1610,11 @@ func (m *MsgCreateValidator) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.RelayerBlsKey) + l = len(m.ChallengerAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.BlsKey) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -1633,7 +1654,11 @@ func (m *MsgEditValidator) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.RelayerBlsKey) + l = len(m.ChallengerAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.BlsKey) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -2106,7 +2131,7 @@ func (m *MsgCreateValidator) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 10: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RelayerBlsKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChallengerAddress", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2134,7 +2159,39 @@ func (m *MsgCreateValidator) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RelayerBlsKey = string(dAtA[iNdEx:postIndex]) + m.ChallengerAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlsKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlsKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -2407,7 +2464,39 @@ func (m *MsgEditValidator) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RelayerBlsKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChallengerAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChallengerAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlsKey", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2435,7 +2524,7 @@ func (m *MsgEditValidator) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RelayerBlsKey = string(dAtA[iNdEx:postIndex]) + m.BlsKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/staking/types/validator.go b/x/staking/types/validator.go index cc69da0d37..3ab5e90e02 100644 --- a/x/staking/types/validator.go +++ b/x/staking/types/validator.go @@ -39,7 +39,7 @@ var ( var _ ValidatorI = Validator{} -// NewSimpleValidator constructs a new Validator with default self delegation, relayer address and nil relayer bls pubkey +// NewSimpleValidator constructs a new Validator with default self delegation, relayer address, challenger address and nil bls pubkey // //nolint:interfacerh func NewSimpleValidator(operator sdk.AccAddress, pubKey cryptotypes.PubKey, description Description) (Validator, error) { @@ -67,7 +67,8 @@ func NewSimpleValidator(operator sdk.AccAddress, pubKey cryptotypes.PubKey, desc MinSelfDelegation: sdk.OneInt(), SelfDelAddress: operator.String(), RelayerAddress: operator.String(), - RelayerBlsKey: blsPk, + ChallengerAddress: operator.String(), + BlsKey: blsPk, }, nil } @@ -77,7 +78,7 @@ func NewSimpleValidator(operator sdk.AccAddress, pubKey cryptotypes.PubKey, desc func NewValidator( operator sdk.AccAddress, pubKey cryptotypes.PubKey, description Description, selfDelegator sdk.AccAddress, - relayer sdk.AccAddress, relayerBlsKey []byte, + relayer sdk.AccAddress, challenger sdk.AccAddress, blsKey []byte, ) (Validator, error) { val, err := NewSimpleValidator(operator, pubKey, description) if err != nil { @@ -86,7 +87,8 @@ func NewValidator( val.SelfDelAddress = selfDelegator.String() val.RelayerAddress = relayer.String() - val.RelayerBlsKey = relayerBlsKey + val.BlsKey = blsKey + val.ChallengerAddress = challenger.String() return val, nil } @@ -308,11 +310,20 @@ func (v Validator) ABCIValidatorUpdate(r math.Int) abci.ValidatorUpdate { } } + var challenger []byte + if len(v.ChallengerAddress) > 0 { + challenger, err = sdk.AccAddressFromHexUnsafe(v.ChallengerAddress) + if err != nil { + panic(err) + } + } + return abci.ValidatorUpdate{ - PubKey: tmProtoPk, - Power: v.ConsensusPower(r), - RelayerAddress: relayer, - RelayerBlsKey: v.RelayerBlsKey, + PubKey: tmProtoPk, + Power: v.ConsensusPower(r), + RelayerAddress: relayer, + ChallengerAddress: challenger, + BlsKey: v.BlsKey, } } @@ -495,7 +506,7 @@ func (v *Validator) MinEqual(other *Validator) bool { v.ConsensusPubkey.Equal(other.ConsensusPubkey) && v.SelfDelAddress == other.SelfDelAddress && v.RelayerAddress == other.RelayerAddress && - bytes.Equal(v.RelayerBlsKey, other.RelayerBlsKey) + bytes.Equal(v.BlsKey, other.BlsKey) } // Equal checks if the receiver equals the parameter @@ -505,10 +516,10 @@ func (v *Validator) Equal(v2 *Validator) bool { v.UnbondingTime.Equal(v2.UnbondingTime) } -func (v Validator) IsJailed() bool { return v.Jailed } -func (v Validator) GetMoniker() string { return v.Description.Moniker } -func (v Validator) GetStatus() BondStatus { return v.Status } -func (v Validator) GetRelayerBlsKey() []byte { return v.RelayerBlsKey } +func (v Validator) IsJailed() bool { return v.Jailed } +func (v Validator) GetMoniker() string { return v.Description.Moniker } +func (v Validator) GetStatus() BondStatus { return v.Status } +func (v Validator) GetBlsKey() []byte { return v.BlsKey } func (v Validator) GetOperator() sdk.AccAddress { if v.OperatorAddress == "" { return nil @@ -542,6 +553,17 @@ func (v Validator) GetRelayer() sdk.AccAddress { return addr } +func (v Validator) GetChallenger() sdk.AccAddress { + if v.ChallengerAddress == "" { + return nil + } + addr, err := sdk.AccAddressFromHexUnsafe(v.ChallengerAddress) + if err != nil { + panic(err) + } + return addr +} + // ConsPubKey returns the validator PubKey as a cryptotypes.PubKey. func (v Validator) ConsPubKey() (cryptotypes.PubKey, error) { pk, ok := v.ConsensusPubkey.GetCachedValue().(cryptotypes.PubKey) From dcf2f000f7c4af65cca40f45cfdf86b5abc577e0 Mon Sep 17 00:00:00 2001 From: dylanhuang Date: Tue, 21 Mar 2023 09:58:37 +0800 Subject: [PATCH 02/10] chore: refine upgrade module for code quality (#144) --- x/upgrade/doc.go | 146 ------------------------------ x/upgrade/keeper/keeper.go | 21 +---- x/upgrade/keeper/keeper_option.go | 1 + x/upgrade/keeper/keeper_test.go | 43 --------- x/upgrade/types/keys.go | 10 -- x/upgrade/types/upgrade_config.go | 6 ++ 6 files changed, 8 insertions(+), 219 deletions(-) delete mode 100644 x/upgrade/doc.go diff --git a/x/upgrade/doc.go b/x/upgrade/doc.go deleted file mode 100644 index 5589ac6eda..0000000000 --- a/x/upgrade/doc.go +++ /dev/null @@ -1,146 +0,0 @@ -/* -Package upgrade provides a Cosmos SDK module that can be used for smoothly upgrading a live Cosmos chain to a -new software version. It accomplishes this by providing a BeginBlocker hook that prevents the blockchain state -machine from proceeding once a pre-defined upgrade block height has been reached. The module does not prescribe -anything regarding how governance decides to do an upgrade, but just the mechanism for coordinating the upgrade safely. -Without software support for upgrades, upgrading a live chain is risky because all of the validators need to pause -their state machines at exactly the same point in the process. If this is not done correctly, there can be state -inconsistencies which are hard to recover from. - -# General Workflow - -Let's assume we are running v0.38.0 of our software in our testnet and want to upgrade to v0.40.0. -How would this look in practice? First of all, we want to finalize the v0.40.0 release candidate -and there install a specially named upgrade handler (eg. "testnet-v2" or even "v0.40.0"). An upgrade -handler should be defined in a new version of the software to define what migrations -to run to migrate from the older version of the software. Naturally, this is app-specific rather -than module specific, and must be defined in `app.go`, even if it imports logic from various -modules to perform the actions. You can register them with `upgradeKeeper.SetUpgradeHandler` -during the app initialization (before starting the abci server), and they serve not only to -perform a migration, but also to identify if this is the old or new version (eg. presence of -a handler registered for the named upgrade). - -Once the release candidate along with an appropriate upgrade handler is frozen, -we can have a governance vote to approve this upgrade at some future block height (e.g. 200000). -This is known as an upgrade.Plan. The v0.38.0 code will not know of this handler, but will -continue to run until block 200000, when the plan kicks in at BeginBlock. It will check -for existence of the handler, and finding it missing, know that it is running the obsolete software, -and gracefully exit. - -Generally the application binary will restart on exit, but then will execute this BeginBlocker -again and exit, causing a restart loop. Either the operator can manually install the new software, -or you can make use of an external watcher daemon to possibly download and then switch binaries, -also potentially doing a backup. An example of such a daemon is https://github.com/cosmos/cosmos-sdk/tree/main/cosmovisor -described below under "Automation". - -When the binary restarts with the upgraded version (here v0.40.0), it will detect we have registered the -"testnet-v2" upgrade handler in the code, and realize it is the new version. It then will run the upgrade handler -and *migrate the database in-place*. Once finished, it marks the upgrade as done, and continues processing -the rest of the block as normal. Once 2/3 of the voting power has upgraded, the blockchain will immediately -resume the consensus mechanism. If the majority of operators add a custom `do-upgrade` script, this should -be a matter of minutes and not even require them to be awake at that time. - -# Integrating With An App - -Setup an upgrade Keeper for the app and then define a BeginBlocker that calls the upgrade -keeper's BeginBlocker method: - - func (app *myApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - app.upgradeKeeper.BeginBlocker(ctx, req) - return abci.ResponseBeginBlock{} - } - -The app must then integrate the upgrade keeper with its governance module as appropriate. The governance module -should call ScheduleUpgrade to schedule an upgrade and ClearUpgradePlan to cancel a pending upgrade. - -# Performing Upgrades - -Upgrades can be scheduled at a predefined block height. Once this block height is reached, the -existing software will cease to process ABCI messages and a new version with code that handles the upgrade must be deployed. -All upgrades are coordinated by a unique upgrade name that cannot be reused on the same blockchain. In order for the upgrade -module to know that the upgrade has been safely applied, a handler with the name of the upgrade must be installed. -Here is an example handler for an upgrade named "my-fancy-upgrade": - - app.upgradeKeeper.SetUpgradeHandler("my-fancy-upgrade", func(ctx sdk.Context, plan upgrade.Plan) { - // Perform any migrations of the state store needed for this upgrade - }) - -This upgrade handler performs the dual function of alerting the upgrade module that the named upgrade has been applied, -as well as providing the opportunity for the upgraded software to perform any necessary state migrations. Both the halt -(with the old binary) and applying the migration (with the new binary) are enforced in the state machine. Actually -switching the binaries is an ops task and not handled inside the sdk / abci app. - -Here is a sample code to set store migrations with an upgrade: - - // this configures a no-op upgrade handler for the "my-fancy-upgrade" upgrade - app.UpgradeKeeper.SetUpgradeHandler("my-fancy-upgrade", func(ctx sdk.Context, plan upgrade.Plan) { - // upgrade changes here - }) - - upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() - if err != nil { - // handle error - } - - if upgradeInfo.Name == "my-fancy-upgrade" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { - storeUpgrades := store.StoreUpgrades{ - Renamed: []store.StoreRename{{ - OldKey: "foo", - NewKey: "bar", - }}, - Deleted: []string{}, - } - - // configure store loader that checks if version == upgradeHeight and applies store upgrades - app.SetStoreLoader(upgrade.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) - } - -# Halt Behavior - -Before halting the ABCI state machine in the BeginBlocker method, the upgrade module will log an error -that looks like: - - UPGRADE "" NEEDED at height : - -where Name are Info are the values of the respective fields on the upgrade Plan. - -To perform the actual halt of the blockchain, the upgrade keeper simply panics which prevents the ABCI state machine -from proceeding but doesn't actually exit the process. Exiting the process can cause issues for other nodes that start -to lose connectivity with the exiting nodes, thus this module prefers to just halt but not exit. - -# Automation and Plan.Info - -We have deprecated calling out to scripts, instead with propose https://github.com/cosmos/cosmos-sdk/tree/main/cosmovisor -as a model for a watcher daemon that can launch simd as a subprocess and then read the upgrade log message -to swap binaries as needed. You can pass in information into Plan.Info according to the format -specified here https://github.com/cosmos/cosmos-sdk/tree/main/cosmovisor/README.md#auto-download . -This will allow a properly configured cosmsod daemon to auto-download new binaries and auto-upgrade. -As noted there, this is intended more for full nodes than validators. - -# Cancelling Upgrades - -There are two ways to cancel a planned upgrade - with on-chain governance or off-chain social consensus. -For the first one, there is a CancelSoftwareUpgrade proposal type, which can be voted on and will -remove the scheduled upgrade plan. Of course this requires that the upgrade was known to be a bad idea -well before the upgrade itself, to allow time for a vote. If you want to allow such a possibility, you -should set the upgrade height to be 2 * (votingperiod + depositperiod) + (safety delta) from the beginning of -the first upgrade proposal. Safety delta is the time available from the success of an upgrade proposal -and the realization it was a bad idea (due to external testing). You can also start a CancelSoftwareUpgrade -proposal while the original SoftwareUpgrade proposal is still being voted upon, as long as the voting -period ends after the SoftwareUpgrade proposal. - -However, let's assume that we don't realize the upgrade has a bug until shortly before it will occur -(or while we try it out - hitting some panic in the migration). It would seem the blockchain is stuck, -but we need to allow an escape for social consensus to overrule the planned upgrade. To do so, there's -a --unsafe-skip-upgrades flag to the start command, which will cause the node to mark the upgrade -as done upon hitting the planned upgrade height(s), without halting and without actually performing a migration. -If over two-thirds run their nodes with this flag on the old binary, it will allow the chain to continue through -the upgrade with a manual override. (This must be well-documented for anyone syncing from genesis later on). - -Example: - - simd start --unsafe-skip-upgrades ... - -NOTE: Here simd is used as an example binary, replace it with original binary -*/ -package upgrade diff --git a/x/upgrade/keeper/keeper.go b/x/upgrade/keeper/keeper.go index b7d6c74457..8d8d945852 100644 --- a/x/upgrade/keeper/keeper.go +++ b/x/upgrade/keeper/keeper.go @@ -27,7 +27,7 @@ type Keeper struct { cdc codec.BinaryCodec // App-wide binary codec upgradeHandlers map[string]types.UpgradeHandler // map of plan name to upgrade handler upgradeInitializer map[string]types.UpgradeInitializer // map of plan name to upgrade initializer - upgradeConfig *types.UpgradeConfig + upgradeConfig *types.UpgradeConfig // upgrade config for upcoming upgrade plan or upgraded plan } // NewKeeper constructs an upgrade Keeper which requires the following arguments: @@ -178,24 +178,6 @@ func (k Keeper) ScheduleUpgrade(ctx sdk.Context, plan types.Plan) error { return nil } -// SetUpgradedClient sets the expected upgraded client for the next version of this chain at the last height the current chain will commit. -func (k Keeper) SetUpgradedClient(ctx sdk.Context, planHeight int64, bz []byte) error { - store := ctx.KVStore(k.storeKey) - store.Set(types.UpgradedClientKey(planHeight), bz) - return nil -} - -// GetUpgradedClient gets the expected upgraded client for the next version of this chain -func (k Keeper) GetUpgradedClient(ctx sdk.Context, height int64) ([]byte, bool) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(types.UpgradedClientKey(height)) - if len(bz) == 0 { - return nil, false - } - - return bz, true -} - // SetUpgradedConsensusState set the expected upgraded consensus state for the next version of this chain // using the last height committed on this chain. func (k Keeper) SetUpgradedConsensusState(ctx sdk.Context, planHeight int64, bz []byte) error { @@ -262,7 +244,6 @@ func (k Keeper) GetDoneHeight(ctx sdk.Context, name string) int64 { func (k Keeper) ClearIBCState(ctx sdk.Context, lastHeight int64) { // delete IBC client and consensus state from store if this is IBC plan store := ctx.KVStore(k.storeKey) - store.Delete(types.UpgradedClientKey(lastHeight)) store.Delete(types.UpgradedConsStateKey(lastHeight)) } diff --git a/x/upgrade/keeper/keeper_option.go b/x/upgrade/keeper/keeper_option.go index 0ea1088e0a..81b876423a 100644 --- a/x/upgrade/keeper/keeper_option.go +++ b/x/upgrade/keeper/keeper_option.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) +// convertUpgradeConfig converts serverconfig.UpgradeConfig to types.UpgradeConfig func convertUpgradeConfig(chainID string, plans []serverconfig.UpgradeConfig) (*types.UpgradeConfig, error) { upgradeConfig := types.NewUpgradeConfig() if chainID == types.MainnetChainID { diff --git a/x/upgrade/keeper/keeper_test.go b/x/upgrade/keeper/keeper_test.go index f4a1c3dbfa..69771f5202 100644 --- a/x/upgrade/keeper/keeper_test.go +++ b/x/upgrade/keeper/keeper_test.go @@ -157,49 +157,6 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { } } -func (s *KeeperTestSuite) TestSetUpgradedClient() { - cs := []byte("IBC client state") - - cases := []struct { - name string - height int64 - setup func() - exists bool - }{ - { - name: "no upgraded client exists", - height: 10, - setup: func() {}, - exists: false, - }, - { - name: "success", - height: 10, - setup: func() { - s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 10, cs) - }, - exists: true, - }, - } - - for _, tc := range cases { - // reset suite - s.SetupTest() - - // setup test case - tc.setup() - - gotCs, exists := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.height) - if tc.exists { - s.Require().Equal(cs, gotCs, "valid case: %s did not retrieve correct client state", tc.name) - s.Require().True(exists, "valid case: %s did not retrieve client state", tc.name) - } else { - s.Require().Nil(gotCs, "invalid case: %s retrieved valid client state", tc.name) - s.Require().False(exists, "invalid case: %s retrieved valid client state", tc.name) - } - } -} - // Tests that the underlying state of x/upgrade is set correctly after // an upgrade. func (s *KeeperTestSuite) TestMigrations() { diff --git a/x/upgrade/types/keys.go b/x/upgrade/types/keys.go index e1a30c77ae..fce5858938 100644 --- a/x/upgrade/types/keys.go +++ b/x/upgrade/types/keys.go @@ -26,20 +26,10 @@ const ( // KeyUpgradedIBCState is the key under which upgraded ibc state is stored in the upgrade store KeyUpgradedIBCState = "upgradedIBCState" - // KeyUpgradedClient is the sub-key under which upgraded client state will be stored - KeyUpgradedClient = "upgradedClient" - // KeyUpgradedConsState is the sub-key under which upgraded consensus state will be stored KeyUpgradedConsState = "upgradedConsState" ) -// UpgradedClientKey is the key under which the upgraded client state is saved -// Connecting IBC chains can verify against the upgraded client in this path before -// upgrading their clients -func UpgradedClientKey(height int64) []byte { - return []byte(fmt.Sprintf("%s/%d/%s", KeyUpgradedIBCState, height, KeyUpgradedClient)) -} - // UpgradedConsStateKey is the key under which the upgraded consensus state is saved // Connecting IBC chains can verify against the upgraded consensus state in this path before // upgrading their clients. diff --git a/x/upgrade/types/upgrade_config.go b/x/upgrade/types/upgrade_config.go index c316df92cc..cedb4dec1f 100644 --- a/x/upgrade/types/upgrade_config.go +++ b/x/upgrade/types/upgrade_config.go @@ -10,9 +10,11 @@ import ( // ) const ( + // EnablePublicDelegationUpgrade is the upgrade name for enabling public delegation EnablePublicDelegationUpgrade = "EnablePublicDelegationUpgrade" ) +// The default upgrade config for networks var ( MainnetChainID = "greenfield_9000-1" MainnetConfig = NewUpgradeConfig() @@ -35,11 +37,13 @@ type key struct { height int64 } +// UpgradeConfig is a list of upgrade plans type UpgradeConfig struct { keys map[string]*key elements map[int64][]*Plan } +// SetPlan sets a new upgrade plan func (c *UpgradeConfig) SetPlan(plan *Plan) *UpgradeConfig { if key, ok := c.keys[plan.Name]; ok { if c.elements[key.height][key.index].Height == plan.Height { @@ -56,6 +60,7 @@ func (c *UpgradeConfig) SetPlan(plan *Plan) *UpgradeConfig { return c } +// Clear removes all upgrade plans at a given height func (c *UpgradeConfig) Clear(height int64) { for _, plan := range c.elements[height] { delete(c.keys, plan.Name) @@ -63,6 +68,7 @@ func (c *UpgradeConfig) Clear(height int64) { c.elements[height] = nil } +// GetPlan returns the upgrade plan at a given height func (c *UpgradeConfig) GetPlan(height int64) []*Plan { plans, exist := c.elements[height] if exist && len(plans) != 0 { From 3234f8814c9d8bbcb4f0806d19897e49f227b38d Mon Sep 17 00:00:00 2001 From: Alexxxxxx <118710506+alexgao001@users.noreply.github.com> Date: Tue, 21 Mar 2023 10:00:50 +0800 Subject: [PATCH 03/10] refactor: refine cross-chain governance (#142) --- proto/cosmos/params/v1beta1/params.proto | 6 ++++-- x/params/client/utils/utils.go | 4 +++- x/params/keeper/sync_params.go | 10 ++++------ x/params/proposal_handler.go | 2 -- x/params/types/proposal/errors.go | 4 ++-- x/params/types/proposal/params.pb.go | 6 ++++-- x/params/types/proposal/proposal.go | 1 + x/params/types/proposal/types.go | 9 ++++----- 8 files changed, 22 insertions(+), 20 deletions(-) diff --git a/proto/cosmos/params/v1beta1/params.proto b/proto/cosmos/params/v1beta1/params.proto index 83936c7d32..65d896071f 100644 --- a/proto/cosmos/params/v1beta1/params.proto +++ b/proto/cosmos/params/v1beta1/params.proto @@ -16,8 +16,10 @@ message ParameterChangeProposal { string title = 1; string description = 2; repeated ParamChange changes = 3 [(gogoproto.nullable) = false]; - bool cross_chain = 4; // flag for cross chain proposal - repeated string addresses = 5; // used with cross_chain field to specify destination smart contract address(es) + // cross_chain is a flag to indicate whether it is a cross-chain proposal + bool cross_chain = 4; + // addresses is destination smart contract address(es), only used when it is a cross-chain proposal + repeated string addresses = 5; } // ParamChange defines an individual parameter change, for use in diff --git a/x/params/client/utils/utils.go b/x/params/client/utils/utils.go index acfc2cc25f..1485d9598f 100644 --- a/x/params/client/utils/utils.go +++ b/x/params/client/utils/utils.go @@ -12,7 +12,9 @@ type ( // ParamChangesJSON defines a slice of ParamChangeJSON objects which can be // converted to a slice of ParamChange objects. ParamChangesJSON []ParamChangeJSON - Addresses []string + + // Addresses defines a slice of addresses string in hex format + Addresses []string // ParamChangeJSON defines a parameter change used in JSON input. This // allows values to be specified in raw JSON instead of being string encoded. diff --git a/x/params/keeper/sync_params.go b/x/params/keeper/sync_params.go index bf42727dda..50248a7a2e 100644 --- a/x/params/keeper/sync_params.go +++ b/x/params/keeper/sync_params.go @@ -15,7 +15,7 @@ func (k Keeper) RegisterCrossChainSyncParamsApp() error { } func (k Keeper) SyncParams(ctx sdk.Context, p *types.ParameterChangeProposal) error { - // this validates content and size of changes is not empty + // validates if change(s) is/are present, proposal content is valid for params change or contract upgrade if err := p.ValidateBasic(); err != nil { return err } @@ -29,18 +29,18 @@ func (k Keeper) SyncParams(ctx sdk.Context, p *types.ParameterChangeProposal) er if c.Key == types.KeyUpgrade { value, err = sdk.AccAddressFromHexUnsafe(c.Value) if err != nil { - return sdkerrors.Wrapf(types.ErrAddressNotValid, "smart contract address is not valid %s", c.Value) + return sdkerrors.Wrapf(types.ErrAddressNotValid, "smart contract address format is not valid, address=%s", c.Value) } } else { value, err = hex.DecodeString(c.Value) if err != nil { - return sdkerrors.Wrapf(types.ErrInvalidValue, "value is not valid %s", c.Value) + return sdkerrors.Wrapf(types.ErrInvalidValue, "ParamChange value is not valid, should be in hex format, value=%s", c.Value) } } values = append(values, value...) addr, err := sdk.AccAddressFromHexUnsafe(p.Addresses[i]) if err != nil { - return sdkerrors.Wrapf(types.ErrAddressNotValid, "smart contract address is not valid %s", p.Addresses[i]) + return sdkerrors.Wrapf(types.ErrAddressNotValid, "smart contract address format is not valid, address=%s", p.Addresses[i]) } addresses = append(addresses, addr.Bytes()...) } @@ -66,8 +66,6 @@ func (k Keeper) SyncParams(ctx sdk.Context, p *types.ParameterChangeProposal) er return err } -// Need these in order to register paramsKeeper to be a CrosschainApp so that it can register channel(3) - func (k Keeper) ExecuteSynPackage(ctx sdk.Context, appCtx *sdk.CrossChainAppContext, payload []byte) sdk.ExecuteResult { k.Logger(ctx).Error("received sync params sync package", "payload", hex.EncodeToString(payload)) return sdk.ExecuteResult{} diff --git a/x/params/proposal_handler.go b/x/params/proposal_handler.go index 68f0b44fb8..59637805a7 100644 --- a/x/params/proposal_handler.go +++ b/x/params/proposal_handler.go @@ -24,8 +24,6 @@ func NewParamChangeProposalHandler(k keeper.Keeper) govtypes.Handler { } func handleParameterChangeProposal(ctx sdk.Context, k keeper.Keeper, p *proposal.ParameterChangeProposal) error { - // for govv1.MsgExecLegacyContent, validation is applied by writing to cache Subspace store, since gnfd does not hold - // the subspace for crosschain parameters. the validation is skipped. if p.CrossChain { return k.SyncParams(ctx, p) } diff --git a/x/params/types/proposal/errors.go b/x/params/types/proposal/errors.go index f619d9e33a..af5f2ae223 100644 --- a/x/params/types/proposal/errors.go +++ b/x/params/types/proposal/errors.go @@ -12,9 +12,9 @@ var ( ErrEmptySubspace = sdkerrors.Register(ModuleName, 5, "parameter subspace is empty") ErrEmptyKey = sdkerrors.Register(ModuleName, 6, "parameter key is empty") ErrEmptyValue = sdkerrors.Register(ModuleName, 7, "parameter value is empty") - ErrAddressSizeNotMatch = sdkerrors.Register(ModuleName, 8, "number of old address not equal to new addresses") + ErrAddressSizeNotMatch = sdkerrors.Register(ModuleName, 8, "number of old addresses does not equal to number of new addresses") ErrAddressNotValid = sdkerrors.Register(ModuleName, 9, "address format is not valid") - ErrExceedParamsChangeLimit = sdkerrors.Register(ModuleName, 10, "exceed params change limit") + ErrExceedParamsChangeLimit = sdkerrors.Register(ModuleName, 10, "exceed params change limit, limit=1") ErrInvalidUpgradeProposal = sdkerrors.Register(ModuleName, 11, "invalid sync params package") ErrInvalidValue = sdkerrors.Register(ModuleName, 12, "decode hex value failed") ) diff --git a/x/params/types/proposal/params.pb.go b/x/params/types/proposal/params.pb.go index af76aec7c3..7001a7e7e4 100644 --- a/x/params/types/proposal/params.pb.go +++ b/x/params/types/proposal/params.pb.go @@ -29,8 +29,10 @@ type ParameterChangeProposal struct { Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` Changes []ParamChange `protobuf:"bytes,3,rep,name=changes,proto3" json:"changes"` - CrossChain bool `protobuf:"varint,4,opt,name=cross_chain,json=crossChain,proto3" json:"cross_chain,omitempty"` - Addresses []string `protobuf:"bytes,5,rep,name=addresses,proto3" json:"addresses,omitempty"` + // cross_chain is a flag to indicate whether it is a cross-chain proposal + CrossChain bool `protobuf:"varint,4,opt,name=cross_chain,json=crossChain,proto3" json:"cross_chain,omitempty"` + // addresses is destination smart contract address(es), only used when it is a cross-chain proposal + Addresses []string `protobuf:"bytes,5,rep,name=addresses,proto3" json:"addresses,omitempty"` } func (m *ParameterChangeProposal) Reset() { *m = ParameterChangeProposal{} } diff --git a/x/params/types/proposal/proposal.go b/x/params/types/proposal/proposal.go index 675c63ea55..264901647d 100644 --- a/x/params/types/proposal/proposal.go +++ b/x/params/types/proposal/proposal.go @@ -24,6 +24,7 @@ func NewParameterChangeProposal(title, description string, changes []ParamChange return &ParameterChangeProposal{Title: title, Description: description, Changes: changes} } +// NewCrossChainParameterChangeProposal creates a proposal for cross chain parameter change or smart contract upgrade func NewCrossChainParameterChangeProposal(title, description string, changes []ParamChange, addresses []string) *ParameterChangeProposal { return &ParameterChangeProposal{Title: title, Description: description, Changes: changes, CrossChain: true, Addresses: addresses} } diff --git a/x/params/types/proposal/types.go b/x/params/types/proposal/types.go index f0a22640ab..1bea888058 100644 --- a/x/params/types/proposal/types.go +++ b/x/params/types/proposal/types.go @@ -8,13 +8,12 @@ const ( KeyUpgrade = "upgrade" ) -var KeySyncParamsRelayerFee = []byte("SyncParamsRelayerFee") - -// SyncParamsPackage is the payload be relayed to BSC +// SyncParamsPackage is the payload to be encoded for cross-chain IBC package type SyncParamsPackage struct { + // Key is the parameter to be changed Key string - // new parameter or new smart contract address(es) if is ungraded proposal + // Value is either new parameter or new smart contract address(es) if it is an upgrade proposal Value []byte - // smart contract address(es) + // Target is the smart contract address(es) Target []byte } From d35abd789ed52d5b99cdf15b9099d367e207b5ef Mon Sep 17 00:00:00 2001 From: Roshan <48975233+Pythonberg1997@users.noreply.github.com> Date: Tue, 21 Mar 2023 10:01:15 +0800 Subject: [PATCH 04/10] chore: refine the code of gashub module (#140) --- proto/cosmos/gashub/v1alpha1/event.proto | 9 +- proto/cosmos/gashub/v1alpha1/gashub.proto | 8 +- proto/cosmos/gashub/v1alpha1/genesis.proto | 2 +- proto/cosmos/gashub/v1alpha1/tx.proto | 6 +- server/json_rpc.go | 4 +- server/jsonrpc/backend/backend.go | 103 +----- server/jsonrpc/backend/blocks.go | 29 -- server/jsonrpc/backend/chain_info.go | 4 +- server/jsonrpc/backend/unimplemented.go | 251 ------------- server/jsonrpc/namespaces/ethereum/eth/api.go | 342 ------------------ server/jsonrpc/namespaces/ethereum/net/api.go | 4 +- types/chain_id.go | 60 +++ types/errors/errors.go | 2 +- types/math.go | 4 +- x/auth/ante/basic.go | 2 +- x/auth/ante/sigverify.go | 42 +-- x/auth/signing/verify.go | 33 +- x/auth/tx/eip712.go | 28 +- x/auth/tx/eip712_test.go | 11 +- x/gashub/types/codec.go | 12 +- x/gashub/types/event.pb.go | 9 +- x/gashub/types/gashub.pb.go | 12 +- x/gashub/types/genesis.pb.go | 2 +- x/gashub/types/{key.go => keys.go} | 0 x/gashub/types/params.go | 3 + x/gashub/types/tx.pb.go | 27 +- 26 files changed, 172 insertions(+), 837 deletions(-) delete mode 100644 server/jsonrpc/backend/unimplemented.go create mode 100644 types/chain_id.go rename x/gashub/types/{key.go => keys.go} (100%) diff --git a/proto/cosmos/gashub/v1alpha1/event.proto b/proto/cosmos/gashub/v1alpha1/event.proto index fd72c0969f..267d844ac8 100644 --- a/proto/cosmos/gashub/v1alpha1/event.proto +++ b/proto/cosmos/gashub/v1alpha1/event.proto @@ -4,9 +4,12 @@ package cosmos.gashub.v1alpha1; option go_package = "github.com/cosmos/cosmos-sdk/x/gashub/types"; -// EventUpdateMsgGasParams is emitted when update a msg's gas params +// EventUpdateMsgGasParams is emitted when updating a message's gas params message EventUpdateMsgGasParams { + // msg_type_url is the type url of the message string msg_type_url = 1; - string from_value = 2; - string to_value = 3; + // from_value is the previous gas params + string from_value = 2; + // to_value is the new gas params + string to_value = 3; } diff --git a/proto/cosmos/gashub/v1alpha1/gashub.proto b/proto/cosmos/gashub/v1alpha1/gashub.proto index 2408bb7e71..bcca4d5ccc 100644 --- a/proto/cosmos/gashub/v1alpha1/gashub.proto +++ b/proto/cosmos/gashub/v1alpha1/gashub.proto @@ -10,9 +10,12 @@ message Params { option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = false; - uint64 max_tx_size = 1 [(gogoproto.customname) = "MaxTxSize"]; + // max_tx_size is the maximum size of a transaction's bytes. + uint64 max_tx_size = 1 [(gogoproto.customname) = "MaxTxSize"]; + // min_gas_per_byte is the minimum gas to be paid per byte of a transaction's uint64 min_gas_per_byte = 2 [(gogoproto.customname) = "MinGasPerByte"]; + // msg_gas_params is the list of gas params for each msg type repeated MsgGasParams msg_gas_params_set = 3 [(gogoproto.customname) = "MsgGasParamsSet"]; } @@ -36,6 +39,7 @@ message MsgGasParams { message FixedGasParams { option (gogoproto.equal) = true; + // fixed_gas is the gas cost for a fixed type msg uint64 fixed_gas = 1 [(gogoproto.customname) = "FixedGas"]; } @@ -43,7 +47,9 @@ message MsgGasParams { message DynamicGasParams { option (gogoproto.equal) = true; + // fixed_gas is the base gas cost for a dynamic type msg uint64 fixed_gas = 1 [(gogoproto.customname) = "FixedGas"]; + // gas_per_item is the gas cost for a dynamic type msg per item uint64 gas_per_item = 2 [(gogoproto.customname) = "GasPerItem"]; } } diff --git a/proto/cosmos/gashub/v1alpha1/genesis.proto b/proto/cosmos/gashub/v1alpha1/genesis.proto index f895dd0d3c..baf005e36b 100644 --- a/proto/cosmos/gashub/v1alpha1/genesis.proto +++ b/proto/cosmos/gashub/v1alpha1/genesis.proto @@ -8,6 +8,6 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/gashub/types"; // GenesisState defines the gashub module's genesis state. message GenesisState { - // params defines all the paramaters of the module. + // params defines all the parameters of the module. Params params = 1 [(gogoproto.nullable) = false]; } diff --git a/proto/cosmos/gashub/v1alpha1/tx.proto b/proto/cosmos/gashub/v1alpha1/tx.proto index a0eeb94891..872d5ae6e6 100644 --- a/proto/cosmos/gashub/v1alpha1/tx.proto +++ b/proto/cosmos/gashub/v1alpha1/tx.proto @@ -17,12 +17,14 @@ service Msg { // MsgUpdateMsgGasParams represents a message to update msg gas params. message MsgUpdateMsgGasParams { // NOTE: The params should be updated by the gov module account after the proposal passes. - option (cosmos.msg.v1.signer) = "sender"; + option (cosmos.msg.v1.signer) = "from"; option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string from = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // from is the message signer for MsgUpdateMsgGasParams + string from = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // new_params_set is the new set of msg gas params to be updated. repeated MsgGasParams new_params_set = 2; } diff --git a/server/json_rpc.go b/server/json_rpc.go index 98ee5ebcac..5471918600 100644 --- a/server/json_rpc.go +++ b/server/json_rpc.go @@ -19,8 +19,8 @@ import ( ) // StartJSONRPC starts the JSON-RPC server -// this server is only meant to be used for wallets connection, so the wallets can sign EIP712 typed msg -// it doesn't include other unnecessary EVM rpc apis like eth_call +// This server is exclusively designed for wallet connections to sign EIP712 typed messages. +// It does not offer any other unnecessary EVM RPC APIs, such as eth_call. func StartJSONRPC(ctx *Context, clientCtx client.Context, tmRPCAddr, diff --git a/server/jsonrpc/backend/backend.go b/server/jsonrpc/backend/backend.go index bd98326d9d..932686555b 100644 --- a/server/jsonrpc/backend/backend.go +++ b/server/jsonrpc/backend/backend.go @@ -3,122 +3,31 @@ package backend import ( "context" "math/big" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/signer/core/apitypes" - rpctypes "github.com/evmos/ethermint/rpc/types" - "github.com/evmos/ethermint/server/config" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/spf13/viper" "github.com/tendermint/tendermint/libs/log" - tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/server/config" sdk "github.com/cosmos/cosmos-sdk/types" + rpctypes "github.com/evmos/ethermint/rpc/types" ) -// BackendI implements the EVM backend. -// this server is only meant to be used for wallets connection, so the wallets can sign EIP712 typed msg -// it doesn't include other unnecessary EVM rpc apis like eth_call -type BackendI interface { - EVMBackend -} - // EVMBackend implements the functionality shared within ethereum namespaces // as defined by EIP-1474: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1474.md // Implemented by Backend. +// This server is exclusively designed for wallet connections to sign EIP712 typed messages. +// It does not offer any other unnecessary EVM RPC APIs, such as eth_call. type EVMBackend interface { - // Node specific queries - Accounts() ([]common.Address, error) - Syncing() (interface{}, error) - SetEtherbase(etherbase common.Address) bool - SetGasPrice(gasPrice hexutil.Big) bool - ImportRawKey(privkey, password string) (common.Address, error) - ListAccounts() ([]common.Address, error) - NewMnemonic(uid string, language keyring.Language, hdPath, bip39Passphrase string, algo keyring.SignatureAlgo) (*keyring.Record, error) - UnprotectedAllowed() bool - RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection - RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection - RPCTxFeeCap() float64 // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for send-transaction variants. The unit is ether. - RPCMinGasPrice() int64 - - // Sign Tx - Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) - SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) - SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) - - // Blocks Info BlockNumber() (hexutil.Uint64, error) GetBlockByNumber(blockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error) - GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) - GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint - GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint - TendermintBlockByNumber(blockNum rpctypes.BlockNumber) (*tmrpctypes.ResultBlock, error) - TendermintBlockResultByNumber(height *int64) (*tmrpctypes.ResultBlockResults, error) - TendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error) - BlockNumberFromTendermint(blockNrOrHash rpctypes.BlockNumberOrHash) (rpctypes.BlockNumber, error) - BlockNumberFromTendermintByHash(blockHash common.Hash) (*big.Int, error) - EthMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults) []*evmtypes.MsgEthereumTx - BlockBloom(blockRes *tmrpctypes.ResultBlockResults) (ethtypes.Bloom, error) - HeaderByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Header, error) - HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) - RPCBlockFromTendermintBlock(resBlock *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults, fullTx bool) (map[string]interface{}, error) - EthBlockByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Block, error) - EthBlockFromTendermintBlock(resBlock *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults) (*ethtypes.Block, error) - - // Account Info - GetCode(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) GetBalance(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Big, error) - GetStorageAt(address common.Address, key string, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) - GetProof(address common.Address, storageKeys []string, blockNrOrHash rpctypes.BlockNumberOrHash) (*rpctypes.AccountResult, error) - GetTransactionCount(address common.Address, blockNum rpctypes.BlockNumber) (*hexutil.Uint64, error) - - // Chain Info ChainID() (*hexutil.Big, error) - ChainConfig() *params.ChainConfig - GlobalMinGasPrice() (sdk.Dec, error) - BaseFee(blockRes *tmrpctypes.ResultBlockResults) (*big.Int, error) - CurrentHeader() *ethtypes.Header - PendingTransactions() ([]*sdk.Tx, error) - GetCoinbase() (sdk.AccAddress, error) - FeeHistory(blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*rpctypes.FeeHistoryResult, error) - SuggestGasTipCap(baseFee *big.Int) (*big.Int, error) - - // Tx Info - GetTransactionByHash(txHash common.Hash) (*rpctypes.RPCTransaction, error) - GetTxByEthHash(txHash common.Hash) (*ethermint.TxResult, error) - GetTxByTxIndex(height int64, txIndex uint) (*ethermint.TxResult, error) - GetTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) - GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) - GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) - GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) - - // Send Transaction - Resend(args evmtypes.TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) - SendRawTransaction(data hexutil.Bytes) (common.Hash, error) - SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error) - EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rpctypes.BlockNumber) (hexutil.Uint64, error) - DoCall(args evmtypes.TransactionArgs, blockNr rpctypes.BlockNumber) (*evmtypes.MsgEthereumTxResponse, error) - GasPrice() (*hexutil.Big, error) - - // Filter API - GetLogs(hash common.Hash) ([][]*ethtypes.Log, error) - GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error) - BloomStatus() (uint64, uint64) - - // Tracing - TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) (interface{}, error) - TraceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConfig, block *tmrpctypes.ResultBlock) ([]*evmtypes.TxTraceResult, error) } -var _ BackendI = (*Backend)(nil) +var _ EVMBackend = (*Backend)(nil) // Backend implements the BackendI interface type Backend struct { @@ -135,7 +44,7 @@ func NewBackend( logger log.Logger, clientCtx client.Context, ) *Backend { - chainID, err := ethermint.ParseChainID(clientCtx.ChainID) + chainID, err := sdk.ParseChainID(clientCtx.ChainID) if err != nil { panic(err) } diff --git a/server/jsonrpc/backend/blocks.go b/server/jsonrpc/backend/blocks.go index 027a257a92..ed398b3ad5 100644 --- a/server/jsonrpc/backend/blocks.go +++ b/server/jsonrpc/backend/blocks.go @@ -8,7 +8,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/trie" rpctypes "github.com/evmos/ethermint/rpc/types" "github.com/pkg/errors" tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" @@ -140,34 +139,6 @@ func (b *Backend) RPCBlockFromTendermintBlock( return formattedBlock, nil } -// EthBlockByNumber returns the Ethereum Block identified by number. -func (b *Backend) EthBlockByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Block, error) { - resBlock, err := b.TendermintBlockByNumber(blockNum) - if err != nil { - return nil, err - } - if resBlock == nil { - // block not found - return nil, fmt.Errorf("block not found for height %d", blockNum) - } - - return b.EthBlockFromTendermintBlock(resBlock, nil) -} - -// EthBlockFromTendermintBlock returns an Ethereum Block type from Tendermint block -// EthBlockFromTendermintBlock -func (b *Backend) EthBlockFromTendermintBlock( - resBlock *tmrpctypes.ResultBlock, - blockRes *tmrpctypes.ResultBlockResults, -) (*ethtypes.Block, error) { - block := resBlock.Block - - ethHeader := EthHeaderFromTendermint(block.Header) - - ethBlock := ethtypes.NewBlock(ethHeader, nil, nil, nil, trie.NewStackTrie(nil)) - return ethBlock, nil -} - func EthHeaderFromTendermint(header tmtypes.Header) *ethtypes.Header { txHash := ethtypes.EmptyRootHash if len(header.DataHash) == 0 { diff --git a/server/jsonrpc/backend/chain_info.go b/server/jsonrpc/backend/chain_info.go index b75427379e..332d0e60c7 100644 --- a/server/jsonrpc/backend/chain_info.go +++ b/server/jsonrpc/backend/chain_info.go @@ -1,15 +1,15 @@ package backend import ( + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" rpctypes "github.com/evmos/ethermint/rpc/types" - ethermint "github.com/evmos/ethermint/types" ) // ChainID is the chain id for the current chain config. func (b *Backend) ChainID() (*hexutil.Big, error) { - chainID, err := ethermint.ParseChainID(b.clientCtx.ChainID) + chainID, err := sdk.ParseChainID(b.clientCtx.ChainID) if err != nil { panic(err) } diff --git a/server/jsonrpc/backend/unimplemented.go b/server/jsonrpc/backend/unimplemented.go deleted file mode 100644 index ab98294cee..0000000000 --- a/server/jsonrpc/backend/unimplemented.go +++ /dev/null @@ -1,251 +0,0 @@ -package backend - -import ( - "fmt" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/signer/core/apitypes" - rpctypes "github.com/evmos/ethermint/rpc/types" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" - tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" - - "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func (b *Backend) TendermintBlockResultByNumber(height *int64) (*tmrpctypes.ResultBlockResults, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) EthMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults) []*evmtypes.MsgEthereumTx { - panic("should not be called") -} - -func (b *Backend) ChainConfig() *params.ChainConfig { - panic("should not be called") -} - -func (b *Backend) GetCoinbase() (sdk.AccAddress, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) FeeHistory(blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*rpctypes.FeeHistoryResult, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) SuggestGasTipCap(baseFee *big.Int) (*big.Int, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) RPCFilterCap() int32 { - panic("should not be called") -} - -func (b *Backend) RPCLogsCap() int32 { - panic("should not be called") -} - -func (b *Backend) RPCBlockRangeCap() int32 { - panic("should not be called") -} - -func (b *Backend) Accounts() ([]common.Address, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) Syncing() (interface{}, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) SetEtherbase(etherbase common.Address) bool { - panic("should not be called") -} - -func (b *Backend) SetGasPrice(gasPrice hexutil.Big) bool { - panic("should not be called") -} - -func (b *Backend) ImportRawKey(privkey, password string) (common.Address, error) { - return common.Address{}, fmt.Errorf("should not be called") -} - -func (b *Backend) ListAccounts() ([]common.Address, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) NewMnemonic(uid string, language keyring.Language, hdPath, bip39Passphrase string, algo keyring.SignatureAlgo) (*keyring.Record, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) UnprotectedAllowed() bool { - panic("should not be called") -} - -func (b *Backend) RPCGasCap() uint64 { - panic("should not be called") -} - -func (b *Backend) RPCEVMTimeout() time.Duration { - panic("should not be called") -} - -func (b *Backend) RPCTxFeeCap() float64 { - panic("should not be called") -} - -func (b *Backend) RPCMinGasPrice() int64 { - panic("should not be called") -} - -func (b *Backend) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) { - return common.Hash{}, fmt.Errorf("should not be called") -} - -func (b *Backend) SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetCode(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetStorageAt(address common.Address, key string, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetProof(address common.Address, storageKeys []string, blockNrOrHash rpctypes.BlockNumberOrHash) (*rpctypes.AccountResult, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetTransactionCount(address common.Address, blockNum rpctypes.BlockNumber) (*hexutil.Uint64, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpctypes.RPCTransaction, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetTxByEthHash(txHash common.Hash) (*ethermint.TxResult, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetTxByTxIndex(height int64, txIndex uint) (*ethermint.TxResult, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetLogs(hash common.Hash) ([][]*ethtypes.Log, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) BloomStatus() (uint64, uint64) { - panic("should not be called") -} - -func (b *Backend) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) (interface{}, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) TraceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConfig, block *tmrpctypes.ResultBlock) ([]*evmtypes.TxTraceResult, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint { - panic("should not be called") -} - -func (b *Backend) GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint { - panic("should not be called") -} - -func (b *Backend) GetBlockTransactionCount(block *tmrpctypes.ResultBlock) *hexutil.Uint { - panic("should not be called") -} - -func (b *Backend) TendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) BlockNumberFromTendermintByHash(blockHash common.Hash) (*big.Int, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) BlockBloom(blockRes *tmrpctypes.ResultBlockResults) (ethtypes.Bloom, error) { - return ethtypes.Bloom{}, fmt.Errorf("should not be called") -} - -func (b *Backend) PendingTransactions() ([]*sdk.Tx, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) GlobalMinGasPrice() (sdk.Dec, error) { - return sdk.Dec{}, fmt.Errorf("should not be called") -} - -func (b *Backend) BaseFee(blockRes *tmrpctypes.ResultBlockResults) (*big.Int, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rpctypes.BlockNumber) (hexutil.Uint64, error) { - return hexutil.Uint64(0), fmt.Errorf("should not be called") -} - -func (b *Backend) DoCall( - args evmtypes.TransactionArgs, blockNr rpctypes.BlockNumber, -) (*evmtypes.MsgEthereumTxResponse, error) { - return nil, fmt.Errorf("should not be called") -} - -func (b *Backend) Resend(args evmtypes.TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { - return common.Hash{}, fmt.Errorf("should not be called") -} - -func (b *Backend) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { - return common.Hash{}, fmt.Errorf("should not be called") -} - -func (b *Backend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error) { - return evmtypes.TransactionArgs{}, fmt.Errorf("should not be called") -} - -func (b *Backend) GasPrice() (*hexutil.Big, error) { - return (*hexutil.Big)(big.NewInt(0)), fmt.Errorf("should not be called") -} diff --git a/server/jsonrpc/namespaces/ethereum/eth/api.go b/server/jsonrpc/namespaces/ethereum/eth/api.go index 340a7958ce..059e620de8 100644 --- a/server/jsonrpc/namespaces/ethereum/eth/api.go +++ b/server/jsonrpc/namespaces/ethereum/eth/api.go @@ -2,105 +2,20 @@ package eth import ( "context" - "fmt" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/signer/core/apitypes" rpctypes "github.com/evmos/ethermint/rpc/types" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/server/jsonrpc/backend" ) type EthereumAPI interface { - // Getting Blocks - // - // Retrieves information from a particular block in the blockchain. BlockNumber() (hexutil.Uint64, error) GetBlockByNumber(ethBlockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error) - GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) - GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint - GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint - - // Reading Transactions - // - // Retrieves information on the state data for addresses regardless of whether - // it is a user or a smart contract. - GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransaction, error) - GetTransactionCount(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Uint64, error) - GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) - GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) - GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) - // eth_getBlockReceipts - - // Writing Transactions - // - // Allows developers to both send ETH from one address to another, write data - // on-chain, and interact with smart contracts. - SendRawTransaction(data hexutil.Bytes) (common.Hash, error) - SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) - // eth_sendPrivateTransaction - // eth_cancel PrivateTransaction - - // Account Information - // - // Returns information regarding an address's stored on-chain data. - Accounts() ([]common.Address, error) GetBalance(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Big, error) - GetStorageAt(address common.Address, key string, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) - GetCode(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) - GetProof(address common.Address, storageKeys []string, blockNrOrHash rpctypes.BlockNumberOrHash) (*rpctypes.AccountResult, error) - - // EVM/Smart Contract Execution - // - // Allows developers to read data from the blockchain which includes executing - // smart contracts. However, no data is published to the Ethereum network. - Call(args evmtypes.TransactionArgs, blockNrOrHash rpctypes.BlockNumberOrHash, _ *rpctypes.StateOverride) (hexutil.Bytes, error) - - // Chain Information - // - // Returns information on the Ethereum network and internal settings. - ProtocolVersion() hexutil.Uint - GasPrice() (*hexutil.Big, error) - EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rpctypes.BlockNumber) (hexutil.Uint64, error) - FeeHistory(blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*rpctypes.FeeHistoryResult, error) - MaxPriorityFeePerGas() (*hexutil.Big, error) ChainId() (*hexutil.Big, error) - - // Getting Uncles - // - // Returns information on uncle blocks are which are network rejected blocks and replaced by a canonical block instead. - GetUncleByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) map[string]interface{} - GetUncleByBlockNumberAndIndex(number, idx hexutil.Uint) map[string]interface{} - GetUncleCountByBlockHash(hash common.Hash) hexutil.Uint - GetUncleCountByBlockNumber(blockNum rpctypes.BlockNumber) hexutil.Uint - - // Proof of Work - Hashrate() hexutil.Uint64 - Mining() bool - - // Other - Syncing() (interface{}, error) - Coinbase() (string, error) - Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) - GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error) - SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) - FillTransaction(args evmtypes.TransactionArgs) (*rpctypes.SignTransactionResult, error) - Resend(ctx context.Context, args evmtypes.TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) - GetPendingTransactions() ([]*rpctypes.RPCTransaction, error) - // eth_signTransaction (on Ethereum.org) - // eth_getCompilers (on Ethereum.org) - // eth_compileSolidity (on Ethereum.org) - // eth_compileLLL (on Ethereum.org) - // eth_compileSerpent (on Ethereum.org) - // eth_getWork (on Ethereum.org) - // eth_submitWork (on Ethereum.org) - // eth_submitHashrate (on Ethereum.org) } var _ EthereumAPI = (*PublicAPI)(nil) @@ -123,10 +38,6 @@ func NewPublicAPI(logger log.Logger, backend backend.EVMBackend) *PublicAPI { return api } -// ///////////////////////////////////////////////////////////////////////////// -// / Blocks /// -// ///////////////////////////////////////////////////////////////////////////// - // BlockNumber returns the current block number. func (e *PublicAPI) BlockNumber() (hexutil.Uint64, error) { e.logger.Debug("eth_blockNumber") @@ -139,267 +50,14 @@ func (e *PublicAPI) GetBlockByNumber(ethBlockNum rpctypes.BlockNumber, fullTx bo return e.backend.GetBlockByNumber(ethBlockNum, fullTx) } -// GetBlockByHash returns the block identified by hash. -func (e *PublicAPI) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) { - e.logger.Debug("eth_getBlockByHash", "hash", hash.Hex(), "full", fullTx) - return e.backend.GetBlockByHash(hash, fullTx) -} - -// ///////////////////////////////////////////////////////////////////////////// -// / Read Txs /// -// ///////////////////////////////////////////////////////////////////////////// - -// GetTransactionByHash returns the transaction identified by hash. -func (e *PublicAPI) GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransaction, error) { - e.logger.Debug("eth_getTransactionByHash", "hash", hash.Hex()) - return e.backend.GetTransactionByHash(hash) -} - -// GetTransactionCount returns the number of transactions at the given address up to the given block number. -func (e *PublicAPI) GetTransactionCount(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Uint64, error) { - e.logger.Debug("eth_getTransactionCount", "address", address.Hex(), "block number or hash", blockNrOrHash) - blockNum, err := e.backend.BlockNumberFromTendermint(blockNrOrHash) - if err != nil { - return nil, err - } - return e.backend.GetTransactionCount(address, blockNum) -} - -// GetTransactionReceipt returns the transaction receipt identified by hash. -func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) { - hexTx := hash.Hex() - e.logger.Debug("eth_getTransactionReceipt", "hash", hexTx) - return e.backend.GetTransactionReceipt(hash) -} - -// GetBlockTransactionCountByHash returns the number of transactions in the block identified by hash. -func (e *PublicAPI) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint { - e.logger.Debug("eth_getBlockTransactionCountByHash", "hash", hash.Hex()) - return e.backend.GetBlockTransactionCountByHash(hash) -} - -// GetBlockTransactionCountByNumber returns the number of transactions in the block identified by number. -func (e *PublicAPI) GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint { - e.logger.Debug("eth_getBlockTransactionCountByNumber", "height", blockNum.Int64()) - return e.backend.GetBlockTransactionCountByNumber(blockNum) -} - -// GetTransactionByBlockHashAndIndex returns the transaction identified by hash and index. -func (e *PublicAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { - e.logger.Debug("eth_getTransactionByBlockHashAndIndex", "hash", hash.Hex(), "index", idx) - return e.backend.GetTransactionByBlockHashAndIndex(hash, idx) -} - -// GetTransactionByBlockNumberAndIndex returns the transaction identified by number and index. -func (e *PublicAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { - e.logger.Debug("eth_getTransactionByBlockNumberAndIndex", "number", blockNum, "index", idx) - return e.backend.GetTransactionByBlockNumberAndIndex(blockNum, idx) -} - -// ///////////////////////////////////////////////////////////////////////////// -// / Write Txs /// -// ///////////////////////////////////////////////////////////////////////////// - -// SendRawTransaction send a raw Ethereum transaction. -func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { - e.logger.Debug("eth_sendRawTransaction", "length", len(data)) - return e.backend.SendRawTransaction(data) -} - -// SendTransaction sends an Ethereum transaction. -func (e *PublicAPI) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) { - e.logger.Debug("eth_sendTransaction", "args", args.String()) - return e.backend.SendTransaction(args) -} - -// ///////////////////////////////////////////////////////////////////////////// -// / Account Information /// -// ///////////////////////////////////////////////////////////////////////////// - -// Accounts returns the list of accounts available to this node. -func (e *PublicAPI) Accounts() ([]common.Address, error) { - e.logger.Debug("eth_accounts") - return e.backend.Accounts() -} - // GetBalance returns the provided account's balance up to the provided block number. func (e *PublicAPI) GetBalance(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Big, error) { e.logger.Debug("eth_getBalance", "address", address.String(), "block number or hash", blockNrOrHash) return e.backend.GetBalance(address, blockNrOrHash) } -// GetStorageAt returns the contract storage at the given address, block number, and key. -func (e *PublicAPI) GetStorageAt(address common.Address, key string, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) { - e.logger.Debug("eth_getStorageAt", "address", address.Hex(), "key", key, "block number or hash", blockNrOrHash) - return e.backend.GetStorageAt(address, key, blockNrOrHash) -} - -// GetCode returns the contract code at the given address and block number. -func (e *PublicAPI) GetCode(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) { - e.logger.Debug("eth_getCode", "address", address.Hex(), "block number or hash", blockNrOrHash) - return e.backend.GetCode(address, blockNrOrHash) -} - -// GetProof returns an account object with proof and any storage proofs -func (e *PublicAPI) GetProof(address common.Address, - storageKeys []string, - blockNrOrHash rpctypes.BlockNumberOrHash, -) (*rpctypes.AccountResult, error) { - e.logger.Debug("eth_getProof", "address", address.Hex(), "keys", storageKeys, "block number or hash", blockNrOrHash) - return e.backend.GetProof(address, storageKeys, blockNrOrHash) -} - -// Call performs a raw contract call. -func (e *PublicAPI) Call(args evmtypes.TransactionArgs, - blockNrOrHash rpctypes.BlockNumberOrHash, - _ *rpctypes.StateOverride, -) (hexutil.Bytes, error) { - e.logger.Debug("eth_call", "args", args.String(), "block number or hash", blockNrOrHash) - return nil, fmt.Errorf("should not be called") -} - -// ///////////////////////////////////////////////////////////////////////////// -// / Chain Information /// -// ///////////////////////////////////////////////////////////////////////////// - -// ProtocolVersion returns the supported Ethereum protocol version. -func (e *PublicAPI) ProtocolVersion() hexutil.Uint { - e.logger.Debug("eth_protocolVersion") - return hexutil.Uint(ethermint.ProtocolVersion) -} - -// GasPrice returns the current gas price based on Ethermint's gas price oracle. -func (e *PublicAPI) GasPrice() (*hexutil.Big, error) { - e.logger.Debug("eth_gasPrice") - return e.backend.GasPrice() -} - -// EstimateGas returns an estimate of gas usage for the given smart contract call. -func (e *PublicAPI) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rpctypes.BlockNumber) (hexutil.Uint64, error) { - e.logger.Debug("eth_estimateGas") - return e.backend.EstimateGas(args, blockNrOptional) -} - -func (e *PublicAPI) FeeHistory(blockCount rpc.DecimalOrHex, - lastBlock rpc.BlockNumber, - rewardPercentiles []float64, -) (*rpctypes.FeeHistoryResult, error) { - e.logger.Debug("eth_feeHistory") - return e.backend.FeeHistory(blockCount, lastBlock, rewardPercentiles) -} - -// MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions. -func (e *PublicAPI) MaxPriorityFeePerGas() (*hexutil.Big, error) { - e.logger.Debug("eth_maxPriorityFeePerGas") - return nil, fmt.Errorf("should not be called") -} - // ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config. func (e *PublicAPI) ChainId() (*hexutil.Big, error) { e.logger.Debug("eth_chainId") return e.backend.ChainID() } - -// ///////////////////////////////////////////////////////////////////////////// -// / Uncles /// -// ///////////////////////////////////////////////////////////////////////////// - -// GetUncleByBlockHashAndIndex returns the uncle identified by hash and index. Always returns nil. -func (e *PublicAPI) GetUncleByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) map[string]interface{} { - return nil -} - -// GetUncleByBlockNumberAndIndex returns the uncle identified by number and index. Always returns nil. -func (e *PublicAPI) GetUncleByBlockNumberAndIndex(number, idx hexutil.Uint) map[string]interface{} { - return nil -} - -// GetUncleCountByBlockHash returns the number of uncles in the block identified by hash. Always zero. -func (e *PublicAPI) GetUncleCountByBlockHash(hash common.Hash) hexutil.Uint { - return 0 -} - -// GetUncleCountByBlockNumber returns the number of uncles in the block identified by number. Always zero. -func (e *PublicAPI) GetUncleCountByBlockNumber(blockNum rpctypes.BlockNumber) hexutil.Uint { - return 0 -} - -// ///////////////////////////////////////////////////////////////////////////// -// / Proof of Work /// -// ///////////////////////////////////////////////////////////////////////////// - -// Hashrate returns the current node's hashrate. Always 0. -func (e *PublicAPI) Hashrate() hexutil.Uint64 { - e.logger.Debug("eth_hashrate") - return 0 -} - -// Mining returns whether this node is currently mining. Always false. -func (e *PublicAPI) Mining() bool { - e.logger.Debug("eth_mining") - return false -} - -// ///////////////////////////////////////////////////////////////////////////// -// / Other /// -// ///////////////////////////////////////////////////////////////////////////// - -// Syncing returns false in case the node is currently not syncing with the network. It can be up-to-date or has not -// yet received the latest block headers from its pears. In case it is synchronizing: -// - startingBlock: block number this node started to synchronize from -// - currentBlock: block number this node is currently importing -// - highestBlock: block number of the highest block header this node has received from peers -// - pulledStates: number of state entries processed until now -// - knownStates: number of known state entries that still need to be pulled -func (e *PublicAPI) Syncing() (interface{}, error) { - e.logger.Debug("eth_syncing") - return e.backend.Syncing() -} - -// Coinbase is the address that staking rewards will be sent to (alias for Etherbase). -func (e *PublicAPI) Coinbase() (string, error) { - e.logger.Debug("eth_coinbase") - return "", fmt.Errorf("should not be called") -} - -// Sign signs the provided data using the private key of address via Geth's signature standard. -func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { - e.logger.Debug("eth_sign", "address", address.Hex(), "data", common.Bytes2Hex(data)) - return e.backend.Sign(address, data) -} - -// GetTransactionLogs returns the logs given a transaction hash. -func (e *PublicAPI) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error) { - e.logger.Debug("eth_getTransactionLogs", "hash", txHash) - return nil, fmt.Errorf("should not be called") -} - -// SignTypedData signs EIP-712 conformal typed data -func (e *PublicAPI) SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) { - e.logger.Debug("eth_signTypedData", "address", address.Hex(), "data", typedData) - return e.backend.SignTypedData(address, typedData) -} - -// FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields) -// on a given unsigned transaction, and returns it to the caller for further -// processing (signing + broadcast). -func (e *PublicAPI) FillTransaction(args evmtypes.TransactionArgs) (*rpctypes.SignTransactionResult, error) { - return nil, fmt.Errorf("should not be called") -} - -// Resend accepts an existing transaction and a new gas price and limit. It will remove -// the given transaction from the pool and reinsert it with the new gas price and limit. -func (e *PublicAPI) Resend(_ context.Context, - args evmtypes.TransactionArgs, - gasPrice *hexutil.Big, - gasLimit *hexutil.Uint64, -) (common.Hash, error) { - e.logger.Debug("eth_resend", "args", args.String()) - return e.backend.Resend(args, gasPrice, gasLimit) -} - -// GetPendingTransactions returns the transactions that are in the transaction pool -// and have a from address that is one of the accounts this node manages. -func (e *PublicAPI) GetPendingTransactions() ([]*rpctypes.RPCTransaction, error) { - return nil, fmt.Errorf("should not be called") -} diff --git a/server/jsonrpc/namespaces/ethereum/net/api.go b/server/jsonrpc/namespaces/ethereum/net/api.go index 8a5e087d0e..42e25e9f95 100644 --- a/server/jsonrpc/namespaces/ethereum/net/api.go +++ b/server/jsonrpc/namespaces/ethereum/net/api.go @@ -4,10 +4,10 @@ import ( "context" "fmt" - ethermint "github.com/evmos/ethermint/types" rpcclient "github.com/tendermint/tendermint/rpc/client" "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" ) // PublicAPI is the eth_ prefixed set of APIs in the Web3 JSON-RPC spec. @@ -19,7 +19,7 @@ type PublicAPI struct { // NewPublicAPI creates an instance of the public Net Web3 API. func NewPublicAPI(clientCtx client.Context) *PublicAPI { // parse the chainID from an integer string - chainIDEpoch, err := ethermint.ParseChainID(clientCtx.ChainID) + chainIDEpoch, err := sdk.ParseChainID(clientCtx.ChainID) if err != nil { panic(err) } diff --git a/types/chain_id.go b/types/chain_id.go new file mode 100644 index 0000000000..5727028e8a --- /dev/null +++ b/types/chain_id.go @@ -0,0 +1,60 @@ +package types + +import ( + "fmt" + "math/big" + "regexp" + "strings" + + "cosmossdk.io/errors" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +var ( + regexChainID = `[a-z]{1,}` + regexEIP155Separator = `_{1}` + regexEIP155 = `[1-9][0-9]*` + regexEpochSeparator = `-{1}` + regexEpoch = `[1-9][0-9]*` + greenfieldChainID = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)%s(%s)$`, + regexChainID, + regexEIP155Separator, + regexEIP155, + regexEpochSeparator, + regexEpoch)) +) + +// ErrInvalidChainID returns an error resulting from an invalid chain ID. +var ErrInvalidChainID = errors.Register(sdkerrors.RootCodespace, 42, "invalid chain ID") + +// IsValidChainID returns false if the given chain identifier is incorrectly formatted. +func IsValidChainID(chainID string) bool { + if len(chainID) > 48 { + return false + } + + return greenfieldChainID.MatchString(chainID) +} + +// ParseChainID parses a string chain identifier's epoch to an Ethereum-compatible +// chain-id in *big.Int format. The function returns an error if the chain-id has an invalid format +func ParseChainID(chainID string) (*big.Int, error) { + chainID = strings.TrimSpace(chainID) + if len(chainID) > 48 { + return nil, errors.Wrapf(ErrInvalidChainID, "chain-id '%s' cannot exceed 48 chars", chainID) + } + + matches := greenfieldChainID.FindStringSubmatch(chainID) + if matches == nil || len(matches) != 4 || matches[1] == "" { + return nil, errors.Wrapf(ErrInvalidChainID, "%s: %v", chainID, matches) + } + + // verify that the chain-id entered is a base 10 integer + chainIDInt, ok := new(big.Int).SetString(matches[2], 10) + if !ok { + return nil, errors.Wrapf(ErrInvalidChainID, "epoch %s must be base-10 integer format", matches[2]) + } + + return chainIDInt, nil +} diff --git a/types/errors/errors.go b/types/errors/errors.go index 87e8b85b59..1bab59ee6e 100644 --- a/types/errors/errors.go +++ b/types/errors/errors.go @@ -6,7 +6,7 @@ import ( // Type Aliases to errors module // -// Deprecated: functionality of this package has been moved to it's own module: +// Deprecated: functionality of this package has been moved to its own module: // // cosmossdk.io/errors // diff --git a/types/math.go b/types/math.go index be46b05916..2204d83950 100644 --- a/types/math.go +++ b/types/math.go @@ -4,9 +4,9 @@ import ( sdkmath "cosmossdk.io/math" ) -// Type aliases to the SDK's math sub-module +// Type aliases to the SDK's math submodule // -// Deprecated: Functionality of this package has been moved to it's own module: +// Deprecated: Functionality of this package has been moved to its own module: // cosmossdk.io/math // // Please use the above module instead of this package. diff --git a/x/auth/ante/basic.go b/x/auth/ante/basic.go index fa0e8c66bc..c005ec1e0e 100644 --- a/x/auth/ante/basic.go +++ b/x/auth/ante/basic.go @@ -120,7 +120,7 @@ func (cgts ConsumeTxSizeGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim pubkey = acc.GetPubKey() } - // use stdsignature to mock the size of a full signature + // use StdSignature to mock the size of a full signature simSig := legacytx.StdSignature{ //nolint:staticcheck // this will be removed when proto is ready Signature: simSecp256k1Sig[:], PubKey: pubkey, diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index 0a0509d722..7ef0b20a1a 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "fmt" + "cosmossdk.io/errors" "github.com/evmos/ethermint/crypto/ethsecp256k1" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" @@ -59,7 +60,7 @@ func NewSetPubKeyDecorator(ak AccountKeeper) SetPubKeyDecorator { func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { sigTx, ok := tx.(authsigning.SigVerifiableTx) if !ok { - return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid tx type") + return ctx, errors.Wrap(sdkerrors.ErrTxDecode, "invalid tx type") } pubkeys, err := sigTx.GetPubKeys() @@ -78,7 +79,7 @@ func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b } // Only make check if simulate=false if !simulate && !bytes.Equal(pk.Address(), signers[i]) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, + return ctx, errors.Wrapf(sdkerrors.ErrInvalidPubKey, "pubKey does not match signer address %s with signer index: %d", signers[i], i) } @@ -92,7 +93,7 @@ func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b } err = acc.SetPubKey(pk) if err != nil { - return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidPubKey, err.Error()) + return ctx, errors.Wrap(sdkerrors.ErrInvalidPubKey, err.Error()) } spkd.ak.SetAccount(ctx, acc) } @@ -213,31 +214,10 @@ func NewSigVerificationDecorator(ak AccountKeeper, signModeHandler authsigning.S } } -// OnlyLegacyAminoSigners checks SignatureData to see if all -// signers are using SIGN_MODE_LEGACY_AMINO_JSON. If this is the case -// then the corresponding SignatureV2 struct will not have account sequence -// explicitly set, and we should skip the explicit verification of sig.Sequence -// in the SigVerificationDecorator's AnteHandler function. -func OnlyLegacyAminoSigners(sigData signing.SignatureData) bool { - switch v := sigData.(type) { - case *signing.SingleSignatureData: - return v.SignMode == signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON - case *signing.MultiSignatureData: - for _, s := range v.Signatures { - if !OnlyLegacyAminoSigners(s) { - return false - } - } - return true - default: - return false - } -} - func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { sigTx, ok := tx.(authsigning.SigVerifiableTx) if !ok { - return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") + return ctx, errors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") } // stdSigs contains the sequence number, account number, and signatures. @@ -251,7 +231,7 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul // check that signer length and signature length are the same if len(sigs) != len(signerAddrs) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signerAddrs), len(sigs)) + return ctx, errors.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signerAddrs), len(sigs)) } for i, sig := range sigs { @@ -293,16 +273,8 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul if !simulate && !ctx.IsReCheckTx() { err := authsigning.VerifySignature(pubKey, signerData, sig.Data, svd.signModeHandler, tx) if err != nil { - // var errMsg string - // if OnlyLegacyAminoSigners(sig.Data) { - // // If all signers are using SIGN_MODE_LEGACY_AMINO, we rely on VerifySignature to check account sequence number, - // // and therefore communicate sequence number as a potential cause of error. - // errMsg = fmt.Sprintf("signature verification failed; please verify account number (%d), sequence (%d) and chain-id (%s)", accNum, acc.GetSequence(), chainID) - // } else { - // errMsg = fmt.Sprintf("signature verification failed; please verify account number (%d) and chain-id (%s)", accNum, chainID) - // } errMsg := fmt.Sprintf("signature verification failed; please verify account (%s) and chain-id (%s)", pubKey.Address(), chainID) - return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, errMsg) + return ctx, errors.Wrap(sdkerrors.ErrUnauthorized, errMsg) } } diff --git a/x/auth/signing/verify.go b/x/auth/signing/verify.go index c67e8835e0..201a43c5de 100644 --- a/x/auth/signing/verify.go +++ b/x/auth/signing/verify.go @@ -20,49 +20,38 @@ func VerifySignature(pubKey cryptotypes.PubKey, signerData SignerData, sigData s switch data := sigData.(type) { case *signing.SingleSignatureData: if data.SignMode == signing.SignMode_SIGN_MODE_EIP_712 { + sig := data.Signature sigHash, err := handler.GetSignBytes(data.SignMode, signerData, tx) if err != nil { return err } - senderSig := data.Signature - if len(senderSig) != ethcrypto.SignatureLength { + // check signature length + if len(sig) != ethcrypto.SignatureLength { return errors.Wrap(sdkerrors.ErrorInvalidSigner, "signature length doesn't match typical [R||S||V] signature 65 bytes") } - // Remove the recovery offset if needed (ie. Metamask eip712 signature) - if senderSig[ethcrypto.RecoveryIDOffset] == 27 || senderSig[ethcrypto.RecoveryIDOffset] == 28 { - senderSig[ethcrypto.RecoveryIDOffset] -= 27 + // remove the recovery offset if needed (ie. Metamask eip712 signature) + if sig[ethcrypto.RecoveryIDOffset] == 27 || sig[ethcrypto.RecoveryIDOffset] == 28 { + sig[ethcrypto.RecoveryIDOffset] -= 27 } - feePayerPubkey, err := secp256k1.RecoverPubkey(sigHash, senderSig) + // recover the pubkey from the signature + feePayerPubkey, err := secp256k1.RecoverPubkey(sigHash, sig) if err != nil { - return errors.Wrap(err, "failed to recover delegated fee payer from sig") + return errors.Wrap(err, "failed to recover fee payer from sig") } - ecPubKey, err := ethcrypto.UnmarshalPubkey(feePayerPubkey) if err != nil { return errors.Wrap(err, "failed to unmarshal recovered fee payer pubkey") } + // check that the recovered pubkey matches the one in the signerData data pk := ðsecp256k1.PubKey{ Key: ethcrypto.CompressPubkey(ecPubKey), } - if !pubKey.Equals(pk) { - return errors.Wrapf(sdkerrors.ErrInvalidPubKey, "feePayer pubkey %s is different from transaction pubkey %s", pubKey, pk) - } - - recoveredFeePayerAcc := sdk.AccAddress(pk.Address().Bytes()) - - if !recoveredFeePayerAcc.Equals(sdk.MustAccAddressFromHex(signerData.Address)) { - return errors.Wrapf(sdkerrors.ErrorInvalidSigner, "failed to verify delegated fee payer %s signature", recoveredFeePayerAcc) - } - - // VerifySignature of ethsecp256k1 accepts 64 byte signature [R||S] - // WARNING! Under NO CIRCUMSTANCES try to use pubKey.VerifySignature there - if !secp256k1.VerifySignature(pubKey.Bytes(), sigHash, senderSig[:len(senderSig)-1]) { - return errors.Wrap(sdkerrors.ErrorInvalidSigner, "unable to verify signer signature of EIP712 typed data") + return errors.Wrapf(sdkerrors.ErrorInvalidSigner, "feePayer's pubkey %s is different from signature's pubkey %s", pubKey, pk) } return nil } else { diff --git a/x/auth/tx/eip712.go b/x/auth/tx/eip712.go index fe2df84be9..099f04d9f3 100644 --- a/x/auth/tx/eip712.go +++ b/x/auth/tx/eip712.go @@ -15,7 +15,6 @@ import ( "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/signer/core/apitypes" - ethermint "github.com/evmos/ethermint/types" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -59,26 +58,25 @@ func (signModeEip712Handler) GetSignBytes(mode signingtypes.SignMode, signerData return nil, fmt.Errorf("expected %s, got %s", signingtypes.SignMode_SIGN_MODE_EIP_712, mode) } - _, ok := tx.(*wrapper) - if !ok { - return nil, fmt.Errorf("can only handle a protobuf Tx, got %T", tx) - } - - typedChainID, err := ethermint.ParseChainID(signerData.ChainID) + // get the EIP155 chainID from the signerData + chainID, err := sdk.ParseChainID(signerData.ChainID) if err != nil { return nil, fmt.Errorf("failed to parse chainID: %s", signerData.ChainID) } - msgTypes, signDoc, err := GetMsgTypes(signerData, tx, typedChainID) + // get the EIP712 types and signDoc from the tx + msgTypes, signDoc, err := GetMsgTypes(signerData, tx, chainID) if err != nil { return nil, errors.Wrapf(err, "failed to get msg types") } - typedData, err := WrapTxToTypedData(typedChainID.Uint64(), signDoc, msgTypes) + // pack the tx data in EIP712 object + typedData, err := WrapTxToTypedData(chainID.Uint64(), signDoc, msgTypes) if err != nil { return nil, errors.Wrapf(err, "failed to pack tx data in EIP712 object") } + // compute the hash sigHash, err := ComputeTypedDataHash(typedData) if err != nil { return nil, err @@ -93,6 +91,7 @@ func GetMsgTypes(signerData signing.SignerData, tx sdk.Tx, typedChainID *big.Int return nil, nil, fmt.Errorf("can only handle a protobuf Tx, got %T", tx) } + // construct the signDoc msgAny, _ := codectypes.NewAnyWithValue(protoTx.GetMsgs()[0]) signDoc := &types.SignDocEip712{ AccountNumber: signerData.AccountNumber, @@ -110,13 +109,14 @@ func GetMsgTypes(signerData signing.SignerData, tx sdk.Tx, typedChainID *big.Int Msg: msgAny, } + // extract the msg types msgTypes, err := extractMsgTypes(protoTx.GetMsgs()[0]) if err != nil { return nil, nil, err } + // patch the msg types to include `Tip` if it's not empty if signDoc.Tip != nil { - // patching msgTypes to include Tip msgTypes["Tx"] = []apitypes.Type{ {Name: "account_number", Type: "uint256"}, {Name: "chain_id", Type: "uint256"}, @@ -177,15 +177,15 @@ func WrapTxToTypedData( delete(txData, "tip") } - // filling nil value + // filling nil value and do other clean up cleanTypesAndMsgValue(msgTypes, "Msg", txData["msg"].(map[string]interface{})) - domainTemp := *domain - domainTemp.ChainId = math.NewHexOrDecimal256(int64(chainID)) + tempDomain := *domain + tempDomain.ChainId = math.NewHexOrDecimal256(int64(chainID)) typedData := apitypes.TypedData{ Types: msgTypes, PrimaryType: "Tx", - Domain: domainTemp, + Domain: tempDomain, Message: txData, } diff --git a/x/auth/tx/eip712_test.go b/x/auth/tx/eip712_test.go index 3f83711b20..0797e12f52 100644 --- a/x/auth/tx/eip712_test.go +++ b/x/auth/tx/eip712_test.go @@ -32,7 +32,7 @@ func TestEIP712Handler(t *testing.T) { txConfig := NewTxConfig(marshaler, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_EIP_712}) txBuilder := txConfig.NewTxBuilder() - chainID := "ethermint_9000" + chainID := "greenfield_9000" testMemo := "some test memo" msg := banktypes.NewMsgSend(addr, addr, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(1)))) accNum, accSeq := uint64(1), uint64(2) // Arbitrary account number/sequence @@ -123,12 +123,15 @@ func TestEIP712ModeHandler_nonDIRECT_MODE(t *testing.T) { func TestEIP712ModeHandler_nonProtoTx(t *testing.T) { var dh signModeEip712Handler - var signingData signing.SignerData + signingData := signing.SignerData{ + ChainID: "greenfield_9000-1", // set chainID to prevent error + } tx := new(nonProtoTx) + _, err := dh.GetSignBytes(signingtypes.SignMode_SIGN_MODE_EIP_712, signingData, tx) require.Error(t, err) - wantErr := fmt.Errorf("can only handle a protobuf Tx, got %T", tx) - require.Equal(t, err, wantErr) + wantErr := fmt.Sprintf("can only handle a protobuf Tx, got %T", tx) + require.Contains(t, err.Error(), wantErr) } func TestMoreMsgs(t *testing.T) { diff --git a/x/gashub/types/codec.go b/x/gashub/types/codec.go index aa8d17c550..c75ca7195d 100644 --- a/x/gashub/types/codec.go +++ b/x/gashub/types/codec.go @@ -27,16 +27,16 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { } var ( - Amino = codec.NewLegacyAmino() - ModuleCdc = codec.NewAminoCodec(Amino) + amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewAminoCodec(amino) ) func init() { - RegisterLegacyAminoCodec(Amino) - cryptocodec.RegisterCrypto(Amino) - sdk.RegisterLegacyAminoCodec(Amino) + RegisterLegacyAminoCodec(amino) + cryptocodec.RegisterCrypto(amino) + sdk.RegisterLegacyAminoCodec(amino) - // Register all Amino interfaces and concrete types on the authz Amino codec so that this can later be + // Register all amino interfaces and concrete types on the authz amino codec so that this can later be // used to properly serialize MsgGrant and MsgExec instances RegisterLegacyAminoCodec(authzcodec.Amino) } diff --git a/x/gashub/types/event.pb.go b/x/gashub/types/event.pb.go index da4d652361..e016f20c34 100644 --- a/x/gashub/types/event.pb.go +++ b/x/gashub/types/event.pb.go @@ -22,11 +22,14 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// EventUpdateMsgGasParams is emitted when update a msg's gas params +// EventUpdateMsgGasParams is emitted when updating a message's gas params type EventUpdateMsgGasParams struct { + // msg_type_url is the type url of the message MsgTypeUrl string `protobuf:"bytes,1,opt,name=msg_type_url,json=msgTypeUrl,proto3" json:"msg_type_url,omitempty"` - FromValue string `protobuf:"bytes,2,opt,name=from_value,json=fromValue,proto3" json:"from_value,omitempty"` - ToValue string `protobuf:"bytes,3,opt,name=to_value,json=toValue,proto3" json:"to_value,omitempty"` + // from_value is the previous gas params + FromValue string `protobuf:"bytes,2,opt,name=from_value,json=fromValue,proto3" json:"from_value,omitempty"` + // to_value is the new gas params + ToValue string `protobuf:"bytes,3,opt,name=to_value,json=toValue,proto3" json:"to_value,omitempty"` } func (m *EventUpdateMsgGasParams) Reset() { *m = EventUpdateMsgGasParams{} } diff --git a/x/gashub/types/gashub.pb.go b/x/gashub/types/gashub.pb.go index e44e8b6e98..62e050788b 100644 --- a/x/gashub/types/gashub.pb.go +++ b/x/gashub/types/gashub.pb.go @@ -25,8 +25,11 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params defines the parameters for the gashub module. type Params struct { - MaxTxSize uint64 `protobuf:"varint,1,opt,name=max_tx_size,json=maxTxSize,proto3" json:"max_tx_size,omitempty"` - MinGasPerByte uint64 `protobuf:"varint,2,opt,name=min_gas_per_byte,json=minGasPerByte,proto3" json:"min_gas_per_byte,omitempty"` + // max_tx_size is the maximum size of a transaction's bytes. + MaxTxSize uint64 `protobuf:"varint,1,opt,name=max_tx_size,json=maxTxSize,proto3" json:"max_tx_size,omitempty"` + // min_gas_per_byte is the minimum gas to be paid per byte of a transaction's + MinGasPerByte uint64 `protobuf:"varint,2,opt,name=min_gas_per_byte,json=minGasPerByte,proto3" json:"min_gas_per_byte,omitempty"` + // msg_gas_params is the list of gas params for each msg type MsgGasParamsSet []*MsgGasParams `protobuf:"bytes,3,rep,name=msg_gas_params_set,json=msgGasParamsSet,proto3" json:"msg_gas_params_set,omitempty"` } @@ -208,6 +211,7 @@ func (*MsgGasParams) XXX_OneofWrappers() []interface{} { // FixedGasParams defines the parameters for fixed gas type. type MsgGasParams_FixedGasParams struct { + // fixed_gas is the gas cost for a fixed type msg FixedGas uint64 `protobuf:"varint,1,opt,name=fixed_gas,json=fixedGas,proto3" json:"fixed_gas,omitempty"` } @@ -253,7 +257,9 @@ func (m *MsgGasParams_FixedGasParams) GetFixedGas() uint64 { // DynamicGasParams defines the parameters for dynamic gas type. type MsgGasParams_DynamicGasParams struct { - FixedGas uint64 `protobuf:"varint,1,opt,name=fixed_gas,json=fixedGas,proto3" json:"fixed_gas,omitempty"` + // fixed_gas is the base gas cost for a dynamic type msg + FixedGas uint64 `protobuf:"varint,1,opt,name=fixed_gas,json=fixedGas,proto3" json:"fixed_gas,omitempty"` + // gas_per_item is the gas cost for a dynamic type msg per item GasPerItem uint64 `protobuf:"varint,2,opt,name=gas_per_item,json=gasPerItem,proto3" json:"gas_per_item,omitempty"` } diff --git a/x/gashub/types/genesis.pb.go b/x/gashub/types/genesis.pb.go index f115f6d449..edb7a9e9c5 100644 --- a/x/gashub/types/genesis.pb.go +++ b/x/gashub/types/genesis.pb.go @@ -25,7 +25,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the gashub module's genesis state. type GenesisState struct { - // params defines all the paramaters of the module. + // params defines all the parameters of the module. Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` } diff --git a/x/gashub/types/key.go b/x/gashub/types/keys.go similarity index 100% rename from x/gashub/types/key.go rename to x/gashub/types/keys.go diff --git a/x/gashub/types/params.go b/x/gashub/types/params.go index 7b652e6437..a56884b61d 100644 --- a/x/gashub/types/params.go +++ b/x/gashub/types/params.go @@ -158,6 +158,7 @@ func (p Params) String() string { return string(out) } +// validateMaxTxSize performs basic validation of MaxTxSize. func validateMaxTxSize(i interface{}) error { v, ok := i.(uint64) if !ok { @@ -171,6 +172,7 @@ func validateMaxTxSize(i interface{}) error { return nil } +// validateMinGasPerByte performs basic validation of MinGasPerByte. func validateMinGasPerByte(i interface{}) error { v, ok := i.(uint64) if !ok { @@ -184,6 +186,7 @@ func validateMinGasPerByte(i interface{}) error { return nil } +// ValidateMsgGasParams performs basic validation of MsgGasParams. func ValidateMsgGasParams(i interface{}) error { v, ok := i.([]*MsgGasParams) if !ok { diff --git a/x/gashub/types/tx.pb.go b/x/gashub/types/tx.pb.go index 1cdcb356e8..56457ba0e7 100644 --- a/x/gashub/types/tx.pb.go +++ b/x/gashub/types/tx.pb.go @@ -32,7 +32,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // MsgUpdateMsgGasParams represents a message to update msg gas params. type MsgUpdateMsgGasParams struct { - From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` + // from is the message signer for MsgUpdateMsgGasParams + From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` + // new_params_set is the new set of msg gas params to be updated. NewParamsSet []*MsgGasParams `protobuf:"bytes,2,rep,name=new_params_set,json=newParamsSet,proto3" json:"new_params_set,omitempty"` } @@ -114,29 +116,28 @@ func init() { func init() { proto.RegisterFile("cosmos/gashub/v1alpha1/tx.proto", fileDescriptor_08053c9491c72816) } var fileDescriptor_08053c9491c72816 = []byte{ - // 338 bytes of a gzipped FileDescriptorProto + // 333 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0x4f, 0x4f, 0x2c, 0xce, 0x28, 0x4d, 0xd2, 0x2f, 0x33, 0x4c, 0xcc, 0x29, 0xc8, 0x48, 0x34, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x83, 0x28, 0xd0, 0x83, 0x28, 0xd0, 0x83, 0x29, 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd1, 0x07, 0xb1, 0x20, 0xaa, 0xa5, 0x94, 0x71, 0x18, 0x07, 0xd5, 0x0d, 0x51, 0x24, 0x09, 0x51, 0x14, 0x0f, 0xd1, 0x0d, 0x35, 0x1f, 0x22, 0x25, 0x0e, 0xd5, 0x9f, 0x5b, 0x9c, 0xae, 0x5f, 0x66, 0x08, 0xa2, 0x20, - 0x12, 0x4a, 0xcb, 0x18, 0xb9, 0x44, 0x7d, 0x8b, 0xd3, 0x43, 0x0b, 0x52, 0x12, 0x4b, 0x52, 0x7d, + 0x12, 0x4a, 0x4b, 0x18, 0xb9, 0x44, 0x7d, 0x8b, 0xd3, 0x43, 0x0b, 0x52, 0x12, 0x4b, 0x52, 0x7d, 0x8b, 0xd3, 0xdd, 0x13, 0x8b, 0x03, 0x12, 0x8b, 0x12, 0x73, 0x8b, 0x85, 0x74, 0xb8, 0x58, 0xd2, 0x8a, 0xf2, 0x73, 0x25, 0x18, 0x15, 0x18, 0x35, 0x38, 0x9d, 0x24, 0x2e, 0x6d, 0xd1, 0x15, 0x81, 0x1a, 0xe9, 0x98, 0x92, 0x52, 0x94, 0x5a, 0x5c, 0x1c, 0x5c, 0x52, 0x94, 0x99, 0x97, 0x1e, 0x04, 0x56, 0x25, 0xe4, 0xc5, 0xc5, 0x97, 0x97, 0x5a, 0x1e, 0x5f, 0x00, 0xd6, 0x1b, 0x5f, 0x9c, 0x5a, 0x22, 0xc1, 0xa4, 0xc0, 0xac, 0xc1, 0x6d, 0xa4, 0xa2, 0x87, 0xdd, 0x9f, 0x7a, 0xc8, 0x76, 0x05, - 0xf1, 0xe4, 0xa5, 0x96, 0x43, 0x98, 0xc1, 0xa9, 0x25, 0x56, 0xc2, 0x1d, 0x0b, 0xe4, 0x19, 0x5e, - 0x2c, 0x90, 0x67, 0x68, 0x7a, 0xbe, 0x41, 0x8b, 0xad, 0x38, 0x35, 0x2f, 0x25, 0xb5, 0x48, 0x49, - 0x9e, 0x4b, 0x16, 0xab, 0x3b, 0x83, 0x52, 0x8b, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x8d, 0x1a, 0x19, - 0xb9, 0x98, 0x7d, 0x8b, 0xd3, 0x85, 0xaa, 0xb8, 0x84, 0xb0, 0xf8, 0x46, 0x17, 0x8f, 0x3b, 0x30, - 0x95, 0x4b, 0x99, 0x92, 0xa4, 0x1c, 0xe6, 0x06, 0x27, 0xd7, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, - 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, - 0x3c, 0x96, 0x63, 0x88, 0xd2, 0x4e, 0xcf, 0x2c, 0x01, 0x19, 0x94, 0x9c, 0x9f, 0x0b, 0x8d, 0x19, - 0x28, 0xa5, 0x5b, 0x9c, 0x92, 0xad, 0x5f, 0x01, 0x8b, 0xd8, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, - 0x36, 0x70, 0xdc, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x35, 0x45, 0x6b, 0x45, 0x02, - 0x00, 0x00, + 0xf1, 0xe4, 0xa5, 0x96, 0x43, 0x98, 0xc1, 0xa9, 0x25, 0x56, 0x82, 0x1d, 0x0b, 0xe4, 0x19, 0x5e, + 0x2c, 0x90, 0x67, 0x68, 0x7a, 0xbe, 0x41, 0x0b, 0x6c, 0xbc, 0x92, 0x3c, 0x97, 0x2c, 0x56, 0x57, + 0x06, 0xa5, 0x16, 0x17, 0xe4, 0xe7, 0x15, 0xa7, 0x1a, 0x35, 0x32, 0x72, 0x31, 0xfb, 0x16, 0xa7, + 0x0b, 0x55, 0x71, 0x09, 0x61, 0xf1, 0x8b, 0x2e, 0x1e, 0x57, 0x60, 0x2a, 0x97, 0x32, 0x25, 0x49, + 0x39, 0xcc, 0x0d, 0x4e, 0xae, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, + 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, + 0x9d, 0x9e, 0x59, 0x02, 0x32, 0x28, 0x39, 0x3f, 0x17, 0x1a, 0x2f, 0x50, 0x4a, 0xb7, 0x38, 0x25, + 0x5b, 0xbf, 0x02, 0x16, 0xad, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, 0x98, 0x31, 0x06, + 0x04, 0x00, 0x00, 0xff, 0xff, 0x14, 0x19, 0xfe, 0x91, 0x43, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. From 5ead103f48bca9c8a738e17176a1c370aebbb127 Mon Sep 17 00:00:00 2001 From: Fynn Date: Tue, 21 Mar 2023 10:01:37 +0800 Subject: [PATCH 05/10] refine the storage tx fee (#141) --- x/gashub/types/params.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x/gashub/types/params.go b/x/gashub/types/params.go index a56884b61d..c7ca0fc635 100644 --- a/x/gashub/types/params.go +++ b/x/gashub/types/params.go @@ -93,23 +93,23 @@ func DefaultParams() Params { NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.sp.MsgDeposit", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.sp.MsgEditStorageProvider", 2e7), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.sp.MsgUpdateSpStoragePrice", 2e7), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateBucket", 2e7), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateBucket", 24e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeleteBucket", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgMirrorBucket", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgUpdateBucketInfo", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateObject", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgSealObject", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgMirrorObject", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgRejectSealObject", 2e6), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgRejectSealObject", 12e4), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeleteObject", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCopyObject", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCancelCreateObject", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateGroup", 2e6), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateGroup", 24e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeleteGroup", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgLeaveGroup", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgUpdateGroupMember", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgMirrorGroup", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgPutPolicy", 2e6), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgPutPolicy", 24e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeletePolicy", 12e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.payment.MsgCreatePaymentAccount", 2e6), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.payment.MsgDeposit", 12e3), From 298e28e977c9a2f20fdc5457b95c6cf42302c2d2 Mon Sep 17 00:00:00 2001 From: zjubfd <296179868@qq.com> Date: Tue, 21 Mar 2023 11:44:11 +0800 Subject: [PATCH 06/10] docs: add licence and disclaim (#143) --- .github/workflows/gosec.yml | 52 +++++++++ COPYING.LESSER | 165 +++++++++++++++++++++++++++++ LICENSE | 204 ------------------------------------ README.md | 11 +- 4 files changed, 227 insertions(+), 205 deletions(-) create mode 100644 .github/workflows/gosec.yml create mode 100644 COPYING.LESSER delete mode 100644 LICENSE diff --git a/.github/workflows/gosec.yml b/.github/workflows/gosec.yml new file mode 100644 index 0000000000..677fca9374 --- /dev/null +++ b/.github/workflows/gosec.yml @@ -0,0 +1,52 @@ +name: gosec + +on: + push: + branches: + - master + - develop + pull_request: + branches: + - master + - develop +jobs: + gosec: + name: gosec + strategy: + matrix: + go-version: [1.18.x] + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} + env: + GOPRIVATE: github.com/bnb-chain + GH_ACCESS_TOKEN: ${{ secrets.GH_TOKEN }} + steps: + - uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go-version }} + - uses: actions/checkout@v3 + - name: Setup GitHub Token + run: git config --global url.https://$GH_ACCESS_TOKEN@github.com/.insteadOf https://github.com/ + - uses: actions/cache@v3 + with: + # In order: + # * Module download cache + # * Build cache (Linux) + # * Build cache (Mac) + # * Build cache (Windows) + path: | + ~/go/pkg/mod + ~/.cache/go-build + ~/Library/Caches/go-build + %LocalAppData%\go-build + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - run: | + go mod tidy + go mod download + + - name: Run Gosec Security Scanner + uses: securego/gosec@master + with: + args: -quiet -confidence high -severity high ./... \ No newline at end of file diff --git a/COPYING.LESSER b/COPYING.LESSER new file mode 100644 index 0000000000..02bbb60bc4 --- /dev/null +++ b/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 1931c12a2b..0000000000 --- a/LICENSE +++ /dev/null @@ -1,204 +0,0 @@ -Cosmos SDK -License: Apache2.0 - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016 All in Bits, Inc - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md index c64d7fbf71..afb9888703 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,11 @@ The Greenfield Block Chain leverages cosmos-sdk to fast build a dApp running wit requirements of Greenfield blockchain that cannot be fully satisfied by cosmos-sdk at present, we have decided to fork the cosmos-sdk repo and add modules and features based on it. +## Disclaimer +**The software and related documentation are under active development, all subject to potential future change without +notification and not ready for production use. The code and security audit have not been fully completed and not ready +for any bug bounty. We advise you to be careful and experiment on the network at your own risk. Stay safe out there.** + ## Key Features 1. **auth**. The address format of the Greenfield blockchain is fully compatible with BSC (and Ethereum). It accepts EIP712 transaction signing and verification. These enable the existing wallet infrastructure to interact with Greenfield at the beginning naturally. @@ -53,4 +58,8 @@ more complex changes, we recommend checking with the core developers first via G to ensure that your changes align with the project's general philosophy. This can also help reduce the workload of both parties and streamline the review and merge process. -## Licence (pending) \ No newline at end of file +## Licence + +The greenfield-cosmos-sdk is licensed under the +[GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.en.html), +also included in our repository in the `COPYING.LESSER` file. \ No newline at end of file From a6cfc5d33307b1b2ba3aa08e77fb8d071ce30dfb Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 22 Mar 2023 20:06:29 +0800 Subject: [PATCH 07/10] chore: refine oracle module (#145) --- proto/cosmos/oracle/v1/oracle.proto | 8 +- x/oracle/client/cli/query.go | 32 +++++++ x/oracle/keeper/keeper.go | 50 ++++++----- x/oracle/keeper/msg_server.go | 128 +++++++++++++--------------- 4 files changed, 127 insertions(+), 91 deletions(-) diff --git a/proto/cosmos/oracle/v1/oracle.proto b/proto/cosmos/oracle/v1/oracle.proto index 673272fd80..87f7dedc43 100644 --- a/proto/cosmos/oracle/v1/oracle.proto +++ b/proto/cosmos/oracle/v1/oracle.proto @@ -5,10 +5,10 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/oracle/types"; // Params holds parameters for the oracle module. message Params { - // Timeout for the in turn relayer - uint64 relayer_timeout = 1; // in s - // RelayInterval is for in-turn relayer - uint64 relayer_interval = 2; // in s + // Timeout for the in turn relayer in seconds + uint64 relayer_timeout = 1; + // RelayInterval is for in-turn relayer in seconds + uint64 relayer_interval = 2; // Reward share for the relayer sends the claim message, // the other relayers signed the bls message will share the reward evenly. uint32 relayer_reward_share = 3; // in percentage diff --git a/x/oracle/client/cli/query.go b/x/oracle/client/cli/query.go index f9f9ad0aa5..e21562cc98 100644 --- a/x/oracle/client/cli/query.go +++ b/x/oracle/client/cli/query.go @@ -22,6 +22,7 @@ func GetQueryCmd() *cobra.Command { cmd.AddCommand( QueryParamsCmd(), + QueryInturnRelayerCmd(), ) return cmd @@ -57,3 +58,34 @@ $ query oracle params return cmd } + +// QueryParamsCmd returns the command handler for evidence parameter querying. +func QueryInturnRelayerCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "inturn-relayer", + Short: "Query the inturn relayer", + Args: cobra.NoArgs, + Long: strings.TrimSpace(`Query the inturn relayer: + +$ query oracle inturn-relayer +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.InturnRelayer(cmd.Context(), &types.QueryInturnRelayerRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/oracle/keeper/keeper.go b/x/oracle/keeper/keeper.go index 8d53373099..cb78ad5b45 100644 --- a/x/oracle/keeper/keeper.go +++ b/x/oracle/keeper/keeper.go @@ -1,8 +1,8 @@ package keeper import ( + "bytes" "encoding/hex" - "fmt" sdkerrors "cosmossdk.io/errors" @@ -96,32 +96,36 @@ func (k Keeper) IsRelayerValid(ctx sdk.Context, relayer sdk.AccAddress, validato } if validatorIndex < 0 { - return false, sdkerrors.Wrapf(types.ErrNotRelayer, fmt.Sprintf("sender(%s) is not a relayer", relayer.String())) + return false, sdkerrors.Wrapf(types.ErrNotRelayer, "sender(%s) is not a relayer", relayer.String()) } inturnRelayerTimeout, relayerInterval := k.GetRelayerParams(ctx) // check whether submitter of msgClaim is an in-turn relayer - inturnRelayer, err := k.GetInturnRelayer(ctx, relayerInterval) + inturnRelayerBlsKey, _, err := k.getInturnRelayer(ctx, relayerInterval) if err != nil { return false, err } - if inturnRelayer.BlsPubKey == hex.EncodeToString(vldr.BlsKey) { + if bytes.Equal(inturnRelayerBlsKey, vldr.BlsKey) { return true, nil } // It is possible that claim comes from out-turn relayers when exceeding the inturnRelayerTimeout, all other // relayers can relay within the in-turn relayer's current interval curTime := ctx.BlockTime().Unix() + if uint64(curTime) < claimTimestamp { + return false, nil + } + return uint64(curTime)-claimTimestamp >= inturnRelayerTimeout, nil } // CheckClaim checks the bls signature -func (k Keeper) CheckClaim(ctx sdk.Context, claim *types.MsgClaim) (sdk.AccAddress, []string, error) { +func (k Keeper) CheckClaim(ctx sdk.Context, claim *types.MsgClaim) (sdk.AccAddress, []sdk.AccAddress, error) { relayer, err := sdk.AccAddressFromHexUnsafe(claim.FromAddress) if err != nil { - return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrInvalidAddress, fmt.Sprintf("from address (%s) is invalid", claim.FromAddress)) + return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrInvalidAddress, "from address (%s) is invalid", claim.FromAddress) } historicalInfo, ok := k.StakingKeeper.GetHistoricalInfo(ctx, ctx.BlockHeight()) @@ -136,7 +140,7 @@ func (k Keeper) CheckClaim(ctx sdk.Context, claim *types.MsgClaim) (sdk.AccAddre } if !isValid { - return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrRelayerNotInTurn, fmt.Sprintf("relayer(%s) is not in turn", claim.FromAddress)) + return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrRelayerNotInTurn, "relayer(%s) is not in turn", claim.FromAddress) } validatorsBitSet := bitset.From(claim.VoteAddressSet) @@ -144,31 +148,31 @@ func (k Keeper) CheckClaim(ctx sdk.Context, claim *types.MsgClaim) (sdk.AccAddre return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrValidatorSet, "number of validator set is larger than validators") } - signedRelayers := make([]string, 0, validatorsBitSet.Count()) + signedRelayers := make([]sdk.AccAddress, 0, validatorsBitSet.Count()) votedPubKeys := make([]bls.PublicKey, 0, validatorsBitSet.Count()) for index, val := range validators { if !validatorsBitSet.Test(uint(index)) { continue } - signedRelayers = append(signedRelayers, val.RelayerAddress) + signedRelayers = append(signedRelayers, sdk.MustAccAddressFromHex(val.RelayerAddress)) votePubKey, err := bls.PublicKeyFromBytes(val.BlsKey) if err != nil { - return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrBlsPubKey, fmt.Sprintf("BLS public key converts failed: %v", err)) + return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrBlsPubKey, "BLS public key converts failed: %v", err) } votedPubKeys = append(votedPubKeys, votePubKey) } // The valid voted validators should be no less than 2/3 validators. if len(votedPubKeys) <= len(validators)*2/3 { - return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrBlsVotesNotEnough, fmt.Sprintf("not enough validators voted, need: %d, voted: %d", len(validators)*2/3, len(votedPubKeys))) + return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrBlsVotesNotEnough, "not enough validators voted, need: %d, voted: %d", len(validators)*2/3, len(votedPubKeys)) } // Verify the aggregated signature. aggSig, err := bls.SignatureFromBytes(claim.AggSignature) if err != nil { - return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrInvalidBlsSignature, fmt.Sprintf("BLS signature converts failed: %v", err)) + return sdk.AccAddress{}, nil, sdkerrors.Wrapf(types.ErrInvalidBlsSignature, "BLS signature converts failed: %v", err) } if !aggSig.FastAggregateVerify(votedPubKeys, claim.GetBlsSignBytes()) { @@ -184,10 +188,10 @@ func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { return params } -func (k Keeper) GetInturnRelayer(ctx sdk.Context, relayerInterval uint64) (*types.QueryInturnRelayerResponse, error) { +func (k Keeper) getInturnRelayer(ctx sdk.Context, relayerInterval uint64) ([]byte, *types.RelayInterval, error) { historicalInfo, ok := k.StakingKeeper.GetHistoricalInfo(ctx, ctx.BlockHeight()) if !ok { - return nil, sdkerrors.Wrapf(types.ErrValidatorSet, "get historical validators failed") + return nil, nil, sdkerrors.Wrapf(types.ErrValidatorSet, "get historical validators failed") } validators := historicalInfo.Valset @@ -207,12 +211,20 @@ func (k Keeper) GetInturnRelayer(ctx sdk.Context, relayerInterval uint64) (*type inturnRelayer := validators[inTurnRelayerIndex] + return inturnRelayer.BlsKey, &types.RelayInterval{ + Start: start, + End: end, + }, nil +} + +func (k Keeper) GetInturnRelayer(ctx sdk.Context, relayerInterval uint64) (*types.QueryInturnRelayerResponse, error) { + blsKey, interval, err := k.getInturnRelayer(ctx, relayerInterval) + if err != nil { + return nil, err + } res := &types.QueryInturnRelayerResponse{ - BlsPubKey: hex.EncodeToString(inturnRelayer.BlsKey), - RelayInterval: &types.RelayInterval{ - Start: start, - End: end, - }, + BlsPubKey: hex.EncodeToString(blsKey), + RelayInterval: interval, } return res, nil } diff --git a/x/oracle/keeper/msg_server.go b/x/oracle/keeper/msg_server.go index daa54719a2..551a3ff49d 100644 --- a/x/oracle/keeper/msg_server.go +++ b/x/oracle/keeper/msg_server.go @@ -4,10 +4,10 @@ import ( "context" "encoding/hex" "fmt" - "math/big" "runtime/debug" sdkerrors "cosmossdk.io/errors" + sdkmath "cosmossdk.io/math" "github.com/gogo/protobuf/proto" "github.com/cosmos/cosmos-sdk/bsc/rlp" @@ -17,14 +17,14 @@ import ( ) type msgServer struct { - oracleKeeper Keeper + Keeper } // NewMsgServerImpl returns an implementation of the oracle MsgServer interface // for the provided Keeper. func NewMsgServerImpl(k Keeper) types.MsgServer { return &msgServer{ - oracleKeeper: k, + k, } } @@ -33,24 +33,24 @@ var _ types.MsgServer = msgServer{} func (k msgServer) Claim(goCtx context.Context, req *types.MsgClaim) (*types.MsgClaimResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - logger := k.oracleKeeper.Logger(ctx) + logger := k.Logger(ctx) // check dest chain id - if sdk.ChainID(req.DestChainId) != k.oracleKeeper.CrossChainKeeper.GetSrcChainID() { - return nil, sdkerrors.Wrapf(types.ErrInvalidDestChainId, fmt.Sprintf("dest chain id(%d) should be %d", req.DestChainId, k.oracleKeeper.CrossChainKeeper.GetSrcChainID())) + if sdk.ChainID(req.DestChainId) != k.CrossChainKeeper.GetSrcChainID() { + return nil, sdkerrors.Wrapf(types.ErrInvalidDestChainId, "dest chain id(%d) should be %d", req.DestChainId, k.CrossChainKeeper.GetSrcChainID()) } // check src chain id - if !k.oracleKeeper.CrossChainKeeper.IsDestChainSupported(sdk.ChainID(req.SrcChainId)) { - return nil, sdkerrors.Wrapf(types.ErrInvalidSrcChainId, fmt.Sprintf("src chain id(%d) is not supported", req.SrcChainId)) + if !k.CrossChainKeeper.IsDestChainSupported(sdk.ChainID(req.SrcChainId)) { + return nil, sdkerrors.Wrapf(types.ErrInvalidSrcChainId, "src chain id(%d) is not supported", req.SrcChainId) } - sequence := k.oracleKeeper.CrossChainKeeper.GetReceiveSequence(ctx, types.RelayPackagesChannelId) + sequence := k.CrossChainKeeper.GetReceiveSequence(ctx, types.RelayPackagesChannelId) if sequence != req.Sequence { - return nil, sdkerrors.Wrapf(types.ErrInvalidReceiveSequence, fmt.Sprintf("current sequence of channel %d is %d", types.RelayPackagesChannelId, sequence)) + return nil, sdkerrors.Wrapf(types.ErrInvalidReceiveSequence, "current sequence of channel %d is %d", types.RelayPackagesChannelId, sequence) } - relayer, signedRelayers, err := k.oracleKeeper.CheckClaim(ctx, req) + relayer, signedRelayers, err := k.CheckClaim(ctx, req) if err != nil { return nil, err } @@ -62,13 +62,12 @@ func (k msgServer) Claim(goCtx context.Context, req *types.MsgClaim) (*types.Msg } events := make([]proto.Message, 0, len(packages)) - totalRelayerFee := big.NewInt(0) + totalRelayerFee := sdkmath.ZeroInt() for idx := range packages { pack := packages[idx] - relayerFee, event, err := handlePackage(ctx, k.oracleKeeper, &pack, req.SrcChainId, req.DestChainId, req.Timestamp) + relayerFee, event, err := k.handlePackage(ctx, &pack, req.SrcChainId, req.DestChainId, req.Timestamp) if err != nil { - // only do log, but let rest package get chance to execute. logger.Error("process package failed", "channel", pack.ChannelId, "sequence", pack.Sequence, "error", err.Error()) return nil, err } @@ -76,74 +75,71 @@ func (k msgServer) Claim(goCtx context.Context, req *types.MsgClaim) (*types.Msg events = append(events, event) - totalRelayerFee = totalRelayerFee.Add(totalRelayerFee, relayerFee) + totalRelayerFee = totalRelayerFee.Add(relayerFee) // increase channel sequence - k.oracleKeeper.CrossChainKeeper.IncrReceiveSequence(ctx, pack.ChannelId) + k.CrossChainKeeper.IncrReceiveSequence(ctx, pack.ChannelId) } - err = distributeReward(ctx, k.oracleKeeper, relayer, signedRelayers, totalRelayerFee) + err = k.distributeReward(ctx, relayer, signedRelayers, totalRelayerFee) if err != nil { return nil, err } - k.oracleKeeper.CrossChainKeeper.IncrReceiveSequence(ctx, types.RelayPackagesChannelId) + k.CrossChainKeeper.IncrReceiveSequence(ctx, types.RelayPackagesChannelId) - ctx.EventManager().EmitTypedEvents(events...) + err = ctx.EventManager().EmitTypedEvents(events...) + if err != nil { + return nil, err + } return &types.MsgClaimResponse{}, nil } // distributeReward will distribute reward to relayers -func distributeReward(ctx sdk.Context, oracleKeeper Keeper, relayer sdk.AccAddress, signedRelayers []string, relayerFee *big.Int) error { - if relayerFee.Cmp(big.NewInt(0)) <= 0 { - oracleKeeper.Logger(ctx).Info("total relayer fee is zero") +func (k Keeper) distributeReward(ctx sdk.Context, relayer sdk.AccAddress, signedRelayers []sdk.AccAddress, relayerFee sdkmath.Int) error { + if !relayerFee.IsPositive() { + k.Logger(ctx).Info("total relayer fee is zero") return nil } otherRelayers := make([]sdk.AccAddress, 0, len(signedRelayers)) - for idx := range signedRelayers { - signedRelayerAddr, err := sdk.AccAddressFromHexUnsafe(signedRelayers[idx]) - if err != nil { - return sdkerrors.Wrapf(types.ErrInvalidAddress, fmt.Sprintf("relayer address (%s) is invalid", relayer)) - } - if !signedRelayerAddr.Equals(relayer) { + for _, signedRelayer := range signedRelayers { + if !signedRelayer.Equals(relayer) { otherRelayers = append(otherRelayers, relayer) } } - totalDistributed, otherRelayerReward := big.NewInt(0), big.NewInt(0) + totalDistributed, otherRelayerReward := sdkmath.ZeroInt(), sdkmath.ZeroInt() - relayerRewardShare := oracleKeeper.GetRelayerRewardShare(ctx) + relayerRewardShare := k.GetRelayerRewardShare(ctx) // calculate the reward to distribute to each other relayer if len(otherRelayers) > 0 { - otherRelayerReward = otherRelayerReward.Mul(big.NewInt(100-int64(relayerRewardShare)), relayerFee) - otherRelayerReward = otherRelayerReward.Div(otherRelayerReward, big.NewInt(100)) - otherRelayerReward = otherRelayerReward.Div(otherRelayerReward, big.NewInt(int64(len(otherRelayers)))) + otherRelayerReward = relayerFee.Mul(sdkmath.NewInt(100 - int64(relayerRewardShare))).Mul(relayerFee).Quo(sdkmath.NewInt(100)).Quo(sdkmath.NewInt(int64(len(otherRelayers)))) } - bondDenom := oracleKeeper.StakingKeeper.BondDenom(ctx) - if otherRelayerReward.Cmp(big.NewInt(0)) > 0 { - for idx := range otherRelayers { - err := oracleKeeper.BankKeeper.SendCoinsFromModuleToAccount(ctx, + bondDenom := k.StakingKeeper.BondDenom(ctx) + if otherRelayerReward.IsPositive() { + for _, signedRelayer := range otherRelayers { + err := k.BankKeeper.SendCoinsFromModuleToAccount(ctx, crosschaintypes.ModuleName, - otherRelayers[idx], - sdk.Coins{sdk.Coin{Denom: bondDenom, Amount: sdk.NewIntFromBigInt(otherRelayerReward)}}, + signedRelayer, + sdk.Coins{sdk.Coin{Denom: bondDenom, Amount: otherRelayerReward}}, ) if err != nil { return err } - totalDistributed = totalDistributed.Add(totalDistributed, otherRelayerReward) + totalDistributed = totalDistributed.Add(otherRelayerReward) } } - remainingReward := relayerFee.Sub(relayerFee, totalDistributed) - if remainingReward.Cmp(big.NewInt(0)) > 0 { - err := oracleKeeper.BankKeeper.SendCoinsFromModuleToAccount(ctx, + remainingReward := relayerFee.Sub(totalDistributed) + if remainingReward.IsPositive() { + err := k.BankKeeper.SendCoinsFromModuleToAccount(ctx, crosschaintypes.ModuleName, relayer, - sdk.Coins{sdk.Coin{Denom: bondDenom, Amount: sdk.NewIntFromBigInt(remainingReward)}}, + sdk.Coins{sdk.Coin{Denom: bondDenom, Amount: remainingReward}}, ) if err != nil { return err @@ -153,40 +149,39 @@ func distributeReward(ctx sdk.Context, oracleKeeper Keeper, relayer sdk.AccAddre return nil } -func handlePackage( +func (k Keeper) handlePackage( ctx sdk.Context, - oracleKeeper Keeper, pack *types.Package, srcChainId uint32, destChainId uint32, timestamp uint64, -) (*big.Int, *types.EventPackageClaim, error) { - logger := oracleKeeper.Logger(ctx) +) (sdkmath.Int, *types.EventPackageClaim, error) { + logger := k.Logger(ctx) - crossChainApp := oracleKeeper.CrossChainKeeper.GetCrossChainApp(pack.ChannelId) + crossChainApp := k.CrossChainKeeper.GetCrossChainApp(pack.ChannelId) if crossChainApp == nil { - return nil, nil, sdkerrors.Wrapf(types.ErrChannelNotRegistered, "channel %d not registered", pack.ChannelId) + return sdkmath.ZeroInt(), nil, sdkerrors.Wrapf(types.ErrChannelNotRegistered, "channel %d not registered", pack.ChannelId) } - sequence := oracleKeeper.CrossChainKeeper.GetReceiveSequence(ctx, pack.ChannelId) + sequence := k.CrossChainKeeper.GetReceiveSequence(ctx, pack.ChannelId) if sequence != pack.Sequence { - return nil, nil, sdkerrors.Wrapf(types.ErrInvalidReceiveSequence, - fmt.Sprintf("current sequence of channel %d is %d", pack.ChannelId, sequence)) + return sdkmath.ZeroInt(), nil, sdkerrors.Wrapf(types.ErrInvalidReceiveSequence, + "current sequence of channel %d is %d", pack.ChannelId, sequence) } packageHeader, err := sdk.DecodePackageHeader(pack.Payload) if err != nil { - return nil, nil, sdkerrors.Wrapf(types.ErrInvalidPayloadHeader, "payload header is invalid") + return sdkmath.ZeroInt(), nil, sdkerrors.Wrapf(types.ErrInvalidPayloadHeader, "payload header is invalid") } if packageHeader.Timestamp != timestamp { - return nil, nil, sdkerrors.Wrapf(types.ErrInvalidPayloadHeader, + return sdkmath.ZeroInt(), nil, sdkerrors.Wrapf(types.ErrInvalidPayloadHeader, "timestamp(%d) is not the same in payload header(%d)", timestamp, packageHeader.Timestamp) } if !sdk.IsValidCrossChainPackageType(packageHeader.PackageType) { - return nil, nil, sdkerrors.Wrapf(types.ErrInvalidPackageType, - fmt.Sprintf("package type %d is invalid", packageHeader.PackageType)) + return sdkmath.ZeroInt(), nil, sdkerrors.Wrapf(types.ErrInvalidPackageType, + "package type %d is invalid", packageHeader.PackageType) } cacheCtx, write := ctx.CacheContext() @@ -199,28 +194,25 @@ func handlePackage( var sendSequence int64 = -1 if packageHeader.PackageType == sdk.SynCrossChainPackageType { if crash { - var ibcErr error - var sendSeq uint64 - if len(pack.Payload) >= sdk.SynPackageHeaderLength { - sendSeq, ibcErr = oracleKeeper.CrossChainKeeper.CreateRawIBCPackageWithFee(ctx, pack.ChannelId, - sdk.FailAckCrossChainPackageType, pack.Payload[sdk.SynPackageHeaderLength:], packageHeader.AckRelayerFee, sdk.NilAckRelayerFee) - } else { + if len(pack.Payload) < sdk.SynPackageHeaderLength { logger.Error("found payload without header", "channelID", pack.ChannelId, "sequence", pack.Sequence, "payload", hex.EncodeToString(pack.Payload)) - return nil, nil, sdkerrors.Wrapf(types.ErrInvalidPackage, "payload without header") + return sdkmath.ZeroInt(), nil, sdkerrors.Wrapf(types.ErrInvalidPackage, "payload without header") } + sendSeq, ibcErr := k.CrossChainKeeper.CreateRawIBCPackageWithFee(ctx, pack.ChannelId, + sdk.FailAckCrossChainPackageType, pack.Payload[sdk.SynPackageHeaderLength:], packageHeader.AckRelayerFee, sdk.NilAckRelayerFee) if ibcErr != nil { logger.Error("failed to write FailAckCrossChainPackage", "err", err) - return nil, nil, ibcErr + return sdkmath.ZeroInt(), nil, ibcErr } sendSequence = int64(sendSeq) } else if len(result.Payload) != 0 { - sendSeq, err := oracleKeeper.CrossChainKeeper.CreateRawIBCPackageWithFee(ctx, pack.ChannelId, + sendSeq, err := k.CrossChainKeeper.CreateRawIBCPackageWithFee(ctx, pack.ChannelId, sdk.AckCrossChainPackageType, result.Payload, packageHeader.AckRelayerFee, sdk.NilAckRelayerFee) if err != nil { logger.Error("failed to write AckCrossChainPackage", "err", err) - return nil, nil, err + return sdkmath.ZeroInt(), nil, err } sendSequence = int64(sendSeq) } @@ -239,7 +231,7 @@ func handlePackage( ErrorMsg: result.ErrMsg(), } - return packageHeader.RelayerFee, claimEvent, nil + return sdkmath.NewIntFromBigInt(packageHeader.RelayerFee), claimEvent, nil } func executeClaim( From 461b280d8b849133a38d70aa8a7075e914f527ea Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 23 Mar 2023 13:50:42 +0800 Subject: [PATCH 08/10] chore: refine crosschain module (#146) * chore: refine crosschain module * fix comments * check init module balance --------- Co-authored-by: yutianwu --- proto/cosmos/crosschain/v1/crosschain.proto | 9 +++- x/crosschain/keeper/grpc_query.go | 15 +++++- x/crosschain/keeper/keeper.go | 15 +++--- x/crosschain/types/crosschain.pb.go | 59 +++++++++++---------- x/crosschain/types/genesis.go | 10 +--- x/crosschain/types/params.go | 23 +++++--- x/oracle/types/oracle.pb.go | 4 +- 7 files changed, 78 insertions(+), 57 deletions(-) diff --git a/proto/cosmos/crosschain/v1/crosschain.proto b/proto/cosmos/crosschain/v1/crosschain.proto index 2d8622e999..0c91f0d15c 100644 --- a/proto/cosmos/crosschain/v1/crosschain.proto +++ b/proto/cosmos/crosschain/v1/crosschain.proto @@ -1,10 +1,17 @@ syntax = "proto3"; package cosmos.crosschain.v1; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; + option go_package = "github.com/cosmos/cosmos-sdk/x/crosschain/types"; // Params holds parameters for the cross chain module. message Params { // initial balance to mint for crosschain module when the chain starts - string init_module_balance = 1; + string init_module_balance = 1 [ + (cosmos_proto.scalar) = "cosmos.Int", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; } diff --git a/x/crosschain/keeper/grpc_query.go b/x/crosschain/keeper/grpc_query.go index 63a16d2e5e..b24e07faf2 100644 --- a/x/crosschain/keeper/grpc_query.go +++ b/x/crosschain/keeper/grpc_query.go @@ -5,6 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/crosschain/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var _ types.QueryServer = Keeper{} @@ -19,8 +21,11 @@ func (k Keeper) Params(c context.Context, _ *types.QueryParamsRequest) (*types.Q // CrossChainPackage returns the specified cross chain package func (k Keeper) CrossChainPackage(c context.Context, req *types.QueryCrossChainPackageRequest) (*types.QueryCrossChainPackageResponse, error) { - ctx := sdk.UnwrapSDKContext(c) + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) pack, err := k.GetCrossChainPackage(ctx, sdk.ChannelID(req.ChannelId), req.Sequence) if err != nil { return nil, err @@ -32,6 +37,10 @@ func (k Keeper) CrossChainPackage(c context.Context, req *types.QueryCrossChainP // SendSequence returns the send sequence of the channel func (k Keeper) SendSequence(c context.Context, req *types.QuerySendSequenceRequest) (*types.QuerySendSequenceResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) sequence := k.GetSendSequence(ctx, sdk.ChannelID(req.ChannelId)) @@ -42,6 +51,10 @@ func (k Keeper) SendSequence(c context.Context, req *types.QuerySendSequenceRequ // ReceiveSequence returns the receive sequence of the channel func (k Keeper) ReceiveSequence(c context.Context, req *types.QueryReceiveSequenceRequest) (*types.QueryReceiveSequenceResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) sequence := k.GetReceiveSequence(ctx, sdk.ChannelID(req.ChannelId)) diff --git a/x/crosschain/keeper/keeper.go b/x/crosschain/keeper/keeper.go index aa60e74305..fa50549d23 100644 --- a/x/crosschain/keeper/keeper.go +++ b/x/crosschain/keeper/keeper.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" + sdkmath "cosmossdk.io/math" "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/codec" @@ -56,7 +57,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState, bankKeep err := bankKeeper.MintCoins(ctx, types.ModuleName, sdk.Coins{sdk.Coin{ Denom: bondDenom, - Amount: sdk.NewIntFromBigInt(initModuleBalance), + Amount: initModuleBalance, }}) if err != nil { panic(fmt.Sprintf("mint initial cross chain module balance error, err=%s", err.Error())) @@ -64,14 +65,10 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState, bankKeep } // GetInitModuleBalance returns the initial balance of cross chain module -func (k Keeper) GetInitModuleBalance(ctx sdk.Context) *big.Int { - var initModuleBlaanceParam string - k.paramSpace.Get(ctx, types.KeyParamInitModuleBalance, &initModuleBlaanceParam) - moduleBalance, valid := big.NewInt(0).SetString(initModuleBlaanceParam, 10) - if !valid { - panic(fmt.Errorf("invalid init module balance: %s", initModuleBlaanceParam)) - } - return moduleBalance +func (k Keeper) GetInitModuleBalance(ctx sdk.Context) sdkmath.Int { + var initModuleBalanceParam sdkmath.Int + k.paramSpace.Get(ctx, types.KeyParamInitModuleBalance, &initModuleBalanceParam) + return initModuleBalanceParam } // SetParams sets the params of cross chain module diff --git a/x/crosschain/types/crosschain.pb.go b/x/crosschain/types/crosschain.pb.go index 727c0836fc..b0a7778e74 100644 --- a/x/crosschain/types/crosschain.pb.go +++ b/x/crosschain/types/crosschain.pb.go @@ -5,6 +5,9 @@ package types import ( fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" io "io" math "math" @@ -25,7 +28,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params holds parameters for the cross chain module. type Params struct { // initial balance to mint for crosschain module when the chain starts - InitModuleBalance string `protobuf:"bytes,1,opt,name=init_module_balance,json=initModuleBalance,proto3" json:"init_module_balance,omitempty"` + InitModuleBalance github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=init_module_balance,json=initModuleBalance,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"init_module_balance"` } func (m *Params) Reset() { *m = Params{} } @@ -61,13 +64,6 @@ func (m *Params) XXX_DiscardUnknown() { var xxx_messageInfo_Params proto.InternalMessageInfo -func (m *Params) GetInitModuleBalance() string { - if m != nil { - return m.InitModuleBalance - } - return "" -} - func init() { proto.RegisterType((*Params)(nil), "cosmos.crosschain.v1.Params") } @@ -77,18 +73,22 @@ func init() { } var fileDescriptor_d7b94a7254cf916a = []byte{ - // 175 bytes of a gzipped FileDescriptorProto + // 227 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4d, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0x4f, 0x2e, 0xca, 0x2f, 0x2e, 0x4e, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x33, 0x44, 0xe2, 0xe9, 0x15, 0x14, 0xe5, 0x97, 0xe4, 0x0b, 0x89, 0x40, 0x94, 0xe9, 0x21, 0x49, 0x94, - 0x19, 0x2a, 0x59, 0x70, 0xb1, 0x05, 0x24, 0x16, 0x25, 0xe6, 0x16, 0x0b, 0xe9, 0x71, 0x09, 0x67, - 0xe6, 0x65, 0x96, 0xc4, 0xe7, 0xe6, 0xa7, 0x94, 0xe6, 0xa4, 0xc6, 0x27, 0x25, 0xe6, 0x24, 0xe6, - 0x25, 0xa7, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x06, 0x09, 0x82, 0xa4, 0x7c, 0xc1, 0x32, 0x4e, - 0x10, 0x09, 0x27, 0xcf, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, - 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xd2, 0x4f, - 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0xb9, 0x0d, 0x4c, 0xe9, 0x16, - 0xa7, 0x64, 0xeb, 0x57, 0x20, 0x3b, 0xb4, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0xec, 0x42, - 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf7, 0xe6, 0x93, 0xeb, 0xca, 0x00, 0x00, 0x00, + 0x19, 0x4a, 0x49, 0x42, 0x44, 0xe3, 0xc1, 0x6a, 0xf4, 0xa1, 0x4a, 0xc0, 0x1c, 0x29, 0x91, 0xf4, + 0xfc, 0xf4, 0x7c, 0x88, 0x38, 0x88, 0x05, 0x11, 0x55, 0x2a, 0xe3, 0x62, 0x0b, 0x48, 0x2c, 0x4a, + 0xcc, 0x2d, 0x16, 0xca, 0xe1, 0x12, 0xce, 0xcc, 0xcb, 0x2c, 0x89, 0xcf, 0xcd, 0x4f, 0x29, 0xcd, + 0x49, 0x8d, 0x4f, 0x4a, 0xcc, 0x49, 0xcc, 0x4b, 0x4e, 0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x74, + 0xb2, 0x39, 0x71, 0x4f, 0x9e, 0xe1, 0xd6, 0x3d, 0x79, 0xb5, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, + 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, 0x98, 0x3b, 0xc1, 0x94, 0x6e, 0x71, 0x4a, 0xb6, 0x7e, 0x49, 0x65, + 0x41, 0x6a, 0xb1, 0x9e, 0x67, 0x5e, 0xc9, 0xa5, 0x2d, 0xba, 0x5c, 0x50, 0xcb, 0x3d, 0xf3, 0x4a, + 0x82, 0x04, 0x41, 0x06, 0xfb, 0x82, 0xcd, 0x75, 0x82, 0x18, 0xeb, 0xe4, 0x79, 0xe2, 0x91, 0x1c, + 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, + 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xfa, 0x78, 0xad, 0xa8, 0x40, 0x0e, 0x17, 0xb0, 0x7d, + 0x49, 0x6c, 0x60, 0x9f, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xd9, 0x23, 0x9a, 0x6c, 0x39, + 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -111,13 +111,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.InitModuleBalance) > 0 { - i -= len(m.InitModuleBalance) - copy(dAtA[i:], m.InitModuleBalance) - i = encodeVarintCrosschain(dAtA, i, uint64(len(m.InitModuleBalance))) - i-- - dAtA[i] = 0xa + { + size := m.InitModuleBalance.Size() + i -= size + if _, err := m.InitModuleBalance.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintCrosschain(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -138,10 +141,8 @@ func (m *Params) Size() (n int) { } var l int _ = l - l = len(m.InitModuleBalance) - if l > 0 { - n += 1 + l + sovCrosschain(uint64(l)) - } + l = m.InitModuleBalance.Size() + n += 1 + l + sovCrosschain(uint64(l)) return n } @@ -210,7 +211,9 @@ func (m *Params) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.InitModuleBalance = string(dAtA[iNdEx:postIndex]) + if err := m.InitModuleBalance.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/crosschain/types/genesis.go b/x/crosschain/types/genesis.go index 889659066b..026426d2d9 100644 --- a/x/crosschain/types/genesis.go +++ b/x/crosschain/types/genesis.go @@ -2,7 +2,6 @@ package types import ( "fmt" - "math/big" ) // NewGenesisState creates a new GenesisState object @@ -23,13 +22,8 @@ func DefaultGenesisState() *GenesisState { // ValidateGenesis validates the cross chain genesis parameters func ValidateGenesis(data GenesisState) error { - balance, valid := big.NewInt(0).SetString(data.Params.InitModuleBalance, 10) - if !valid { - return fmt.Errorf("invalid module balance, is %s", data.Params.InitModuleBalance) - } - - if balance.Cmp(big.NewInt(0)) < 0 { - return fmt.Errorf("init module balance should be positive, is %s", balance.String()) + if data.Params.InitModuleBalance.IsNil() || !data.Params.InitModuleBalance.IsPositive() { + return fmt.Errorf("init module balance should be positive, is %s", data.Params.InitModuleBalance.String()) } return nil diff --git a/x/crosschain/types/params.go b/x/crosschain/types/params.go index aa065ec2ff..05198e68dd 100644 --- a/x/crosschain/types/params.go +++ b/x/crosschain/types/params.go @@ -2,12 +2,20 @@ package types import ( "fmt" - "math/big" + sdkmath "cosmossdk.io/math" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) -const DefaultInitModuleBalance string = "2000000000000000000000000" // 2M +var DefaultInitModuleBalance sdkmath.Int + +func init() { + initModuleBalance, ok := sdkmath.NewIntFromString("2000000000000000000000000") // 2M + if !ok { + panic("invalid init module balance") + } + DefaultInitModuleBalance = initModuleBalance +} var KeyParamInitModuleBalance = []byte("InitModuleBalance") @@ -29,18 +37,17 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { } func validateInitModuleBalance(i interface{}) error { - v, ok := i.(string) + v, ok := i.(sdkmath.Int) if !ok { return fmt.Errorf("invalid parameter type: %T", i) } - balance, valid := big.NewInt(0).SetString(v, 10) - if !valid { - return fmt.Errorf("invalid module balance, is %s", v) + if v.IsNil() { + return fmt.Errorf("init module balance should not be nil") } - if balance.Cmp(big.NewInt(0)) < 0 { - return fmt.Errorf("init module balance should be positive, is %s", v) + if !v.IsPositive() { + return fmt.Errorf("init module balance should be positive, is %s", v.String()) } return nil diff --git a/x/oracle/types/oracle.pb.go b/x/oracle/types/oracle.pb.go index 66de90e8bb..6c901b6e93 100644 --- a/x/oracle/types/oracle.pb.go +++ b/x/oracle/types/oracle.pb.go @@ -24,9 +24,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params holds parameters for the oracle module. type Params struct { - // Timeout for the in turn relayer + // Timeout for the in turn relayer in seconds RelayerTimeout uint64 `protobuf:"varint,1,opt,name=relayer_timeout,json=relayerTimeout,proto3" json:"relayer_timeout,omitempty"` - // RelayInterval is for in-turn relayer + // RelayInterval is for in-turn relayer in seconds RelayerInterval uint64 `protobuf:"varint,2,opt,name=relayer_interval,json=relayerInterval,proto3" json:"relayer_interval,omitempty"` // Reward share for the relayer sends the claim message, // the other relayers signed the bls message will share the reward evenly. From 9f1a5fc433ced06247b556524b71f0ba6b3a3bfc Mon Sep 17 00:00:00 2001 From: dylanhuang Date: Fri, 24 Mar 2023 10:23:12 +0800 Subject: [PATCH 09/10] chore: refine the default gas (#147) --- x/auth/ante/msg_gas_test.go | 4 +- x/gashub/types/params.go | 88 ++++++++++++++++++------------------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/x/auth/ante/msg_gas_test.go b/x/auth/ante/msg_gas_test.go index ff5e9cc019..5cc6ab5f3d 100644 --- a/x/auth/ante/msg_gas_test.go +++ b/x/auth/ante/msg_gas_test.go @@ -47,8 +47,8 @@ func (suite *AnteTestSuite) TestMsgGas() { expectedGas uint64 } testCases := []testCase{ - {"MsgSend", msgSend, 12000}, - {"MsgMultiSend", msgMultiSend, 32000}, + {"MsgSend", msgSend, 1200}, + {"MsgMultiSend", msgMultiSend, 3200}, } for _, tc := range testCases { suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // Create new txBuilder for each test diff --git a/x/gashub/types/params.go b/x/gashub/types/params.go index c7ca0fc635..9def5940fe 100644 --- a/x/gashub/types/params.go +++ b/x/gashub/types/params.go @@ -69,60 +69,60 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { // DefaultParams returns a default set of parameters. func DefaultParams() Params { defaultMsgGasParamsSet := []*MsgGasParams{ - NewMsgGasParamsWithFixedGas("/cosmos.authz.v1beta1.MsgExec", 12e3), - NewMsgGasParamsWithFixedGas("/cosmos.authz.v1beta1.MsgRevoke", 12e3), - NewMsgGasParamsWithFixedGas("/cosmos.bank.v1beta1.MsgSend", 12e3), - NewMsgGasParamsWithFixedGas("/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", 12e3), - NewMsgGasParamsWithFixedGas("/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", 12e3), - NewMsgGasParamsWithFixedGas("/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission", 12e3), - NewMsgGasParamsWithFixedGas("/cosmos.feegrant.v1beta1.MsgRevokeAllowance", 12e3), - NewMsgGasParamsWithFixedGas("/cosmos.gov.v1.MsgDeposit", 12e3), + NewMsgGasParamsWithFixedGas("/cosmos.authz.v1beta1.MsgExec", 1.2e3), + NewMsgGasParamsWithFixedGas("/cosmos.authz.v1beta1.MsgRevoke", 1.2e3), + NewMsgGasParamsWithFixedGas("/cosmos.bank.v1beta1.MsgSend", 1.2e3), + NewMsgGasParamsWithFixedGas("/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", 1.2e3), + NewMsgGasParamsWithFixedGas("/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", 1.2e3), + NewMsgGasParamsWithFixedGas("/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission", 1.2e3), + NewMsgGasParamsWithFixedGas("/cosmos.feegrant.v1beta1.MsgRevokeAllowance", 1.2e3), + NewMsgGasParamsWithFixedGas("/cosmos.gov.v1.MsgDeposit", 1.2e3), NewMsgGasParamsWithFixedGas("/cosmos.gov.v1.MsgSubmitProposal", 2e8), NewMsgGasParamsWithFixedGas("/cosmos.gov.v1.MsgVote", 2e7), NewMsgGasParamsWithFixedGas("/cosmos.gov.v1.MsgVoteWeighted", 2e7), NewMsgGasParamsWithFixedGas("/cosmos.oracle.v1.MsgClaim", 1e3), - NewMsgGasParamsWithFixedGas("/cosmos.slashing.v1beta1.MsgUnjail", 12e3), - NewMsgGasParamsWithFixedGas("/cosmos.staking.v1beta1.MsgBeginRedelegate", 12e3), - NewMsgGasParamsWithFixedGas("/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation", 12e3), + NewMsgGasParamsWithFixedGas("/cosmos.slashing.v1beta1.MsgUnjail", 1.2e3), + NewMsgGasParamsWithFixedGas("/cosmos.staking.v1beta1.MsgBeginRedelegate", 1.2e3), + NewMsgGasParamsWithFixedGas("/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation", 1.2e3), NewMsgGasParamsWithFixedGas("/cosmos.staking.v1beta1.MsgCreateValidator", 2e8), - NewMsgGasParamsWithFixedGas("/cosmos.staking.v1beta1.MsgDelegate", 12e3), + NewMsgGasParamsWithFixedGas("/cosmos.staking.v1beta1.MsgDelegate", 1.2e3), NewMsgGasParamsWithFixedGas("/cosmos.staking.v1beta1.MsgEditValidator", 2e7), - NewMsgGasParamsWithFixedGas("/cosmos.staking.v1beta1.MsgUndelegate", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.bridge.MsgTransferOut", 12e3), + NewMsgGasParamsWithFixedGas("/cosmos.staking.v1beta1.MsgUndelegate", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.bridge.MsgTransferOut", 1.2e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.sp.MsgCreateStorageProvider", 2e8), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.sp.MsgDeposit", 12e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.sp.MsgDeposit", 1.2e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.sp.MsgEditStorageProvider", 2e7), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.sp.MsgUpdateSpStoragePrice", 2e7), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateBucket", 24e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeleteBucket", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgMirrorBucket", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgUpdateBucketInfo", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateObject", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgSealObject", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgMirrorObject", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgRejectSealObject", 12e4), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeleteObject", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCopyObject", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCancelCreateObject", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateGroup", 24e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeleteGroup", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgLeaveGroup", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgUpdateGroupMember", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgMirrorGroup", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgPutPolicy", 24e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeletePolicy", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.payment.MsgCreatePaymentAccount", 2e6), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.payment.MsgDeposit", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.payment.MsgWithdraw", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.payment.MsgDisableRefund", 12e3), - NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.challenge.MsgSubmit", 12e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateBucket", 2.4e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeleteBucket", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgMirrorBucket", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgUpdateBucketInfo", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateObject", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgSealObject", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgMirrorObject", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgRejectSealObject", 1.2e4), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeleteObject", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCopyObject", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCancelCreateObject", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgCreateGroup", 2.4e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeleteGroup", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgLeaveGroup", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgUpdateGroupMember", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgMirrorGroup", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgPutPolicy", 2.4e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.storage.MsgDeletePolicy", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.payment.MsgCreatePaymentAccount", 2e5), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.payment.MsgDeposit", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.payment.MsgWithdraw", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.payment.MsgDisableRefund", 1.2e3), + NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.challenge.MsgSubmit", 1.2e3), NewMsgGasParamsWithFixedGas("/bnbchain.greenfield.challenge.MsgAttest", 1e2), NewMsgGasParamsWithDynamicGas( "/cosmos.authz.v1beta1.MsgGrant", &MsgGasParams_GrantType{ GrantType: &MsgGasParams_DynamicGasParams{ - FixedGas: 8e3, - GasPerItem: 8e3, + FixedGas: 8e2, + GasPerItem: 8e2, }, }, ), @@ -130,8 +130,8 @@ func DefaultParams() Params { "/cosmos.bank.v1beta1.MsgMultiSend", &MsgGasParams_MultiSendType{ MultiSendType: &MsgGasParams_DynamicGasParams{ - FixedGas: 8e3, - GasPerItem: 8e3, + FixedGas: 8e2, + GasPerItem: 8e2, }, }, ), @@ -139,8 +139,8 @@ func DefaultParams() Params { "/cosmos.feegrant.v1beta1.MsgGrantAllowance", &MsgGasParams_GrantAllowanceType{ GrantAllowanceType: &MsgGasParams_DynamicGasParams{ - FixedGas: 8e3, - GasPerItem: 8e3, + FixedGas: 8e2, + GasPerItem: 8e2, }, }, ), From 393c34f65dfa81388313d74ae3011ec79f321544 Mon Sep 17 00:00:00 2001 From: randyahx <62416962+randyahx@users.noreply.github.com> Date: Fri, 24 Mar 2023 15:55:22 +0800 Subject: [PATCH 10/10] release: prepare for release v0.0.12 (#148) --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c870e78c1a..cfcfa431be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,17 @@ # Changelog +## v0.0.12 +This is a maintenance release. + +* [\#147](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/147) chore: refine the default gas +* [\#146](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/146) chore: refine crosschain module +* [\#145](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/145) chore: refine oracle module +* [\#143](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/143) docs: add licence and disclaim +* [\#141](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/141) refine the storage tx fee +* [\#140](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/140) chore: refine the code of gashub module +* [\#142](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/142) refactor: refine cross-chain governance +* [\#144](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/144) chore: refine upgrade module for code quality +* [\#129](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/129) feat: add challenger address to validators + ## v0.0.11 This is a maintenance release.