diff --git a/clientcontroller/babylon.go b/clientcontroller/babylon.go index d68ea7e2..88843a61 100644 --- a/clientcontroller/babylon.go +++ b/clientcontroller/babylon.go @@ -167,7 +167,7 @@ func (bc *BabylonController) GetStakingParams() (*StakingParams, error) { MinSlashingTxFeeSat: btcutil.Amount(stakingParamRes.Params.MinSlashingTxFeeSat), JuryPk: juryPk, SlashingAddress: stakingParamRes.Params.SlashingAddress, - MinComissionRate: stakingParamRes.Params.MinCommissionRate, + MinCommissionRate: stakingParamRes.Params.MinCommissionRate, }, nil } @@ -268,7 +268,7 @@ func (bc *BabylonController) RegisterValidator( bbnPubKey *secp256k1.PubKey, btcPubKey *bbntypes.BIP340PubKey, pop *btcstakingtypes.ProofOfPossession, - commission sdkTypes.Dec, + commission *sdkTypes.Dec, description *sttypes.Description, ) (*provider.RelayerTxResponse, error) { @@ -277,7 +277,7 @@ func (bc *BabylonController) RegisterValidator( BabylonPk: bbnPubKey, BtcPk: btcPubKey, Pop: pop, - Commission: &commission, + Commission: commission, Description: description, } diff --git a/clientcontroller/interface.go b/clientcontroller/interface.go index 56044800..15bfa0f9 100644 --- a/clientcontroller/interface.go +++ b/clientcontroller/interface.go @@ -37,8 +37,8 @@ type StakingParams struct { // Address to which slashing transactions are sent SlashingAddress string - // Minimum comission required by babylon - MinComissionRate sdkTypes.Dec + // Minimum commission required by babylon + MinCommissionRate sdkTypes.Dec } // TODO replace babylon types with general ones @@ -50,7 +50,7 @@ type ClientController interface { bbnPubKey *secp256k1.PubKey, btcPubKey *bbntypes.BIP340PubKey, pop *btcstakingtypes.ProofOfPossession, - commission sdkTypes.Dec, + commission *sdkTypes.Dec, description *stakingtypes.Description, ) (*provider.RelayerTxResponse, error) // CommitPubRandList commits a list of Schnorr public randomness via a MsgCommitPubRand to Babylon diff --git a/cmd/valcli/daemoncmd.go b/cmd/valcli/daemoncmd.go index 0ef235ee..465ea5be 100644 --- a/cmd/valcli/daemoncmd.go +++ b/cmd/valcli/daemoncmd.go @@ -6,6 +6,7 @@ import ( "fmt" "strconv" + "cosmossdk.io/math" "github.com/babylonchain/babylon/x/checkpointing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/urfave/cli" @@ -45,6 +46,8 @@ const ( websiteFlag = "website" securityContractFlag = "security-contract" detailsFlag = "details" + + commissionRateFlag = "commission" ) var ( @@ -100,6 +103,11 @@ var createValDaemonCmd = cli.Command{ Usage: "The unique name of the validator key", Required: true, }, + cli.StringFlag{ + Name: commissionRateFlag, + Usage: "The commission rate for the validator, e.g., 0.05", + Value: "0.05", + }, cli.StringFlag{ Name: monikerFlag, Usage: "A human-readable name for the validator", @@ -132,6 +140,12 @@ var createValDaemonCmd = cli.Command{ func createValDaemon(ctx *cli.Context) error { daemonAddress := ctx.String(valdDaemonAddressFlag) keyName := ctx.String(keyNameFlag) + + commissionRate, err := math.LegacyNewDecFromStr(ctx.String(commissionRateFlag)) + if err != nil { + return err + } + description, err := getDesciptionFromContext(ctx) if err != nil { return err @@ -143,7 +157,7 @@ func createValDaemon(ctx *cli.Context) error { } defer cleanUp() - info, err := client.CreateValidator(context.Background(), keyName, &description) + info, err := client.CreateValidator(context.Background(), keyName, &description, &commissionRate) if err != nil { return err diff --git a/cmd/valcli/validators.go b/cmd/valcli/validators.go index daa7406e..a69accf9 100644 --- a/cmd/valcli/validators.go +++ b/cmd/valcli/validators.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "fmt" + "cosmossdk.io/math" "github.com/urfave/cli" "github.com/babylonchain/btc-validator/proto" @@ -56,6 +57,11 @@ var createValCmd = cli.Command{ Name: keyringDirFlag, Usage: "The directory where the keyring is stored", }, + cli.StringFlag{ + Name: commissionRateFlag, + Usage: "The commission rate for the validator, e.g., 0.05", + Value: "0.05", + }, cli.StringFlag{ Name: monikerFlag, Usage: "A human-readable name for the validator", @@ -103,6 +109,11 @@ func createVal(ctx *cli.Context) error { return err } + commissionRate, err := math.LegacyNewDecFromStr(ctx.String(commissionRateFlag)) + if err != nil { + return err + } + if krController.ValidatorKeyNameTaken() { return fmt.Errorf("the key name %s is taken", krController.GetKeyName()) } @@ -112,11 +123,18 @@ func createVal(ctx *cli.Context) error { return err } - validator, err := krController.CreateBTCValidator(&description) + btcPk, bbnPk, err := krController.CreateValidatorKeys() if err != nil { return err } + pop, err := krController.CreatePop() + if err != nil { + return err + } + + validator := val.NewStoreValidator(bbnPk, btcPk, krController.GetKeyName(), pop, &description, &commissionRate) + vs, err := getValStoreFromCtx(ctx) if err != nil { return err diff --git a/go.mod b/go.mod index 30ea8815..afddf9d5 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/babylonchain/btc-validator go 1.20 require ( - cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/math v1.0.1 github.com/avast/retry-go/v4 v4.3.3 github.com/babylonchain/babylon v0.7.1 github.com/btcsuite/btcd v0.23.5-0.20230228185050-38331963bddd @@ -11,6 +11,7 @@ require ( github.com/btcsuite/btcd/btcutil v1.1.3 github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 github.com/cometbft/cometbft v0.37.2 + github.com/cosmos/cosmos-proto v1.0.0-beta.2 github.com/cosmos/cosmos-sdk v0.47.3 github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/gogoproto v1.4.10 @@ -42,8 +43,8 @@ require ( cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.3 // indirect + cosmossdk.io/errors v1.0.0-beta.7 // indirect cosmossdk.io/log v1.1.0 // indirect - cosmossdk.io/math v1.0.1 // indirect cosmossdk.io/tools/rosetta v0.2.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -83,7 +84,6 @@ require ( github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v0.20.0 // indirect github.com/cosmos/ibc-go/v7 v7.2.0 // indirect diff --git a/itest/e2e_test.go b/itest/e2e_test.go index 236871cb..10251ae3 100644 --- a/itest/e2e_test.go +++ b/itest/e2e_test.go @@ -18,7 +18,6 @@ import ( "github.com/stretchr/testify/require" "github.com/babylonchain/btc-validator/clientcontroller" - "github.com/babylonchain/btc-validator/proto" "github.com/babylonchain/btc-validator/service" "github.com/babylonchain/btc-validator/types" "github.com/babylonchain/btc-validator/val" @@ -221,12 +220,7 @@ func TestDoubleSigning(t *testing.T) { require.NoError(t, err) require.True(t, localKey.Key.Equals(&extractedKey.Key) || localKey.Key.Negate().Equals(&extractedKey.Key)) - // try to submit another signature and should get error due to being slashed already - _, _, err = valIns.TestSubmitFinalitySignatureAndExtractPrivKey(b) - require.ErrorIs(t, err, types.ErrValidatorSlashed) - - tm.WaitForValStopped(t, valIns.GetBabylonPk()) - require.Equal(t, proto.ValidatorStatus_SLASHED, valIns.GetStatus()) + t.Logf("the equivocation attack is successful") } func getBtcPrivKey(kr keyring.Keyring, keyName val.KeyName) (*btcec.PrivateKey, error) { diff --git a/itest/test_manager.go b/itest/test_manager.go index 1c11a664..18417c15 100644 --- a/itest/test_manager.go +++ b/itest/test_manager.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "strconv" + "strings" "sync" "testing" "time" @@ -20,13 +21,14 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdktypes "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/relayer/v2/relayer/provider" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "github.com/babylonchain/btc-validator/clientcontroller" "github.com/babylonchain/btc-validator/service" - "github.com/babylonchain/btc-validator/testutil" "github.com/babylonchain/btc-validator/types" "github.com/babylonchain/btc-validator/valcfg" ) @@ -80,6 +82,7 @@ func StartManager(t *testing.T, isJury bool) *TestManager { bc, err := clientcontroller.NewBabylonController(bh.GetNodeDataDir(), cfg.BabylonConfig, logger) // making sure the fee is sufficient cfg.BabylonConfig.GasAdjustment = 1.5 + cfg.BabylonConfig.GasPrices = "0.1ubbn" require.NoError(t, err) valApp, err := service.NewValidatorAppFromConfig(cfg, logger, bc) @@ -113,12 +116,17 @@ func StartManagerWithValidator(t *testing.T, n int, isJury bool) *TestManager { tm := StartManager(t, isJury) app := tm.Va - var newValName = "test-val-" + var ( + valNamePrefix = "test-val-" + monikerPrefix = "moniker-" + ) for i := 0; i < n; i++ { - newValName += strconv.Itoa(i) - _, err := app.CreateValidator(newValName, testutil.EmptyDescription()) + valName := valNamePrefix + strconv.Itoa(i) + moniker := monikerPrefix + strconv.Itoa(i) + commission := sdktypes.OneDec() + _, err := app.CreateValidator(valName, newDescription(moniker), &commission) require.NoError(t, err) - _, bbnPk, err := app.RegisterValidator(newValName) + _, bbnPk, err := app.RegisterValidator(valName) require.NoError(t, err) err = app.StartHandlingValidator(bbnPk) require.NoError(t, err) @@ -126,6 +134,30 @@ func StartManagerWithValidator(t *testing.T, n int, isJury bool) *TestManager { require.NoError(t, err) require.True(t, valIns.IsRunning()) require.NoError(t, err) + + // check validators on Babylon side + require.Eventually(t, func() bool { + vals, err := tm.BabylonClient.QueryValidators() + if err != nil { + t.Logf("failed to query validtors from Babylon %s", err.Error()) + return false + } + + if len(vals) != i+1 { + return false + } + + for _, v := range vals { + if !strings.Contains(v.Description.Moniker, monikerPrefix) { + return false + } + if !v.Commission.Equal(sdktypes.OneDec()) { + return false + } + } + + return true + }, eventuallyWaitTimeOut, eventuallyPollTime) } require.Equal(t, n, len(app.ListValidatorInstances())) @@ -527,3 +559,8 @@ func tempDirWithName(name string) (string, error) { return tempName, nil } + +func newDescription(moniker string) *stakingtypes.Description { + dec := stakingtypes.NewDescription(moniker, "", "", "", "") + return &dec +} diff --git a/proto/validators.pb.go b/proto/validators.pb.go index 4854020a..ba2522ef 100644 --- a/proto/validators.pb.go +++ b/proto/validators.pb.go @@ -7,6 +7,7 @@ package proto import ( + _ "github.com/cosmos/cosmos-proto" types "github.com/cosmos/cosmos-sdk/x/staking/types" _ "github.com/cosmos/gogoproto/gogoproto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -192,6 +193,9 @@ type CreateValidatorRequest struct { KeyName string `protobuf:"bytes,1,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` // description defines the description terms for the validator Description *types.Description `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // commission defines the commission rate for the validator + // TODO failed to use the customized type: github.com/cosmos/cosmos-sdk/types.Dec + Commission string `protobuf:"bytes,3,opt,name=commission,proto3" json:"commission,omitempty"` } func (x *CreateValidatorRequest) Reset() { @@ -240,6 +244,13 @@ func (x *CreateValidatorRequest) GetDescription() *types.Description { return nil } +func (x *CreateValidatorRequest) GetCommission() string { + if x != nil { + return x.Commission + } + return "" +} + type CreateValidatorResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -716,20 +727,23 @@ type StoreValidator struct { BtcPk []byte `protobuf:"bytes,2,opt,name=btc_pk,json=btcPk,proto3" json:"btc_pk,omitempty"` // description defines the description terms for the validator Description *types.Description `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // commission defines the commission rate for the validator + // TODO failed to use the customized type: github.com/cosmos/cosmos-sdk/types.Dec + Commission string `protobuf:"bytes,4,opt,name=commission,proto3" json:"commission,omitempty"` // pop is the proof of possession of babylon_pk and btc_pk - Pop *ProofOfPossession `protobuf:"bytes,4,opt,name=pop,proto3" json:"pop,omitempty"` + Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` // key_name is the identifier of the keyring - KeyName string `protobuf:"bytes,5,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` + KeyName string `protobuf:"bytes,6,opt,name=key_name,json=keyName,proto3" json:"key_name,omitempty"` // last_voted_height defines the height of the last voted Babylon block - LastVotedHeight uint64 `protobuf:"varint,6,opt,name=last_voted_height,json=lastVotedHeight,proto3" json:"last_voted_height,omitempty"` + LastVotedHeight uint64 `protobuf:"varint,7,opt,name=last_voted_height,json=lastVotedHeight,proto3" json:"last_voted_height,omitempty"` // last_committed_height defines the height of the last Babylon block // to which the validator committed a randomness pair - LastCommittedHeight uint64 `protobuf:"varint,7,opt,name=last_committed_height,json=lastCommittedHeight,proto3" json:"last_committed_height,omitempty"` + LastCommittedHeight uint64 `protobuf:"varint,8,opt,name=last_committed_height,json=lastCommittedHeight,proto3" json:"last_committed_height,omitempty"` // last_processed_height defines the height of the last successfully processed block // even though the vote is not cast - LastProcessedHeight uint64 `protobuf:"varint,8,opt,name=last_processed_height,json=lastProcessedHeight,proto3" json:"last_processed_height,omitempty"` + LastProcessedHeight uint64 `protobuf:"varint,9,opt,name=last_processed_height,json=lastProcessedHeight,proto3" json:"last_processed_height,omitempty"` // status defines the current validator status - Status ValidatorStatus `protobuf:"varint,9,opt,name=status,proto3,enum=proto.ValidatorStatus" json:"status,omitempty"` + Status ValidatorStatus `protobuf:"varint,10,opt,name=status,proto3,enum=proto.ValidatorStatus" json:"status,omitempty"` } func (x *StoreValidator) Reset() { @@ -785,6 +799,13 @@ func (x *StoreValidator) GetDescription() *types.Description { return nil } +func (x *StoreValidator) GetCommission() string { + if x != nil { + return x.Commission + } + return "" +} + func (x *StoreValidator) GetPop() *ProofOfPossession { if x != nil { return x.Pop @@ -839,13 +860,16 @@ type ValidatorInfo struct { BtcPkHex string `protobuf:"bytes,2,opt,name=btc_pk_hex,json=btcPkHex,proto3" json:"btc_pk_hex,omitempty"` // description defines the description terms for the validator Description *types.Description `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // commission defines the commission rate for the validator + // TODO failed to use the customized type: github.com/cosmos/cosmos-sdk/types.Dec + Commission string `protobuf:"bytes,4,opt,name=commission,proto3" json:"commission,omitempty"` // last_voted_height defines the height of the last voted Babylon block - LastVotedHeight uint64 `protobuf:"varint,4,opt,name=last_voted_height,json=lastVotedHeight,proto3" json:"last_voted_height,omitempty"` + LastVotedHeight uint64 `protobuf:"varint,5,opt,name=last_voted_height,json=lastVotedHeight,proto3" json:"last_voted_height,omitempty"` // last_committed_height defines the height of the last Babylon block // to which the validator committed a randomness pair - LastCommittedHeight uint64 `protobuf:"varint,5,opt,name=last_committed_height,json=lastCommittedHeight,proto3" json:"last_committed_height,omitempty"` + LastCommittedHeight uint64 `protobuf:"varint,6,opt,name=last_committed_height,json=lastCommittedHeight,proto3" json:"last_committed_height,omitempty"` // status defines the current validator status - Status ValidatorStatus `protobuf:"varint,6,opt,name=status,proto3,enum=proto.ValidatorStatus" json:"status,omitempty"` + Status ValidatorStatus `protobuf:"varint,7,opt,name=status,proto3,enum=proto.ValidatorStatus" json:"status,omitempty"` } func (x *ValidatorInfo) Reset() { @@ -901,6 +925,13 @@ func (x *ValidatorInfo) GetDescription() *types.Description { return nil } +func (x *ValidatorInfo) GetCommission() string { + if x != nil { + return x.Commission + } + return "" +} + func (x *ValidatorInfo) GetLastVotedHeight() uint64 { if x != nil { return x.LastVotedHeight @@ -1046,88 +1077,101 @@ var file_validators_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x10, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2b, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x7a, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, - 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, - 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x4f, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, - 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x5f, 0x70, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x50, 0x6b, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x74, - 0x63, 0x5f, 0x70, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x74, 0x63, 0x50, - 0x6b, 0x22, 0x35, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, - 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x34, 0x0a, 0x19, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x10, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x2b, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0xd4, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, + 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x0a, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x38, 0xda, 0xde, 0x1f, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, + 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x4f, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x5f, 0x70, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x50, 0x6b, + 0x12, 0x15, 0x0a, 0x06, 0x62, 0x74, 0x63, 0x5f, 0x70, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x62, 0x74, 0x63, 0x50, 0x6b, 0x22, 0x35, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x34, + 0x0a, 0x19, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, + 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, + 0x48, 0x61, 0x73, 0x68, 0x22, 0x7e, 0x0a, 0x1b, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x5f, 0x70, + 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, + 0x50, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x61, + 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x48, 0x61, 0x73, 0x68, 0x22, 0x83, 0x01, 0x0a, 0x1c, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0x7e, - 0x0a, 0x1b, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x5f, 0x70, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x50, 0x6b, 0x12, 0x16, 0x0a, 0x06, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, - 0x6c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x48, 0x61, 0x73, 0x68, 0x22, 0x83, - 0x01, 0x0a, 0x1c, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x28, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x72, - 0x61, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x6b, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x53, 0x6b, 0x48, - 0x65, 0x78, 0x12, 0x20, 0x0a, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x73, 0x6b, 0x5f, 0x68, - 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x53, - 0x6b, 0x48, 0x65, 0x78, 0x22, 0x36, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x5f, 0x70, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x50, 0x6b, 0x22, 0x4c, 0x0a, 0x16, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x1b, 0x0a, 0x19, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x52, 0x0a, 0x1a, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x98, 0x03, 0x0a, 0x0e, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, - 0x0a, 0x0a, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x5f, 0x70, 0x6b, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x50, 0x6b, 0x12, 0x15, 0x0a, - 0x06, 0x62, 0x74, 0x63, 0x5f, 0x70, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, - 0x74, 0x63, 0x50, 0x6b, 0x12, 0x45, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x03, 0x70, - 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x28, + 0x0a, 0x10, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x6b, 0x5f, 0x68, + 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x65, 0x64, 0x53, 0x6b, 0x48, 0x65, 0x78, 0x12, 0x20, 0x0a, 0x0c, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x73, 0x6b, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x6b, 0x48, 0x65, 0x78, 0x22, 0x36, 0x0a, 0x15, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x5f, 0x70, + 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, + 0x50, 0x6b, 0x22, 0x4c, 0x0a, 0x16, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x09, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x22, 0x1b, 0x0a, 0x19, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x52, 0x0a, + 0x1a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x73, 0x22, 0xf2, 0x03, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x5f, + 0x70, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, + 0x6e, 0x50, 0x6b, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x74, 0x63, 0x5f, 0x70, 0x6b, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x74, 0x63, 0x50, 0x6b, 0x12, 0x45, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x58, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xda, 0xde, 0x1f, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x65, + 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, + 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x03, 0x70, + 0x6f, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x50, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x70, 0x6f, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, + 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x64, - 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6c, + 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, - 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6c, + 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x73, 0x73, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xaa, 0x02, 0x0a, 0x0d, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x84, 0x03, 0x0a, 0x0d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x5f, 0x70, 0x6b, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x50, 0x6b, 0x48, 0x65, 0x78, 0x12, 0x1c, @@ -1137,71 +1181,76 @@ var file_validators_proto_rawDesc = []byte{ 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x76, 0x6f, 0x74, 0x65, - 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, - 0x6c, 0x61, 0x73, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, - 0x32, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, - 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, - 0x6c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x22, 0x4d, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x50, 0x6f, - 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x62, 0x79, - 0x6c, 0x6f, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, - 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x74, 0x63, - 0x5f, 0x73, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x74, 0x63, 0x53, - 0x69, 0x67, 0x22, 0x47, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, 0x72, 0x52, 0x61, 0x6e, - 0x64, 0x50, 0x61, 0x69, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x75, 0x62, 0x5f, 0x72, 0x61, 0x6e, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x75, 0x62, 0x52, 0x61, 0x6e, 0x64, - 0x12, 0x19, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x73, 0x65, 0x63, 0x52, 0x61, 0x6e, 0x64, 0x2a, 0x9f, 0x01, 0x0a, 0x0f, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x18, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x1a, 0x0b, 0x8a, 0x9d, - 0x20, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x52, 0x45, 0x47, - 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x0e, 0x8a, 0x9d, 0x20, 0x0a, 0x52, - 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x43, 0x54, - 0x49, 0x56, 0x45, 0x10, 0x02, 0x1a, 0x0a, 0x8a, 0x9d, 0x20, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, - 0x45, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x03, 0x1a, - 0x0c, 0x8a, 0x9d, 0x20, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x12, 0x18, 0x0a, - 0x07, 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x10, 0x04, 0x1a, 0x0b, 0x8a, 0x9d, 0x20, 0x07, - 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, 0x44, 0x1a, 0x04, 0x88, 0xa3, 0x1e, 0x00, 0x32, 0xfe, 0x03, - 0x0a, 0x0d, 0x42, 0x74, 0x63, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, - 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x52, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, - 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, - 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, - 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x62, - 0x79, 0x6c, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x62, 0x74, 0x63, 0x2d, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xda, 0xde, 0x1f, 0x26, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, + 0x63, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, + 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x56, 0x6f, + 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x61, 0x73, + 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x2e, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x4d, 0x0a, + 0x11, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x50, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x5f, 0x73, 0x69, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, + 0x53, 0x69, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x74, 0x63, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x74, 0x63, 0x53, 0x69, 0x67, 0x22, 0x47, 0x0a, 0x0f, + 0x53, 0x63, 0x68, 0x6e, 0x6f, 0x72, 0x72, 0x52, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x69, 0x72, 0x12, + 0x19, 0x0a, 0x08, 0x70, 0x75, 0x62, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x70, 0x75, 0x62, 0x52, 0x61, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x65, + 0x63, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x65, + 0x63, 0x52, 0x61, 0x6e, 0x64, 0x2a, 0x9f, 0x01, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x52, 0x45, + 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x1a, 0x0b, 0x8a, 0x9d, 0x20, 0x07, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x45, + 0x44, 0x10, 0x01, 0x1a, 0x0e, 0x8a, 0x9d, 0x20, 0x0a, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, + 0x52, 0x45, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x1a, + 0x0a, 0x8a, 0x9d, 0x20, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x12, 0x1a, 0x0a, 0x08, 0x49, + 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x03, 0x1a, 0x0c, 0x8a, 0x9d, 0x20, 0x08, 0x49, + 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x4c, 0x41, 0x53, 0x48, + 0x45, 0x44, 0x10, 0x04, 0x1a, 0x0b, 0x8a, 0x9d, 0x20, 0x07, 0x53, 0x4c, 0x41, 0x53, 0x48, 0x45, + 0x44, 0x1a, 0x04, 0x88, 0xa3, 0x1e, 0x00, 0x32, 0xfe, 0x03, 0x0a, 0x0d, 0x42, 0x74, 0x63, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x47, 0x65, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, + 0x14, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, + 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, + 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, + 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4c, + 0x69, 0x73, 0x74, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x2f, 0x62, 0x74, 0x63, 0x2d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/validators.proto b/proto/validators.proto index 4b7e19f0..ae79fb41 100644 --- a/proto/validators.proto +++ b/proto/validators.proto @@ -4,6 +4,7 @@ package proto; import "gogoproto/gogo.proto"; import "cosmos/staking/v1beta1/staking.proto"; +import "cosmos_proto/cosmos.proto"; option go_package = "github.com/babylonchain/btc-validator/proto"; @@ -44,6 +45,12 @@ message CreateValidatorRequest { string key_name = 1; // description defines the description terms for the validator cosmos.staking.v1beta1.Description description = 2; + // commission defines the commission rate for the validator + // TODO failed to use the customized type: github.com/cosmos/cosmos-sdk/types.Dec + string commission = 3 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec" + ]; } message CreateValidatorResponse { @@ -106,20 +113,26 @@ message StoreValidator { bytes btc_pk = 2; // description defines the description terms for the validator cosmos.staking.v1beta1.Description description = 3; + // commission defines the commission rate for the validator + // TODO failed to use the customized type: github.com/cosmos/cosmos-sdk/types.Dec + string commission = 4 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec" + ]; // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 4; + ProofOfPossession pop = 5; // key_name is the identifier of the keyring - string key_name = 5; + string key_name = 6; // last_voted_height defines the height of the last voted Babylon block - uint64 last_voted_height = 6; + uint64 last_voted_height = 7; // last_committed_height defines the height of the last Babylon block // to which the validator committed a randomness pair - uint64 last_committed_height = 7; + uint64 last_committed_height = 8; // last_processed_height defines the height of the last successfully processed block // even though the vote is not cast - uint64 last_processed_height = 8; + uint64 last_processed_height = 9; // status defines the current validator status - ValidatorStatus status = 9; + ValidatorStatus status = 10; } // ValidatorInfo is the basic information of a validator mainly for external usage @@ -130,13 +143,19 @@ message ValidatorInfo { string btc_pk_hex = 2; // description defines the description terms for the validator cosmos.staking.v1beta1.Description description = 3; + // commission defines the commission rate for the validator + // TODO failed to use the customized type: github.com/cosmos/cosmos-sdk/types.Dec + string commission = 4 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec" + ]; // last_voted_height defines the height of the last voted Babylon block - uint64 last_voted_height = 4; + uint64 last_voted_height = 5; // last_committed_height defines the height of the last Babylon block // to which the validator committed a randomness pair - uint64 last_committed_height = 5; + uint64 last_committed_height = 6; // status defines the current validator status - ValidatorStatus status = 6; + ValidatorStatus status = 7; } // ProofOfPossession is the proof of possession that a Babylon secp256k1 diff --git a/service/app.go b/service/app.go index d1b0ee51..7239f3d8 100644 --- a/service/app.go +++ b/service/app.go @@ -4,11 +4,13 @@ import ( "fmt" "sync" + "cosmossdk.io/math" bbntypes "github.com/babylonchain/babylon/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdktypes "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/sirupsen/logrus" @@ -152,11 +154,17 @@ func (app *ValidatorApp) RegisterValidator(keyName string) (*RegisterValidatorRe BtcSigType: bstypes.BTCSigType_BIP340, } + commissionRate, err := math.LegacyNewDecFromStr(validator.Commission) + if err != nil { + return nil, nil, err + } + request := ®isterValidatorRequest{ bbnPubKey: validator.GetBabylonPK(), btcPubKey: validator.MustGetBIP340BTCPK(), pop: pop, description: validator.Description, + commission: &commissionRate, errResponse: make(chan error, 1), successResponse: make(chan *RegisterValidatorResponse, 1), } @@ -426,10 +434,11 @@ func (app *ValidatorApp) Stop() error { return stopErr } -func (app *ValidatorApp) CreateValidator(keyName string, description *stakingtypes.Description) (*CreateValidatorResult, error) { +func (app *ValidatorApp) CreateValidator(keyName string, description *stakingtypes.Description, commission *sdktypes.Dec) (*CreateValidatorResult, error) { req := &createValidatorRequest{ keyName: keyName, description: description, + commission: commission, errResponse: make(chan error, 1), successResponse: make(chan *createValidatorResponse, 1), } @@ -469,11 +478,18 @@ func (app *ValidatorApp) handleCreateValidatorRequest(req *createValidatorReques // TODO should not expose direct proto here, as this is internal db representation // connected to serialization - validator, err := kr.CreateBTCValidator(req.description) + btcPk, bbnPk, err := kr.CreateValidatorKeys() if err != nil { return nil, fmt.Errorf("failed to create validator: %w", err) } + pop, err := kr.CreatePop() + if err != nil { + return nil, fmt.Errorf("failed to create proof-of-possession of the validator: %w", err) + } + + validator := val.NewStoreValidator(bbnPk, btcPk, kr.GetKeyName(), pop, req.description, req.commission) + if err := app.vs.SaveValidator(validator); err != nil { return nil, fmt.Errorf("failed to save validator: %w", err) } diff --git a/service/app_test.go b/service/app_test.go index 1566b42c..411b0bcf 100644 --- a/service/app_test.go +++ b/service/app_test.go @@ -15,7 +15,6 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - ctrl "github.com/babylonchain/btc-validator/clientcontroller" "github.com/babylonchain/btc-validator/proto" "github.com/babylonchain/btc-validator/service" "github.com/babylonchain/btc-validator/testutil" @@ -63,14 +62,12 @@ func FuzzRegisterValidator(f *testing.F) { } txHash := testutil.GenRandomHexStr(r, 32) - defaultParams := ctrl.StakingParams{} - mockClientController.EXPECT().GetStakingParams().Return(&defaultParams, nil) mockClientController.EXPECT(). RegisterValidator( validator.GetBabylonPK(), validator.MustGetBIP340BTCPK(), pop, - defaultParams.MinComissionRate, + testutil.ZeroCommissionRate(), testutil.EmptyDescription(), ).Return(&provider.RelayerTxResponse{TxHash: txHash}, nil).AnyTimes() diff --git a/service/client/rpcclient.go b/service/client/rpcclient.go index 3d9cadbd..fa2b2777 100644 --- a/service/client/rpcclient.go +++ b/service/client/rpcclient.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + sdktypes "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -50,8 +51,8 @@ func (c *ValidatorServiceGRpcClient) RegisterValidator(ctx context.Context, keyN return res, nil } -func (c *ValidatorServiceGRpcClient) CreateValidator(ctx context.Context, keyName string, description *stakingtypes.Description) (*proto.CreateValidatorResponse, error) { - req := &proto.CreateValidatorRequest{KeyName: keyName, Description: description} +func (c *ValidatorServiceGRpcClient) CreateValidator(ctx context.Context, keyName string, description *stakingtypes.Description, commission *sdktypes.Dec) (*proto.CreateValidatorResponse, error) { + req := &proto.CreateValidatorRequest{KeyName: keyName, Description: description, Commission: commission.String()} res, err := c.client.CreateValidator(ctx, req) if err != nil { return nil, err diff --git a/service/event_loop.go b/service/event_loop.go index f1ca258f..afd0e7ba 100644 --- a/service/event_loop.go +++ b/service/event_loop.go @@ -130,23 +130,10 @@ func (app *ValidatorApp) handleSentToBabylonLoop() { for { select { case req := <-app.registerValidatorRequestChan: - params, err := app.cc.GetStakingParams() - - if err != nil { - app.logger.WithFields(logrus.Fields{ - "err": err, - "bbnPubKey": hex.EncodeToString(req.bbnPubKey.Key), - "btcPubKey": req.btcPubKey.MarshalHex(), - }).Error("failed to get staking params") - req.errResponse <- err - continue - } - // we won't do any retries here to not block the loop for more important messages. // Most probably it fails due so some user error so we just return the error to the user. // TODO: need to start passing context here to be able to cancel the request in case of app quiting - // TODO: for now use minimum commission rate, but ultimately it should be configurable - res, err := app.cc.RegisterValidator(req.bbnPubKey, req.btcPubKey, req.pop, params.MinComissionRate, req.description) + res, err := app.cc.RegisterValidator(req.bbnPubKey, req.btcPubKey, req.pop, req.commission, req.description) if err != nil { app.logger.WithFields(logrus.Fields{ diff --git a/service/rpcserver.go b/service/rpcserver.go index c5bd6ac0..f6c449fb 100644 --- a/service/rpcserver.go +++ b/service/rpcserver.go @@ -7,6 +7,8 @@ import ( "sync" "sync/atomic" + "cosmossdk.io/math" + bbntypes "github.com/babylonchain/babylon/types" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/lightningnetwork/lnd/signal" @@ -102,16 +104,21 @@ func (r *rpcServer) GetInfo(context.Context, *proto.GetInfoRequest) (*proto.GetI // CreateValidator generates a validator object and saves it in the database func (r *rpcServer) CreateValidator(ctx context.Context, req *proto.CreateValidatorRequest) ( *proto.CreateValidatorResponse, error) { - result, err := r.app.CreateValidator(req.KeyName, req.Description) + commissionRate, err := math.LegacyNewDecFromStr(req.Commission) if err != nil { return nil, err } + result, err := r.app.CreateValidator(req.KeyName, req.Description, &commissionRate) - btcPk := schnorr.SerializePubKey(&result.BtcValidatorPk) + if err != nil { + return nil, err + } + + btcPk := bbntypes.BIP340PubKey(schnorr.SerializePubKey(&result.BtcValidatorPk)) return &proto.CreateValidatorResponse{ - BtcPk: hex.EncodeToString(btcPk), + BtcPk: btcPk.MarshalHex(), BabylonPk: hex.EncodeToString(result.BabylonValidatorPk.Key), }, nil diff --git a/service/types.go b/service/types.go index dcf358e6..ad61dd7f 100644 --- a/service/types.go +++ b/service/types.go @@ -5,6 +5,7 @@ import ( btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdktypes "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -15,6 +16,7 @@ type createValidatorResponse struct { type createValidatorRequest struct { keyName string description *stakingtypes.Description + commission *sdktypes.Dec errResponse chan error successResponse chan *createValidatorResponse } @@ -25,6 +27,7 @@ type registerValidatorRequest struct { // TODO we should have our own representation of PoP pop *btcstakingtypes.ProofOfPossession description *stakingtypes.Description + commission *sdktypes.Dec errResponse chan error successResponse chan *RegisterValidatorResponse } diff --git a/service/validator_instance.go b/service/validator_instance.go index 0596b5d0..624030a8 100644 --- a/service/validator_instance.go +++ b/service/validator_instance.go @@ -1030,32 +1030,12 @@ func (v *ValidatorInstance) signEotsSig(b *types.BlockInfo) (*bbntypes.SchnorrEO // this API is the same as SubmitFinalitySignature except that we don't constraint the voting height and update status // Note: this should not be used in the submission loop func (v *ValidatorInstance) TestSubmitFinalitySignatureAndExtractPrivKey(b *types.BlockInfo) (*provider.RelayerTxResponse, *btcec.PrivateKey, error) { - btcPk := v.GetBtcPkBIP340() - // check last committed height if v.GetLastCommittedHeight() < b.Height { return nil, nil, fmt.Errorf("the validator's last committed height %v is lower than the current block height %v", v.GetLastCommittedHeight(), b.Height) } - // check voting power - power, err := v.cc.QueryValidatorVotingPower(btcPk, b.Height) - if err != nil { - return nil, nil, fmt.Errorf("failed to query the consumer chain for the validator's voting power: %w", err) - } - if power == 0 { - if v.GetStatus() == proto.ValidatorStatus_ACTIVE { - // the validator is slashed or unbonded from the consumer chain - v.MustSetStatus(proto.ValidatorStatus_INACTIVE) - } - v.logger.WithFields(logrus.Fields{ - "btc_pk_hex": btcPk.MarshalHex(), - "block_height": b.Height, - }).Debug("the validator's voting power is 0, skip voting") - - return nil, nil, nil - } - eotsSig, err := v.signEotsSig(b) if err != nil { return nil, nil, err diff --git a/testutil/datagen.go b/testutil/datagen.go index 917ee653..73808347 100644 --- a/testutil/datagen.go +++ b/testutil/datagen.go @@ -89,9 +89,14 @@ func GenStoredValidator(r *rand.Rand, t *testing.T, app *service.ValidatorApp) * require.NoError(t, err) // create validator using the keyring - validator, err := kc.CreateBTCValidator(EmptyDescription()) + btcPk, bbnPk, err := kc.CreateValidatorKeys() require.NoError(t, err) + pop, err := kc.CreatePop() + require.NoError(t, err) + + validator := val.NewStoreValidator(bbnPk, btcPk, kc.GetKeyName(), pop, EmptyDescription(), ZeroCommissionRate()) + // save the validator s := app.GetValidatorStore() err = s.SaveValidator(validator) diff --git a/testutil/mocks/babylon.go b/testutil/mocks/babylon.go index 58026af7..41b71dba 100644 --- a/testutil/mocks/babylon.go +++ b/testutil/mocks/babylon.go @@ -252,7 +252,7 @@ func (mr *MockClientControllerMockRecorder) QueryValidatorVotingPower(btcPubKey, } // RegisterValidator mocks base method. -func (m *MockClientController) RegisterValidator(bbnPubKey *secp256k1.PubKey, btcPubKey *types.BIP340PubKey, pop *types0.ProofOfPossession, commission types2.Dec, description *types3.Description) (*provider.RelayerTxResponse, error) { +func (m *MockClientController) RegisterValidator(bbnPubKey *secp256k1.PubKey, btcPubKey *types.BIP340PubKey, pop *types0.ProofOfPossession, commission *types2.Dec, description *types3.Description) (*provider.RelayerTxResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RegisterValidator", bbnPubKey, btcPubKey, pop, commission, description) ret0, _ := ret[0].(*provider.RelayerTxResponse) diff --git a/testutil/utils.go b/testutil/utils.go index 9003d951..05200486 100644 --- a/testutil/utils.go +++ b/testutil/utils.go @@ -6,6 +6,7 @@ import ( coretypes "github.com/cometbft/cometbft/rpc/core/types" cometbfttypes "github.com/cometbft/cometbft/types" + sdktypes "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/golang/mock/gomock" @@ -16,6 +17,11 @@ func EmptyDescription() *stakingtypes.Description { return &stakingtypes.Description{} } +func ZeroCommissionRate() *sdktypes.Dec { + zeroCom := sdktypes.ZeroDec() + return &zeroCom +} + func PrepareMockedClientController(t *testing.T, r *rand.Rand, startHeight, currentHeight uint64) *mocks.MockClientController { ctl := gomock.NewController(t) mockClientController := mocks.NewMockClientController(ctl) diff --git a/val/keyringcontroller.go b/val/keyringcontroller.go index 2aecf10c..e2a71341 100644 --- a/val/keyringcontroller.go +++ b/val/keyringcontroller.go @@ -10,10 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/go-bip39" - - "github.com/babylonchain/btc-validator/proto" ) const ( @@ -73,27 +70,21 @@ func NewKeyringControllerWithKeyring(kr keyring.Keyring, name string) (*KeyringC }, nil } -// CreateBTCValidator creates a BTC validator object using the keyring -func (kc *KeyringController) CreateBTCValidator(des *stakingtypes.Description) (*proto.StoreValidator, error) { +// CreateValidatorKeys creates a BTC validator object using the keyring +func (kc *KeyringController) CreateValidatorKeys() (*types.BIP340PubKey, *secp256k1.PubKey, error) { // create babylon key pair stored in the keyring babylonPubKey, err := kc.createBabylonKeyPair() if err != nil { - return nil, err + return nil, nil, err } // create BTC key pair stored in the keyring btcPubKey, err := kc.createBIP340KeyPair() if err != nil { - return nil, err - } - - // create proof of possession - pop, err := kc.createPop() - if err != nil { - return nil, err + return nil, nil, err } - return NewStoreValidator(babylonPubKey, btcPubKey, kc.GetKeyName(), pop, des), nil + return btcPubKey, babylonPubKey, nil } func (kc *KeyringController) GetKeyName() string { @@ -200,10 +191,10 @@ func (kc *KeyringController) createKey(name string) (*secp256k1.PubKey, error) { } } -// createPop creates proof-of-possession of Babylon and BTC public keys +// CreatePop creates proof-of-possession of Babylon and BTC public keys // the input is the bytes of BTC public key used to sign // this requires both keys created beforehand -func (kc *KeyringController) createPop() (*bstypes.ProofOfPossession, error) { +func (kc *KeyringController) CreatePop() (*bstypes.ProofOfPossession, error) { if !kc.ValidatorKeyExists() { return nil, fmt.Errorf("the keys do not exist") } diff --git a/val/keyringcontroller_test.go b/val/keyringcontroller_test.go index eb12467f..424cfb4a 100644 --- a/val/keyringcontroller_test.go +++ b/val/keyringcontroller_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/babylonchain/babylon/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/stretchr/testify/require" "github.com/babylonchain/btc-validator/testutil" @@ -30,22 +29,17 @@ func FuzzCreatePoP(f *testing.F) { require.NoError(t, err) require.False(t, kc.ValidatorKeyExists()) - validator, err := kc.CreateBTCValidator(testutil.EmptyDescription()) + btcPk, bbnPk, err := kc.CreateValidatorKeys() require.NoError(t, err) require.True(t, kc.ValidatorKeyExists() && kc.ValidatorKeyNameTaken()) - // TODO avoid conversion after btcstaking protos are introduced - btcPk := validator.MustGetBIP340BTCPK() - bbnPk := validator.GetBabylonPK() + pop, err := kc.CreatePop() + require.NoError(t, err) + validator := val.NewStoreValidator(bbnPk, btcPk, kc.GetKeyName(), pop, testutil.EmptyDescription(), testutil.ZeroCommissionRate()) + btcSig := new(types.BIP340Signature) err = btcSig.Unmarshal(validator.Pop.BtcSig) require.NoError(t, err) - pop := &bstypes.ProofOfPossession{ - BabylonSig: validator.Pop.BabylonSig, - BtcSig: btcSig.MustMarshal(), - BtcSigType: bstypes.BTCSigType_BIP340, - } - err = pop.Verify(bbnPk, btcPk) require.NoError(t, err) }) diff --git a/val/valstore.go b/val/valstore.go index 0a44ee9c..b81570bb 100644 --- a/val/valstore.go +++ b/val/valstore.go @@ -21,7 +21,7 @@ const ( randPairPrefix = "rand-pair" ) -func NewStoreValidator(babylonPk *secp256k1.PubKey, btcPk *types.BIP340PubKey, keyName string, pop *bstypes.ProofOfPossession, des *stakingtypes.Description) *proto.StoreValidator { +func NewStoreValidator(babylonPk *secp256k1.PubKey, btcPk *types.BIP340PubKey, keyName string, pop *bstypes.ProofOfPossession, des *stakingtypes.Description, com *sdktypes.Dec) *proto.StoreValidator { return &proto.StoreValidator{ KeyName: keyName, BabylonPk: babylonPk.Bytes(), @@ -32,6 +32,7 @@ func NewStoreValidator(babylonPk *secp256k1.PubKey, btcPk *types.BIP340PubKey, k }, Status: proto.ValidatorStatus_CREATED, Description: des, + Commission: com.String(), } }