From dde076d626a575ff810b51968211c1da1d57f876 Mon Sep 17 00:00:00 2001 From: samliok Date: Wed, 4 Jun 2025 21:17:36 -0700 Subject: [PATCH 01/19] add simplex pkg and bls structs --- simplex/bls.go | 127 ++++++++++++++++++++++++++++++++++++++++++ simplex/bls_test.go | 133 ++++++++++++++++++++++++++++++++++++++++++++ simplex/config.go | 33 +++++++++++ 3 files changed, 293 insertions(+) create mode 100644 simplex/bls.go create mode 100644 simplex/bls_test.go create mode 100644 simplex/config.go diff --git a/simplex/bls.go b/simplex/bls.go new file mode 100644 index 000000000000..7fa125d81434 --- /dev/null +++ b/simplex/bls.go @@ -0,0 +1,127 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex + +import ( + "encoding/asn1" + "errors" + "fmt" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/simplex" +) + +var ( + errSignatureVerificationFailed = errors.New("signature verification failed") + errSignerNotFound = errors.New("signer not found in the membership set") +) + +var _ simplex.Signer = (*BLSSigner)(nil) + +type SignFunc func(msg []byte) (*bls.Signature, error) + +// BLSSigner signs messages encoded with the provided ChainID and NetworkID +// using the SignBLS function. +type BLSSigner struct { + chainID ids.ID + subnetID ids.ID + // signBLS is passed in because we support both software and hardware BLS signing. + signBLS SignFunc + nodeID ids.NodeID +} + +type BLSVerifier struct { + nodeID2PK map[ids.NodeID]bls.PublicKey + subnetID ids.ID + chainID ids.ID +} + +func NewBLSAuth(config *Config) (BLSSigner, BLSVerifier) { + return BLSSigner{ + chainID: config.Ctx.ChainID, + subnetID: config.Ctx.SubnetID, + nodeID: config.Ctx.NodeID, + signBLS: config.SignBLS, + }, createVerifier(config) +} + +// Sign returns a signature on the given message using BLS signature scheme. +// It encodes the message to sign with the chain ID, and subnet ID, +func (s *BLSSigner) Sign(message []byte) ([]byte, error) { + message2Sign, err := encodeMessageToSign(message, s.chainID, s.subnetID) + if err != nil { + return nil, fmt.Errorf("failed to encode message to sign: %w", err) + } + + sig, err := s.signBLS(message2Sign) + if err != nil { + return nil, err + } + + sigBytes := bls.SignatureToBytes(sig) + return sigBytes, nil +} + +type encodedSimplexMessage struct { + Message []byte + ChainID []byte + SubnetID []byte +} + +// encodesMessageToSign returns a byte slice [simplexLabel][chainID][networkID][message length][message]. +func encodeMessageToSign(message []byte, chainID ids.ID, subnetID ids.ID) ([]byte, error) { + encodedSimplexMessage := encodedSimplexMessage{ + Message: message, + ChainID: chainID[:], + SubnetID: subnetID[:], + } + return asn1.Marshal(encodedSimplexMessage) +} + +func (v BLSVerifier) Verify(message []byte, signature []byte, signer simplex.NodeID) error { + if len(signer) != ids.NodeIDLen { + return fmt.Errorf("expected signer to be %d bytes but got %d bytes", ids.NodeIDLen, len(signer)) + } + + key := ids.NodeID(signer) + pk, exists := v.nodeID2PK[key] + if !exists { + return fmt.Errorf("%w: signer %x", errSignerNotFound, key) + } + + sig, err := bls.SignatureFromBytes(signature) + if err != nil { + return fmt.Errorf("failed to parse signature: %w", err) + } + + message2Verify, err := encodeMessageToSign(message, v.chainID, v.subnetID) + if err != nil { + return fmt.Errorf("failed to encode message to verify: %w", err) + } + + if !bls.Verify(&pk, sig, message2Verify) { + return errSignatureVerificationFailed + } + + return nil +} + +func createVerifier(config *Config) BLSVerifier { + verifier := BLSVerifier{ + nodeID2PK: make(map[ids.NodeID]bls.PublicKey), + subnetID: config.Ctx.SubnetID, + chainID: config.Ctx.ChainID, + } + + nodes := config.Validators.GetValidatorIDs(config.Ctx.SubnetID) + for _, node := range nodes { + validator, ok := config.Validators.GetValidator(config.Ctx.SubnetID, node) + if !ok { + continue + } + verifier.nodeID2PK[node] = *validator.PublicKey + } + return verifier +} diff --git a/simplex/bls_test.go b/simplex/bls_test.go new file mode 100644 index 000000000000..74dc3b5d0deb --- /dev/null +++ b/simplex/bls_test.go @@ -0,0 +1,133 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex + +import ( + "testing" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" + "github.com/stretchr/testify/require" +) + +var _ ValidatorInfo = (*testValidatorInfo)(nil) + +// testValidatorInfo is a mock implementation of ValidatorInfo for testing purposes. +// it assumes all validators are in the same subnet and returns all of them for any subnetID. +type testValidatorInfo struct { + validators map[ids.NodeID]validators.Validator +} + +func (v *testValidatorInfo) GetValidatorIDs(_ ids.ID) []ids.NodeID { + if v.validators == nil { + return nil + } + + ids := make([]ids.NodeID, 0, len(v.validators)) + for id := range v.validators { + ids = append(ids, id) + } + return ids +} + +func (v *testValidatorInfo) GetValidator(_ ids.ID, nodeID ids.NodeID) (*validators.Validator, bool) { + if v.validators == nil { + return nil, false + } + + val, exists := v.validators[nodeID] + if !exists { + return nil, false + } + return &val, true +} + +func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) *testValidatorInfo { + if len(nodeIds) != len(pks) { + panic("nodeIds and pks must have the same length") + } + + vds := make(map[ids.NodeID]validators.Validator, len(pks)) + for i, pk := range pks { + validator := validators.Validator{ + PublicKey: pk, + NodeID: nodeIds[i], + } + vds[nodeIds[i]] = validator + } + // all we need is to generate the public keys for the validators + return &testValidatorInfo{ + validators: vds, + } +} + +func newEngineConfig(ls *localsigner.LocalSigner) *Config { + nodeID := ids.GenerateTestNodeID() + + simplexChainContext := SimplexChainContext{ + NodeID: nodeID, + ChainID: ids.GenerateTestID(), + SubnetID: ids.GenerateTestID(), + } + + return &Config{ + Ctx: simplexChainContext, + Validators: newTestValidatorInfo([]ids.NodeID{nodeID}, []*bls.PublicKey{ls.PublicKey()}), + SignBLS: ls.Sign, + } +} + +func TestBLSSignVerify(t *testing.T) { + ls, err := localsigner.New() + require.NoError(t, err) + + config := newEngineConfig(ls) + + signer, verifier := NewBLSAuth(config) + + msg := "Begin at the beginning, and go on till you come to the end: then stop" + + sig, err := signer.Sign([]byte(msg)) + require.NoError(t, err) + + err = verifier.Verify([]byte(msg), sig, signer.nodeID[:]) + require.NoError(t, err) +} + +func TestSignerNotInMemberSet(t *testing.T) { + ls, err := localsigner.New() + require.NoError(t, err) + + config := newEngineConfig(ls) + signer, verifier := NewBLSAuth(config) + + msg := "Begin at the beginning, and go on till you come to the end: then stop" + + sig, err := signer.Sign([]byte(msg)) + require.NoError(t, err) + + notInMembershipSet := ids.GenerateTestNodeID() + err = verifier.Verify([]byte(msg), sig, notInMembershipSet[:]) + require.ErrorIs(t, err, errSignerNotFound) +} + +func TestSignerInvalidMessageEncoding(t *testing.T) { + ls, err := localsigner.New() + require.NoError(t, err) + + config := newEngineConfig(ls) + + // sign a message with invalid encoding + dummyMsg := []byte("dummy message") + sig, err := ls.Sign(dummyMsg) + require.NoError(t, err) + + sigBytes := bls.SignatureToBytes(sig) + + _, verifier := NewBLSAuth(config) + err = verifier.Verify(dummyMsg, sigBytes, config.Ctx.NodeID[:]) + require.ErrorIs(t, err, errSignatureVerificationFailed) +} diff --git a/simplex/config.go b/simplex/config.go new file mode 100644 index 000000000000..97e72e0f2efc --- /dev/null +++ b/simplex/config.go @@ -0,0 +1,33 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex + +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/logging" +) + +type ValidatorInfo interface { + GetValidatorIDs(subnetID ids.ID) []ids.NodeID + GetValidator(subnetID ids.ID, nodeID ids.NodeID) (*validators.Validator, bool) +} + +// Config wraps all the parameters needed for a simplex engine +type Config struct { + Ctx SimplexChainContext + Log logging.Logger + Validators ValidatorInfo + SignBLS SignFunc +} + +// Context is information about the current execution. +// [SubnitID] is the ID of the subnet this context exists within. +// [ChainID] is the ID of the chain this context exists within. +// [NodeID] is the ID of this node +type SimplexChainContext struct { + NodeID ids.NodeID + ChainID ids.ID + SubnetID ids.ID +} From c5be0a4459dd4c09f7d7c362a2b6052bc58c81fa Mon Sep 17 00:00:00 2001 From: samliok Date: Thu, 5 Jun 2025 10:26:54 -0700 Subject: [PATCH 02/19] add simplex to go mod + lint --- go.mod | 1 + go.sum | 2 ++ simplex/bls.go | 14 ++++++++------ simplex/bls_test.go | 5 +++-- simplex/config.go | 4 ++-- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 1b43e438972c..8b9ffb89a875 100644 --- a/go.mod +++ b/go.mod @@ -85,6 +85,7 @@ require ( github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect + github.com/ava-labs/simplex v0.0.0-20250605162940-db8e6d44f53d github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect diff --git a/go.sum b/go.sum index b686626c524e..cddaf16b2fd9 100644 --- a/go.sum +++ b/go.sum @@ -74,6 +74,8 @@ github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60 h1:EL github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60/go.mod h1:/7qKobTfbzBu7eSTVaXMTr56yTYk4j2Px6/8G+idxHo= github.com/ava-labs/libevm v1.13.14-0.2.0.release h1:uKGCc5/ceeBbfAPRVtBUxbQt50WzB2pEDb8Uy93ePgQ= github.com/ava-labs/libevm v1.13.14-0.2.0.release/go.mod h1:+Iol+sVQ1KyoBsHf3veyrBmHCXr3xXRWq6ZXkgVfNLU= +github.com/ava-labs/simplex v0.0.0-20250605162940-db8e6d44f53d h1:D/BOS3USdAigun2OP/6khvukKnn4BIKviYAdKLHN6zc= +github.com/ava-labs/simplex v0.0.0-20250605162940-db8e6d44f53d/go.mod h1:GVzumIo3zR23/qGRN2AdnVkIPHcKMq/D89EGWZfMGQ0= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= diff --git a/simplex/bls.go b/simplex/bls.go index 7fa125d81434..f767dba21651 100644 --- a/simplex/bls.go +++ b/simplex/bls.go @@ -8,28 +8,29 @@ import ( "errors" "fmt" + "github.com/ava-labs/simplex" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/simplex" ) var ( errSignatureVerificationFailed = errors.New("signature verification failed") errSignerNotFound = errors.New("signer not found in the membership set") + simplexLabel = []byte("simplex") ) var _ simplex.Signer = (*BLSSigner)(nil) type SignFunc func(msg []byte) (*bls.Signature, error) -// BLSSigner signs messages encoded with the provided ChainID and NetworkID +// BLSSigner signs messages encoded with the provided ChainID and SubnetID. // using the SignBLS function. type BLSSigner struct { chainID ids.ID subnetID ids.ID // signBLS is passed in because we support both software and hardware BLS signing. signBLS SignFunc - nodeID ids.NodeID } type BLSVerifier struct { @@ -42,7 +43,6 @@ func NewBLSAuth(config *Config) (BLSSigner, BLSVerifier) { return BLSSigner{ chainID: config.Ctx.ChainID, subnetID: config.Ctx.SubnetID, - nodeID: config.Ctx.NodeID, signBLS: config.SignBLS, }, createVerifier(config) } @@ -64,18 +64,20 @@ func (s *BLSSigner) Sign(message []byte) ([]byte, error) { return sigBytes, nil } -type encodedSimplexMessage struct { +type encodedSimplexSignedPayload struct { Message []byte ChainID []byte SubnetID []byte + Label []byte } // encodesMessageToSign returns a byte slice [simplexLabel][chainID][networkID][message length][message]. func encodeMessageToSign(message []byte, chainID ids.ID, subnetID ids.ID) ([]byte, error) { - encodedSimplexMessage := encodedSimplexMessage{ + encodedSimplexMessage := encodedSimplexSignedPayload{ Message: message, ChainID: chainID[:], SubnetID: subnetID[:], + Label: simplexLabel, } return asn1.Marshal(encodedSimplexMessage) } diff --git a/simplex/bls_test.go b/simplex/bls_test.go index 74dc3b5d0deb..8797866e03c8 100644 --- a/simplex/bls_test.go +++ b/simplex/bls_test.go @@ -6,11 +6,12 @@ package simplex import ( "testing" + "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" - "github.com/stretchr/testify/require" ) var _ ValidatorInfo = (*testValidatorInfo)(nil) @@ -93,7 +94,7 @@ func TestBLSSignVerify(t *testing.T) { sig, err := signer.Sign([]byte(msg)) require.NoError(t, err) - err = verifier.Verify([]byte(msg), sig, signer.nodeID[:]) + err = verifier.Verify([]byte(msg), sig, config.Ctx.NodeID[:]) require.NoError(t, err) } diff --git a/simplex/config.go b/simplex/config.go index 97e72e0f2efc..8e16e26e3e99 100644 --- a/simplex/config.go +++ b/simplex/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package simplex @@ -23,7 +23,7 @@ type Config struct { } // Context is information about the current execution. -// [SubnitID] is the ID of the subnet this context exists within. +// [SubnetID] is the ID of the subnet this context exists within. // [ChainID] is the ID of the chain this context exists within. // [NodeID] is the ID of this node type SimplexChainContext struct { From 5de26b1fbee3bf4958a4ab4922059111748b1e0d Mon Sep 17 00:00:00 2001 From: samliok Date: Thu, 5 Jun 2025 13:16:07 -0700 Subject: [PATCH 03/19] added comm, writing tests --- .../messagemock/outbound_message_builder.go | 106 +++++++ message/outbound_msg_builder.go | 2 + message/simplex_outbound_msg_builder.go | 295 ++++++++++++++++++ simplex/comm.go | 121 +++++++ simplex/comm_test.go | 35 +++ simplex/config.go | 5 + 6 files changed, 564 insertions(+) create mode 100644 message/simplex_outbound_msg_builder.go create mode 100644 simplex/comm.go create mode 100644 simplex/comm_test.go diff --git a/message/messagemock/outbound_message_builder.go b/message/messagemock/outbound_message_builder.go index 89794619de73..456f08619fd9 100644 --- a/message/messagemock/outbound_message_builder.go +++ b/message/messagemock/outbound_message_builder.go @@ -18,6 +18,7 @@ import ( message "github.com/ava-labs/avalanchego/message" p2p "github.com/ava-labs/avalanchego/proto/pb/p2p" ips "github.com/ava-labs/avalanchego/utils/ips" + simplex "github.com/ava-labs/simplex" gomock "go.uber.org/mock/gomock" ) @@ -165,6 +166,21 @@ func (mr *OutboundMsgBuilderMockRecorder) AppResponse(chainID, requestID, msg an return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*OutboundMsgBuilder)(nil).AppResponse), chainID, requestID, msg) } +// BlockProposal mocks base method. +func (m *OutboundMsgBuilder) BlockProposal(chainID ids.ID, block []byte, vote simplex.Vote) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BlockProposal", chainID, block, vote) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BlockProposal indicates an expected call of BlockProposal. +func (mr *OutboundMsgBuilderMockRecorder) BlockProposal(chainID, block, vote any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockProposal", reflect.TypeOf((*OutboundMsgBuilder)(nil).BlockProposal), chainID, block, vote) +} + // Chits mocks base method. func (m *OutboundMsgBuilder) Chits(chainID ids.ID, requestID uint32, preferredID, preferredIDAtHeight, acceptedID ids.ID, acceptedHeight uint64) (message.OutboundMessage, error) { m.ctrl.T.Helper() @@ -180,6 +196,66 @@ func (mr *OutboundMsgBuilderMockRecorder) Chits(chainID, requestID, preferredID, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chits", reflect.TypeOf((*OutboundMsgBuilder)(nil).Chits), chainID, requestID, preferredID, preferredIDAtHeight, acceptedID, acceptedHeight) } +// EmptyNotarization mocks base method. +func (m *OutboundMsgBuilder) EmptyNotarization(chainID ids.ID, protocolMetadata simplex.ProtocolMetadata, qc []byte) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EmptyNotarization", chainID, protocolMetadata, qc) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EmptyNotarization indicates an expected call of EmptyNotarization. +func (mr *OutboundMsgBuilderMockRecorder) EmptyNotarization(chainID, protocolMetadata, qc any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmptyNotarization", reflect.TypeOf((*OutboundMsgBuilder)(nil).EmptyNotarization), chainID, protocolMetadata, qc) +} + +// EmptyVote mocks base method. +func (m *OutboundMsgBuilder) EmptyVote(chainID ids.ID, protocolMetadata simplex.ProtocolMetadata, signature simplex.Signature) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EmptyVote", chainID, protocolMetadata, signature) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EmptyVote indicates an expected call of EmptyVote. +func (mr *OutboundMsgBuilderMockRecorder) EmptyVote(chainID, protocolMetadata, signature any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmptyVote", reflect.TypeOf((*OutboundMsgBuilder)(nil).EmptyVote), chainID, protocolMetadata, signature) +} + +// Finalization mocks base method. +func (m *OutboundMsgBuilder) Finalization(chainID ids.ID, blockHeader simplex.BlockHeader, qc []byte) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Finalization", chainID, blockHeader, qc) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Finalization indicates an expected call of Finalization. +func (mr *OutboundMsgBuilderMockRecorder) Finalization(chainID, blockHeader, qc any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Finalization", reflect.TypeOf((*OutboundMsgBuilder)(nil).Finalization), chainID, blockHeader, qc) +} + +// FinalizeVote mocks base method. +func (m *OutboundMsgBuilder) FinalizeVote(chainID ids.ID, blockHeader simplex.BlockHeader, signature simplex.Signature) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FinalizeVote", chainID, blockHeader, signature) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FinalizeVote indicates an expected call of FinalizeVote. +func (mr *OutboundMsgBuilderMockRecorder) FinalizeVote(chainID, blockHeader, signature any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinalizeVote", reflect.TypeOf((*OutboundMsgBuilder)(nil).FinalizeVote), chainID, blockHeader, signature) +} + // Get mocks base method. func (m *OutboundMsgBuilder) Get(chainID ids.ID, requestID uint32, deadline time.Duration, containerID ids.ID) (message.OutboundMessage, error) { m.ctrl.T.Helper() @@ -300,6 +376,21 @@ func (mr *OutboundMsgBuilderMockRecorder) Handshake(networkID, myTime, ip, clien return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*OutboundMsgBuilder)(nil).Handshake), networkID, myTime, ip, client, major, minor, patch, ipSigningTime, ipNodeIDSig, ipBLSSig, trackedSubnets, supportedACPs, objectedACPs, knownPeersFilter, knownPeersSalt, requestAllSubnetIPs) } +// Notarization mocks base method. +func (m *OutboundMsgBuilder) Notarization(chainID ids.ID, blockHeader simplex.BlockHeader, qc []byte) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Notarization", chainID, blockHeader, qc) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Notarization indicates an expected call of Notarization. +func (mr *OutboundMsgBuilderMockRecorder) Notarization(chainID, blockHeader, qc any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Notarization", reflect.TypeOf((*OutboundMsgBuilder)(nil).Notarization), chainID, blockHeader, qc) +} + // PeerList mocks base method. func (m *OutboundMsgBuilder) PeerList(peers []*ips.ClaimedIPPort, bypassThrottling bool) (message.OutboundMessage, error) { m.ctrl.T.Helper() @@ -404,3 +495,18 @@ func (mr *OutboundMsgBuilderMockRecorder) StateSummaryFrontier(chainID, requestI mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSummaryFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).StateSummaryFrontier), chainID, requestID, summary) } + +// Vote mocks base method. +func (m *OutboundMsgBuilder) Vote(chainID ids.ID, blockHeader simplex.BlockHeader, signature simplex.Signature) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Vote", chainID, blockHeader, signature) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Vote indicates an expected call of Vote. +func (mr *OutboundMsgBuilderMockRecorder) Vote(chainID, blockHeader, signature any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Vote", reflect.TypeOf((*OutboundMsgBuilder)(nil).Vote), chainID, blockHeader, signature) +} diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index 042236c81482..52bca0a67e98 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -181,6 +181,8 @@ type OutboundMsgBuilder interface { chainID ids.ID, msg []byte, ) (OutboundMessage, error) + + SimplexOutboundMessageBuilder } type outMsgBuilder struct { diff --git a/message/simplex_outbound_msg_builder.go b/message/simplex_outbound_msg_builder.go new file mode 100644 index 000000000000..43daef3d5a23 --- /dev/null +++ b/message/simplex_outbound_msg_builder.go @@ -0,0 +1,295 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package message + +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/proto/pb/p2p" + "github.com/ava-labs/simplex" +) + +type SimplexOutboundMessageBuilder interface { + BlockProposal( + chainID ids.ID, + block []byte, + vote simplex.Vote, + ) (OutboundMessage, error) + + Vote( + chainID ids.ID, + blockHeader simplex.BlockHeader, + signature simplex.Signature, + ) (OutboundMessage, error) + + EmptyVote( + chainID ids.ID, + protocolMetadata simplex.ProtocolMetadata, + signature simplex.Signature, + ) (OutboundMessage, error) + + FinalizeVote( + chainID ids.ID, + blockHeader simplex.BlockHeader, + signature simplex.Signature, + ) (OutboundMessage, error) + + Notarization( + chainID ids.ID, + blockHeader simplex.BlockHeader, + qc []byte, + ) (OutboundMessage, error) + + EmptyNotarization( + chainID ids.ID, + protocolMetadata simplex.ProtocolMetadata, + qc []byte, + ) (OutboundMessage, error) + + Finalization( + chainID ids.ID, + blockHeader simplex.BlockHeader, + qc []byte, + ) (OutboundMessage, error) +} + + +func (b *outMsgBuilder) BlockProposal( + chainID ids.ID, + block []byte, + vote simplex.Vote, +) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.Simplex{ + ChainId: chainID[:], + Message: &p2p.Simplex_BlockProposal{ + BlockProposal: &p2p.BlockProposal{ + Block: block, + Vote: &p2p.Vote{ + Vote: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(vote.Vote.Version), + Epoch: vote.Vote.Epoch, + Round: vote.Vote.Round, + Seq: vote.Vote.Seq, + Prev: vote.Vote.Prev[:], + }, + Digest: vote.Vote.Digest[:], + }, + Signature: &p2p.Signature{ + Signer: vote.Signature.Signer[:], + Value: vote.Signature.Value[:], + }, + }, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) Vote( + chainID ids.ID, + blockHeader simplex.BlockHeader, + signature simplex.Signature, +) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.Simplex{ + ChainId: chainID[:], + Message: &p2p.Simplex_Vote{ + Vote: &p2p.Vote{ + Vote: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(blockHeader.Version), + Epoch: blockHeader.Epoch, + Round: blockHeader.Round, + Seq: blockHeader.Seq, + Prev: blockHeader.Prev[:], + }, + Digest: blockHeader.Digest[:], + }, + Signature: &p2p.Signature{ + Signer: signature.Signer[:], + Value: signature.Value[:], + }, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) EmptyVote( + chainID ids.ID, + protocolMetadata simplex.ProtocolMetadata, + signature simplex.Signature, +) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.Simplex{ + ChainId: chainID[:], + Message: &p2p.Simplex_EmptyVote{ + EmptyVote: &p2p.EmptyVote{ + Vote: &p2p.ProtocolMetadata{ + Version: uint32(protocolMetadata.Version), + Epoch: protocolMetadata.Epoch, + Round: protocolMetadata.Round, + Seq: protocolMetadata.Seq, + Prev: protocolMetadata.Prev[:], + }, + Signature: &p2p.Signature{ + Signer: signature.Signer[:], + Value: signature.Value[:], + }, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) FinalizeVote( + chainID ids.ID, + blockHeader simplex.BlockHeader, + signature simplex.Signature, +) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.Simplex{ + ChainId: chainID[:], + Message: &p2p.Simplex_FinalizeVote{ + FinalizeVote: &p2p.Vote{ + Vote: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(blockHeader.Version), + Epoch: blockHeader.Epoch, + Round: blockHeader.Round, + Seq: blockHeader.Seq, + Prev: blockHeader.Prev[:], + }, + Digest: blockHeader.Digest[:], + }, + Signature: &p2p.Signature{ + Signer: signature.Signer[:], + Value: signature.Value[:], + }, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) Notarization( + chainID ids.ID, + blockHeader simplex.BlockHeader, + qc []byte, +) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.Simplex{ + ChainId: chainID[:], + Message: &p2p.Simplex_Notarization{ + Notarization: &p2p.QuorumCertificate{ + Finalization: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(blockHeader.Version), + Epoch: blockHeader.Epoch, + Round: blockHeader.Round, + Seq: blockHeader.Seq, + Prev: blockHeader.Prev[:], + }, + Digest: blockHeader.Digest[:], + }, + QuorumCertificate: qc, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) EmptyNotarization( + chainID ids.ID, + protocolMetadata simplex.ProtocolMetadata, + qc []byte, +) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.Simplex{ + ChainId: chainID[:], + Message: &p2p.Simplex_EmptyNotarization{ + EmptyNotarization: &p2p.EmptyNotarization{ + EmptyVote: &p2p.ProtocolMetadata{ + Version: uint32(protocolMetadata.Version), + Epoch: protocolMetadata.Epoch, + Round: protocolMetadata.Round, + Seq: protocolMetadata.Seq, + Prev: protocolMetadata.Prev[:], + }, + QuorumCertificate: qc, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) Finalization( + chainID ids.ID, + blockHeader simplex.BlockHeader, + qc []byte, +) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.Simplex{ + ChainId: chainID[:], + Message: &p2p.Simplex_Finalization{ + Finalization: &p2p.QuorumCertificate{ + Finalization: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(blockHeader.Version), + Epoch: blockHeader.Epoch, + Round: blockHeader.Round, + Seq: blockHeader.Seq, + Prev: blockHeader.Prev[:], + }, + Digest: blockHeader.Digest[:], + }, + QuorumCertificate: qc, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} \ No newline at end of file diff --git a/simplex/comm.go b/simplex/comm.go new file mode 100644 index 000000000000..cf69f4540710 --- /dev/null +++ b/simplex/comm.go @@ -0,0 +1,121 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex + +import ( + "errors" + "fmt" + "sort" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/message" + "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/networking/sender" + "github.com/ava-labs/avalanchego/subnets" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/simplex" + "go.uber.org/zap" +) + +var ( + errNodeNotFound = errors.New("node not found in the validator list") +) + +type Comm struct { + logger simplex.Logger + subnetID ids.ID + chainID ids.ID + // nodeID is this nodes ID + nodeID simplex.NodeID + // nodes are the IDs of all the nodes in the subnet + nodes []simplex.NodeID + // sender is used to send messages to other nodes + sender sender.ExternalSender + msgBuilder message.SimplexOutboundMessageBuilder +} + +func NewComm(config *Config) (*Comm, error) { + var nodes []simplex.NodeID + // grab all the nodes that are validators for the subnet + for _, id := range config.Validators.GetValidatorIDs(config.Ctx.SubnetID) { + nodes = append(nodes, id[:]) + } + + sortedNodes := sortNodes(nodes) + + var found bool + for _, node := range sortedNodes { + if node.Equals(config.Ctx.NodeID[:]) { + found = true + break + } + } + + if !found { + return nil, fmt.Errorf("%w: %s", errNodeNotFound, config.Ctx.NodeID) + } + + c := &Comm{ + subnetID: config.Ctx.SubnetID, + nodes: sortedNodes, + nodeID: config.Ctx.NodeID[:], + logger: config.Log, + sender: config.Sender, + msgBuilder: config.OutboundMsgBuilder, + chainID: config.Ctx.ChainID, + } + + return c, nil +} + +func sortNodes(nodes []simplex.NodeID) []simplex.NodeID { + sort.Slice(nodes, func(i, j int) bool { + return nodes[i].String() < nodes[j].String() + }) + return nodes +} + +func (c *Comm) ListNodes() []simplex.NodeID { + return c.nodes +} + +func (c *Comm) SendMessage(msg *simplex.Message, destination simplex.NodeID) { + var outboundMessage message.OutboundMessage + var err error + switch { + case msg.VerifiedBlockMessage != nil: + outboundMessage, err = c.msgBuilder.BlockProposal(c.chainID, msg.VerifiedBlockMessage.VerifiedBlock.Bytes(), msg.VerifiedBlockMessage.Vote) + case msg.VoteMessage != nil: + outboundMessage, err = c.msgBuilder.Vote(c.chainID, msg.VoteMessage.Vote.BlockHeader, msg.VoteMessage.Signature) + case msg.EmptyVoteMessage != nil: + outboundMessage, err = c.msgBuilder.EmptyVote(c.chainID, msg.EmptyVoteMessage.Vote.ProtocolMetadata, msg.EmptyVoteMessage.Signature) + case msg.FinalizeVote != nil: + outboundMessage, err = c.msgBuilder.FinalizeVote(c.chainID, msg.FinalizeVote.Finalization.BlockHeader, msg.FinalizeVote.Signature) + case msg.Notarization != nil: + outboundMessage, err = c.msgBuilder.Notarization(c.chainID, msg.Notarization.Vote.BlockHeader, msg.Notarization.QC.Bytes()) + case msg.EmptyNotarization != nil: + outboundMessage, err = c.msgBuilder.EmptyNotarization(c.chainID, msg.EmptyNotarization.Vote.ProtocolMetadata, msg.EmptyNotarization.QC.Bytes()) + case msg.Finalization != nil: + outboundMessage, err = c.msgBuilder.Finalization(c.chainID, msg.Finalization.Finalization.BlockHeader, msg.Finalization.QC.Bytes()) + } + + if err != nil { + c.logger.Error("Failed creating message: %w", zap.Error(err)) + return + } + + dest := ids.NodeID(destination) + + c.sender.Send(outboundMessage, common.SendConfig{NodeIDs: set.Of(dest)}, c.subnetID, subnets.NoOpAllower) +} + +func (c *Comm) Broadcast(msg *simplex.Message) { + for _, node := range c.nodes { + if node.Equals(c.nodeID) { + continue + } + + c.SendMessage(msg, node) + } +} diff --git a/simplex/comm_test.go b/simplex/comm_test.go new file mode 100644 index 000000000000..15b6956f921f --- /dev/null +++ b/simplex/comm_test.go @@ -0,0 +1,35 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex + +import ( + "testing" + + "github.com/ava-labs/avalanchego/message/messagemock" + "github.com/ava-labs/avalanchego/snow/networking/sender/sendermock" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" +) + +func TestComm(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + msgCreator := messagemock.NewOutboundMsgBuilder(ctrl) + sender := sendermock.NewExternalSender(ctrl) + + comm, err := NewComm(&Config{ + { + + }) + +} + +func TestCommBroadcast(){ + +} + +func TestCommFailsWithoutCurrentNode() { + +} \ No newline at end of file diff --git a/simplex/config.go b/simplex/config.go index 8e16e26e3e99..34dff772c3a4 100644 --- a/simplex/config.go +++ b/simplex/config.go @@ -5,6 +5,8 @@ package simplex import ( "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/message" + "github.com/ava-labs/avalanchego/snow/networking/sender" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/logging" ) @@ -20,6 +22,9 @@ type Config struct { Log logging.Logger Validators ValidatorInfo SignBLS SignFunc + + Sender sender.ExternalSender + OutboundMsgBuilder message.SimplexOutboundMessageBuilder } // Context is information about the current execution. From 52d343ebca586d51ac348456d92b7dea903142b9 Mon Sep 17 00:00:00 2001 From: samliok Date: Thu, 5 Jun 2025 13:17:46 -0700 Subject: [PATCH 04/19] add log to createVerifier --- simplex/bls.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/simplex/bls.go b/simplex/bls.go index f767dba21651..e7b1ce25259c 100644 --- a/simplex/bls.go +++ b/simplex/bls.go @@ -9,6 +9,7 @@ import ( "fmt" "github.com/ava-labs/simplex" + "go.uber.org/zap" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -121,6 +122,7 @@ func createVerifier(config *Config) BLSVerifier { for _, node := range nodes { validator, ok := config.Validators.GetValidator(config.Ctx.SubnetID, node) if !ok { + config.Log.Error("failed to get validator for node %s in subnet %s", zap.Stringer("node", node), zap.Stringer("subnetID", config.Ctx.SubnetID)) continue } verifier.nodeID2PK[node] = *validator.PublicKey From 3f740242c9282abedab1194998c0c598f682042b Mon Sep 17 00:00:00 2001 From: samliok Date: Thu, 5 Jun 2025 14:08:03 -0700 Subject: [PATCH 05/19] add comm tests --- message/simplex_outbound_msg_builder.go | 93 ++++++++++++------------ simplex/bls_test.go | 84 +-------------------- simplex/comm.go | 3 + simplex/comm_test.go | 84 ++++++++++++++++++--- simplex/test_utils.go | 97 +++++++++++++++++++++++++ 5 files changed, 222 insertions(+), 139 deletions(-) create mode 100644 simplex/test_utils.go diff --git a/message/simplex_outbound_msg_builder.go b/message/simplex_outbound_msg_builder.go index 43daef3d5a23..832c6620bf1c 100644 --- a/message/simplex_outbound_msg_builder.go +++ b/message/simplex_outbound_msg_builder.go @@ -53,7 +53,6 @@ type SimplexOutboundMessageBuilder interface { ) (OutboundMessage, error) } - func (b *outMsgBuilder) BlockProposal( chainID ids.ID, block []byte, @@ -63,31 +62,31 @@ func (b *outMsgBuilder) BlockProposal( &p2p.Message{ Message: &p2p.Message_Simplex{ Simplex: &p2p.Simplex{ - ChainId: chainID[:], - Message: &p2p.Simplex_BlockProposal{ - BlockProposal: &p2p.BlockProposal{ - Block: block, - Vote: &p2p.Vote{ - Vote: &p2p.BlockHeader{ - Metadata: &p2p.ProtocolMetadata{ - Version: uint32(vote.Vote.Version), - Epoch: vote.Vote.Epoch, - Round: vote.Vote.Round, - Seq: vote.Vote.Seq, - Prev: vote.Vote.Prev[:], + ChainId: chainID[:], + Message: &p2p.Simplex_BlockProposal{ + BlockProposal: &p2p.BlockProposal{ + Block: block, + Vote: &p2p.Vote{ + Vote: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(vote.Vote.Version), + Epoch: vote.Vote.Epoch, + Round: vote.Vote.Round, + Seq: vote.Vote.Seq, + Prev: vote.Vote.Prev[:], + }, + Digest: vote.Vote.Digest[:], + }, + Signature: &p2p.Signature{ + Signer: vote.Signature.Signer[:], + Value: vote.Signature.Value[:], }, - Digest: vote.Vote.Digest[:], - }, - Signature: &p2p.Signature{ - Signer: vote.Signature.Signer[:], - Value: vote.Signature.Value[:], }, }, }, }, }, }, - }, b.compressionType, false, ) @@ -108,16 +107,16 @@ func (b *outMsgBuilder) Vote( Vote: &p2p.BlockHeader{ Metadata: &p2p.ProtocolMetadata{ Version: uint32(blockHeader.Version), - Epoch: blockHeader.Epoch, - Round: blockHeader.Round, - Seq: blockHeader.Seq, - Prev: blockHeader.Prev[:], + Epoch: blockHeader.Epoch, + Round: blockHeader.Round, + Seq: blockHeader.Seq, + Prev: blockHeader.Prev[:], }, Digest: blockHeader.Digest[:], }, Signature: &p2p.Signature{ Signer: signature.Signer[:], - Value: signature.Value[:], + Value: signature.Value[:], }, }, }, @@ -143,14 +142,14 @@ func (b *outMsgBuilder) EmptyVote( EmptyVote: &p2p.EmptyVote{ Vote: &p2p.ProtocolMetadata{ Version: uint32(protocolMetadata.Version), - Epoch: protocolMetadata.Epoch, - Round: protocolMetadata.Round, - Seq: protocolMetadata.Seq, - Prev: protocolMetadata.Prev[:], + Epoch: protocolMetadata.Epoch, + Round: protocolMetadata.Round, + Seq: protocolMetadata.Seq, + Prev: protocolMetadata.Prev[:], }, Signature: &p2p.Signature{ Signer: signature.Signer[:], - Value: signature.Value[:], + Value: signature.Value[:], }, }, }, @@ -177,16 +176,16 @@ func (b *outMsgBuilder) FinalizeVote( Vote: &p2p.BlockHeader{ Metadata: &p2p.ProtocolMetadata{ Version: uint32(blockHeader.Version), - Epoch: blockHeader.Epoch, - Round: blockHeader.Round, - Seq: blockHeader.Seq, - Prev: blockHeader.Prev[:], + Epoch: blockHeader.Epoch, + Round: blockHeader.Round, + Seq: blockHeader.Seq, + Prev: blockHeader.Prev[:], }, Digest: blockHeader.Digest[:], }, Signature: &p2p.Signature{ Signer: signature.Signer[:], - Value: signature.Value[:], + Value: signature.Value[:], }, }, }, @@ -213,10 +212,10 @@ func (b *outMsgBuilder) Notarization( Finalization: &p2p.BlockHeader{ Metadata: &p2p.ProtocolMetadata{ Version: uint32(blockHeader.Version), - Epoch: blockHeader.Epoch, - Round: blockHeader.Round, - Seq: blockHeader.Seq, - Prev: blockHeader.Prev[:], + Epoch: blockHeader.Epoch, + Round: blockHeader.Round, + Seq: blockHeader.Seq, + Prev: blockHeader.Prev[:], }, Digest: blockHeader.Digest[:], }, @@ -245,10 +244,10 @@ func (b *outMsgBuilder) EmptyNotarization( EmptyNotarization: &p2p.EmptyNotarization{ EmptyVote: &p2p.ProtocolMetadata{ Version: uint32(protocolMetadata.Version), - Epoch: protocolMetadata.Epoch, - Round: protocolMetadata.Round, - Seq: protocolMetadata.Seq, - Prev: protocolMetadata.Prev[:], + Epoch: protocolMetadata.Epoch, + Round: protocolMetadata.Round, + Seq: protocolMetadata.Seq, + Prev: protocolMetadata.Prev[:], }, QuorumCertificate: qc, }, @@ -276,10 +275,10 @@ func (b *outMsgBuilder) Finalization( Finalization: &p2p.BlockHeader{ Metadata: &p2p.ProtocolMetadata{ Version: uint32(blockHeader.Version), - Epoch: blockHeader.Epoch, - Round: blockHeader.Round, - Seq: blockHeader.Seq, - Prev: blockHeader.Prev[:], + Epoch: blockHeader.Epoch, + Round: blockHeader.Round, + Seq: blockHeader.Seq, + Prev: blockHeader.Prev[:], }, Digest: blockHeader.Digest[:], }, @@ -292,4 +291,4 @@ func (b *outMsgBuilder) Finalization( b.compressionType, false, ) -} \ No newline at end of file +} diff --git a/simplex/bls_test.go b/simplex/bls_test.go index 8797866e03c8..5552ba4ff379 100644 --- a/simplex/bls_test.go +++ b/simplex/bls_test.go @@ -9,83 +9,11 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" ) -var _ ValidatorInfo = (*testValidatorInfo)(nil) - -// testValidatorInfo is a mock implementation of ValidatorInfo for testing purposes. -// it assumes all validators are in the same subnet and returns all of them for any subnetID. -type testValidatorInfo struct { - validators map[ids.NodeID]validators.Validator -} - -func (v *testValidatorInfo) GetValidatorIDs(_ ids.ID) []ids.NodeID { - if v.validators == nil { - return nil - } - - ids := make([]ids.NodeID, 0, len(v.validators)) - for id := range v.validators { - ids = append(ids, id) - } - return ids -} - -func (v *testValidatorInfo) GetValidator(_ ids.ID, nodeID ids.NodeID) (*validators.Validator, bool) { - if v.validators == nil { - return nil, false - } - - val, exists := v.validators[nodeID] - if !exists { - return nil, false - } - return &val, true -} - -func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) *testValidatorInfo { - if len(nodeIds) != len(pks) { - panic("nodeIds and pks must have the same length") - } - - vds := make(map[ids.NodeID]validators.Validator, len(pks)) - for i, pk := range pks { - validator := validators.Validator{ - PublicKey: pk, - NodeID: nodeIds[i], - } - vds[nodeIds[i]] = validator - } - // all we need is to generate the public keys for the validators - return &testValidatorInfo{ - validators: vds, - } -} - -func newEngineConfig(ls *localsigner.LocalSigner) *Config { - nodeID := ids.GenerateTestNodeID() - - simplexChainContext := SimplexChainContext{ - NodeID: nodeID, - ChainID: ids.GenerateTestID(), - SubnetID: ids.GenerateTestID(), - } - - return &Config{ - Ctx: simplexChainContext, - Validators: newTestValidatorInfo([]ids.NodeID{nodeID}, []*bls.PublicKey{ls.PublicKey()}), - SignBLS: ls.Sign, - } -} - func TestBLSSignVerify(t *testing.T) { - ls, err := localsigner.New() - require.NoError(t, err) - - config := newEngineConfig(ls) + config, _ := newTestEngineConfig(t, 0) signer, verifier := NewBLSAuth(config) @@ -99,10 +27,7 @@ func TestBLSSignVerify(t *testing.T) { } func TestSignerNotInMemberSet(t *testing.T) { - ls, err := localsigner.New() - require.NoError(t, err) - - config := newEngineConfig(ls) + config, _ := newTestEngineConfig(t, 0) signer, verifier := NewBLSAuth(config) msg := "Begin at the beginning, and go on till you come to the end: then stop" @@ -116,10 +41,7 @@ func TestSignerNotInMemberSet(t *testing.T) { } func TestSignerInvalidMessageEncoding(t *testing.T) { - ls, err := localsigner.New() - require.NoError(t, err) - - config := newEngineConfig(ls) + config, ls := newTestEngineConfig(t, 0) // sign a message with invalid encoding dummyMsg := []byte("dummy message") diff --git a/simplex/comm.go b/simplex/comm.go index cf69f4540710..0e6a3be29e21 100644 --- a/simplex/comm.go +++ b/simplex/comm.go @@ -81,6 +81,8 @@ func (c *Comm) ListNodes() []simplex.NodeID { } func (c *Comm) SendMessage(msg *simplex.Message, destination simplex.NodeID) { + // TODO: do we want to check if the destination is in the subnet? + var outboundMessage message.OutboundMessage var err error switch { @@ -98,6 +100,7 @@ func (c *Comm) SendMessage(msg *simplex.Message, destination simplex.NodeID) { outboundMessage, err = c.msgBuilder.EmptyNotarization(c.chainID, msg.EmptyNotarization.Vote.ProtocolMetadata, msg.EmptyNotarization.QC.Bytes()) case msg.Finalization != nil: outboundMessage, err = c.msgBuilder.Finalization(c.chainID, msg.Finalization.Finalization.BlockHeader, msg.Finalization.QC.Bytes()) + // TODO: create replication messages } if err != nil { diff --git a/simplex/comm_test.go b/simplex/comm_test.go index 15b6956f921f..449c514b3b88 100644 --- a/simplex/comm_test.go +++ b/simplex/comm_test.go @@ -6,30 +6,92 @@ package simplex import ( "testing" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message/messagemock" "github.com/ava-labs/avalanchego/snow/networking/sender/sendermock" + "github.com/ava-labs/simplex" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) -func TestComm(t *testing.T) { - require := require.New(t) +var testSimplexMessage = simplex.Message{ + VoteMessage: &simplex.Vote{ + Vote: simplex.ToBeSignedVote{ + BlockHeader: simplex.BlockHeader{ + ProtocolMetadata: simplex.ProtocolMetadata{ + Version: 1, + Epoch: 1, + Round: 1, + Seq: 1, + }, + }, + }, + Signature: simplex.Signature{ + Signer: []byte("dummy_node_id"), + Value: []byte("dummy_signature"), + }, + }, +} + +func TestComm(t *testing.T) { + config, _ := newTestEngineConfig(t, 1) + destinationNodeID := ids.GenerateTestNodeID() + ctrl := gomock.NewController(t) + msgCreator := messagemock.NewOutboundMsgBuilder(ctrl) + sender := sendermock.NewExternalSender(ctrl) + + config.OutboundMsgBuilder = msgCreator + config.Sender = sender - msgCreator := messagemock.NewOutboundMsgBuilder(ctrl) - sender := sendermock.NewExternalSender(ctrl) + comm, err := NewComm(config) + require.NoError(t, err) - comm, err := NewComm(&Config{ - { - - }) + msgCreator.EXPECT().Vote(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, nil) + sender.EXPECT().Send(gomock.Any(), gomock.Any(), comm.subnetID, gomock.Any()) + comm.SendMessage(&testSimplexMessage, destinationNodeID[:]) } -func TestCommBroadcast(){ +// TestCommBroadcast tests the Broadcast method sends to all nodes in the subnet +// not including the sending node. +func TestCommBroadcast(t *testing.T) { + config, _ := newTestEngineConfig(t, 3) + + ctrl := gomock.NewController(t) + msgCreator := messagemock.NewOutboundMsgBuilder(ctrl) + sender := sendermock.NewExternalSender(ctrl) + + config.OutboundMsgBuilder = msgCreator + config.Sender = sender + comm, err := NewComm(config) + require.NoError(t, err) + + msgCreator.EXPECT().Vote(gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, nil).Times(3) + sender.EXPECT().Send(gomock.Any(), gomock.Any(), comm.subnetID, gomock.Any()).Times(3) + + comm.Broadcast(&testSimplexMessage) } -func TestCommFailsWithoutCurrentNode() { +func TestCommFailsWithoutCurrentNode(t *testing.T) { + config, _ := newTestEngineConfig(t, 3) + + ctrl := gomock.NewController(t) + msgCreator := messagemock.NewOutboundMsgBuilder(ctrl) + sender := sendermock.NewExternalSender(ctrl) -} \ No newline at end of file + config.OutboundMsgBuilder = msgCreator + config.Sender = sender + + // set the curNode to a different nodeID than the one in the config + nodeID := ids.GenerateTestNodeID() + vdrs, err := newTestValidatorInfo(nodeID, nil, 3) + require.NoError(t, err) + config.Validators = vdrs + + _, err = NewComm(config) + require.ErrorIs(t, err, errNodeNotFound) +} diff --git a/simplex/test_utils.go b/simplex/test_utils.go new file mode 100644 index 000000000000..3bfe97c91afc --- /dev/null +++ b/simplex/test_utils.go @@ -0,0 +1,97 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex + +import ( + "testing" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" + "github.com/stretchr/testify/require" +) + +var _ ValidatorInfo = (*testValidatorInfo)(nil) + +// testValidatorInfo is a mock implementation of ValidatorInfo for testing purposes. +// it assumes all validators are in the same subnet and returns all of them for any subnetID. +type testValidatorInfo struct { + validators map[ids.NodeID]validators.Validator +} + +func (v *testValidatorInfo) GetValidatorIDs(_ ids.ID) []ids.NodeID { + if v.validators == nil { + return nil + } + + ids := make([]ids.NodeID, 0, len(v.validators)) + for id := range v.validators { + ids = append(ids, id) + } + return ids +} + +func (v *testValidatorInfo) GetValidator(_ ids.ID, nodeID ids.NodeID) (*validators.Validator, bool) { + if v.validators == nil { + return nil, false + } + + val, exists := v.validators[nodeID] + if !exists { + return nil, false + } + return &val, true +} + +func newTestValidatorInfo(curNodeId ids.NodeID, curNodePk *bls.PublicKey, numExtraNodes int) (*testValidatorInfo, error) { + vds := make(map[ids.NodeID]validators.Validator, numExtraNodes+1) + + vds[curNodeId] = validators.Validator{ + PublicKey: curNodePk, + NodeID: curNodeId, + } + + for range numExtraNodes { + ls, err := localsigner.New() + nodeID := ids.GenerateTestNodeID() + if err != nil { + return nil, err + } + + validator := validators.Validator{ + PublicKey: ls.PublicKey(), + NodeID: nodeID, + } + vds[nodeID] = validator + } + + // all we need is to generate the public keys for the validators + return &testValidatorInfo{ + validators: vds, + }, nil +} + +// newTestEngineConfig returns a new simplex Config for testing purposes +// and also returns the LocalSigner associated with this nodes config. +func newTestEngineConfig(t *testing.T, numNodes int) (*Config, *localsigner.LocalSigner) { + ls, err := localsigner.New() + require.NoError(t, err) + + nodeID := ids.GenerateTestNodeID() + simplexChainContext := SimplexChainContext{ + NodeID: nodeID, + ChainID: ids.GenerateTestID(), + SubnetID: ids.GenerateTestID(), + } + + vdrs, err := newTestValidatorInfo(nodeID, ls.PublicKey(), numNodes) + require.NoError(t, err) + + return &Config{ + Ctx: simplexChainContext, + Validators: vdrs, + SignBLS: ls.Sign, + }, ls +} From 458d540ea0cf1adbcb018d7fbbe7ac86eca19345 Mon Sep 17 00:00:00 2001 From: samliok Date: Mon, 9 Jun 2025 14:35:01 -0500 Subject: [PATCH 06/19] separate into utils file --- simplex/bls_test.go | 83 +++----------------------------------------- simplex/test_util.go | 83 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 79 deletions(-) create mode 100644 simplex/test_util.go diff --git a/simplex/bls_test.go b/simplex/bls_test.go index 8797866e03c8..e5c59662b356 100644 --- a/simplex/bls_test.go +++ b/simplex/bls_test.go @@ -9,84 +9,13 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" ) -var _ ValidatorInfo = (*testValidatorInfo)(nil) - -// testValidatorInfo is a mock implementation of ValidatorInfo for testing purposes. -// it assumes all validators are in the same subnet and returns all of them for any subnetID. -type testValidatorInfo struct { - validators map[ids.NodeID]validators.Validator -} - -func (v *testValidatorInfo) GetValidatorIDs(_ ids.ID) []ids.NodeID { - if v.validators == nil { - return nil - } - - ids := make([]ids.NodeID, 0, len(v.validators)) - for id := range v.validators { - ids = append(ids, id) - } - return ids -} - -func (v *testValidatorInfo) GetValidator(_ ids.ID, nodeID ids.NodeID) (*validators.Validator, bool) { - if v.validators == nil { - return nil, false - } - - val, exists := v.validators[nodeID] - if !exists { - return nil, false - } - return &val, true -} - -func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) *testValidatorInfo { - if len(nodeIds) != len(pks) { - panic("nodeIds and pks must have the same length") - } - - vds := make(map[ids.NodeID]validators.Validator, len(pks)) - for i, pk := range pks { - validator := validators.Validator{ - PublicKey: pk, - NodeID: nodeIds[i], - } - vds[nodeIds[i]] = validator - } - // all we need is to generate the public keys for the validators - return &testValidatorInfo{ - validators: vds, - } -} - -func newEngineConfig(ls *localsigner.LocalSigner) *Config { - nodeID := ids.GenerateTestNodeID() - - simplexChainContext := SimplexChainContext{ - NodeID: nodeID, - ChainID: ids.GenerateTestID(), - SubnetID: ids.GenerateTestID(), - } - - return &Config{ - Ctx: simplexChainContext, - Validators: newTestValidatorInfo([]ids.NodeID{nodeID}, []*bls.PublicKey{ls.PublicKey()}), - SignBLS: ls.Sign, - } -} - func TestBLSSignVerify(t *testing.T) { - ls, err := localsigner.New() + config, err := newEngineConfig() require.NoError(t, err) - config := newEngineConfig(ls) - signer, verifier := NewBLSAuth(config) msg := "Begin at the beginning, and go on till you come to the end: then stop" @@ -99,10 +28,8 @@ func TestBLSSignVerify(t *testing.T) { } func TestSignerNotInMemberSet(t *testing.T) { - ls, err := localsigner.New() + config, err := newEngineConfig() require.NoError(t, err) - - config := newEngineConfig(ls) signer, verifier := NewBLSAuth(config) msg := "Begin at the beginning, and go on till you come to the end: then stop" @@ -116,14 +43,12 @@ func TestSignerNotInMemberSet(t *testing.T) { } func TestSignerInvalidMessageEncoding(t *testing.T) { - ls, err := localsigner.New() + config, err := newEngineConfig() require.NoError(t, err) - config := newEngineConfig(ls) - // sign a message with invalid encoding dummyMsg := []byte("dummy message") - sig, err := ls.Sign(dummyMsg) + sig, err := config.SignBLS(dummyMsg) require.NoError(t, err) sigBytes := bls.SignatureToBytes(sig) diff --git a/simplex/test_util.go b/simplex/test_util.go new file mode 100644 index 000000000000..e926fe686a4a --- /dev/null +++ b/simplex/test_util.go @@ -0,0 +1,83 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex + +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" +) + +var _ ValidatorInfo = (*testValidatorInfo)(nil) + +// testValidatorInfo is a mock implementation of ValidatorInfo for testing purposes. +// it assumes all validators are in the same subnet and returns all of them for any subnetID. +type testValidatorInfo struct { + validators map[ids.NodeID]validators.Validator +} + +func (v *testValidatorInfo) GetValidatorIDs(_ ids.ID) []ids.NodeID { + if v.validators == nil { + return nil + } + + ids := make([]ids.NodeID, 0, len(v.validators)) + for id := range v.validators { + ids = append(ids, id) + } + return ids +} + +func (v *testValidatorInfo) GetValidator(_ ids.ID, nodeID ids.NodeID) (*validators.Validator, bool) { + if v.validators == nil { + return nil, false + } + + val, exists := v.validators[nodeID] + if !exists { + return nil, false + } + return &val, true +} + +func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) *testValidatorInfo { + if len(nodeIds) != len(pks) { + panic("nodeIds and pks must have the same length") + } + + vds := make(map[ids.NodeID]validators.Validator, len(pks)) + for i, pk := range pks { + validator := validators.Validator{ + PublicKey: pk, + NodeID: nodeIds[i], + } + vds[nodeIds[i]] = validator + } + // all we need is to generate the public keys for the validators + return &testValidatorInfo{ + validators: vds, + } +} + +func newEngineConfig() (*Config, error) { + ls, err := localsigner.New() + if err != nil { + return nil, err + } + + nodeID := ids.GenerateTestNodeID() + + simplexChainContext := SimplexChainContext{ + NodeID: nodeID, + ChainID: ids.GenerateTestID(), + SubnetID: ids.GenerateTestID(), + } + + return &Config{ + Ctx: simplexChainContext, + Validators: newTestValidatorInfo([]ids.NodeID{nodeID}, []*bls.PublicKey{ls.PublicKey()}), + SignBLS: ls.Sign, + }, nil +} From 49aa0bbd9152938a00cd20543fd0c7bf0e89eb5f Mon Sep 17 00:00:00 2001 From: samliok Date: Tue, 10 Jun 2025 16:17:25 -0500 Subject: [PATCH 07/19] style improvements --- simplex/bls.go | 1 - simplex/test_util.go | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/simplex/bls.go b/simplex/bls.go index e7b1ce25259c..be9687e26288 100644 --- a/simplex/bls.go +++ b/simplex/bls.go @@ -72,7 +72,6 @@ type encodedSimplexSignedPayload struct { Label []byte } -// encodesMessageToSign returns a byte slice [simplexLabel][chainID][networkID][message length][message]. func encodeMessageToSign(message []byte, chainID ids.ID, subnetID ids.ID) ([]byte, error) { encodedSimplexMessage := encodedSimplexSignedPayload{ Message: message, diff --git a/simplex/test_util.go b/simplex/test_util.go index e926fe686a4a..7cbbcbaf2a2c 100644 --- a/simplex/test_util.go +++ b/simplex/test_util.go @@ -19,10 +19,6 @@ type testValidatorInfo struct { } func (v *testValidatorInfo) GetValidatorIDs(_ ids.ID) []ids.NodeID { - if v.validators == nil { - return nil - } - ids := make([]ids.NodeID, 0, len(v.validators)) for id := range v.validators { ids = append(ids, id) @@ -36,10 +32,7 @@ func (v *testValidatorInfo) GetValidator(_ ids.ID, nodeID ids.NodeID) (*validato } val, exists := v.validators[nodeID] - if !exists { - return nil, false - } - return &val, true + return &val, exists } func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) *testValidatorInfo { From 4dfdb34cf8e0de2ee4732850a210be415506e60e Mon Sep 17 00:00:00 2001 From: samliok Date: Tue, 10 Jun 2025 19:52:56 -0500 Subject: [PATCH 08/19] use GetValidatorSet for consistent validator set --- simplex/bls.go | 26 +++++++++++++++----------- simplex/bls_test.go | 9 ++++++--- simplex/config.go | 12 ++++++++++-- simplex/test_util.go | 29 +++++++++++------------------ 4 files changed, 42 insertions(+), 34 deletions(-) diff --git a/simplex/bls.go b/simplex/bls.go index be9687e26288..626c66d3937b 100644 --- a/simplex/bls.go +++ b/simplex/bls.go @@ -4,6 +4,7 @@ package simplex import ( + "context" "encoding/asn1" "errors" "fmt" @@ -40,12 +41,14 @@ type BLSVerifier struct { chainID ids.ID } -func NewBLSAuth(config *Config) (BLSSigner, BLSVerifier) { +func NewBLSAuth(config *Config) (BLSSigner, BLSVerifier, error) { + verifier, err := createVerifier(config) + return BLSSigner{ chainID: config.Ctx.ChainID, subnetID: config.Ctx.SubnetID, signBLS: config.SignBLS, - }, createVerifier(config) + }, verifier, err } // Sign returns a signature on the given message using BLS signature scheme. @@ -110,21 +113,22 @@ func (v BLSVerifier) Verify(message []byte, signature []byte, signer simplex.Nod return nil } -func createVerifier(config *Config) BLSVerifier { +func createVerifier(config *Config) (BLSVerifier, error) { verifier := BLSVerifier{ nodeID2PK: make(map[ids.NodeID]bls.PublicKey), subnetID: config.Ctx.SubnetID, chainID: config.Ctx.ChainID, } - nodes := config.Validators.GetValidatorIDs(config.Ctx.SubnetID) + nodes, err := config.Validators.GetValidatorSet(context.Background(), 0, config.Ctx.SubnetID) + if err != nil { + config.Log.Error("failed to get validator set", zap.Error(err), zap.Stringer("subnetID", config.Ctx.SubnetID)) + return BLSVerifier{}, err + } + for _, node := range nodes { - validator, ok := config.Validators.GetValidator(config.Ctx.SubnetID, node) - if !ok { - config.Log.Error("failed to get validator for node %s in subnet %s", zap.Stringer("node", node), zap.Stringer("subnetID", config.Ctx.SubnetID)) - continue - } - verifier.nodeID2PK[node] = *validator.PublicKey + verifier.nodeID2PK[node.NodeID] = *node.PublicKey } - return verifier + + return verifier, nil } diff --git a/simplex/bls_test.go b/simplex/bls_test.go index e5c59662b356..b08b36ab2da5 100644 --- a/simplex/bls_test.go +++ b/simplex/bls_test.go @@ -16,7 +16,8 @@ func TestBLSSignVerify(t *testing.T) { config, err := newEngineConfig() require.NoError(t, err) - signer, verifier := NewBLSAuth(config) + signer, verifier, err := NewBLSAuth(config) + require.NoError(t, err) msg := "Begin at the beginning, and go on till you come to the end: then stop" @@ -30,7 +31,8 @@ func TestBLSSignVerify(t *testing.T) { func TestSignerNotInMemberSet(t *testing.T) { config, err := newEngineConfig() require.NoError(t, err) - signer, verifier := NewBLSAuth(config) + signer, verifier, err := NewBLSAuth(config) + require.NoError(t, err) msg := "Begin at the beginning, and go on till you come to the end: then stop" @@ -53,7 +55,8 @@ func TestSignerInvalidMessageEncoding(t *testing.T) { sigBytes := bls.SignatureToBytes(sig) - _, verifier := NewBLSAuth(config) + _, verifier, err := NewBLSAuth(config) + require.NoError(t, err) err = verifier.Verify(dummyMsg, sigBytes, config.Ctx.NodeID[:]) require.ErrorIs(t, err, errSignatureVerificationFailed) } diff --git a/simplex/config.go b/simplex/config.go index 8e16e26e3e99..e778e408de12 100644 --- a/simplex/config.go +++ b/simplex/config.go @@ -4,14 +4,22 @@ package simplex import ( + "context" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/logging" ) type ValidatorInfo interface { - GetValidatorIDs(subnetID ids.ID) []ids.NodeID - GetValidator(subnetID ids.ID, nodeID ids.NodeID) (*validators.Validator, bool) + // GetValidatorSet returns the validators of the provided subnet at the + // requested P-chain height. + // The returned map should not be modified. + GetValidatorSet( + ctx context.Context, + height uint64, + subnetID ids.ID, + ) (map[ids.NodeID]*validators.GetValidatorOutput, error) } // Config wraps all the parameters needed for a simplex engine diff --git a/simplex/test_util.go b/simplex/test_util.go index 7cbbcbaf2a2c..2ac87c13ffd2 100644 --- a/simplex/test_util.go +++ b/simplex/test_util.go @@ -4,6 +4,8 @@ package simplex import ( + "context" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -15,24 +17,15 @@ var _ ValidatorInfo = (*testValidatorInfo)(nil) // testValidatorInfo is a mock implementation of ValidatorInfo for testing purposes. // it assumes all validators are in the same subnet and returns all of them for any subnetID. type testValidatorInfo struct { - validators map[ids.NodeID]validators.Validator -} - -func (v *testValidatorInfo) GetValidatorIDs(_ ids.ID) []ids.NodeID { - ids := make([]ids.NodeID, 0, len(v.validators)) - for id := range v.validators { - ids = append(ids, id) - } - return ids + validators map[ids.NodeID]*validators.GetValidatorOutput } -func (v *testValidatorInfo) GetValidator(_ ids.ID, nodeID ids.NodeID) (*validators.Validator, bool) { - if v.validators == nil { - return nil, false - } - - val, exists := v.validators[nodeID] - return &val, exists +func (t *testValidatorInfo) GetValidatorSet( + context.Context, + uint64, + ids.ID, +) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + return t.validators, nil } func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) *testValidatorInfo { @@ -40,9 +33,9 @@ func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) *testValid panic("nodeIds and pks must have the same length") } - vds := make(map[ids.NodeID]validators.Validator, len(pks)) + vds := make(map[ids.NodeID]*validators.GetValidatorOutput, len(pks)) for i, pk := range pks { - validator := validators.Validator{ + validator := &validators.GetValidatorOutput{ PublicKey: pk, NodeID: nodeIds[i], } From 8c78c03eb627fdb67dbee3d70ba74c70dc284a11 Mon Sep 17 00:00:00 2001 From: samliok Date: Wed, 11 Jun 2025 11:23:56 -0500 Subject: [PATCH 09/19] pass in membership set to config --- simplex/bls.go | 20 ++++++-------------- simplex/bls_test.go | 9 +++------ simplex/config.go | 27 ++++++++++----------------- simplex/test_util.go | 24 ++---------------------- 4 files changed, 21 insertions(+), 59 deletions(-) diff --git a/simplex/bls.go b/simplex/bls.go index 626c66d3937b..524c91842da8 100644 --- a/simplex/bls.go +++ b/simplex/bls.go @@ -4,13 +4,11 @@ package simplex import ( - "context" "encoding/asn1" "errors" "fmt" "github.com/ava-labs/simplex" - "go.uber.org/zap" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -41,14 +39,14 @@ type BLSVerifier struct { chainID ids.ID } -func NewBLSAuth(config *Config) (BLSSigner, BLSVerifier, error) { - verifier, err := createVerifier(config) +func NewBLSAuth(config *Config) (BLSSigner, BLSVerifier) { + verifier := createVerifier(config) return BLSSigner{ chainID: config.Ctx.ChainID, subnetID: config.Ctx.SubnetID, signBLS: config.SignBLS, - }, verifier, err + }, verifier } // Sign returns a signature on the given message using BLS signature scheme. @@ -113,22 +111,16 @@ func (v BLSVerifier) Verify(message []byte, signature []byte, signer simplex.Nod return nil } -func createVerifier(config *Config) (BLSVerifier, error) { +func createVerifier(config *Config) BLSVerifier { verifier := BLSVerifier{ nodeID2PK: make(map[ids.NodeID]bls.PublicKey), subnetID: config.Ctx.SubnetID, chainID: config.Ctx.ChainID, } - nodes, err := config.Validators.GetValidatorSet(context.Background(), 0, config.Ctx.SubnetID) - if err != nil { - config.Log.Error("failed to get validator set", zap.Error(err), zap.Stringer("subnetID", config.Ctx.SubnetID)) - return BLSVerifier{}, err - } - - for _, node := range nodes { + for _, node := range config.Validators { verifier.nodeID2PK[node.NodeID] = *node.PublicKey } - return verifier, nil + return verifier } diff --git a/simplex/bls_test.go b/simplex/bls_test.go index b08b36ab2da5..e5c59662b356 100644 --- a/simplex/bls_test.go +++ b/simplex/bls_test.go @@ -16,8 +16,7 @@ func TestBLSSignVerify(t *testing.T) { config, err := newEngineConfig() require.NoError(t, err) - signer, verifier, err := NewBLSAuth(config) - require.NoError(t, err) + signer, verifier := NewBLSAuth(config) msg := "Begin at the beginning, and go on till you come to the end: then stop" @@ -31,8 +30,7 @@ func TestBLSSignVerify(t *testing.T) { func TestSignerNotInMemberSet(t *testing.T) { config, err := newEngineConfig() require.NoError(t, err) - signer, verifier, err := NewBLSAuth(config) - require.NoError(t, err) + signer, verifier := NewBLSAuth(config) msg := "Begin at the beginning, and go on till you come to the end: then stop" @@ -55,8 +53,7 @@ func TestSignerInvalidMessageEncoding(t *testing.T) { sigBytes := bls.SignatureToBytes(sig) - _, verifier, err := NewBLSAuth(config) - require.NoError(t, err) + _, verifier := NewBLSAuth(config) err = verifier.Verify(dummyMsg, sigBytes, config.Ctx.NodeID[:]) require.ErrorIs(t, err, errSignatureVerificationFailed) } diff --git a/simplex/config.go b/simplex/config.go index e778e408de12..ecd792eb3646 100644 --- a/simplex/config.go +++ b/simplex/config.go @@ -4,30 +4,23 @@ package simplex import ( - "context" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/logging" ) -type ValidatorInfo interface { - // GetValidatorSet returns the validators of the provided subnet at the - // requested P-chain height. - // The returned map should not be modified. - GetValidatorSet( - ctx context.Context, - height uint64, - subnetID ids.ID, - ) (map[ids.NodeID]*validators.GetValidatorOutput, error) -} - // Config wraps all the parameters needed for a simplex engine type Config struct { - Ctx SimplexChainContext - Log logging.Logger - Validators ValidatorInfo - SignBLS SignFunc + Ctx SimplexChainContext + Log logging.Logger + + // Validators is a map of node IDs to their validator information. + // This tells the node about the current membership set, and should be consistent + // across all nodes in the subnet. + Validators map[ids.NodeID]*validators.GetValidatorOutput + + // SignBLS is the signing function used for this node to sign messages. + SignBLS SignFunc } // Context is information about the current execution. diff --git a/simplex/test_util.go b/simplex/test_util.go index 2ac87c13ffd2..86e0c4323045 100644 --- a/simplex/test_util.go +++ b/simplex/test_util.go @@ -4,31 +4,13 @@ package simplex import ( - "context" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" ) -var _ ValidatorInfo = (*testValidatorInfo)(nil) - -// testValidatorInfo is a mock implementation of ValidatorInfo for testing purposes. -// it assumes all validators are in the same subnet and returns all of them for any subnetID. -type testValidatorInfo struct { - validators map[ids.NodeID]*validators.GetValidatorOutput -} - -func (t *testValidatorInfo) GetValidatorSet( - context.Context, - uint64, - ids.ID, -) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - return t.validators, nil -} - -func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) *testValidatorInfo { +func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) map[ids.NodeID]*validators.GetValidatorOutput { if len(nodeIds) != len(pks) { panic("nodeIds and pks must have the same length") } @@ -42,9 +24,7 @@ func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) *testValid vds[nodeIds[i]] = validator } // all we need is to generate the public keys for the validators - return &testValidatorInfo{ - validators: vds, - } + return vds } func newEngineConfig() (*Config, error) { From 14ad42faaa6b73395d4ceb651711efe0f2393a51 Mon Sep 17 00:00:00 2001 From: samliok Date: Wed, 11 Jun 2025 11:31:19 -0500 Subject: [PATCH 10/19] remove comment --- simplex/test_util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simplex/test_util.go b/simplex/test_util.go index 86e0c4323045..9541a6d2b2dd 100644 --- a/simplex/test_util.go +++ b/simplex/test_util.go @@ -23,7 +23,7 @@ func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) map[ids.No } vds[nodeIds[i]] = validator } - // all we need is to generate the public keys for the validators + return vds } From ed4422b956188ebd520aa00fcf447586551c6766 Mon Sep 17 00:00:00 2001 From: samliok Date: Thu, 12 Jun 2025 14:03:38 -0500 Subject: [PATCH 11/19] test_util simplified --- simplex/test_util.go | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/simplex/test_util.go b/simplex/test_util.go index 9541a6d2b2dd..0e8a90378eb6 100644 --- a/simplex/test_util.go +++ b/simplex/test_util.go @@ -6,22 +6,13 @@ package simplex import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" ) -func newTestValidatorInfo(nodeIds []ids.NodeID, pks []*bls.PublicKey) map[ids.NodeID]*validators.GetValidatorOutput { - if len(nodeIds) != len(pks) { - panic("nodeIds and pks must have the same length") - } - - vds := make(map[ids.NodeID]*validators.GetValidatorOutput, len(pks)) - for i, pk := range pks { - validator := &validators.GetValidatorOutput{ - PublicKey: pk, - NodeID: nodeIds[i], - } - vds[nodeIds[i]] = validator +func newTestValidatorInfo(allVds []validators.GetValidatorOutput) map[ids.NodeID]*validators.GetValidatorOutput { + vds := make(map[ids.NodeID]*validators.GetValidatorOutput, len(allVds)) + for _, vd := range allVds { + vds[vd.NodeID] = &vd } return vds @@ -41,9 +32,14 @@ func newEngineConfig() (*Config, error) { SubnetID: ids.GenerateTestID(), } + nodeInfo := validators.GetValidatorOutput{ + NodeID: nodeID, + PublicKey: ls.PublicKey(), + } + return &Config{ Ctx: simplexChainContext, - Validators: newTestValidatorInfo([]ids.NodeID{nodeID}, []*bls.PublicKey{ls.PublicKey()}), + Validators: newTestValidatorInfo([]validators.GetValidatorOutput{nodeInfo}), SignBLS: ls.Sign, }, nil } From 14aef3ea24bee9bc6304f0f56c3af6db1243618c Mon Sep 17 00:00:00 2001 From: samliok Date: Thu, 12 Jun 2025 14:24:19 -0500 Subject: [PATCH 12/19] add replication outbound msgs --- api/grpcclient/client.go | 71 + api/server/http2_router.go | 57 + api/server/http2_router_test.go | 71 + api/server/server.go | 94 +- go.mod | 5 +- go.sum | 10 +- .../messagemock/outbound_message_builder.go | 30 + message/simplex_outbound_msg_builder.go | 199 ++- proto/p2p/p2p.proto | 8 +- proto/pb/p2p/p2p.pb.go | 161 +-- proto/pb/vm/vm.pb.go | 1206 +++++++++-------- proto/pb/vm/vm_grpc.pb.go | 37 + proto/pb/xsvm/service.pb.go | 286 ++++ proto/pb/xsvm/service_grpc.pb.go | 179 +++ proto/vm/vm.proto | 7 + proto/xsvm/service.proto | 26 + simplex/bls.go | 15 +- simplex/bls_test.go | 11 +- simplex/comm.go | 32 +- simplex/comm_test.go | 26 +- simplex/config.go | 19 +- simplex/test_util.go | 71 + simplex/test_utils.go | 97 -- .../vertex/vertexmock/linearizable_vm.go | 15 + snow/engine/common/vm.go | 4 + snow/engine/enginetest/vm.go | 63 +- .../snowman/block/blockmock/chain_vm.go | 15 + tests/e2e/vms/xsvm.go | 83 ++ tests/fixture/tmpnet/flags/kubeconfig.go | 9 +- tests/fixture/tmpnet/kube_runtime.go | 20 +- vms/avm/vm.go | 4 + vms/example/xsvm/api/ping.go | 69 + vms/example/xsvm/vm.go | 10 + vms/platformvm/vm.go | 4 + vms/rpcchainvm/ghttp/http_client.go | 9 +- vms/rpcchainvm/vm_client.go | 19 + vms/rpcchainvm/vm_server.go | 28 + 37 files changed, 2130 insertions(+), 940 deletions(-) create mode 100644 api/grpcclient/client.go create mode 100644 api/server/http2_router.go create mode 100644 api/server/http2_router_test.go create mode 100644 proto/pb/xsvm/service.pb.go create mode 100644 proto/pb/xsvm/service_grpc.pb.go create mode 100644 proto/xsvm/service.proto create mode 100644 simplex/test_util.go delete mode 100644 simplex/test_utils.go create mode 100644 vms/example/xsvm/api/ping.go diff --git a/api/grpcclient/client.go b/api/grpcclient/client.go new file mode 100644 index 000000000000..31bf0c968040 --- /dev/null +++ b/api/grpcclient/client.go @@ -0,0 +1,71 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package grpcclient + +import ( + "context" + "fmt" + + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" + + "github.com/ava-labs/avalanchego/ids" +) + +// NewChainClient returns a grpc.ClientConn that sets the chain-id header for +// all requests +func NewChainClient(uri string, chainID ids.ID, opts ...grpc.DialOption) (*grpc.ClientConn, error) { + dialOpts := []grpc.DialOption{ + grpc.WithUnaryInterceptor(SetChainIDHeaderUnaryClientInterceptor(chainID)), + grpc.WithStreamInterceptor(SetChainIDHeaderStreamClientInterceptor(chainID)), + } + + dialOpts = append(dialOpts, opts...) + + conn, err := grpc.NewClient(uri, dialOpts...) + if err != nil { + return nil, fmt.Errorf("failed to initialize chain grpc client: %w", err) + } + + return conn, nil +} + +// SetChainIDHeaderUnaryClientInterceptor sets the chain-id header for unary +// requests +func SetChainIDHeaderUnaryClientInterceptor(chainID ids.ID) grpc.UnaryClientInterceptor { + return func( + ctx context.Context, + method string, + req any, + reply any, + cc *grpc.ClientConn, + invoker grpc.UnaryInvoker, + opts ...grpc.CallOption, + ) error { + ctx = newContextWithChainIDHeader(ctx, chainID) + return invoker(ctx, method, req, reply, cc, opts...) + } +} + +// SetChainIDHeaderStreamClientInterceptor sets the chain-id header for +// streaming requests +func SetChainIDHeaderStreamClientInterceptor(chainID ids.ID) grpc.StreamClientInterceptor { + return func( + ctx context.Context, + desc *grpc.StreamDesc, + cc *grpc.ClientConn, + method string, + streamer grpc.Streamer, + opts ...grpc.CallOption, + ) (grpc.ClientStream, error) { + ctx = newContextWithChainIDHeader(ctx, chainID) + return streamer(ctx, desc, cc, method, opts...) + } +} + +// newContextWithChainHeader sets the chain-id header which the server uses +// to route the client grpc request +func newContextWithChainIDHeader(ctx context.Context, chainID ids.ID) context.Context { + return metadata.AppendToOutgoingContext(ctx, "chain-id", chainID.String()) +} diff --git a/api/server/http2_router.go b/api/server/http2_router.go new file mode 100644 index 000000000000..ff630e4d443b --- /dev/null +++ b/api/server/http2_router.go @@ -0,0 +1,57 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package server + +import ( + "net/http" + "sync" + + "github.com/ava-labs/avalanchego/ids" +) + +var _ http.Handler = (*http2Router)(nil) + +type http2Router struct { + lock sync.RWMutex + handlers map[string]http.Handler +} + +func newHTTP2Router() *http2Router { + return &http2Router{ + handlers: make(map[string]http.Handler), + } +} + +func (h *http2Router) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // the chain-id header must be set to route the request to the correct chain + // http2 handler + chainID := r.Header.Get("chain-id") + if len(chainID) == 0 { + w.WriteHeader(http.StatusBadRequest) + return + } + + h.lock.RLock() + handler, ok := h.handlers[chainID] + h.lock.RUnlock() + if !ok { + w.WriteHeader(http.StatusNotFound) + return + } + + handler.ServeHTTP(w, r) +} + +func (h *http2Router) Add(chainID ids.ID, handler http.Handler) bool { + h.lock.Lock() + defer h.lock.Unlock() + + chainIDStr := chainID.String() + if _, ok := h.handlers[chainIDStr]; ok { + return false + } + + h.handlers[chainIDStr] = handler + return true +} diff --git a/api/server/http2_router_test.go b/api/server/http2_router_test.go new file mode 100644 index 000000000000..4123206405a7 --- /dev/null +++ b/api/server/http2_router_test.go @@ -0,0 +1,71 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package server + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" +) + +func TestHTTP2RouterAdd(t *testing.T) { + require := require.New(t) + h := newHTTP2Router() + handler := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}) + + require.True(h.Add(ids.Empty, handler)) + require.False(h.Add(ids.Empty, handler)) +} + +func TestHTTP2RouterServeHTTP(t *testing.T) { + tests := []struct { + name string + chainIDs []ids.ID + header http.Header + wantCode int + }{ + { + name: "missing chain-id header", + wantCode: http.StatusBadRequest, + }, + { + name: "unknown referenced chain-id", + header: http.Header{ + http.CanonicalHeaderKey("chain-id"): []string{ids.Empty.String()}, + }, + wantCode: http.StatusNotFound, + }, + { + name: "valid handler", + chainIDs: []ids.ID{ids.Empty}, + header: http.Header{ + http.CanonicalHeaderKey("chain-id"): []string{ids.Empty.String()}, + }, + wantCode: http.StatusOK, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + + h := newHTTP2Router() + handler := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}) + writer := httptest.NewRecorder() + request := httptest.NewRequest(http.MethodPost, "/", nil) + request.Header = tt.header + + for _, chainID := range tt.chainIDs { + require.True(h.Add(chainID, handler)) + } + + h.ServeHTTP(writer, request) + require.Equal(tt.wantCode, writer.Code) + }) + } +} diff --git a/api/server/server.go b/api/server/server.go index 8156a4964dcc..6bbd0b610467 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -12,11 +12,11 @@ import ( "path" "time" - "github.com/NYTimes/gziphandler" "github.com/prometheus/client_golang/prometheus" "github.com/rs/cors" "go.uber.org/zap" "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" "github.com/ava-labs/avalanchego/api" "github.com/ava-labs/avalanchego/ids" @@ -88,7 +88,8 @@ type server struct { metrics *metrics // Maps endpoints to handlers - router *router + router *router + http2Router *http2Router srv *http.Server @@ -115,33 +116,29 @@ func New( } router := newRouter() - allowedHostsHandler := filterInvalidHosts(router, allowedHosts) - corsHandler := cors.New(cors.Options{ - AllowedOrigins: allowedOrigins, - AllowCredentials: true, - }).Handler(allowedHostsHandler) - gzipHandler := gziphandler.GzipHandler(corsHandler) - var handler http.Handler = http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - // Attach this node's ID as a header - w.Header().Set("node-id", nodeID.String()) - gzipHandler.ServeHTTP(w, r) - }, - ) + handler := wrapHandler(router, nodeID, allowedOrigins, allowedHosts) + + http2Router := newHTTP2Router() + http2Handler := wrapHandler(http2Router, nodeID, allowedOrigins, allowedHosts) httpServer := &http.Server{ - Handler: handler, + Handler: h2c.NewHandler( + http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.ProtoMajor == 2 { + http2Handler.ServeHTTP(w, r) + return + } + + handler.ServeHTTP(w, r) + }), + &http2.Server{ + MaxConcurrentStreams: maxConcurrentStreams, + }), ReadTimeout: httpConfig.ReadTimeout, ReadHeaderTimeout: httpConfig.ReadHeaderTimeout, WriteTimeout: httpConfig.WriteTimeout, IdleTimeout: httpConfig.IdleTimeout, } - err = http2.ConfigureServer(httpServer, &http2.Server{ - MaxConcurrentStreams: maxConcurrentStreams, - }) - if err != nil { - return nil, err - } log.Info("API created", zap.Strings("allowedOrigins", allowedOrigins), @@ -154,6 +151,7 @@ func New( tracer: tracer, metrics: m, router: router, + http2Router: http2Router, srv: httpServer, listener: listener, }, nil @@ -199,6 +197,30 @@ func (s *server) RegisterChain(chainName string, ctx *snow.ConsensusContext, vm ) } } + + ctx.Lock.Lock() + http2Handler, err := vm.CreateHTTP2Handler(context.TODO()) + ctx.Lock.Unlock() + if err != nil { + s.log.Error("failed to create http2 handler", + zap.String("chainName", chainName), + zap.Error(err), + ) + return + } + + if http2Handler == nil { + return + } + + http2Handler = s.wrapMiddleware(chainName, http2Handler, ctx) + if !s.http2Router.Add(ctx.ChainID, http2Handler) { + s.log.Error( + "failed to add route to http2 handler", + zap.String("chainName", chainName), + zap.Error(err), + ) + } } func (s *server) addChainRoute(chainName string, handler http.Handler, ctx *snow.ConsensusContext, base, endpoint string) error { @@ -207,13 +229,17 @@ func (s *server) addChainRoute(chainName string, handler http.Handler, ctx *snow zap.String("url", url), zap.String("endpoint", endpoint), ) + handler = s.wrapMiddleware(chainName, handler, ctx) + return s.router.AddRouter(url, endpoint, handler) +} + +func (s *server) wrapMiddleware(chainName string, handler http.Handler, ctx *snow.ConsensusContext) http.Handler { if s.tracingEnabled { handler = api.TraceHandler(handler, chainName, s.tracer) } // Apply middleware to reject calls to the handler before the chain finishes bootstrapping handler = rejectMiddleware(handler, ctx) - handler = s.metrics.wrapHandler(chainName, handler) - return s.router.AddRouter(url, endpoint, handler) + return s.metrics.wrapHandler(chainName, handler) } func (s *server) AddRoute(handler http.Handler, base, endpoint string) error { @@ -299,3 +325,23 @@ func (a readPathAdder) AddRoute(handler http.Handler, base, endpoint string) err func (a readPathAdder) AddAliases(endpoint string, aliases ...string) error { return a.pather.AddAliasesWithReadLock(endpoint, aliases...) } + +func wrapHandler( + handler http.Handler, + nodeID ids.NodeID, + allowedOrigins []string, + allowedHosts []string, +) http.Handler { + h := filterInvalidHosts(handler, allowedHosts) + h = cors.New(cors.Options{ + AllowedOrigins: allowedOrigins, + AllowCredentials: true, + }).Handler(h) + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + // Attach this node's ID as a header + w.Header().Set("node-id", nodeID.String()) + h.ServeHTTP(w, r) + }, + ) +} diff --git a/go.mod b/go.mod index 8b9ffb89a875..62b5e5bc8b69 100644 --- a/go.mod +++ b/go.mod @@ -11,12 +11,11 @@ go 1.23.9 require ( github.com/DataDog/zstd v1.5.2 - github.com/NYTimes/gziphandler v1.1.1 github.com/StephenButtolph/canoto v0.15.0 github.com/antithesishq/antithesis-sdk-go v0.3.8 - github.com/ava-labs/coreth v0.15.1-rc.0.0.20250530184801-28421010abae + github.com/ava-labs/coreth v0.15.2-rc.0.0.20250610170140-2fcf45f828a2 github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60 - github.com/ava-labs/libevm v1.13.14-0.2.0.release + github.com/ava-labs/libevm v0.0.0-20250610142802-2672fbd7cdfc github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 github.com/compose-spec/compose-go v1.20.2 diff --git a/go.sum b/go.sum index cddaf16b2fd9..265cffc1dda4 100644 --- a/go.sum +++ b/go.sum @@ -52,8 +52,6 @@ github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1 github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/StephenButtolph/canoto v0.15.0 h1:3iGdyTSQZ7/y09WaJCe0O/HIi53ZyTrnmVzfCqt64mM= github.com/StephenButtolph/canoto v0.15.0/go.mod h1:IcnAHC6nJUfQFVR9y60ko2ecUqqHHSB6UwI9NnBFZnE= @@ -68,14 +66,14 @@ github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/ava-labs/coreth v0.15.1-rc.0.0.20250530184801-28421010abae h1:PPcOEtY3SoXruzMPYJMxoeoExRVhf5UOiH7SvdPHQwY= -github.com/ava-labs/coreth v0.15.1-rc.0.0.20250530184801-28421010abae/go.mod h1:Tl6TfpOwSq0bXvN7DTENXB4As3hml8ma9OQEWS9DH9I= +github.com/ava-labs/coreth v0.15.2-rc.0.0.20250610170140-2fcf45f828a2 h1:/E1w2S6xvEhkO2+C9sGCV8W80qaeSN5WBFqdKLl12HM= +github.com/ava-labs/coreth v0.15.2-rc.0.0.20250610170140-2fcf45f828a2/go.mod h1:cqwBag+zzqifDutdPVzZKovfC2d0L8Zxq4YgTGaMCwg= github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60 h1:EL66gtXOAwR/4KYBjOV03LTWgkEXvLePribLlJNu4g0= github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60/go.mod h1:/7qKobTfbzBu7eSTVaXMTr56yTYk4j2Px6/8G+idxHo= -github.com/ava-labs/libevm v1.13.14-0.2.0.release h1:uKGCc5/ceeBbfAPRVtBUxbQt50WzB2pEDb8Uy93ePgQ= -github.com/ava-labs/libevm v1.13.14-0.2.0.release/go.mod h1:+Iol+sVQ1KyoBsHf3veyrBmHCXr3xXRWq6ZXkgVfNLU= github.com/ava-labs/simplex v0.0.0-20250605162940-db8e6d44f53d h1:D/BOS3USdAigun2OP/6khvukKnn4BIKviYAdKLHN6zc= github.com/ava-labs/simplex v0.0.0-20250605162940-db8e6d44f53d/go.mod h1:GVzumIo3zR23/qGRN2AdnVkIPHcKMq/D89EGWZfMGQ0= +github.com/ava-labs/libevm v0.0.0-20250610142802-2672fbd7cdfc h1:cSXaUY4hdmoJ2FJOgOzn+WiovN/ZB/zkNRgnZhE50OA= +github.com/ava-labs/libevm v0.0.0-20250610142802-2672fbd7cdfc/go.mod h1:+Iol+sVQ1KyoBsHf3veyrBmHCXr3xXRWq6ZXkgVfNLU= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= diff --git a/message/messagemock/outbound_message_builder.go b/message/messagemock/outbound_message_builder.go index 456f08619fd9..dec1dffa8b4c 100644 --- a/message/messagemock/outbound_message_builder.go +++ b/message/messagemock/outbound_message_builder.go @@ -481,6 +481,21 @@ func (mr *OutboundMsgBuilderMockRecorder) Put(chainID, requestID, container any) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*OutboundMsgBuilder)(nil).Put), chainID, requestID, container) } +// ReplicationRequest mocks base method. +func (m *OutboundMsgBuilder) ReplicationRequest(chainID ids.ID, seqs []uint64, latestRound uint64) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReplicationRequest", chainID, seqs, latestRound) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReplicationRequest indicates an expected call of ReplicationRequest. +func (mr *OutboundMsgBuilderMockRecorder) ReplicationRequest(chainID, seqs, latestRound any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplicationRequest", reflect.TypeOf((*OutboundMsgBuilder)(nil).ReplicationRequest), chainID, seqs, latestRound) +} + // StateSummaryFrontier mocks base method. func (m *OutboundMsgBuilder) StateSummaryFrontier(chainID ids.ID, requestID uint32, summary []byte) (message.OutboundMessage, error) { m.ctrl.T.Helper() @@ -496,6 +511,21 @@ func (mr *OutboundMsgBuilderMockRecorder) StateSummaryFrontier(chainID, requestI return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSummaryFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).StateSummaryFrontier), chainID, requestID, summary) } +// VerifiedReplicationResponse mocks base method. +func (m *OutboundMsgBuilder) VerifiedReplicationResponse(chainID ids.ID, data []simplex.VerifiedQuorumRound, latestRound *simplex.VerifiedQuorumRound) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VerifiedReplicationResponse", chainID, data, latestRound) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// VerifiedReplicationResponse indicates an expected call of VerifiedReplicationResponse. +func (mr *OutboundMsgBuilderMockRecorder) VerifiedReplicationResponse(chainID, data, latestRound any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifiedReplicationResponse", reflect.TypeOf((*OutboundMsgBuilder)(nil).VerifiedReplicationResponse), chainID, data, latestRound) +} + // Vote mocks base method. func (m *OutboundMsgBuilder) Vote(chainID ids.ID, blockHeader simplex.BlockHeader, signature simplex.Signature) (message.OutboundMessage, error) { m.ctrl.T.Helper() diff --git a/message/simplex_outbound_msg_builder.go b/message/simplex_outbound_msg_builder.go index 832c6620bf1c..8b6285ecd547 100644 --- a/message/simplex_outbound_msg_builder.go +++ b/message/simplex_outbound_msg_builder.go @@ -4,9 +4,10 @@ package message import ( + "github.com/ava-labs/simplex" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/proto/pb/p2p" - "github.com/ava-labs/simplex" ) type SimplexOutboundMessageBuilder interface { @@ -51,6 +52,18 @@ type SimplexOutboundMessageBuilder interface { blockHeader simplex.BlockHeader, qc []byte, ) (OutboundMessage, error) + + ReplicationRequest( + chainID ids.ID, + seqs []uint64, + latestRound uint64, + ) (OutboundMessage, error) + + VerifiedReplicationResponse( + chainID ids.ID, + data []simplex.VerifiedQuorumRound, + latestRound *simplex.VerifiedQuorumRound, + ) (OutboundMessage, error) } func (b *outMsgBuilder) BlockProposal( @@ -67,19 +80,10 @@ func (b *outMsgBuilder) BlockProposal( BlockProposal: &p2p.BlockProposal{ Block: block, Vote: &p2p.Vote{ - Vote: &p2p.BlockHeader{ - Metadata: &p2p.ProtocolMetadata{ - Version: uint32(vote.Vote.Version), - Epoch: vote.Vote.Epoch, - Round: vote.Vote.Round, - Seq: vote.Vote.Seq, - Prev: vote.Vote.Prev[:], - }, - Digest: vote.Vote.Digest[:], - }, + BlockHeader: simplexBlockheaderToP2P(vote.Vote.BlockHeader), Signature: &p2p.Signature{ - Signer: vote.Signature.Signer[:], - Value: vote.Signature.Value[:], + Signer: vote.Signature.Signer, + Value: vote.Signature.Value, }, }, }, @@ -104,19 +108,10 @@ func (b *outMsgBuilder) Vote( ChainId: chainID[:], Message: &p2p.Simplex_Vote{ Vote: &p2p.Vote{ - Vote: &p2p.BlockHeader{ - Metadata: &p2p.ProtocolMetadata{ - Version: uint32(blockHeader.Version), - Epoch: blockHeader.Epoch, - Round: blockHeader.Round, - Seq: blockHeader.Seq, - Prev: blockHeader.Prev[:], - }, - Digest: blockHeader.Digest[:], - }, + BlockHeader: simplexBlockheaderToP2P(blockHeader), Signature: &p2p.Signature{ - Signer: signature.Signer[:], - Value: signature.Value[:], + Signer: signature.Signer, + Value: signature.Value, }, }, }, @@ -140,16 +135,10 @@ func (b *outMsgBuilder) EmptyVote( ChainId: chainID[:], Message: &p2p.Simplex_EmptyVote{ EmptyVote: &p2p.EmptyVote{ - Vote: &p2p.ProtocolMetadata{ - Version: uint32(protocolMetadata.Version), - Epoch: protocolMetadata.Epoch, - Round: protocolMetadata.Round, - Seq: protocolMetadata.Seq, - Prev: protocolMetadata.Prev[:], - }, + Metadata: simplexProtocolMetadataToP2P(protocolMetadata), Signature: &p2p.Signature{ - Signer: signature.Signer[:], - Value: signature.Value[:], + Signer: signature.Signer, + Value: signature.Value, }, }, }, @@ -173,19 +162,10 @@ func (b *outMsgBuilder) FinalizeVote( ChainId: chainID[:], Message: &p2p.Simplex_FinalizeVote{ FinalizeVote: &p2p.Vote{ - Vote: &p2p.BlockHeader{ - Metadata: &p2p.ProtocolMetadata{ - Version: uint32(blockHeader.Version), - Epoch: blockHeader.Epoch, - Round: blockHeader.Round, - Seq: blockHeader.Seq, - Prev: blockHeader.Prev[:], - }, - Digest: blockHeader.Digest[:], - }, + BlockHeader: simplexBlockheaderToP2P(blockHeader), Signature: &p2p.Signature{ - Signer: signature.Signer[:], - Value: signature.Value[:], + Signer: signature.Signer, + Value: signature.Value, }, }, }, @@ -209,16 +189,7 @@ func (b *outMsgBuilder) Notarization( ChainId: chainID[:], Message: &p2p.Simplex_Notarization{ Notarization: &p2p.QuorumCertificate{ - Finalization: &p2p.BlockHeader{ - Metadata: &p2p.ProtocolMetadata{ - Version: uint32(blockHeader.Version), - Epoch: blockHeader.Epoch, - Round: blockHeader.Round, - Seq: blockHeader.Seq, - Prev: blockHeader.Prev[:], - }, - Digest: blockHeader.Digest[:], - }, + BlockHeader: simplexBlockheaderToP2P(blockHeader), QuorumCertificate: qc, }, }, @@ -242,13 +213,7 @@ func (b *outMsgBuilder) EmptyNotarization( ChainId: chainID[:], Message: &p2p.Simplex_EmptyNotarization{ EmptyNotarization: &p2p.EmptyNotarization{ - EmptyVote: &p2p.ProtocolMetadata{ - Version: uint32(protocolMetadata.Version), - Epoch: protocolMetadata.Epoch, - Round: protocolMetadata.Round, - Seq: protocolMetadata.Seq, - Prev: protocolMetadata.Prev[:], - }, + Metadata: simplexProtocolMetadataToP2P(protocolMetadata), QuorumCertificate: qc, }, }, @@ -272,16 +237,7 @@ func (b *outMsgBuilder) Finalization( ChainId: chainID[:], Message: &p2p.Simplex_Finalization{ Finalization: &p2p.QuorumCertificate{ - Finalization: &p2p.BlockHeader{ - Metadata: &p2p.ProtocolMetadata{ - Version: uint32(blockHeader.Version), - Epoch: blockHeader.Epoch, - Round: blockHeader.Round, - Seq: blockHeader.Seq, - Prev: blockHeader.Prev[:], - }, - Digest: blockHeader.Digest[:], - }, + BlockHeader: simplexBlockheaderToP2P(blockHeader), QuorumCertificate: qc, }, }, @@ -292,3 +248,100 @@ func (b *outMsgBuilder) Finalization( false, ) } + +func (b *outMsgBuilder) ReplicationRequest( + chainID ids.ID, + seqs []uint64, + latestRound uint64, +) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.Simplex{ + ChainId: chainID[:], + Message: &p2p.Simplex_ReplicationRequest{ + ReplicationRequest: &p2p.ReplicationRequest{ + Seqs: seqs, + LatestRound: latestRound, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) VerifiedReplicationResponse( + chainID ids.ID, + data []simplex.VerifiedQuorumRound, + latestRound *simplex.VerifiedQuorumRound, +) (OutboundMessage, error) { + qrs := make([]*p2p.QuorumRound, 0, len(data)) + for _, qr := range data { + qrs = append(qrs, simplexQuorumRoundToP2P(&qr)) + } + + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.Simplex{ + ChainId: chainID[:], + Message: &p2p.Simplex_ReplicationResponse{ + ReplicationResponse: &p2p.ReplicationResponse{ + Data: qrs, + LatestRound: simplexQuorumRoundToP2P(latestRound), + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func simplexBlockheaderToP2P(bh simplex.BlockHeader) *p2p.BlockHeader { + return &p2p.BlockHeader{ + Metadata: simplexProtocolMetadataToP2P(bh.ProtocolMetadata), + Digest: bh.Digest[:], + } +} + +func simplexProtocolMetadataToP2P(md simplex.ProtocolMetadata) *p2p.ProtocolMetadata { + return &p2p.ProtocolMetadata{ + Version: uint32(md.Version), + Epoch: md.Epoch, + Round: md.Round, + Seq: md.Seq, + Prev: md.Prev[:], + } +} + +func simplexQuorumRoundToP2P(qr *simplex.VerifiedQuorumRound) *p2p.QuorumRound { + p2pQR := &p2p.QuorumRound{} + + if qr.VerifiedBlock != nil { + p2pQR.Block = qr.VerifiedBlock.Bytes() + } + if qr.Notarization != nil { + p2pQR.Notarization = &p2p.QuorumCertificate{ + BlockHeader: simplexBlockheaderToP2P(qr.Notarization.Vote.BlockHeader), + QuorumCertificate: qr.Notarization.QC.Bytes(), + } + } + if qr.Finalization != nil { + p2pQR.Finalization = &p2p.QuorumCertificate{ + BlockHeader: simplexBlockheaderToP2P(qr.Finalization.Finalization.BlockHeader), + QuorumCertificate: qr.Finalization.QC.Bytes(), + } + } + if qr.EmptyNotarization != nil { + p2pQR.EmptyNotarization = &p2p.EmptyNotarization{ + Metadata: simplexProtocolMetadataToP2P(qr.EmptyNotarization.Vote.ProtocolMetadata), + QuorumCertificate: qr.EmptyNotarization.QC.Bytes(), + } + } + return p2pQR +} diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index 7600849362f6..deef3c9deb99 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -473,22 +473,22 @@ message Signature { } message Vote { - BlockHeader vote = 1; + BlockHeader block_header = 1; Signature signature = 2; } message EmptyVote { - ProtocolMetadata vote = 1; + ProtocolMetadata metadata = 1; Signature signature = 2; } message QuorumCertificate { - BlockHeader finalization = 1; + BlockHeader block_header = 1; bytes quorum_certificate = 2; } message EmptyNotarization { - ProtocolMetadata empty_vote = 1; + ProtocolMetadata metadata = 1; bytes quorum_certificate = 2; } diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index b84c8ac2f0ba..2a5833abd4ce 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -2893,8 +2893,8 @@ type Vote struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Vote *BlockHeader `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote,omitempty"` - Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` + BlockHeader *BlockHeader `protobuf:"bytes,1,opt,name=block_header,json=blockHeader,proto3" json:"block_header,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` } func (x *Vote) Reset() { @@ -2927,9 +2927,9 @@ func (*Vote) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{33} } -func (x *Vote) GetVote() *BlockHeader { +func (x *Vote) GetBlockHeader() *BlockHeader { if x != nil { - return x.Vote + return x.BlockHeader } return nil } @@ -2946,7 +2946,7 @@ type EmptyVote struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Vote *ProtocolMetadata `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote,omitempty"` + Metadata *ProtocolMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` } @@ -2980,9 +2980,9 @@ func (*EmptyVote) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{34} } -func (x *EmptyVote) GetVote() *ProtocolMetadata { +func (x *EmptyVote) GetMetadata() *ProtocolMetadata { if x != nil { - return x.Vote + return x.Metadata } return nil } @@ -2999,7 +2999,7 @@ type QuorumCertificate struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Finalization *BlockHeader `protobuf:"bytes,1,opt,name=finalization,proto3" json:"finalization,omitempty"` + BlockHeader *BlockHeader `protobuf:"bytes,1,opt,name=block_header,json=blockHeader,proto3" json:"block_header,omitempty"` QuorumCertificate []byte `protobuf:"bytes,2,opt,name=quorum_certificate,json=quorumCertificate,proto3" json:"quorum_certificate,omitempty"` } @@ -3033,9 +3033,9 @@ func (*QuorumCertificate) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{35} } -func (x *QuorumCertificate) GetFinalization() *BlockHeader { +func (x *QuorumCertificate) GetBlockHeader() *BlockHeader { if x != nil { - return x.Finalization + return x.BlockHeader } return nil } @@ -3052,7 +3052,7 @@ type EmptyNotarization struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - EmptyVote *ProtocolMetadata `protobuf:"bytes,1,opt,name=empty_vote,json=emptyVote,proto3" json:"empty_vote,omitempty"` + Metadata *ProtocolMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` QuorumCertificate []byte `protobuf:"bytes,2,opt,name=quorum_certificate,json=quorumCertificate,proto3" json:"quorum_certificate,omitempty"` } @@ -3086,9 +3086,9 @@ func (*EmptyNotarization) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{36} } -func (x *EmptyNotarization) GetEmptyVote() *ProtocolMetadata { +func (x *EmptyNotarization) GetMetadata() *ProtocolMetadata { if x != nil { - return x.EmptyVote + return x.Metadata } return nil } @@ -3652,70 +3652,71 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5a, 0x0a, 0x04, 0x56, 0x6f, 0x74, 0x65, - 0x12, 0x24, 0x0a, 0x04, 0x76, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x52, 0x04, 0x76, 0x6f, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, - 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x22, 0x64, 0x0a, 0x09, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x6f, 0x74, - 0x65, 0x12, 0x29, 0x0a, 0x04, 0x76, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x04, 0x76, 0x6f, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, - 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x78, 0x0a, 0x11, 0x51, 0x75, - 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, - 0x34, 0x0a, 0x0c, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0c, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, - 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x11, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x22, 0x78, 0x0a, 0x11, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4e, 0x6f, 0x74, - 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x0a, 0x65, 0x6d, 0x70, - 0x74, 0x79, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x70, 0x32, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x52, 0x09, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x6f, 0x74, 0x65, 0x12, - 0x2d, 0x0a, 0x12, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x71, 0x75, 0x6f, - 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x4b, - 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x71, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x04, 0x52, 0x04, 0x73, 0x65, 0x71, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6c, 0x61, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, - 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x70, 0x0a, 0x13, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x52, 0x6f, 0x75, - 0x6e, 0x64, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x0c, 0x6c, 0x61, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x52, 0x6f, 0x75, 0x6e, 0x64, - 0x52, 0x0b, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0xe2, 0x01, - 0x0a, 0x0b, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x14, 0x0a, - 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x12, 0x3a, 0x0a, 0x0c, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x32, 0x70, 0x2e, - 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x52, 0x0c, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x45, 0x0a, 0x12, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x0c, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, + 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x69, 0x0a, 0x04, 0x56, 0x6f, 0x74, 0x65, + 0x12, 0x33, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x22, 0x6c, 0x0a, 0x09, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x6f, 0x74, 0x65, + 0x12, 0x31, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x22, 0x77, 0x0a, 0x11, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, + 0x32, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0b, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x71, + 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x75, 0x0a, 0x11, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x31, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x2d, 0x0a, 0x12, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, + 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x22, 0x4b, 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x71, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x04, 0x52, 0x04, 0x73, 0x65, 0x71, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6c, + 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0b, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x70, + 0x0a, 0x13, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, + 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x0c, 0x6c, + 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x52, 0x6f, + 0x75, 0x6e, 0x64, 0x52, 0x0b, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, + 0x22, 0xe2, 0x01, 0x0a, 0x0b, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x52, 0x6f, 0x75, 0x6e, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x3a, 0x0a, 0x0c, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, - 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, 0x41, - 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, 0x49, - 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, 0x10, - 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x32, - 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x12, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x6e, 0x6f, 0x74, 0x61, + 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x4e, 0x6f, 0x74, + 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x0c, 0x66, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x41, 0x56, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, + 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, + 0x41, 0x4e, 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, + 0x2f, 0x70, 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3817,12 +3818,12 @@ var file_p2p_p2p_proto_depIdxs = []int32{ 39, // 38: p2p.Simplex.replication_response:type_name -> p2p.ReplicationResponse 34, // 39: p2p.BlockProposal.vote:type_name -> p2p.Vote 31, // 40: p2p.BlockHeader.metadata:type_name -> p2p.ProtocolMetadata - 32, // 41: p2p.Vote.vote:type_name -> p2p.BlockHeader + 32, // 41: p2p.Vote.block_header:type_name -> p2p.BlockHeader 33, // 42: p2p.Vote.signature:type_name -> p2p.Signature - 31, // 43: p2p.EmptyVote.vote:type_name -> p2p.ProtocolMetadata + 31, // 43: p2p.EmptyVote.metadata:type_name -> p2p.ProtocolMetadata 33, // 44: p2p.EmptyVote.signature:type_name -> p2p.Signature - 32, // 45: p2p.QuorumCertificate.finalization:type_name -> p2p.BlockHeader - 31, // 46: p2p.EmptyNotarization.empty_vote:type_name -> p2p.ProtocolMetadata + 32, // 45: p2p.QuorumCertificate.block_header:type_name -> p2p.BlockHeader + 31, // 46: p2p.EmptyNotarization.metadata:type_name -> p2p.ProtocolMetadata 40, // 47: p2p.ReplicationResponse.data:type_name -> p2p.QuorumRound 40, // 48: p2p.ReplicationResponse.latest_round:type_name -> p2p.QuorumRound 36, // 49: p2p.QuorumRound.notarization:type_name -> p2p.QuorumCertificate diff --git a/proto/pb/vm/vm.pb.go b/proto/pb/vm/vm.pb.go index 239ac90a3299..9ad3b5d3b5d2 100644 --- a/proto/pb/vm/vm.pb.go +++ b/proto/pb/vm/vm.pb.go @@ -177,7 +177,7 @@ func (x StateSummaryAcceptResponse_Mode) Number() protoreflect.EnumNumber { // Deprecated: Use StateSummaryAcceptResponse_Mode.Descriptor instead. func (StateSummaryAcceptResponse_Mode) EnumDescriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{41, 0} + return file_vm_vm_proto_rawDescGZIP(), []int{42, 0} } type InitializeRequest struct { @@ -751,6 +751,53 @@ func (x *CreateHandlersResponse) GetHandlers() []*Handler { return nil } +type CreateHTTP2HandlerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // server_addr is the address of the gRPC server which serves the + // HTTP service + ServerAddr string `protobuf:"bytes,1,opt,name=server_addr,json=serverAddr,proto3" json:"server_addr,omitempty"` +} + +func (x *CreateHTTP2HandlerResponse) Reset() { + *x = CreateHTTP2HandlerResponse{} + mi := &file_vm_vm_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTP2HandlerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTP2HandlerResponse) ProtoMessage() {} + +func (x *CreateHTTP2HandlerResponse) ProtoReflect() protoreflect.Message { + mi := &file_vm_vm_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateHTTP2HandlerResponse.ProtoReflect.Descriptor instead. +func (*CreateHTTP2HandlerResponse) Descriptor() ([]byte, []int) { + return file_vm_vm_proto_rawDescGZIP(), []int{6} +} + +func (x *CreateHTTP2HandlerResponse) GetServerAddr() string { + if x != nil { + return x.ServerAddr + } + return "" +} + type Handler struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -764,7 +811,7 @@ type Handler struct { func (x *Handler) Reset() { *x = Handler{} - mi := &file_vm_vm_proto_msgTypes[6] + mi := &file_vm_vm_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -776,7 +823,7 @@ func (x *Handler) String() string { func (*Handler) ProtoMessage() {} func (x *Handler) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[6] + mi := &file_vm_vm_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -789,7 +836,7 @@ func (x *Handler) ProtoReflect() protoreflect.Message { // Deprecated: Use Handler.ProtoReflect.Descriptor instead. func (*Handler) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{6} + return file_vm_vm_proto_rawDescGZIP(), []int{7} } func (x *Handler) GetPrefix() string { @@ -816,7 +863,7 @@ type BuildBlockRequest struct { func (x *BuildBlockRequest) Reset() { *x = BuildBlockRequest{} - mi := &file_vm_vm_proto_msgTypes[7] + mi := &file_vm_vm_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -828,7 +875,7 @@ func (x *BuildBlockRequest) String() string { func (*BuildBlockRequest) ProtoMessage() {} func (x *BuildBlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[7] + mi := &file_vm_vm_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -841,7 +888,7 @@ func (x *BuildBlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BuildBlockRequest.ProtoReflect.Descriptor instead. func (*BuildBlockRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{7} + return file_vm_vm_proto_rawDescGZIP(), []int{8} } func (x *BuildBlockRequest) GetPChainHeight() uint64 { @@ -867,7 +914,7 @@ type BuildBlockResponse struct { func (x *BuildBlockResponse) Reset() { *x = BuildBlockResponse{} - mi := &file_vm_vm_proto_msgTypes[8] + mi := &file_vm_vm_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -879,7 +926,7 @@ func (x *BuildBlockResponse) String() string { func (*BuildBlockResponse) ProtoMessage() {} func (x *BuildBlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[8] + mi := &file_vm_vm_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -892,7 +939,7 @@ func (x *BuildBlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BuildBlockResponse.ProtoReflect.Descriptor instead. func (*BuildBlockResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{8} + return file_vm_vm_proto_rawDescGZIP(), []int{9} } func (x *BuildBlockResponse) GetId() []byte { @@ -947,7 +994,7 @@ type ParseBlockRequest struct { func (x *ParseBlockRequest) Reset() { *x = ParseBlockRequest{} - mi := &file_vm_vm_proto_msgTypes[9] + mi := &file_vm_vm_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -959,7 +1006,7 @@ func (x *ParseBlockRequest) String() string { func (*ParseBlockRequest) ProtoMessage() {} func (x *ParseBlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[9] + mi := &file_vm_vm_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -972,7 +1019,7 @@ func (x *ParseBlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseBlockRequest.ProtoReflect.Descriptor instead. func (*ParseBlockRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{9} + return file_vm_vm_proto_rawDescGZIP(), []int{10} } func (x *ParseBlockRequest) GetBytes() []byte { @@ -996,7 +1043,7 @@ type ParseBlockResponse struct { func (x *ParseBlockResponse) Reset() { *x = ParseBlockResponse{} - mi := &file_vm_vm_proto_msgTypes[10] + mi := &file_vm_vm_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1008,7 +1055,7 @@ func (x *ParseBlockResponse) String() string { func (*ParseBlockResponse) ProtoMessage() {} func (x *ParseBlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[10] + mi := &file_vm_vm_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1021,7 +1068,7 @@ func (x *ParseBlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseBlockResponse.ProtoReflect.Descriptor instead. func (*ParseBlockResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{10} + return file_vm_vm_proto_rawDescGZIP(), []int{11} } func (x *ParseBlockResponse) GetId() []byte { @@ -1069,7 +1116,7 @@ type GetBlockRequest struct { func (x *GetBlockRequest) Reset() { *x = GetBlockRequest{} - mi := &file_vm_vm_proto_msgTypes[11] + mi := &file_vm_vm_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1081,7 +1128,7 @@ func (x *GetBlockRequest) String() string { func (*GetBlockRequest) ProtoMessage() {} func (x *GetBlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[11] + mi := &file_vm_vm_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1094,7 +1141,7 @@ func (x *GetBlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockRequest.ProtoReflect.Descriptor instead. func (*GetBlockRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{11} + return file_vm_vm_proto_rawDescGZIP(), []int{12} } func (x *GetBlockRequest) GetId() []byte { @@ -1120,7 +1167,7 @@ type GetBlockResponse struct { func (x *GetBlockResponse) Reset() { *x = GetBlockResponse{} - mi := &file_vm_vm_proto_msgTypes[12] + mi := &file_vm_vm_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1132,7 +1179,7 @@ func (x *GetBlockResponse) String() string { func (*GetBlockResponse) ProtoMessage() {} func (x *GetBlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[12] + mi := &file_vm_vm_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1145,7 +1192,7 @@ func (x *GetBlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockResponse.ProtoReflect.Descriptor instead. func (*GetBlockResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{12} + return file_vm_vm_proto_rawDescGZIP(), []int{13} } func (x *GetBlockResponse) GetParentId() []byte { @@ -1200,7 +1247,7 @@ type SetPreferenceRequest struct { func (x *SetPreferenceRequest) Reset() { *x = SetPreferenceRequest{} - mi := &file_vm_vm_proto_msgTypes[13] + mi := &file_vm_vm_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1212,7 +1259,7 @@ func (x *SetPreferenceRequest) String() string { func (*SetPreferenceRequest) ProtoMessage() {} func (x *SetPreferenceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[13] + mi := &file_vm_vm_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1225,7 +1272,7 @@ func (x *SetPreferenceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetPreferenceRequest.ProtoReflect.Descriptor instead. func (*SetPreferenceRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{13} + return file_vm_vm_proto_rawDescGZIP(), []int{14} } func (x *SetPreferenceRequest) GetId() []byte { @@ -1248,7 +1295,7 @@ type BlockVerifyRequest struct { func (x *BlockVerifyRequest) Reset() { *x = BlockVerifyRequest{} - mi := &file_vm_vm_proto_msgTypes[14] + mi := &file_vm_vm_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1260,7 +1307,7 @@ func (x *BlockVerifyRequest) String() string { func (*BlockVerifyRequest) ProtoMessage() {} func (x *BlockVerifyRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[14] + mi := &file_vm_vm_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1273,7 +1320,7 @@ func (x *BlockVerifyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockVerifyRequest.ProtoReflect.Descriptor instead. func (*BlockVerifyRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{14} + return file_vm_vm_proto_rawDescGZIP(), []int{15} } func (x *BlockVerifyRequest) GetBytes() []byte { @@ -1300,7 +1347,7 @@ type BlockVerifyResponse struct { func (x *BlockVerifyResponse) Reset() { *x = BlockVerifyResponse{} - mi := &file_vm_vm_proto_msgTypes[15] + mi := &file_vm_vm_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1312,7 +1359,7 @@ func (x *BlockVerifyResponse) String() string { func (*BlockVerifyResponse) ProtoMessage() {} func (x *BlockVerifyResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[15] + mi := &file_vm_vm_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1325,7 +1372,7 @@ func (x *BlockVerifyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockVerifyResponse.ProtoReflect.Descriptor instead. func (*BlockVerifyResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{15} + return file_vm_vm_proto_rawDescGZIP(), []int{16} } func (x *BlockVerifyResponse) GetTimestamp() *timestamppb.Timestamp { @@ -1345,7 +1392,7 @@ type BlockAcceptRequest struct { func (x *BlockAcceptRequest) Reset() { *x = BlockAcceptRequest{} - mi := &file_vm_vm_proto_msgTypes[16] + mi := &file_vm_vm_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1357,7 +1404,7 @@ func (x *BlockAcceptRequest) String() string { func (*BlockAcceptRequest) ProtoMessage() {} func (x *BlockAcceptRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[16] + mi := &file_vm_vm_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1370,7 +1417,7 @@ func (x *BlockAcceptRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockAcceptRequest.ProtoReflect.Descriptor instead. func (*BlockAcceptRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{16} + return file_vm_vm_proto_rawDescGZIP(), []int{17} } func (x *BlockAcceptRequest) GetId() []byte { @@ -1390,7 +1437,7 @@ type BlockRejectRequest struct { func (x *BlockRejectRequest) Reset() { *x = BlockRejectRequest{} - mi := &file_vm_vm_proto_msgTypes[17] + mi := &file_vm_vm_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1402,7 +1449,7 @@ func (x *BlockRejectRequest) String() string { func (*BlockRejectRequest) ProtoMessage() {} func (x *BlockRejectRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[17] + mi := &file_vm_vm_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1415,7 +1462,7 @@ func (x *BlockRejectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockRejectRequest.ProtoReflect.Descriptor instead. func (*BlockRejectRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{17} + return file_vm_vm_proto_rawDescGZIP(), []int{18} } func (x *BlockRejectRequest) GetId() []byte { @@ -1435,7 +1482,7 @@ type HealthResponse struct { func (x *HealthResponse) Reset() { *x = HealthResponse{} - mi := &file_vm_vm_proto_msgTypes[18] + mi := &file_vm_vm_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1447,7 +1494,7 @@ func (x *HealthResponse) String() string { func (*HealthResponse) ProtoMessage() {} func (x *HealthResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[18] + mi := &file_vm_vm_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1460,7 +1507,7 @@ func (x *HealthResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use HealthResponse.ProtoReflect.Descriptor instead. func (*HealthResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{18} + return file_vm_vm_proto_rawDescGZIP(), []int{19} } func (x *HealthResponse) GetDetails() []byte { @@ -1480,7 +1527,7 @@ type VersionResponse struct { func (x *VersionResponse) Reset() { *x = VersionResponse{} - mi := &file_vm_vm_proto_msgTypes[19] + mi := &file_vm_vm_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1492,7 +1539,7 @@ func (x *VersionResponse) String() string { func (*VersionResponse) ProtoMessage() {} func (x *VersionResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[19] + mi := &file_vm_vm_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1505,7 +1552,7 @@ func (x *VersionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionResponse.ProtoReflect.Descriptor instead. func (*VersionResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{19} + return file_vm_vm_proto_rawDescGZIP(), []int{20} } func (x *VersionResponse) GetVersion() string { @@ -1532,7 +1579,7 @@ type AppRequestMsg struct { func (x *AppRequestMsg) Reset() { *x = AppRequestMsg{} - mi := &file_vm_vm_proto_msgTypes[20] + mi := &file_vm_vm_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1544,7 +1591,7 @@ func (x *AppRequestMsg) String() string { func (*AppRequestMsg) ProtoMessage() {} func (x *AppRequestMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[20] + mi := &file_vm_vm_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1557,7 +1604,7 @@ func (x *AppRequestMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use AppRequestMsg.ProtoReflect.Descriptor instead. func (*AppRequestMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{20} + return file_vm_vm_proto_rawDescGZIP(), []int{21} } func (x *AppRequestMsg) GetNodeId() []byte { @@ -1605,7 +1652,7 @@ type AppRequestFailedMsg struct { func (x *AppRequestFailedMsg) Reset() { *x = AppRequestFailedMsg{} - mi := &file_vm_vm_proto_msgTypes[21] + mi := &file_vm_vm_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1617,7 +1664,7 @@ func (x *AppRequestFailedMsg) String() string { func (*AppRequestFailedMsg) ProtoMessage() {} func (x *AppRequestFailedMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[21] + mi := &file_vm_vm_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1630,7 +1677,7 @@ func (x *AppRequestFailedMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use AppRequestFailedMsg.ProtoReflect.Descriptor instead. func (*AppRequestFailedMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{21} + return file_vm_vm_proto_rawDescGZIP(), []int{22} } func (x *AppRequestFailedMsg) GetNodeId() []byte { @@ -1676,7 +1723,7 @@ type AppResponseMsg struct { func (x *AppResponseMsg) Reset() { *x = AppResponseMsg{} - mi := &file_vm_vm_proto_msgTypes[22] + mi := &file_vm_vm_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1688,7 +1735,7 @@ func (x *AppResponseMsg) String() string { func (*AppResponseMsg) ProtoMessage() {} func (x *AppResponseMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[22] + mi := &file_vm_vm_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1701,7 +1748,7 @@ func (x *AppResponseMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use AppResponseMsg.ProtoReflect.Descriptor instead. func (*AppResponseMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{22} + return file_vm_vm_proto_rawDescGZIP(), []int{23} } func (x *AppResponseMsg) GetNodeId() []byte { @@ -1738,7 +1785,7 @@ type AppGossipMsg struct { func (x *AppGossipMsg) Reset() { *x = AppGossipMsg{} - mi := &file_vm_vm_proto_msgTypes[23] + mi := &file_vm_vm_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1750,7 +1797,7 @@ func (x *AppGossipMsg) String() string { func (*AppGossipMsg) ProtoMessage() {} func (x *AppGossipMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[23] + mi := &file_vm_vm_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1763,7 +1810,7 @@ func (x *AppGossipMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use AppGossipMsg.ProtoReflect.Descriptor instead. func (*AppGossipMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{23} + return file_vm_vm_proto_rawDescGZIP(), []int{24} } func (x *AppGossipMsg) GetNodeId() []byte { @@ -1796,7 +1843,7 @@ type ConnectedRequest struct { func (x *ConnectedRequest) Reset() { *x = ConnectedRequest{} - mi := &file_vm_vm_proto_msgTypes[24] + mi := &file_vm_vm_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1808,7 +1855,7 @@ func (x *ConnectedRequest) String() string { func (*ConnectedRequest) ProtoMessage() {} func (x *ConnectedRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[24] + mi := &file_vm_vm_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1821,7 +1868,7 @@ func (x *ConnectedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConnectedRequest.ProtoReflect.Descriptor instead. func (*ConnectedRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{24} + return file_vm_vm_proto_rawDescGZIP(), []int{25} } func (x *ConnectedRequest) GetNodeId() []byte { @@ -1869,7 +1916,7 @@ type DisconnectedRequest struct { func (x *DisconnectedRequest) Reset() { *x = DisconnectedRequest{} - mi := &file_vm_vm_proto_msgTypes[25] + mi := &file_vm_vm_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1881,7 +1928,7 @@ func (x *DisconnectedRequest) String() string { func (*DisconnectedRequest) ProtoMessage() {} func (x *DisconnectedRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[25] + mi := &file_vm_vm_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1894,7 +1941,7 @@ func (x *DisconnectedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DisconnectedRequest.ProtoReflect.Descriptor instead. func (*DisconnectedRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{25} + return file_vm_vm_proto_rawDescGZIP(), []int{26} } func (x *DisconnectedRequest) GetNodeId() []byte { @@ -1917,7 +1964,7 @@ type GetAncestorsRequest struct { func (x *GetAncestorsRequest) Reset() { *x = GetAncestorsRequest{} - mi := &file_vm_vm_proto_msgTypes[26] + mi := &file_vm_vm_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1929,7 +1976,7 @@ func (x *GetAncestorsRequest) String() string { func (*GetAncestorsRequest) ProtoMessage() {} func (x *GetAncestorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[26] + mi := &file_vm_vm_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1942,7 +1989,7 @@ func (x *GetAncestorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAncestorsRequest.ProtoReflect.Descriptor instead. func (*GetAncestorsRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{26} + return file_vm_vm_proto_rawDescGZIP(), []int{27} } func (x *GetAncestorsRequest) GetBlkId() []byte { @@ -1983,7 +2030,7 @@ type GetAncestorsResponse struct { func (x *GetAncestorsResponse) Reset() { *x = GetAncestorsResponse{} - mi := &file_vm_vm_proto_msgTypes[27] + mi := &file_vm_vm_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1995,7 +2042,7 @@ func (x *GetAncestorsResponse) String() string { func (*GetAncestorsResponse) ProtoMessage() {} func (x *GetAncestorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[27] + mi := &file_vm_vm_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2008,7 +2055,7 @@ func (x *GetAncestorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAncestorsResponse.ProtoReflect.Descriptor instead. func (*GetAncestorsResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{27} + return file_vm_vm_proto_rawDescGZIP(), []int{28} } func (x *GetAncestorsResponse) GetBlksBytes() [][]byte { @@ -2028,7 +2075,7 @@ type BatchedParseBlockRequest struct { func (x *BatchedParseBlockRequest) Reset() { *x = BatchedParseBlockRequest{} - mi := &file_vm_vm_proto_msgTypes[28] + mi := &file_vm_vm_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2040,7 +2087,7 @@ func (x *BatchedParseBlockRequest) String() string { func (*BatchedParseBlockRequest) ProtoMessage() {} func (x *BatchedParseBlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[28] + mi := &file_vm_vm_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2053,7 +2100,7 @@ func (x *BatchedParseBlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BatchedParseBlockRequest.ProtoReflect.Descriptor instead. func (*BatchedParseBlockRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{28} + return file_vm_vm_proto_rawDescGZIP(), []int{29} } func (x *BatchedParseBlockRequest) GetRequest() [][]byte { @@ -2073,7 +2120,7 @@ type BatchedParseBlockResponse struct { func (x *BatchedParseBlockResponse) Reset() { *x = BatchedParseBlockResponse{} - mi := &file_vm_vm_proto_msgTypes[29] + mi := &file_vm_vm_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2085,7 +2132,7 @@ func (x *BatchedParseBlockResponse) String() string { func (*BatchedParseBlockResponse) ProtoMessage() {} func (x *BatchedParseBlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[29] + mi := &file_vm_vm_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2098,7 +2145,7 @@ func (x *BatchedParseBlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BatchedParseBlockResponse.ProtoReflect.Descriptor instead. func (*BatchedParseBlockResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{29} + return file_vm_vm_proto_rawDescGZIP(), []int{30} } func (x *BatchedParseBlockResponse) GetResponse() []*ParseBlockResponse { @@ -2118,7 +2165,7 @@ type GetBlockIDAtHeightRequest struct { func (x *GetBlockIDAtHeightRequest) Reset() { *x = GetBlockIDAtHeightRequest{} - mi := &file_vm_vm_proto_msgTypes[30] + mi := &file_vm_vm_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2130,7 +2177,7 @@ func (x *GetBlockIDAtHeightRequest) String() string { func (*GetBlockIDAtHeightRequest) ProtoMessage() {} func (x *GetBlockIDAtHeightRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[30] + mi := &file_vm_vm_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2143,7 +2190,7 @@ func (x *GetBlockIDAtHeightRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockIDAtHeightRequest.ProtoReflect.Descriptor instead. func (*GetBlockIDAtHeightRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{30} + return file_vm_vm_proto_rawDescGZIP(), []int{31} } func (x *GetBlockIDAtHeightRequest) GetHeight() uint64 { @@ -2164,7 +2211,7 @@ type GetBlockIDAtHeightResponse struct { func (x *GetBlockIDAtHeightResponse) Reset() { *x = GetBlockIDAtHeightResponse{} - mi := &file_vm_vm_proto_msgTypes[31] + mi := &file_vm_vm_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2176,7 +2223,7 @@ func (x *GetBlockIDAtHeightResponse) String() string { func (*GetBlockIDAtHeightResponse) ProtoMessage() {} func (x *GetBlockIDAtHeightResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[31] + mi := &file_vm_vm_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2189,7 +2236,7 @@ func (x *GetBlockIDAtHeightResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockIDAtHeightResponse.ProtoReflect.Descriptor instead. func (*GetBlockIDAtHeightResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{31} + return file_vm_vm_proto_rawDescGZIP(), []int{32} } func (x *GetBlockIDAtHeightResponse) GetBlkId() []byte { @@ -2216,7 +2263,7 @@ type GatherResponse struct { func (x *GatherResponse) Reset() { *x = GatherResponse{} - mi := &file_vm_vm_proto_msgTypes[32] + mi := &file_vm_vm_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2228,7 +2275,7 @@ func (x *GatherResponse) String() string { func (*GatherResponse) ProtoMessage() {} func (x *GatherResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[32] + mi := &file_vm_vm_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2241,7 +2288,7 @@ func (x *GatherResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GatherResponse.ProtoReflect.Descriptor instead. func (*GatherResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{32} + return file_vm_vm_proto_rawDescGZIP(), []int{33} } func (x *GatherResponse) GetMetricFamilies() []*_go.MetricFamily { @@ -2262,7 +2309,7 @@ type StateSyncEnabledResponse struct { func (x *StateSyncEnabledResponse) Reset() { *x = StateSyncEnabledResponse{} - mi := &file_vm_vm_proto_msgTypes[33] + mi := &file_vm_vm_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2274,7 +2321,7 @@ func (x *StateSyncEnabledResponse) String() string { func (*StateSyncEnabledResponse) ProtoMessage() {} func (x *StateSyncEnabledResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[33] + mi := &file_vm_vm_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2287,7 +2334,7 @@ func (x *StateSyncEnabledResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSyncEnabledResponse.ProtoReflect.Descriptor instead. func (*StateSyncEnabledResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{33} + return file_vm_vm_proto_rawDescGZIP(), []int{34} } func (x *StateSyncEnabledResponse) GetEnabled() bool { @@ -2317,7 +2364,7 @@ type GetOngoingSyncStateSummaryResponse struct { func (x *GetOngoingSyncStateSummaryResponse) Reset() { *x = GetOngoingSyncStateSummaryResponse{} - mi := &file_vm_vm_proto_msgTypes[34] + mi := &file_vm_vm_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2329,7 +2376,7 @@ func (x *GetOngoingSyncStateSummaryResponse) String() string { func (*GetOngoingSyncStateSummaryResponse) ProtoMessage() {} func (x *GetOngoingSyncStateSummaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[34] + mi := &file_vm_vm_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2342,7 +2389,7 @@ func (x *GetOngoingSyncStateSummaryResponse) ProtoReflect() protoreflect.Message // Deprecated: Use GetOngoingSyncStateSummaryResponse.ProtoReflect.Descriptor instead. func (*GetOngoingSyncStateSummaryResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{34} + return file_vm_vm_proto_rawDescGZIP(), []int{35} } func (x *GetOngoingSyncStateSummaryResponse) GetId() []byte { @@ -2386,7 +2433,7 @@ type GetLastStateSummaryResponse struct { func (x *GetLastStateSummaryResponse) Reset() { *x = GetLastStateSummaryResponse{} - mi := &file_vm_vm_proto_msgTypes[35] + mi := &file_vm_vm_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2398,7 +2445,7 @@ func (x *GetLastStateSummaryResponse) String() string { func (*GetLastStateSummaryResponse) ProtoMessage() {} func (x *GetLastStateSummaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[35] + mi := &file_vm_vm_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2411,7 +2458,7 @@ func (x *GetLastStateSummaryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLastStateSummaryResponse.ProtoReflect.Descriptor instead. func (*GetLastStateSummaryResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{35} + return file_vm_vm_proto_rawDescGZIP(), []int{36} } func (x *GetLastStateSummaryResponse) GetId() []byte { @@ -2452,7 +2499,7 @@ type ParseStateSummaryRequest struct { func (x *ParseStateSummaryRequest) Reset() { *x = ParseStateSummaryRequest{} - mi := &file_vm_vm_proto_msgTypes[36] + mi := &file_vm_vm_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2464,7 +2511,7 @@ func (x *ParseStateSummaryRequest) String() string { func (*ParseStateSummaryRequest) ProtoMessage() {} func (x *ParseStateSummaryRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[36] + mi := &file_vm_vm_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2477,7 +2524,7 @@ func (x *ParseStateSummaryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseStateSummaryRequest.ProtoReflect.Descriptor instead. func (*ParseStateSummaryRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{36} + return file_vm_vm_proto_rawDescGZIP(), []int{37} } func (x *ParseStateSummaryRequest) GetBytes() []byte { @@ -2499,7 +2546,7 @@ type ParseStateSummaryResponse struct { func (x *ParseStateSummaryResponse) Reset() { *x = ParseStateSummaryResponse{} - mi := &file_vm_vm_proto_msgTypes[37] + mi := &file_vm_vm_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2511,7 +2558,7 @@ func (x *ParseStateSummaryResponse) String() string { func (*ParseStateSummaryResponse) ProtoMessage() {} func (x *ParseStateSummaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[37] + mi := &file_vm_vm_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2524,7 +2571,7 @@ func (x *ParseStateSummaryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseStateSummaryResponse.ProtoReflect.Descriptor instead. func (*ParseStateSummaryResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{37} + return file_vm_vm_proto_rawDescGZIP(), []int{38} } func (x *ParseStateSummaryResponse) GetId() []byte { @@ -2558,7 +2605,7 @@ type GetStateSummaryRequest struct { func (x *GetStateSummaryRequest) Reset() { *x = GetStateSummaryRequest{} - mi := &file_vm_vm_proto_msgTypes[38] + mi := &file_vm_vm_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2570,7 +2617,7 @@ func (x *GetStateSummaryRequest) String() string { func (*GetStateSummaryRequest) ProtoMessage() {} func (x *GetStateSummaryRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[38] + mi := &file_vm_vm_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2583,7 +2630,7 @@ func (x *GetStateSummaryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetStateSummaryRequest.ProtoReflect.Descriptor instead. func (*GetStateSummaryRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{38} + return file_vm_vm_proto_rawDescGZIP(), []int{39} } func (x *GetStateSummaryRequest) GetHeight() uint64 { @@ -2605,7 +2652,7 @@ type GetStateSummaryResponse struct { func (x *GetStateSummaryResponse) Reset() { *x = GetStateSummaryResponse{} - mi := &file_vm_vm_proto_msgTypes[39] + mi := &file_vm_vm_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2617,7 +2664,7 @@ func (x *GetStateSummaryResponse) String() string { func (*GetStateSummaryResponse) ProtoMessage() {} func (x *GetStateSummaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[39] + mi := &file_vm_vm_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2630,7 +2677,7 @@ func (x *GetStateSummaryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetStateSummaryResponse.ProtoReflect.Descriptor instead. func (*GetStateSummaryResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{39} + return file_vm_vm_proto_rawDescGZIP(), []int{40} } func (x *GetStateSummaryResponse) GetId() []byte { @@ -2664,7 +2711,7 @@ type StateSummaryAcceptRequest struct { func (x *StateSummaryAcceptRequest) Reset() { *x = StateSummaryAcceptRequest{} - mi := &file_vm_vm_proto_msgTypes[40] + mi := &file_vm_vm_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2676,7 +2723,7 @@ func (x *StateSummaryAcceptRequest) String() string { func (*StateSummaryAcceptRequest) ProtoMessage() {} func (x *StateSummaryAcceptRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[40] + mi := &file_vm_vm_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2689,7 +2736,7 @@ func (x *StateSummaryAcceptRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSummaryAcceptRequest.ProtoReflect.Descriptor instead. func (*StateSummaryAcceptRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{40} + return file_vm_vm_proto_rawDescGZIP(), []int{41} } func (x *StateSummaryAcceptRequest) GetBytes() []byte { @@ -2710,7 +2757,7 @@ type StateSummaryAcceptResponse struct { func (x *StateSummaryAcceptResponse) Reset() { *x = StateSummaryAcceptResponse{} - mi := &file_vm_vm_proto_msgTypes[41] + mi := &file_vm_vm_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2722,7 +2769,7 @@ func (x *StateSummaryAcceptResponse) String() string { func (*StateSummaryAcceptResponse) ProtoMessage() {} func (x *StateSummaryAcceptResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[41] + mi := &file_vm_vm_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2735,7 +2782,7 @@ func (x *StateSummaryAcceptResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSummaryAcceptResponse.ProtoReflect.Descriptor instead. func (*StateSummaryAcceptResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{41} + return file_vm_vm_proto_rawDescGZIP(), []int{42} } func (x *StateSummaryAcceptResponse) GetMode() StateSummaryAcceptResponse_Mode { @@ -2904,22 +2951,41 @@ var file_vm_vm_proto_rawDesc = []byte{ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x08, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x76, 0x6d, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x08, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, - 0x22, 0x42, 0x0a, 0x07, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x70, - 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, - 0x66, 0x69, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x41, 0x64, 0x64, 0x72, 0x22, 0x51, 0x0a, 0x11, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x5f, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xd9, 0x01, 0x0a, 0x12, 0x42, 0x75, 0x69, 0x6c, - 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x22, 0x3d, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x32, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x22, + 0x42, 0x0a, 0x07, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x22, 0x51, 0x0a, 0x11, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x5f, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x48, 0x00, 0x52, 0x0c, 0x70, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xd9, 0x01, 0x0a, 0x12, 0x42, 0x75, 0x69, 0x6c, 0x64, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, + 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x77, 0x69, 0x74, + 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x22, 0x29, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xc3, 0x01, + 0x0a, 0x12, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, @@ -2927,334 +2993,323 @@ var file_vm_vm_proto_rawDesc = []byte{ 0x61, 0x6d, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x22, 0x29, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xc3, - 0x01, 0x0a, 0x12, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x77, - 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x22, 0x21, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0xe4, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, - 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, - 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x12, 0x2e, - 0x0a, 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x76, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x26, - 0x0a, 0x14, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, + 0x65, 0x78, 0x74, 0x22, 0x21, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x68, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, - 0x0f, 0x5f, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x22, 0x4f, 0x0a, 0x13, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x22, 0x24, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x24, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2a, 0x0a, - 0x0e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x2b, 0x0a, 0x0f, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 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, 0x99, 0x01, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x36, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, - 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x22, 0x91, 0x01, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, - 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, - 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, - 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x64, 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, 0x0c, - 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, - 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, - 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0x81, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, - 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, - 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, - 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, - 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, - 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x2e, 0x0a, 0x13, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0xb3, 0x01, 0x0a, 0x13, - 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, - 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x4e, 0x75, 0x6d, - 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x37, 0x0a, 0x18, 0x6d, 0x61, 0x78, 0x5f, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x54, 0x69, 0x6d, - 0x65, 0x22, 0x35, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6b, - 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x62, - 0x6c, 0x6b, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4f, - 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x33, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x22, 0x50, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x5d, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, - 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, - 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x52, 0x0e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, 0x61, 0x6d, - 0x69, 0x6c, 0x69, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, - 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, - 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x7f, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x4f, - 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 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, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, - 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x78, 0x0a, 0x1b, 0x47, 0x65, 0x74, - 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 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, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, - 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x18, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0x60, 0x0a, 0x19, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, - 0x69, 0x64, 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, 0x1b, 0x0a, 0x03, 0x65, 0x72, - 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x5c, 0x0a, 0x17, 0x47, 0x65, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, - 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x1a, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x6d, 0x6f, 0x64, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, - 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, - 0x51, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, - 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x01, 0x12, - 0x0f, 0x0a, 0x0b, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x02, - 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x49, 0x43, - 0x10, 0x03, 0x2a, 0x65, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, - 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x53, - 0x54, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, - 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4e, 0x4f, - 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x6b, 0x0a, 0x05, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, - 0x12, 0x24, 0x0a, 0x20, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, - 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, - 0x4e, 0x54, 0x45, 0x44, 0x10, 0x03, 0x32, 0x91, 0x0f, 0x0a, 0x02, 0x56, 0x4d, 0x12, 0x3b, 0x0a, - 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x15, 0x2e, 0x76, 0x6d, - 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, - 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x65, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, - 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, - 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x12, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, - 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x17, - 0x2e, 0x76, 0x6d, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x3b, 0x0a, 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, - 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, - 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, - 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, - 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x41, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x76, - 0x6d, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x11, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x10, 0x41, 0x70, - 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x17, - 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, - 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x39, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, - 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, - 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x41, 0x70, - 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x10, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, - 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x34, 0x0a, 0x06, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, - 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, - 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, - 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, - 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, - 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, - 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, + 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0xe4, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x16, + 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, + 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x12, 0x2e, 0x0a, + 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x76, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x26, 0x0a, + 0x14, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x68, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, + 0x5f, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, + 0x4f, 0x0a, 0x13, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x22, 0x24, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x24, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, + 0x65, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2a, 0x0a, 0x0e, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x2b, 0x0a, 0x0f, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 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, 0x99, 0x01, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x36, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x64, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x91, 0x01, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, + 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x64, 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, 0x0c, 0x41, + 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, + 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0x81, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, + 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, + 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, + 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x2e, 0x0a, 0x13, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0xb3, 0x01, 0x0a, 0x13, 0x47, + 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, + 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x4e, 0x75, 0x6d, 0x12, + 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x37, 0x0a, 0x18, 0x6d, 0x61, 0x78, 0x5f, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, + 0x22, 0x35, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6b, 0x73, + 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, + 0x6b, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4f, 0x0a, + 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, + 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, + 0x0a, 0x19, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x22, 0x50, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x48, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, - 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x1a, 0x47, - 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x26, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, - 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, - 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, - 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x50, 0x61, 0x72, - 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, - 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, - 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x47, - 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, - 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, - 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x65, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x5d, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, 0x61, + 0x6d, 0x69, 0x6c, 0x79, 0x52, 0x0e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, 0x61, 0x6d, 0x69, + 0x6c, 0x69, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, + 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x7f, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x4f, 0x6e, + 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 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, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, + 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x78, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4c, + 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 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, + 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, + 0x72, 0x72, 0x22, 0x30, 0x0a, 0x18, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x22, 0x60, 0x0a, 0x19, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, + 0x64, 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, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x5c, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x1a, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, + 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, + 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x51, + 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, + 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0f, + 0x0a, 0x0b, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x02, 0x12, + 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x49, 0x43, 0x10, + 0x03, 0x2a, 0x65, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, + 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, + 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4e, 0x4f, 0x52, + 0x4d, 0x41, 0x4c, 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x6b, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x12, + 0x24, 0x0a, 0x20, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, + 0x59, 0x4e, 0x43, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, + 0x54, 0x45, 0x44, 0x10, 0x03, 0x32, 0xdf, 0x0f, 0x0a, 0x02, 0x56, 0x4d, 0x12, 0x3b, 0x0a, 0x0a, + 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, + 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, + 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3a, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, + 0x32, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, + 0x32, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x39, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x14, 0x2e, + 0x76, 0x6d, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, + 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0a, + 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, + 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x50, 0x61, 0x72, + 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, + 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, + 0x0d, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, + 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x34, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, + 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x76, + 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, + 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, + 0x64, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0b, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x76, 0x6d, + 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, + 0x73, 0x73, 0x69, 0x70, 0x12, 0x10, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, + 0x73, 0x69, 0x70, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, + 0x0a, 0x06, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, + 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x76, + 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x47, 0x65, 0x74, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, + 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, + 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, + 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4f, + 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, + 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, + 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x53, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, - 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, + 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x76, 0x6d, + 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x50, + 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x76, 0x6d, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x6d, + 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, + 0x63, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x12, 0x53, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, + 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x70, 0x62, 0x2f, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3270,7 +3325,7 @@ func file_vm_vm_proto_rawDescGZIP() []byte { } var file_vm_vm_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_vm_vm_proto_msgTypes = make([]protoimpl.MessageInfo, 42) +var file_vm_vm_proto_msgTypes = make([]protoimpl.MessageInfo, 43) var file_vm_vm_proto_goTypes = []any{ (State)(0), // 0: vm.State (Error)(0), // 1: vm.Error @@ -3281,75 +3336,76 @@ var file_vm_vm_proto_goTypes = []any{ (*SetStateRequest)(nil), // 6: vm.SetStateRequest (*SetStateResponse)(nil), // 7: vm.SetStateResponse (*CreateHandlersResponse)(nil), // 8: vm.CreateHandlersResponse - (*Handler)(nil), // 9: vm.Handler - (*BuildBlockRequest)(nil), // 10: vm.BuildBlockRequest - (*BuildBlockResponse)(nil), // 11: vm.BuildBlockResponse - (*ParseBlockRequest)(nil), // 12: vm.ParseBlockRequest - (*ParseBlockResponse)(nil), // 13: vm.ParseBlockResponse - (*GetBlockRequest)(nil), // 14: vm.GetBlockRequest - (*GetBlockResponse)(nil), // 15: vm.GetBlockResponse - (*SetPreferenceRequest)(nil), // 16: vm.SetPreferenceRequest - (*BlockVerifyRequest)(nil), // 17: vm.BlockVerifyRequest - (*BlockVerifyResponse)(nil), // 18: vm.BlockVerifyResponse - (*BlockAcceptRequest)(nil), // 19: vm.BlockAcceptRequest - (*BlockRejectRequest)(nil), // 20: vm.BlockRejectRequest - (*HealthResponse)(nil), // 21: vm.HealthResponse - (*VersionResponse)(nil), // 22: vm.VersionResponse - (*AppRequestMsg)(nil), // 23: vm.AppRequestMsg - (*AppRequestFailedMsg)(nil), // 24: vm.AppRequestFailedMsg - (*AppResponseMsg)(nil), // 25: vm.AppResponseMsg - (*AppGossipMsg)(nil), // 26: vm.AppGossipMsg - (*ConnectedRequest)(nil), // 27: vm.ConnectedRequest - (*DisconnectedRequest)(nil), // 28: vm.DisconnectedRequest - (*GetAncestorsRequest)(nil), // 29: vm.GetAncestorsRequest - (*GetAncestorsResponse)(nil), // 30: vm.GetAncestorsResponse - (*BatchedParseBlockRequest)(nil), // 31: vm.BatchedParseBlockRequest - (*BatchedParseBlockResponse)(nil), // 32: vm.BatchedParseBlockResponse - (*GetBlockIDAtHeightRequest)(nil), // 33: vm.GetBlockIDAtHeightRequest - (*GetBlockIDAtHeightResponse)(nil), // 34: vm.GetBlockIDAtHeightResponse - (*GatherResponse)(nil), // 35: vm.GatherResponse - (*StateSyncEnabledResponse)(nil), // 36: vm.StateSyncEnabledResponse - (*GetOngoingSyncStateSummaryResponse)(nil), // 37: vm.GetOngoingSyncStateSummaryResponse - (*GetLastStateSummaryResponse)(nil), // 38: vm.GetLastStateSummaryResponse - (*ParseStateSummaryRequest)(nil), // 39: vm.ParseStateSummaryRequest - (*ParseStateSummaryResponse)(nil), // 40: vm.ParseStateSummaryResponse - (*GetStateSummaryRequest)(nil), // 41: vm.GetStateSummaryRequest - (*GetStateSummaryResponse)(nil), // 42: vm.GetStateSummaryResponse - (*StateSummaryAcceptRequest)(nil), // 43: vm.StateSummaryAcceptRequest - (*StateSummaryAcceptResponse)(nil), // 44: vm.StateSummaryAcceptResponse - (*timestamppb.Timestamp)(nil), // 45: google.protobuf.Timestamp - (*_go.MetricFamily)(nil), // 46: io.prometheus.client.MetricFamily - (*emptypb.Empty)(nil), // 47: google.protobuf.Empty + (*CreateHTTP2HandlerResponse)(nil), // 9: vm.CreateHTTP2HandlerResponse + (*Handler)(nil), // 10: vm.Handler + (*BuildBlockRequest)(nil), // 11: vm.BuildBlockRequest + (*BuildBlockResponse)(nil), // 12: vm.BuildBlockResponse + (*ParseBlockRequest)(nil), // 13: vm.ParseBlockRequest + (*ParseBlockResponse)(nil), // 14: vm.ParseBlockResponse + (*GetBlockRequest)(nil), // 15: vm.GetBlockRequest + (*GetBlockResponse)(nil), // 16: vm.GetBlockResponse + (*SetPreferenceRequest)(nil), // 17: vm.SetPreferenceRequest + (*BlockVerifyRequest)(nil), // 18: vm.BlockVerifyRequest + (*BlockVerifyResponse)(nil), // 19: vm.BlockVerifyResponse + (*BlockAcceptRequest)(nil), // 20: vm.BlockAcceptRequest + (*BlockRejectRequest)(nil), // 21: vm.BlockRejectRequest + (*HealthResponse)(nil), // 22: vm.HealthResponse + (*VersionResponse)(nil), // 23: vm.VersionResponse + (*AppRequestMsg)(nil), // 24: vm.AppRequestMsg + (*AppRequestFailedMsg)(nil), // 25: vm.AppRequestFailedMsg + (*AppResponseMsg)(nil), // 26: vm.AppResponseMsg + (*AppGossipMsg)(nil), // 27: vm.AppGossipMsg + (*ConnectedRequest)(nil), // 28: vm.ConnectedRequest + (*DisconnectedRequest)(nil), // 29: vm.DisconnectedRequest + (*GetAncestorsRequest)(nil), // 30: vm.GetAncestorsRequest + (*GetAncestorsResponse)(nil), // 31: vm.GetAncestorsResponse + (*BatchedParseBlockRequest)(nil), // 32: vm.BatchedParseBlockRequest + (*BatchedParseBlockResponse)(nil), // 33: vm.BatchedParseBlockResponse + (*GetBlockIDAtHeightRequest)(nil), // 34: vm.GetBlockIDAtHeightRequest + (*GetBlockIDAtHeightResponse)(nil), // 35: vm.GetBlockIDAtHeightResponse + (*GatherResponse)(nil), // 36: vm.GatherResponse + (*StateSyncEnabledResponse)(nil), // 37: vm.StateSyncEnabledResponse + (*GetOngoingSyncStateSummaryResponse)(nil), // 38: vm.GetOngoingSyncStateSummaryResponse + (*GetLastStateSummaryResponse)(nil), // 39: vm.GetLastStateSummaryResponse + (*ParseStateSummaryRequest)(nil), // 40: vm.ParseStateSummaryRequest + (*ParseStateSummaryResponse)(nil), // 41: vm.ParseStateSummaryResponse + (*GetStateSummaryRequest)(nil), // 42: vm.GetStateSummaryRequest + (*GetStateSummaryResponse)(nil), // 43: vm.GetStateSummaryResponse + (*StateSummaryAcceptRequest)(nil), // 44: vm.StateSummaryAcceptRequest + (*StateSummaryAcceptResponse)(nil), // 45: vm.StateSummaryAcceptResponse + (*timestamppb.Timestamp)(nil), // 46: google.protobuf.Timestamp + (*_go.MetricFamily)(nil), // 47: io.prometheus.client.MetricFamily + (*emptypb.Empty)(nil), // 48: google.protobuf.Empty } var file_vm_vm_proto_depIdxs = []int32{ 4, // 0: vm.InitializeRequest.network_upgrades:type_name -> vm.NetworkUpgrades - 45, // 1: vm.NetworkUpgrades.apricot_phase_1_time:type_name -> google.protobuf.Timestamp - 45, // 2: vm.NetworkUpgrades.apricot_phase_2_time:type_name -> google.protobuf.Timestamp - 45, // 3: vm.NetworkUpgrades.apricot_phase_3_time:type_name -> google.protobuf.Timestamp - 45, // 4: vm.NetworkUpgrades.apricot_phase_4_time:type_name -> google.protobuf.Timestamp - 45, // 5: vm.NetworkUpgrades.apricot_phase_5_time:type_name -> google.protobuf.Timestamp - 45, // 6: vm.NetworkUpgrades.apricot_phase_pre_6_time:type_name -> google.protobuf.Timestamp - 45, // 7: vm.NetworkUpgrades.apricot_phase_6_time:type_name -> google.protobuf.Timestamp - 45, // 8: vm.NetworkUpgrades.apricot_phase_post_6_time:type_name -> google.protobuf.Timestamp - 45, // 9: vm.NetworkUpgrades.banff_time:type_name -> google.protobuf.Timestamp - 45, // 10: vm.NetworkUpgrades.cortina_time:type_name -> google.protobuf.Timestamp - 45, // 11: vm.NetworkUpgrades.durango_time:type_name -> google.protobuf.Timestamp - 45, // 12: vm.NetworkUpgrades.etna_time:type_name -> google.protobuf.Timestamp - 45, // 13: vm.NetworkUpgrades.fortuna_time:type_name -> google.protobuf.Timestamp - 45, // 14: vm.NetworkUpgrades.granite_time:type_name -> google.protobuf.Timestamp - 45, // 15: vm.InitializeResponse.timestamp:type_name -> google.protobuf.Timestamp + 46, // 1: vm.NetworkUpgrades.apricot_phase_1_time:type_name -> google.protobuf.Timestamp + 46, // 2: vm.NetworkUpgrades.apricot_phase_2_time:type_name -> google.protobuf.Timestamp + 46, // 3: vm.NetworkUpgrades.apricot_phase_3_time:type_name -> google.protobuf.Timestamp + 46, // 4: vm.NetworkUpgrades.apricot_phase_4_time:type_name -> google.protobuf.Timestamp + 46, // 5: vm.NetworkUpgrades.apricot_phase_5_time:type_name -> google.protobuf.Timestamp + 46, // 6: vm.NetworkUpgrades.apricot_phase_pre_6_time:type_name -> google.protobuf.Timestamp + 46, // 7: vm.NetworkUpgrades.apricot_phase_6_time:type_name -> google.protobuf.Timestamp + 46, // 8: vm.NetworkUpgrades.apricot_phase_post_6_time:type_name -> google.protobuf.Timestamp + 46, // 9: vm.NetworkUpgrades.banff_time:type_name -> google.protobuf.Timestamp + 46, // 10: vm.NetworkUpgrades.cortina_time:type_name -> google.protobuf.Timestamp + 46, // 11: vm.NetworkUpgrades.durango_time:type_name -> google.protobuf.Timestamp + 46, // 12: vm.NetworkUpgrades.etna_time:type_name -> google.protobuf.Timestamp + 46, // 13: vm.NetworkUpgrades.fortuna_time:type_name -> google.protobuf.Timestamp + 46, // 14: vm.NetworkUpgrades.granite_time:type_name -> google.protobuf.Timestamp + 46, // 15: vm.InitializeResponse.timestamp:type_name -> google.protobuf.Timestamp 0, // 16: vm.SetStateRequest.state:type_name -> vm.State - 45, // 17: vm.SetStateResponse.timestamp:type_name -> google.protobuf.Timestamp - 9, // 18: vm.CreateHandlersResponse.handlers:type_name -> vm.Handler - 45, // 19: vm.BuildBlockResponse.timestamp:type_name -> google.protobuf.Timestamp - 45, // 20: vm.ParseBlockResponse.timestamp:type_name -> google.protobuf.Timestamp - 45, // 21: vm.GetBlockResponse.timestamp:type_name -> google.protobuf.Timestamp + 46, // 17: vm.SetStateResponse.timestamp:type_name -> google.protobuf.Timestamp + 10, // 18: vm.CreateHandlersResponse.handlers:type_name -> vm.Handler + 46, // 19: vm.BuildBlockResponse.timestamp:type_name -> google.protobuf.Timestamp + 46, // 20: vm.ParseBlockResponse.timestamp:type_name -> google.protobuf.Timestamp + 46, // 21: vm.GetBlockResponse.timestamp:type_name -> google.protobuf.Timestamp 1, // 22: vm.GetBlockResponse.err:type_name -> vm.Error - 45, // 23: vm.BlockVerifyResponse.timestamp:type_name -> google.protobuf.Timestamp - 45, // 24: vm.AppRequestMsg.deadline:type_name -> google.protobuf.Timestamp - 13, // 25: vm.BatchedParseBlockResponse.response:type_name -> vm.ParseBlockResponse + 46, // 23: vm.BlockVerifyResponse.timestamp:type_name -> google.protobuf.Timestamp + 46, // 24: vm.AppRequestMsg.deadline:type_name -> google.protobuf.Timestamp + 14, // 25: vm.BatchedParseBlockResponse.response:type_name -> vm.ParseBlockResponse 1, // 26: vm.GetBlockIDAtHeightResponse.err:type_name -> vm.Error - 46, // 27: vm.GatherResponse.metric_families:type_name -> io.prometheus.client.MetricFamily + 47, // 27: vm.GatherResponse.metric_families:type_name -> io.prometheus.client.MetricFamily 1, // 28: vm.StateSyncEnabledResponse.err:type_name -> vm.Error 1, // 29: vm.GetOngoingSyncStateSummaryResponse.err:type_name -> vm.Error 1, // 30: vm.GetLastStateSummaryResponse.err:type_name -> vm.Error @@ -3359,64 +3415,66 @@ var file_vm_vm_proto_depIdxs = []int32{ 1, // 34: vm.StateSummaryAcceptResponse.err:type_name -> vm.Error 3, // 35: vm.VM.Initialize:input_type -> vm.InitializeRequest 6, // 36: vm.VM.SetState:input_type -> vm.SetStateRequest - 47, // 37: vm.VM.Shutdown:input_type -> google.protobuf.Empty - 47, // 38: vm.VM.CreateHandlers:input_type -> google.protobuf.Empty - 27, // 39: vm.VM.Connected:input_type -> vm.ConnectedRequest - 28, // 40: vm.VM.Disconnected:input_type -> vm.DisconnectedRequest - 10, // 41: vm.VM.BuildBlock:input_type -> vm.BuildBlockRequest - 12, // 42: vm.VM.ParseBlock:input_type -> vm.ParseBlockRequest - 14, // 43: vm.VM.GetBlock:input_type -> vm.GetBlockRequest - 16, // 44: vm.VM.SetPreference:input_type -> vm.SetPreferenceRequest - 47, // 45: vm.VM.Health:input_type -> google.protobuf.Empty - 47, // 46: vm.VM.Version:input_type -> google.protobuf.Empty - 23, // 47: vm.VM.AppRequest:input_type -> vm.AppRequestMsg - 24, // 48: vm.VM.AppRequestFailed:input_type -> vm.AppRequestFailedMsg - 25, // 49: vm.VM.AppResponse:input_type -> vm.AppResponseMsg - 26, // 50: vm.VM.AppGossip:input_type -> vm.AppGossipMsg - 47, // 51: vm.VM.Gather:input_type -> google.protobuf.Empty - 29, // 52: vm.VM.GetAncestors:input_type -> vm.GetAncestorsRequest - 31, // 53: vm.VM.BatchedParseBlock:input_type -> vm.BatchedParseBlockRequest - 33, // 54: vm.VM.GetBlockIDAtHeight:input_type -> vm.GetBlockIDAtHeightRequest - 47, // 55: vm.VM.StateSyncEnabled:input_type -> google.protobuf.Empty - 47, // 56: vm.VM.GetOngoingSyncStateSummary:input_type -> google.protobuf.Empty - 47, // 57: vm.VM.GetLastStateSummary:input_type -> google.protobuf.Empty - 39, // 58: vm.VM.ParseStateSummary:input_type -> vm.ParseStateSummaryRequest - 41, // 59: vm.VM.GetStateSummary:input_type -> vm.GetStateSummaryRequest - 17, // 60: vm.VM.BlockVerify:input_type -> vm.BlockVerifyRequest - 19, // 61: vm.VM.BlockAccept:input_type -> vm.BlockAcceptRequest - 20, // 62: vm.VM.BlockReject:input_type -> vm.BlockRejectRequest - 43, // 63: vm.VM.StateSummaryAccept:input_type -> vm.StateSummaryAcceptRequest - 5, // 64: vm.VM.Initialize:output_type -> vm.InitializeResponse - 7, // 65: vm.VM.SetState:output_type -> vm.SetStateResponse - 47, // 66: vm.VM.Shutdown:output_type -> google.protobuf.Empty - 8, // 67: vm.VM.CreateHandlers:output_type -> vm.CreateHandlersResponse - 47, // 68: vm.VM.Connected:output_type -> google.protobuf.Empty - 47, // 69: vm.VM.Disconnected:output_type -> google.protobuf.Empty - 11, // 70: vm.VM.BuildBlock:output_type -> vm.BuildBlockResponse - 13, // 71: vm.VM.ParseBlock:output_type -> vm.ParseBlockResponse - 15, // 72: vm.VM.GetBlock:output_type -> vm.GetBlockResponse - 47, // 73: vm.VM.SetPreference:output_type -> google.protobuf.Empty - 21, // 74: vm.VM.Health:output_type -> vm.HealthResponse - 22, // 75: vm.VM.Version:output_type -> vm.VersionResponse - 47, // 76: vm.VM.AppRequest:output_type -> google.protobuf.Empty - 47, // 77: vm.VM.AppRequestFailed:output_type -> google.protobuf.Empty - 47, // 78: vm.VM.AppResponse:output_type -> google.protobuf.Empty - 47, // 79: vm.VM.AppGossip:output_type -> google.protobuf.Empty - 35, // 80: vm.VM.Gather:output_type -> vm.GatherResponse - 30, // 81: vm.VM.GetAncestors:output_type -> vm.GetAncestorsResponse - 32, // 82: vm.VM.BatchedParseBlock:output_type -> vm.BatchedParseBlockResponse - 34, // 83: vm.VM.GetBlockIDAtHeight:output_type -> vm.GetBlockIDAtHeightResponse - 36, // 84: vm.VM.StateSyncEnabled:output_type -> vm.StateSyncEnabledResponse - 37, // 85: vm.VM.GetOngoingSyncStateSummary:output_type -> vm.GetOngoingSyncStateSummaryResponse - 38, // 86: vm.VM.GetLastStateSummary:output_type -> vm.GetLastStateSummaryResponse - 40, // 87: vm.VM.ParseStateSummary:output_type -> vm.ParseStateSummaryResponse - 42, // 88: vm.VM.GetStateSummary:output_type -> vm.GetStateSummaryResponse - 18, // 89: vm.VM.BlockVerify:output_type -> vm.BlockVerifyResponse - 47, // 90: vm.VM.BlockAccept:output_type -> google.protobuf.Empty - 47, // 91: vm.VM.BlockReject:output_type -> google.protobuf.Empty - 44, // 92: vm.VM.StateSummaryAccept:output_type -> vm.StateSummaryAcceptResponse - 64, // [64:93] is the sub-list for method output_type - 35, // [35:64] is the sub-list for method input_type + 48, // 37: vm.VM.Shutdown:input_type -> google.protobuf.Empty + 48, // 38: vm.VM.CreateHandlers:input_type -> google.protobuf.Empty + 48, // 39: vm.VM.CreateHTTP2Handler:input_type -> google.protobuf.Empty + 28, // 40: vm.VM.Connected:input_type -> vm.ConnectedRequest + 29, // 41: vm.VM.Disconnected:input_type -> vm.DisconnectedRequest + 11, // 42: vm.VM.BuildBlock:input_type -> vm.BuildBlockRequest + 13, // 43: vm.VM.ParseBlock:input_type -> vm.ParseBlockRequest + 15, // 44: vm.VM.GetBlock:input_type -> vm.GetBlockRequest + 17, // 45: vm.VM.SetPreference:input_type -> vm.SetPreferenceRequest + 48, // 46: vm.VM.Health:input_type -> google.protobuf.Empty + 48, // 47: vm.VM.Version:input_type -> google.protobuf.Empty + 24, // 48: vm.VM.AppRequest:input_type -> vm.AppRequestMsg + 25, // 49: vm.VM.AppRequestFailed:input_type -> vm.AppRequestFailedMsg + 26, // 50: vm.VM.AppResponse:input_type -> vm.AppResponseMsg + 27, // 51: vm.VM.AppGossip:input_type -> vm.AppGossipMsg + 48, // 52: vm.VM.Gather:input_type -> google.protobuf.Empty + 30, // 53: vm.VM.GetAncestors:input_type -> vm.GetAncestorsRequest + 32, // 54: vm.VM.BatchedParseBlock:input_type -> vm.BatchedParseBlockRequest + 34, // 55: vm.VM.GetBlockIDAtHeight:input_type -> vm.GetBlockIDAtHeightRequest + 48, // 56: vm.VM.StateSyncEnabled:input_type -> google.protobuf.Empty + 48, // 57: vm.VM.GetOngoingSyncStateSummary:input_type -> google.protobuf.Empty + 48, // 58: vm.VM.GetLastStateSummary:input_type -> google.protobuf.Empty + 40, // 59: vm.VM.ParseStateSummary:input_type -> vm.ParseStateSummaryRequest + 42, // 60: vm.VM.GetStateSummary:input_type -> vm.GetStateSummaryRequest + 18, // 61: vm.VM.BlockVerify:input_type -> vm.BlockVerifyRequest + 20, // 62: vm.VM.BlockAccept:input_type -> vm.BlockAcceptRequest + 21, // 63: vm.VM.BlockReject:input_type -> vm.BlockRejectRequest + 44, // 64: vm.VM.StateSummaryAccept:input_type -> vm.StateSummaryAcceptRequest + 5, // 65: vm.VM.Initialize:output_type -> vm.InitializeResponse + 7, // 66: vm.VM.SetState:output_type -> vm.SetStateResponse + 48, // 67: vm.VM.Shutdown:output_type -> google.protobuf.Empty + 8, // 68: vm.VM.CreateHandlers:output_type -> vm.CreateHandlersResponse + 9, // 69: vm.VM.CreateHTTP2Handler:output_type -> vm.CreateHTTP2HandlerResponse + 48, // 70: vm.VM.Connected:output_type -> google.protobuf.Empty + 48, // 71: vm.VM.Disconnected:output_type -> google.protobuf.Empty + 12, // 72: vm.VM.BuildBlock:output_type -> vm.BuildBlockResponse + 14, // 73: vm.VM.ParseBlock:output_type -> vm.ParseBlockResponse + 16, // 74: vm.VM.GetBlock:output_type -> vm.GetBlockResponse + 48, // 75: vm.VM.SetPreference:output_type -> google.protobuf.Empty + 22, // 76: vm.VM.Health:output_type -> vm.HealthResponse + 23, // 77: vm.VM.Version:output_type -> vm.VersionResponse + 48, // 78: vm.VM.AppRequest:output_type -> google.protobuf.Empty + 48, // 79: vm.VM.AppRequestFailed:output_type -> google.protobuf.Empty + 48, // 80: vm.VM.AppResponse:output_type -> google.protobuf.Empty + 48, // 81: vm.VM.AppGossip:output_type -> google.protobuf.Empty + 36, // 82: vm.VM.Gather:output_type -> vm.GatherResponse + 31, // 83: vm.VM.GetAncestors:output_type -> vm.GetAncestorsResponse + 33, // 84: vm.VM.BatchedParseBlock:output_type -> vm.BatchedParseBlockResponse + 35, // 85: vm.VM.GetBlockIDAtHeight:output_type -> vm.GetBlockIDAtHeightResponse + 37, // 86: vm.VM.StateSyncEnabled:output_type -> vm.StateSyncEnabledResponse + 38, // 87: vm.VM.GetOngoingSyncStateSummary:output_type -> vm.GetOngoingSyncStateSummaryResponse + 39, // 88: vm.VM.GetLastStateSummary:output_type -> vm.GetLastStateSummaryResponse + 41, // 89: vm.VM.ParseStateSummary:output_type -> vm.ParseStateSummaryResponse + 43, // 90: vm.VM.GetStateSummary:output_type -> vm.GetStateSummaryResponse + 19, // 91: vm.VM.BlockVerify:output_type -> vm.BlockVerifyResponse + 48, // 92: vm.VM.BlockAccept:output_type -> google.protobuf.Empty + 48, // 93: vm.VM.BlockReject:output_type -> google.protobuf.Empty + 45, // 94: vm.VM.StateSummaryAccept:output_type -> vm.StateSummaryAcceptResponse + 65, // [65:95] is the sub-list for method output_type + 35, // [35:65] is the sub-list for method input_type 35, // [35:35] is the sub-list for extension type_name 35, // [35:35] is the sub-list for extension extendee 0, // [0:35] is the sub-list for field type_name @@ -3427,15 +3485,15 @@ func file_vm_vm_proto_init() { if File_vm_vm_proto != nil { return } - file_vm_vm_proto_msgTypes[7].OneofWrappers = []any{} - file_vm_vm_proto_msgTypes[14].OneofWrappers = []any{} + file_vm_vm_proto_msgTypes[8].OneofWrappers = []any{} + file_vm_vm_proto_msgTypes[15].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vm_vm_proto_rawDesc, NumEnums: 3, - NumMessages: 42, + NumMessages: 43, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/pb/vm/vm_grpc.pb.go b/proto/pb/vm/vm_grpc.pb.go index f1b43307faab..498daeb57a84 100644 --- a/proto/pb/vm/vm_grpc.pb.go +++ b/proto/pb/vm/vm_grpc.pb.go @@ -24,6 +24,7 @@ const ( VM_SetState_FullMethodName = "/vm.VM/SetState" VM_Shutdown_FullMethodName = "/vm.VM/Shutdown" VM_CreateHandlers_FullMethodName = "/vm.VM/CreateHandlers" + VM_CreateHTTP2Handler_FullMethodName = "/vm.VM/CreateHTTP2Handler" VM_Connected_FullMethodName = "/vm.VM/Connected" VM_Disconnected_FullMethodName = "/vm.VM/Disconnected" VM_BuildBlock_FullMethodName = "/vm.VM/BuildBlock" @@ -65,6 +66,7 @@ type VMClient interface { Shutdown(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) // Creates the HTTP handlers for custom chain network calls. CreateHandlers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateHandlersResponse, error) + CreateHTTP2Handler(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateHTTP2HandlerResponse, error) Connected(ctx context.Context, in *ConnectedRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) Disconnected(ctx context.Context, in *DisconnectedRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) // Attempt to create a new block from data contained in the VM. @@ -161,6 +163,15 @@ func (c *vMClient) CreateHandlers(ctx context.Context, in *emptypb.Empty, opts . return out, nil } +func (c *vMClient) CreateHTTP2Handler(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateHTTP2HandlerResponse, error) { + out := new(CreateHTTP2HandlerResponse) + err := c.cc.Invoke(ctx, VM_CreateHTTP2Handler_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vMClient) Connected(ctx context.Context, in *ConnectedRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, VM_Connected_FullMethodName, in, out, opts...) @@ -400,6 +411,7 @@ type VMServer interface { Shutdown(context.Context, *emptypb.Empty) (*emptypb.Empty, error) // Creates the HTTP handlers for custom chain network calls. CreateHandlers(context.Context, *emptypb.Empty) (*CreateHandlersResponse, error) + CreateHTTP2Handler(context.Context, *emptypb.Empty) (*CreateHTTP2HandlerResponse, error) Connected(context.Context, *ConnectedRequest) (*emptypb.Empty, error) Disconnected(context.Context, *DisconnectedRequest) (*emptypb.Empty, error) // Attempt to create a new block from data contained in the VM. @@ -469,6 +481,9 @@ func (UnimplementedVMServer) Shutdown(context.Context, *emptypb.Empty) (*emptypb func (UnimplementedVMServer) CreateHandlers(context.Context, *emptypb.Empty) (*CreateHandlersResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateHandlers not implemented") } +func (UnimplementedVMServer) CreateHTTP2Handler(context.Context, *emptypb.Empty) (*CreateHTTP2HandlerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateHTTP2Handler not implemented") +} func (UnimplementedVMServer) Connected(context.Context, *ConnectedRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method Connected not implemented") } @@ -629,6 +644,24 @@ func _VM_CreateHandlers_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _VM_CreateHTTP2Handler_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).CreateHTTP2Handler(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VM_CreateHTTP2Handler_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).CreateHTTP2Handler(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + func _VM_Connected_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ConnectedRequest) if err := dec(in); err != nil { @@ -1102,6 +1135,10 @@ var VM_ServiceDesc = grpc.ServiceDesc{ MethodName: "CreateHandlers", Handler: _VM_CreateHandlers_Handler, }, + { + MethodName: "CreateHTTP2Handler", + Handler: _VM_CreateHTTP2Handler_Handler, + }, { MethodName: "Connected", Handler: _VM_Connected_Handler, diff --git a/proto/pb/xsvm/service.pb.go b/proto/pb/xsvm/service.pb.go new file mode 100644 index 000000000000..738007b356cc --- /dev/null +++ b/proto/pb/xsvm/service.pb.go @@ -0,0 +1,286 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc (unknown) +// source: xsvm/service.proto + +package xsvm + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *PingRequest) Reset() { + *x = PingRequest{} + mi := &file_xsvm_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PingRequest) ProtoMessage() {} + +func (x *PingRequest) ProtoReflect() protoreflect.Message { + mi := &file_xsvm_service_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. +func (*PingRequest) Descriptor() ([]byte, []int) { + return file_xsvm_service_proto_rawDescGZIP(), []int{0} +} + +func (x *PingRequest) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type PingReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *PingReply) Reset() { + *x = PingReply{} + mi := &file_xsvm_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PingReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PingReply) ProtoMessage() {} + +func (x *PingReply) ProtoReflect() protoreflect.Message { + mi := &file_xsvm_service_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PingReply.ProtoReflect.Descriptor instead. +func (*PingReply) Descriptor() ([]byte, []int) { + return file_xsvm_service_proto_rawDescGZIP(), []int{1} +} + +func (x *PingReply) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type StreamPingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *StreamPingRequest) Reset() { + *x = StreamPingRequest{} + mi := &file_xsvm_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamPingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamPingRequest) ProtoMessage() {} + +func (x *StreamPingRequest) ProtoReflect() protoreflect.Message { + mi := &file_xsvm_service_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamPingRequest.ProtoReflect.Descriptor instead. +func (*StreamPingRequest) Descriptor() ([]byte, []int) { + return file_xsvm_service_proto_rawDescGZIP(), []int{2} +} + +func (x *StreamPingRequest) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type StreamPingReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *StreamPingReply) Reset() { + *x = StreamPingReply{} + mi := &file_xsvm_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamPingReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamPingReply) ProtoMessage() {} + +func (x *StreamPingReply) ProtoReflect() protoreflect.Message { + mi := &file_xsvm_service_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamPingReply.ProtoReflect.Descriptor instead. +func (*StreamPingReply) Descriptor() ([]byte, []int) { + return file_xsvm_service_proto_rawDescGZIP(), []int{3} +} + +func (x *StreamPingReply) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +var File_xsvm_service_proto protoreflect.FileDescriptor + +var file_xsvm_service_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x78, 0x73, 0x76, 0x6d, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x78, 0x73, 0x76, 0x6d, 0x22, 0x27, 0x0a, 0x0b, 0x50, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x25, 0x0a, 0x09, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2d, 0x0a, 0x11, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2b, 0x0a, 0x0f, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x74, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x2a, + 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x11, 0x2e, 0x78, 0x73, 0x76, 0x6d, 0x2e, 0x50, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x78, 0x73, 0x76, 0x6d, + 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x40, 0x0a, 0x0a, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x17, 0x2e, 0x78, 0x73, 0x76, 0x6d, 0x2e, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x15, 0x2e, 0x78, 0x73, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x28, 0x01, 0x30, 0x01, 0x42, 0x2f, 0x5a, 0x2d, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, + 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x78, 0x73, 0x76, 0x6d, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_xsvm_service_proto_rawDescOnce sync.Once + file_xsvm_service_proto_rawDescData = file_xsvm_service_proto_rawDesc +) + +func file_xsvm_service_proto_rawDescGZIP() []byte { + file_xsvm_service_proto_rawDescOnce.Do(func() { + file_xsvm_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_xsvm_service_proto_rawDescData) + }) + return file_xsvm_service_proto_rawDescData +} + +var file_xsvm_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_xsvm_service_proto_goTypes = []any{ + (*PingRequest)(nil), // 0: xsvm.PingRequest + (*PingReply)(nil), // 1: xsvm.PingReply + (*StreamPingRequest)(nil), // 2: xsvm.StreamPingRequest + (*StreamPingReply)(nil), // 3: xsvm.StreamPingReply +} +var file_xsvm_service_proto_depIdxs = []int32{ + 0, // 0: xsvm.Ping.Ping:input_type -> xsvm.PingRequest + 2, // 1: xsvm.Ping.StreamPing:input_type -> xsvm.StreamPingRequest + 1, // 2: xsvm.Ping.Ping:output_type -> xsvm.PingReply + 3, // 3: xsvm.Ping.StreamPing:output_type -> xsvm.StreamPingReply + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_xsvm_service_proto_init() } +func file_xsvm_service_proto_init() { + if File_xsvm_service_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_xsvm_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_xsvm_service_proto_goTypes, + DependencyIndexes: file_xsvm_service_proto_depIdxs, + MessageInfos: file_xsvm_service_proto_msgTypes, + }.Build() + File_xsvm_service_proto = out.File + file_xsvm_service_proto_rawDesc = nil + file_xsvm_service_proto_goTypes = nil + file_xsvm_service_proto_depIdxs = nil +} diff --git a/proto/pb/xsvm/service_grpc.pb.go b/proto/pb/xsvm/service_grpc.pb.go new file mode 100644 index 000000000000..3a3c2e4cbf00 --- /dev/null +++ b/proto/pb/xsvm/service_grpc.pb.go @@ -0,0 +1,179 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: xsvm/service.proto + +package xsvm + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + Ping_Ping_FullMethodName = "/xsvm.Ping/Ping" + Ping_StreamPing_FullMethodName = "/xsvm.Ping/StreamPing" +) + +// PingClient is the client API for Ping service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type PingClient interface { + Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingReply, error) + StreamPing(ctx context.Context, opts ...grpc.CallOption) (Ping_StreamPingClient, error) +} + +type pingClient struct { + cc grpc.ClientConnInterface +} + +func NewPingClient(cc grpc.ClientConnInterface) PingClient { + return &pingClient{cc} +} + +func (c *pingClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingReply, error) { + out := new(PingReply) + err := c.cc.Invoke(ctx, Ping_Ping_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pingClient) StreamPing(ctx context.Context, opts ...grpc.CallOption) (Ping_StreamPingClient, error) { + stream, err := c.cc.NewStream(ctx, &Ping_ServiceDesc.Streams[0], Ping_StreamPing_FullMethodName, opts...) + if err != nil { + return nil, err + } + x := &pingStreamPingClient{stream} + return x, nil +} + +type Ping_StreamPingClient interface { + Send(*StreamPingRequest) error + Recv() (*StreamPingReply, error) + grpc.ClientStream +} + +type pingStreamPingClient struct { + grpc.ClientStream +} + +func (x *pingStreamPingClient) Send(m *StreamPingRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *pingStreamPingClient) Recv() (*StreamPingReply, error) { + m := new(StreamPingReply) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// PingServer is the server API for Ping service. +// All implementations must embed UnimplementedPingServer +// for forward compatibility +type PingServer interface { + Ping(context.Context, *PingRequest) (*PingReply, error) + StreamPing(Ping_StreamPingServer) error + mustEmbedUnimplementedPingServer() +} + +// UnimplementedPingServer must be embedded to have forward compatible implementations. +type UnimplementedPingServer struct { +} + +func (UnimplementedPingServer) Ping(context.Context, *PingRequest) (*PingReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") +} +func (UnimplementedPingServer) StreamPing(Ping_StreamPingServer) error { + return status.Errorf(codes.Unimplemented, "method StreamPing not implemented") +} +func (UnimplementedPingServer) mustEmbedUnimplementedPingServer() {} + +// UnsafePingServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PingServer will +// result in compilation errors. +type UnsafePingServer interface { + mustEmbedUnimplementedPingServer() +} + +func RegisterPingServer(s grpc.ServiceRegistrar, srv PingServer) { + s.RegisterService(&Ping_ServiceDesc, srv) +} + +func _Ping_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PingServer).Ping(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Ping_Ping_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PingServer).Ping(ctx, req.(*PingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Ping_StreamPing_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(PingServer).StreamPing(&pingStreamPingServer{stream}) +} + +type Ping_StreamPingServer interface { + Send(*StreamPingReply) error + Recv() (*StreamPingRequest, error) + grpc.ServerStream +} + +type pingStreamPingServer struct { + grpc.ServerStream +} + +func (x *pingStreamPingServer) Send(m *StreamPingReply) error { + return x.ServerStream.SendMsg(m) +} + +func (x *pingStreamPingServer) Recv() (*StreamPingRequest, error) { + m := new(StreamPingRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// Ping_ServiceDesc is the grpc.ServiceDesc for Ping service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Ping_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "xsvm.Ping", + HandlerType: (*PingServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Ping", + Handler: _Ping_Ping_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "StreamPing", + Handler: _Ping_StreamPing_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "xsvm/service.proto", +} diff --git a/proto/vm/vm.proto b/proto/vm/vm.proto index 7990ebf733ff..34334e8e540a 100644 --- a/proto/vm/vm.proto +++ b/proto/vm/vm.proto @@ -21,6 +21,7 @@ service VM { rpc Shutdown(google.protobuf.Empty) returns (google.protobuf.Empty); // Creates the HTTP handlers for custom chain network calls. rpc CreateHandlers(google.protobuf.Empty) returns (CreateHandlersResponse); + rpc CreateHTTP2Handler(google.protobuf.Empty) returns (CreateHTTP2HandlerResponse); rpc Connected(ConnectedRequest) returns (google.protobuf.Empty); rpc Disconnected(DisconnectedRequest) returns (google.protobuf.Empty); // Attempt to create a new block from data contained in the VM. @@ -158,6 +159,12 @@ message CreateHandlersResponse { repeated Handler handlers = 1; } +message CreateHTTP2HandlerResponse { + // server_addr is the address of the gRPC server which serves the + // HTTP service + string server_addr = 1; +} + message Handler { string prefix = 1; // server_addr is the address of the gRPC server which serves the diff --git a/proto/xsvm/service.proto b/proto/xsvm/service.proto new file mode 100644 index 000000000000..5d6329356f59 --- /dev/null +++ b/proto/xsvm/service.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package xsvm; + +option go_package = "github.com/ava-labs/avalanchego/proto/pb/xsvm"; + +service Ping { + rpc Ping(PingRequest) returns (PingReply); + rpc StreamPing(stream StreamPingRequest) returns (stream StreamPingReply); +} + +message PingRequest { + string message = 1; +} + +message PingReply { + string message = 1; +} + +message StreamPingRequest { + string message = 1; +} + +message StreamPingReply { + string message = 1; +} diff --git a/simplex/bls.go b/simplex/bls.go index f767dba21651..524c91842da8 100644 --- a/simplex/bls.go +++ b/simplex/bls.go @@ -40,11 +40,13 @@ type BLSVerifier struct { } func NewBLSAuth(config *Config) (BLSSigner, BLSVerifier) { + verifier := createVerifier(config) + return BLSSigner{ chainID: config.Ctx.ChainID, subnetID: config.Ctx.SubnetID, signBLS: config.SignBLS, - }, createVerifier(config) + }, verifier } // Sign returns a signature on the given message using BLS signature scheme. @@ -71,7 +73,6 @@ type encodedSimplexSignedPayload struct { Label []byte } -// encodesMessageToSign returns a byte slice [simplexLabel][chainID][networkID][message length][message]. func encodeMessageToSign(message []byte, chainID ids.ID, subnetID ids.ID) ([]byte, error) { encodedSimplexMessage := encodedSimplexSignedPayload{ Message: message, @@ -117,13 +118,9 @@ func createVerifier(config *Config) BLSVerifier { chainID: config.Ctx.ChainID, } - nodes := config.Validators.GetValidatorIDs(config.Ctx.SubnetID) - for _, node := range nodes { - validator, ok := config.Validators.GetValidator(config.Ctx.SubnetID, node) - if !ok { - continue - } - verifier.nodeID2PK[node] = *validator.PublicKey + for _, node := range config.Validators { + verifier.nodeID2PK[node.NodeID] = *node.PublicKey } + return verifier } diff --git a/simplex/bls_test.go b/simplex/bls_test.go index 5552ba4ff379..a4e9047b6348 100644 --- a/simplex/bls_test.go +++ b/simplex/bls_test.go @@ -13,7 +13,8 @@ import ( ) func TestBLSSignVerify(t *testing.T) { - config, _ := newTestEngineConfig(t, 0) + config, err := newEngineConfig(1) + require.NoError(t, err) signer, verifier := NewBLSAuth(config) @@ -27,7 +28,8 @@ func TestBLSSignVerify(t *testing.T) { } func TestSignerNotInMemberSet(t *testing.T) { - config, _ := newTestEngineConfig(t, 0) + config, err := newEngineConfig(1) + require.NoError(t, err) signer, verifier := NewBLSAuth(config) msg := "Begin at the beginning, and go on till you come to the end: then stop" @@ -41,11 +43,12 @@ func TestSignerNotInMemberSet(t *testing.T) { } func TestSignerInvalidMessageEncoding(t *testing.T) { - config, ls := newTestEngineConfig(t, 0) + config, err := newEngineConfig(1) + require.NoError(t, err) // sign a message with invalid encoding dummyMsg := []byte("dummy message") - sig, err := ls.Sign(dummyMsg) + sig, err := config.SignBLS(dummyMsg) require.NoError(t, err) sigBytes := bls.SignatureToBytes(sig) diff --git a/simplex/comm.go b/simplex/comm.go index 0e6a3be29e21..9f5d012e1acf 100644 --- a/simplex/comm.go +++ b/simplex/comm.go @@ -6,7 +6,11 @@ package simplex import ( "errors" "fmt" - "sort" + "slices" + "strings" + + "github.com/ava-labs/simplex" + "go.uber.org/zap" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" @@ -14,13 +18,9 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/sender" "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/simplex" - "go.uber.org/zap" ) -var ( - errNodeNotFound = errors.New("node not found in the validator list") -) +var errNodeNotFound = errors.New("node not found in the validator list") type Comm struct { logger simplex.Logger @@ -36,10 +36,11 @@ type Comm struct { } func NewComm(config *Config) (*Comm, error) { - var nodes []simplex.NodeID + nodes := make([]simplex.NodeID, 0, len(config.Validators)) + // grab all the nodes that are validators for the subnet - for _, id := range config.Validators.GetValidatorIDs(config.Ctx.SubnetID) { - nodes = append(nodes, id[:]) + for _, vd := range config.Validators { + nodes = append(nodes, vd.NodeID[:]) } sortedNodes := sortNodes(nodes) @@ -70,8 +71,8 @@ func NewComm(config *Config) (*Comm, error) { } func sortNodes(nodes []simplex.NodeID) []simplex.NodeID { - sort.Slice(nodes, func(i, j int) bool { - return nodes[i].String() < nodes[j].String() + slices.SortFunc(nodes, func(i, j simplex.NodeID) int { + return strings.Compare(i.String(), j.String()) }) return nodes } @@ -81,8 +82,6 @@ func (c *Comm) ListNodes() []simplex.NodeID { } func (c *Comm) SendMessage(msg *simplex.Message, destination simplex.NodeID) { - // TODO: do we want to check if the destination is in the subnet? - var outboundMessage message.OutboundMessage var err error switch { @@ -100,11 +99,14 @@ func (c *Comm) SendMessage(msg *simplex.Message, destination simplex.NodeID) { outboundMessage, err = c.msgBuilder.EmptyNotarization(c.chainID, msg.EmptyNotarization.Vote.ProtocolMetadata, msg.EmptyNotarization.QC.Bytes()) case msg.Finalization != nil: outboundMessage, err = c.msgBuilder.Finalization(c.chainID, msg.Finalization.Finalization.BlockHeader, msg.Finalization.QC.Bytes()) - // TODO: create replication messages + case msg.ReplicationRequest != nil: + outboundMessage, err = c.msgBuilder.ReplicationRequest(c.chainID, msg.ReplicationRequest.Seqs, msg.ReplicationRequest.LatestRound) + case msg.VerifiedReplicationResponse != nil: + outboundMessage, err = c.msgBuilder.VerifiedReplicationResponse(c.chainID, msg.VerifiedReplicationResponse.Data, msg.VerifiedReplicationResponse.LatestRound) } if err != nil { - c.logger.Error("Failed creating message: %w", zap.Error(err)) + c.logger.Error("Failed creating message", zap.Error(err)) return } diff --git a/simplex/comm_test.go b/simplex/comm_test.go index 449c514b3b88..bd712da9095b 100644 --- a/simplex/comm_test.go +++ b/simplex/comm_test.go @@ -6,12 +6,13 @@ package simplex import ( "testing" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/message/messagemock" - "github.com/ava-labs/avalanchego/snow/networking/sender/sendermock" "github.com/ava-labs/simplex" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/message/messagemock" + "github.com/ava-labs/avalanchego/snow/networking/sender/sendermock" ) var testSimplexMessage = simplex.Message{ @@ -34,7 +35,9 @@ var testSimplexMessage = simplex.Message{ } func TestComm(t *testing.T) { - config, _ := newTestEngineConfig(t, 1) + config, err := newEngineConfig(1) + require.NoError(t, err) + destinationNodeID := ids.GenerateTestNodeID() ctrl := gomock.NewController(t) @@ -57,7 +60,8 @@ func TestComm(t *testing.T) { // TestCommBroadcast tests the Broadcast method sends to all nodes in the subnet // not including the sending node. func TestCommBroadcast(t *testing.T) { - config, _ := newTestEngineConfig(t, 3) + config, err := newEngineConfig(3) + require.NoError(t, err) ctrl := gomock.NewController(t) msgCreator := messagemock.NewOutboundMsgBuilder(ctrl) @@ -70,14 +74,15 @@ func TestCommBroadcast(t *testing.T) { require.NoError(t, err) msgCreator.EXPECT().Vote(gomock.Any(), gomock.Any(), gomock.Any()). - Return(nil, nil).Times(3) - sender.EXPECT().Send(gomock.Any(), gomock.Any(), comm.subnetID, gomock.Any()).Times(3) + Return(nil, nil).Times(2) + sender.EXPECT().Send(gomock.Any(), gomock.Any(), comm.subnetID, gomock.Any()).Times(2) comm.Broadcast(&testSimplexMessage) } func TestCommFailsWithoutCurrentNode(t *testing.T) { - config, _ := newTestEngineConfig(t, 3) + config, err := newEngineConfig(3) + require.NoError(t, err) ctrl := gomock.NewController(t) msgCreator := messagemock.NewOutboundMsgBuilder(ctrl) @@ -87,10 +92,9 @@ func TestCommFailsWithoutCurrentNode(t *testing.T) { config.Sender = sender // set the curNode to a different nodeID than the one in the config - nodeID := ids.GenerateTestNodeID() - vdrs, err := newTestValidatorInfo(nodeID, nil, 3) + vdrs, err := generateTestValidators(3) require.NoError(t, err) - config.Validators = vdrs + config.Validators = newTestValidators(vdrs) _, err = NewComm(config) require.ErrorIs(t, err, errNodeNotFound) diff --git a/simplex/config.go b/simplex/config.go index 34dff772c3a4..0b58d5993740 100644 --- a/simplex/config.go +++ b/simplex/config.go @@ -11,20 +11,21 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" ) -type ValidatorInfo interface { - GetValidatorIDs(subnetID ids.ID) []ids.NodeID - GetValidator(subnetID ids.ID, nodeID ids.NodeID) (*validators.Validator, bool) -} - // Config wraps all the parameters needed for a simplex engine type Config struct { - Ctx SimplexChainContext - Log logging.Logger - Validators ValidatorInfo - SignBLS SignFunc + Ctx SimplexChainContext + Log logging.Logger Sender sender.ExternalSender OutboundMsgBuilder message.SimplexOutboundMessageBuilder + + // Validators is a map of node IDs to their validator information. + // This tells the node about the current membership set, and should be consistent + // across all nodes in the subnet. + Validators map[ids.NodeID]*validators.GetValidatorOutput + + // SignBLS is the signing function used for this node to sign messages. + SignBLS SignFunc } // Context is information about the current execution. diff --git a/simplex/test_util.go b/simplex/test_util.go new file mode 100644 index 000000000000..4a7cc991fe5f --- /dev/null +++ b/simplex/test_util.go @@ -0,0 +1,71 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex + +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" +) + +func newTestValidators(allVds []validators.GetValidatorOutput) map[ids.NodeID]*validators.GetValidatorOutput { + vds := make(map[ids.NodeID]*validators.GetValidatorOutput, len(allVds)) + for _, vd := range allVds { + vds[vd.NodeID] = &vd + } + + return vds +} + +func newEngineConfig(numNodes uint64) (*Config, error) { + if numNodes == 0 { + numNodes = 1 // Ensure at least one node for testing + } + + ls, err := localsigner.New() + if err != nil { + return nil, err + } + + nodeID := ids.GenerateTestNodeID() + + simplexChainContext := SimplexChainContext{ + NodeID: nodeID, + ChainID: ids.GenerateTestID(), + SubnetID: ids.GenerateTestID(), + } + + nodeInfo := validators.GetValidatorOutput{ + NodeID: nodeID, + PublicKey: ls.PublicKey(), + } + + validators, err := generateTestValidators(numNodes - 1) + if err != nil { + return nil, err + } + + return &Config{ + Ctx: simplexChainContext, + Validators: newTestValidators(append(validators, nodeInfo)), + SignBLS: ls.Sign, + }, nil +} + +func generateTestValidators(num uint64) ([]validators.GetValidatorOutput, error) { + vds := make([]validators.GetValidatorOutput, num) + for i := uint64(0); i < num; i++ { + ls, err := localsigner.New() + if err != nil { + return nil, err + } + + nodeID := ids.GenerateTestNodeID() + vds[i] = validators.GetValidatorOutput{ + NodeID: nodeID, + PublicKey: ls.PublicKey(), + } + } + return vds, nil +} diff --git a/simplex/test_utils.go b/simplex/test_utils.go deleted file mode 100644 index 3bfe97c91afc..000000000000 --- a/simplex/test_utils.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package simplex - -import ( - "testing" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" - "github.com/stretchr/testify/require" -) - -var _ ValidatorInfo = (*testValidatorInfo)(nil) - -// testValidatorInfo is a mock implementation of ValidatorInfo for testing purposes. -// it assumes all validators are in the same subnet and returns all of them for any subnetID. -type testValidatorInfo struct { - validators map[ids.NodeID]validators.Validator -} - -func (v *testValidatorInfo) GetValidatorIDs(_ ids.ID) []ids.NodeID { - if v.validators == nil { - return nil - } - - ids := make([]ids.NodeID, 0, len(v.validators)) - for id := range v.validators { - ids = append(ids, id) - } - return ids -} - -func (v *testValidatorInfo) GetValidator(_ ids.ID, nodeID ids.NodeID) (*validators.Validator, bool) { - if v.validators == nil { - return nil, false - } - - val, exists := v.validators[nodeID] - if !exists { - return nil, false - } - return &val, true -} - -func newTestValidatorInfo(curNodeId ids.NodeID, curNodePk *bls.PublicKey, numExtraNodes int) (*testValidatorInfo, error) { - vds := make(map[ids.NodeID]validators.Validator, numExtraNodes+1) - - vds[curNodeId] = validators.Validator{ - PublicKey: curNodePk, - NodeID: curNodeId, - } - - for range numExtraNodes { - ls, err := localsigner.New() - nodeID := ids.GenerateTestNodeID() - if err != nil { - return nil, err - } - - validator := validators.Validator{ - PublicKey: ls.PublicKey(), - NodeID: nodeID, - } - vds[nodeID] = validator - } - - // all we need is to generate the public keys for the validators - return &testValidatorInfo{ - validators: vds, - }, nil -} - -// newTestEngineConfig returns a new simplex Config for testing purposes -// and also returns the LocalSigner associated with this nodes config. -func newTestEngineConfig(t *testing.T, numNodes int) (*Config, *localsigner.LocalSigner) { - ls, err := localsigner.New() - require.NoError(t, err) - - nodeID := ids.GenerateTestNodeID() - simplexChainContext := SimplexChainContext{ - NodeID: nodeID, - ChainID: ids.GenerateTestID(), - SubnetID: ids.GenerateTestID(), - } - - vdrs, err := newTestValidatorInfo(nodeID, ls.PublicKey(), numNodes) - require.NoError(t, err) - - return &Config{ - Ctx: simplexChainContext, - Validators: vdrs, - SignBLS: ls.Sign, - }, ls -} diff --git a/snow/engine/avalanche/vertex/vertexmock/linearizable_vm.go b/snow/engine/avalanche/vertex/vertexmock/linearizable_vm.go index 19c2c4290475..abd1acc33599 100644 --- a/snow/engine/avalanche/vertex/vertexmock/linearizable_vm.go +++ b/snow/engine/avalanche/vertex/vertexmock/linearizable_vm.go @@ -134,6 +134,21 @@ func (mr *LinearizableVMMockRecorder) Connected(ctx, nodeID, nodeVersion any) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*LinearizableVM)(nil).Connected), ctx, nodeID, nodeVersion) } +// CreateHTTP2Handler mocks base method. +func (m *LinearizableVM) CreateHTTP2Handler(ctx context.Context) (http.Handler, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateHTTP2Handler", ctx) + ret0, _ := ret[0].(http.Handler) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateHTTP2Handler indicates an expected call of CreateHTTP2Handler. +func (mr *LinearizableVMMockRecorder) CreateHTTP2Handler(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateHTTP2Handler", reflect.TypeOf((*LinearizableVM)(nil).CreateHTTP2Handler), ctx) +} + // CreateHandlers mocks base method. func (m *LinearizableVM) CreateHandlers(arg0 context.Context) (map[string]http.Handler, error) { m.ctrl.T.Helper() diff --git a/snow/engine/common/vm.go b/snow/engine/common/vm.go index 65cbfb158656..3d9c021d208d 100644 --- a/snow/engine/common/vm.go +++ b/snow/engine/common/vm.go @@ -77,4 +77,8 @@ type VM interface { // it have an extension called `accounts`, where clients could get // information about their accounts. CreateHandlers(context.Context) (map[string]http.Handler, error) + + // CreateHTTP2Handler returns the http/2 handler to register into the + // avalanchego api server. + CreateHTTP2Handler(ctx context.Context) (http.Handler, error) } diff --git a/snow/engine/enginetest/vm.go b/snow/engine/enginetest/vm.go index f3c430e58404..6a69b70a1a4c 100644 --- a/snow/engine/enginetest/vm.go +++ b/snow/engine/enginetest/vm.go @@ -20,18 +20,19 @@ import ( ) var ( - errInitialize = errors.New("unexpectedly called Initialize") - errSetState = errors.New("unexpectedly called SetState") - errShutdown = errors.New("unexpectedly called Shutdown") - errCreateHandlers = errors.New("unexpectedly called CreateHandlers") - errHealthCheck = errors.New("unexpectedly called HealthCheck") - errConnected = errors.New("unexpectedly called Connected") - errDisconnected = errors.New("unexpectedly called Disconnected") - errVersion = errors.New("unexpectedly called Version") - errAppRequest = errors.New("unexpectedly called AppRequest") - errAppResponse = errors.New("unexpectedly called AppResponse") - errAppRequestFailed = errors.New("unexpectedly called AppRequestFailed") - errAppGossip = errors.New("unexpectedly called AppGossip") + errInitialize = errors.New("unexpectedly called Initialize") + errSetState = errors.New("unexpectedly called SetState") + errShutdown = errors.New("unexpectedly called Shutdown") + errCreateHandlers = errors.New("unexpectedly called CreateHandlers") + errCreateHTTP2Handler = errors.New("unexpectedly called CreateHTTP2Handler") + errHealthCheck = errors.New("unexpectedly called HealthCheck") + errConnected = errors.New("unexpectedly called Connected") + errDisconnected = errors.New("unexpectedly called Disconnected") + errVersion = errors.New("unexpectedly called Version") + errAppRequest = errors.New("unexpectedly called AppRequest") + errAppResponse = errors.New("unexpectedly called AppResponse") + errAppRequestFailed = errors.New("unexpectedly called AppRequestFailed") + errAppGossip = errors.New("unexpectedly called AppGossip") _ common.VM = (*VM)(nil) ) @@ -41,22 +42,23 @@ type VM struct { T *testing.T CantInitialize, CantSetState, - CantShutdown, CantCreateHandlers, + CantShutdown, CantCreateHandlers, CantCreateHTTP2Handler, CantHealthCheck, CantConnected, CantDisconnected, CantVersion, CantAppRequest, CantAppResponse, CantAppGossip, CantAppRequestFailed bool - InitializeF func(ctx context.Context, chainCtx *snow.Context, db database.Database, genesisBytes []byte, upgradeBytes []byte, configBytes []byte, msgChan chan<- common.Message, fxs []*common.Fx, appSender common.AppSender) error - SetStateF func(ctx context.Context, state snow.State) error - ShutdownF func(context.Context) error - CreateHandlersF func(context.Context) (map[string]http.Handler, error) - ConnectedF func(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error - DisconnectedF func(ctx context.Context, nodeID ids.NodeID) error - HealthCheckF func(context.Context) (interface{}, error) - AppRequestF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, msg []byte) error - AppResponseF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, msg []byte) error - AppGossipF func(ctx context.Context, nodeID ids.NodeID, msg []byte) error - AppRequestFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error - VersionF func(context.Context) (string, error) + InitializeF func(ctx context.Context, chainCtx *snow.Context, db database.Database, genesisBytes []byte, upgradeBytes []byte, configBytes []byte, msgChan chan<- common.Message, fxs []*common.Fx, appSender common.AppSender) error + SetStateF func(ctx context.Context, state snow.State) error + ShutdownF func(context.Context) error + CreateHandlersF func(context.Context) (map[string]http.Handler, error) + CreateHTTP2HandlerF func(context.Context) (http.Handler, error) + ConnectedF func(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error + DisconnectedF func(ctx context.Context, nodeID ids.NodeID) error + HealthCheckF func(context.Context) (interface{}, error) + AppRequestF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, msg []byte) error + AppResponseF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, msg []byte) error + AppGossipF func(ctx context.Context, nodeID ids.NodeID, msg []byte) error + AppRequestFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error + VersionF func(context.Context) (string, error) } func (vm *VM) Default(cant bool) { @@ -140,6 +142,17 @@ func (vm *VM) CreateHandlers(ctx context.Context) (map[string]http.Handler, erro return nil, nil } +func (vm *VM) CreateHTTP2Handler(ctx context.Context) (http.Handler, error) { + if vm.CreateHandlersF != nil { + return vm.CreateHTTP2HandlerF(ctx) + } + if vm.CantCreateHTTP2Handler && vm.T != nil { + require.FailNow(vm.T, errCreateHTTP2Handler.Error()) + } + + return nil, nil +} + func (vm *VM) HealthCheck(ctx context.Context) (interface{}, error) { if vm.HealthCheckF != nil { return vm.HealthCheckF(ctx) diff --git a/snow/engine/snowman/block/blockmock/chain_vm.go b/snow/engine/snowman/block/blockmock/chain_vm.go index 051287561454..a93f1be66e88 100644 --- a/snow/engine/snowman/block/blockmock/chain_vm.go +++ b/snow/engine/snowman/block/blockmock/chain_vm.go @@ -133,6 +133,21 @@ func (mr *ChainVMMockRecorder) Connected(ctx, nodeID, nodeVersion any) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*ChainVM)(nil).Connected), ctx, nodeID, nodeVersion) } +// CreateHTTP2Handler mocks base method. +func (m *ChainVM) CreateHTTP2Handler(ctx context.Context) (http.Handler, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateHTTP2Handler", ctx) + ret0, _ := ret[0].(http.Handler) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateHTTP2Handler indicates an expected call of CreateHTTP2Handler. +func (mr *ChainVMMockRecorder) CreateHTTP2Handler(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateHTTP2Handler", reflect.TypeOf((*ChainVM)(nil).CreateHTTP2Handler), ctx) +} + // CreateHandlers mocks base method. func (m *ChainVM) CreateHandlers(arg0 context.Context) (map[string]http.Handler, error) { m.ctrl.T.Helper() diff --git a/tests/e2e/vms/xsvm.go b/tests/e2e/vms/xsvm.go index b81720917ac5..81b43fd86726 100644 --- a/tests/e2e/vms/xsvm.go +++ b/tests/e2e/vms/xsvm.go @@ -5,13 +5,18 @@ package vms import ( "fmt" + "strings" + "sync" "time" "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/proto/pb/xsvm" "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/tests/fixture/subnet" "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" @@ -178,6 +183,84 @@ var _ = ginkgo.Describe("[XSVM]", ginkgo.Label("xsvm"), func() { _ = e2e.CheckBootstrapIsPossible(tc, network) }) + + ginkgo.It("should serve grpc api requests", func() { + network := e2e.GetEnv(tc).GetNetwork() + log := tc.Log() + if network.DefaultRuntimeConfig.Kube != nil { + ginkgo.Skip("h2c is not currently supported in kube") + } + + tc.By("establishing connection") + nodeID := network.GetSubnet(subnetAName).ValidatorIDs[0] + node, err := network.GetNode(nodeID) + require.NoError(err) + + uri := strings.TrimPrefix(node.URI, "http://") + chainID := network.GetSubnet(subnetAName).Chains[0].ChainID + client, conn, err := api.NewPingClient( + uri, + chainID, + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + require.NoError(err) + ginkgo.DeferCleanup(func() { + require.NoError(conn.Close()) + }) + + tc.By("serving unary rpc") + msg := "foobar" + reply, err := client.Ping(tc.DefaultContext(), &xsvm.PingRequest{ + Message: msg, + }) + require.NoError(err) + require.Equal(msg, reply.Message) + + tc.By("serving bidirectional streaming rpc") + stream, err := client.StreamPing(tc.DefaultContext()) + require.NoError(err) + + ginkgo.DeferCleanup(func() { + require.NoError(stream.CloseSend()) + }) + + // Stream pings to the server and block until all events are received + // back. + wg := &sync.WaitGroup{} + wg.Add(2) + + n := 10 + go func() { + defer func() { + ginkgo.GinkgoRecover() + wg.Done() + }() + + for i := 0; i < n; i++ { + msg := fmt.Sprintf("ping-%d", i) + require.NoError(stream.Send(&xsvm.StreamPingRequest{ + Message: msg, + })) + log.Info("sent message", zap.String("msg", msg)) + } + }() + + go func() { + defer func() { + ginkgo.GinkgoRecover() + wg.Done() + }() + + for i := 0; i < n; i++ { + reply, err := stream.Recv() + require.NoError(err) + require.Equal(fmt.Sprintf("ping-%d", i), reply.Message) + log.Info("received message", zap.String("msg", reply.Message)) + } + }() + + wg.Wait() + }) }) // Retrieve the nodes corresponding to the provided IDs diff --git a/tests/fixture/tmpnet/flags/kubeconfig.go b/tests/fixture/tmpnet/flags/kubeconfig.go index b8bfe9353094..48ee5b6d327e 100644 --- a/tests/fixture/tmpnet/flags/kubeconfig.go +++ b/tests/fixture/tmpnet/flags/kubeconfig.go @@ -45,10 +45,17 @@ func newKubeconfigFlagSetVars(flagSet *pflag.FlagSet, docPrefix string) *Kubecon } func (v *KubeconfigVars) register(stringVar varFunc[string], docPrefix string) { + // the default kubeConfig path is set to empty to allow for the use of a projected + // token when running in-cluster + var defaultKubeConfigPath string + if !tmpnet.IsRunningInCluster() { + defaultKubeConfigPath = os.ExpandEnv("$HOME/.kube/config") + } + stringVar( &v.Path, "kubeconfig", - tmpnet.GetEnvWithDefault(KubeconfigPathEnvVar, os.ExpandEnv("$HOME/.kube/config")), + tmpnet.GetEnvWithDefault(KubeconfigPathEnvVar, defaultKubeConfigPath), docPrefix+fmt.Sprintf( "The path to a kubernetes configuration file for the target cluster. Also possible to configure via the %s env variable.", KubeconfigPathEnvVar, diff --git a/tests/fixture/tmpnet/kube_runtime.go b/tests/fixture/tmpnet/kube_runtime.go index f100b42aafda..11ca4ddf0545 100644 --- a/tests/fixture/tmpnet/kube_runtime.go +++ b/tests/fixture/tmpnet/kube_runtime.go @@ -144,8 +144,10 @@ func (p *KubeRuntime) GetLocalURI(ctx context.Context) (string, func(), error) { } } - // TODO(marun) Detect whether this test code is running inside the cluster - // and use the URI directly + // Use direct pod URI if running inside the cluster + if IsRunningInCluster() { + return p.node.URI, func() {}, nil + } port, stopChan, err := p.forwardPort(ctx, config.DefaultHTTPPort) if err != nil { @@ -164,8 +166,10 @@ func (p *KubeRuntime) GetLocalStakingAddress(ctx context.Context) (netip.AddrPor } } - // TODO(marun) Detect whether this test code is running inside the cluster - // and use the URI directly + // Use direct pod staking address if running inside the cluster + if IsRunningInCluster() { + return p.node.StakingAddress, func() {}, nil + } port, stopChan, err := p.forwardPort(ctx, config.DefaultStakingPort) if err != nil { @@ -837,3 +841,11 @@ func configureExclusiveScheduling(template *corev1.PodTemplateSpec, labelKey str }, } } + +// IsRunningInCluster detects if this code is running inside a Kubernetes cluster +// by checking for the presence of the service account token that's automatically +// mounted in every pod. +func IsRunningInCluster() bool { + _, err := os.Stat("/var/run/secrets/kubernetes.io/serviceaccount/token") + return err == nil +} diff --git a/vms/avm/vm.go b/vms/avm/vm.go index 89f76bebd08e..dd4c6d0ddc1b 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -318,6 +318,10 @@ func (vm *VM) CreateHandlers(context.Context) (map[string]http.Handler, error) { }, err } +func (*VM) CreateHTTP2Handler(context.Context) (http.Handler, error) { + return nil, nil +} + /* ****************************************************************************** ********************************** Chain VM ********************************** diff --git a/vms/example/xsvm/api/ping.go b/vms/example/xsvm/api/ping.go new file mode 100644 index 000000000000..f8c901c759e1 --- /dev/null +++ b/vms/example/xsvm/api/ping.go @@ -0,0 +1,69 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package api + +import ( + "context" + "errors" + "fmt" + "io" + + "go.uber.org/zap" + "google.golang.org/grpc" + + "github.com/ava-labs/avalanchego/api/grpcclient" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/proto/pb/xsvm" + "github.com/ava-labs/avalanchego/utils/logging" +) + +var _ xsvm.PingServer = (*PingService)(nil) + +type PingService struct { + xsvm.UnsafePingServer + + Log logging.Logger +} + +func (p *PingService) Ping(_ context.Context, request *xsvm.PingRequest) (*xsvm.PingReply, error) { + p.Log.Debug("ping", zap.String("message", request.Message)) + return &xsvm.PingReply{ + Message: request.Message, + }, nil +} + +func (p *PingService) StreamPing(server xsvm.Ping_StreamPingServer) error { + for { + request, err := server.Recv() + if errors.Is(err, io.EOF) { + // Client closed the send stream + return nil + } + if err != nil { + return fmt.Errorf("failed to receive message: %w", err) + } + + p.Log.Debug("stream ping", zap.String("message", request.Message)) + err = server.Send(&xsvm.StreamPingReply{ + Message: request.Message, + }) + if err != nil { + return fmt.Errorf("failed to send message: %w", err) + } + } +} + +// NewPingClient returns a client for PingService +func NewPingClient( + uri string, + chainID ids.ID, + opts ...grpc.DialOption, +) (xsvm.PingClient, *grpc.ClientConn, error) { + conn, err := grpcclient.NewChainClient(uri, chainID, opts...) + if err != nil { + return nil, nil, err + } + + return xsvm.NewPingClient(conn), conn, nil +} diff --git a/vms/example/xsvm/vm.go b/vms/example/xsvm/vm.go index d7386fafad40..9fd85f8e77bc 100644 --- a/vms/example/xsvm/vm.go +++ b/vms/example/xsvm/vm.go @@ -11,12 +11,15 @@ import ( "github.com/gorilla/rpc/v2" "github.com/prometheus/client_golang/prometheus" "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/database/versiondb" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/network/p2p" "github.com/ava-labs/avalanchego/network/p2p/acp118" + "github.com/ava-labs/avalanchego/proto/pb/xsvm" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" @@ -152,6 +155,13 @@ func (vm *VM) CreateHandlers(context.Context) (map[string]http.Handler, error) { }, server.RegisterService(api, constants.XSVMName) } +func (vm *VM) CreateHTTP2Handler(context.Context) (http.Handler, error) { + server := grpc.NewServer() + server.RegisterService(&xsvm.Ping_ServiceDesc, &api.PingService{Log: vm.chainContext.Log}) + reflection.Register(server) + return server, nil +} + func (*VM) HealthCheck(context.Context) (interface{}, error) { return http.StatusOK, nil } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index d5958a5703c2..e541452609e9 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -466,6 +466,10 @@ func (vm *VM) CreateHandlers(context.Context) (map[string]http.Handler, error) { }, err } +func (*VM) CreateHTTP2Handler(context.Context) (http.Handler, error) { + return nil, nil +} + func (vm *VM) Connected(ctx context.Context, nodeID ids.NodeID, version *version.Application) error { if err := vm.uptimeManager.Connect(nodeID); err != nil { return err diff --git a/vms/rpcchainvm/ghttp/http_client.go b/vms/rpcchainvm/ghttp/http_client.go index 7370d05dcd6c..f9eb586f877d 100644 --- a/vms/rpcchainvm/ghttp/http_client.go +++ b/vms/rpcchainvm/ghttp/http_client.go @@ -36,7 +36,10 @@ func (c *Client) ServeHTTP(w http.ResponseWriter, r *http.Request) { // to specify a communication protocols it supports and would like to // use. Upgrade (e.g. websockets) is a more expensive transaction and // if not required use the less expensive HTTPSimple. - if !isUpgradeRequest(r) { + // + // Http/2 explicitly does not allow the use of the Upgrade header. + // (ref: https://httpwg.org/specs/rfc9113.html#informational-responses) + if !isUpgradeRequest(r) && !isHTTP2Request(r) { c.serveHTTPSimple(w, r) return } @@ -218,3 +221,7 @@ func convertWriteResponse(w http.ResponseWriter, resp *httppb.HandleSimpleHTTPRe func isUpgradeRequest(req *http.Request) bool { return req.Header.Get("Upgrade") != "" } + +func isHTTP2Request(req *http.Request) bool { + return req.ProtoMajor == 2 +} diff --git a/vms/rpcchainvm/vm_client.go b/vms/rpcchainvm/vm_client.go index 497dc09d3dd7..1125e054fc2f 100644 --- a/vms/rpcchainvm/vm_client.go +++ b/vms/rpcchainvm/vm_client.go @@ -389,6 +389,25 @@ func (vm *VMClient) CreateHandlers(ctx context.Context) (map[string]http.Handler return handlers, nil } +func (vm *VMClient) CreateHTTP2Handler(ctx context.Context) (http.Handler, error) { + resp, err := vm.client.CreateHTTP2Handler(ctx, &emptypb.Empty{}) + if err != nil { + return nil, err + } + + if resp.ServerAddr == "" { + return nil, nil + } + + clientConn, err := grpcutils.Dial(resp.ServerAddr) + if err != nil { + return nil, err + } + + vm.conns = append(vm.conns, clientConn) + return ghttp.NewClient(httppb.NewHTTPClient(clientConn)), nil +} + func (vm *VMClient) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { _, err := vm.client.Connected(ctx, &vmpb.ConnectedRequest{ NodeId: nodeID.Bytes(), diff --git a/vms/rpcchainvm/vm_server.go b/vms/rpcchainvm/vm_server.go index 9b9584066542..370f8ad633b8 100644 --- a/vms/rpcchainvm/vm_server.go +++ b/vms/rpcchainvm/vm_server.go @@ -359,6 +359,34 @@ func (vm *VMServer) CreateHandlers(ctx context.Context, _ *emptypb.Empty) (*vmpb return resp, nil } +func (vm *VMServer) CreateHTTP2Handler(ctx context.Context, _ *emptypb.Empty) (*vmpb.CreateHTTP2HandlerResponse, error) { + handler, err := vm.vm.CreateHTTP2Handler(ctx) + if err != nil { + return nil, err + } + + // The vm does not expose an HTTP2 handler + if handler == nil { + return &vmpb.CreateHTTP2HandlerResponse{}, nil + } + + serverListener, err := grpcutils.NewListener() + if err != nil { + return nil, err + } + + server := grpcutils.NewServer() + vm.serverCloser.Add(server) + httppb.RegisterHTTPServer(server, ghttp.NewServer(handler)) + + // Start HTTP service + go grpcutils.Serve(serverListener, server) + + return &vmpb.CreateHTTP2HandlerResponse{ + ServerAddr: serverListener.Addr().String(), + }, nil +} + func (vm *VMServer) Connected(ctx context.Context, req *vmpb.ConnectedRequest) (*emptypb.Empty, error) { nodeID, err := ids.ToNodeID(req.NodeId) if err != nil { From b13bc729e69731a4ddafa31e33f46a6a639f5e19 Mon Sep 17 00:00:00 2001 From: samliok Date: Thu, 12 Jun 2025 14:26:58 -0500 Subject: [PATCH 13/19] lint --- simplex/test_util.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/simplex/test_util.go b/simplex/test_util.go index 9449daa90751..4a7cc991fe5f 100644 --- a/simplex/test_util.go +++ b/simplex/test_util.go @@ -22,7 +22,7 @@ func newEngineConfig(numNodes uint64) (*Config, error) { if numNodes == 0 { numNodes = 1 // Ensure at least one node for testing } - + ls, err := localsigner.New() if err != nil { return nil, err @@ -69,4 +69,3 @@ func generateTestValidators(num uint64) ([]validators.GetValidatorOutput, error) } return vds, nil } - From 88b06d5958dc29584ddacfd5bc4462c759b0c600 Mon Sep 17 00:00:00 2001 From: samliok Date: Thu, 12 Jun 2025 14:38:28 -0500 Subject: [PATCH 14/19] go get --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 62b5e5bc8b69..18c41928d458 100644 --- a/go.mod +++ b/go.mod @@ -84,7 +84,7 @@ require ( github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect - github.com/ava-labs/simplex v0.0.0-20250605162940-db8e6d44f53d + github.com/ava-labs/simplex v0.0.0-20250611154800-78b82e9820e5 github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect diff --git a/go.sum b/go.sum index 265cffc1dda4..5eedbfcb4301 100644 --- a/go.sum +++ b/go.sum @@ -70,10 +70,10 @@ github.com/ava-labs/coreth v0.15.2-rc.0.0.20250610170140-2fcf45f828a2 h1:/E1w2S6 github.com/ava-labs/coreth v0.15.2-rc.0.0.20250610170140-2fcf45f828a2/go.mod h1:cqwBag+zzqifDutdPVzZKovfC2d0L8Zxq4YgTGaMCwg= github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60 h1:EL66gtXOAwR/4KYBjOV03LTWgkEXvLePribLlJNu4g0= github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60/go.mod h1:/7qKobTfbzBu7eSTVaXMTr56yTYk4j2Px6/8G+idxHo= -github.com/ava-labs/simplex v0.0.0-20250605162940-db8e6d44f53d h1:D/BOS3USdAigun2OP/6khvukKnn4BIKviYAdKLHN6zc= -github.com/ava-labs/simplex v0.0.0-20250605162940-db8e6d44f53d/go.mod h1:GVzumIo3zR23/qGRN2AdnVkIPHcKMq/D89EGWZfMGQ0= github.com/ava-labs/libevm v0.0.0-20250610142802-2672fbd7cdfc h1:cSXaUY4hdmoJ2FJOgOzn+WiovN/ZB/zkNRgnZhE50OA= github.com/ava-labs/libevm v0.0.0-20250610142802-2672fbd7cdfc/go.mod h1:+Iol+sVQ1KyoBsHf3veyrBmHCXr3xXRWq6ZXkgVfNLU= +github.com/ava-labs/simplex v0.0.0-20250611154800-78b82e9820e5 h1:rwPm63i5nJ2XIuNjO2H68gDmMKje0VW7orLZMISPrC8= +github.com/ava-labs/simplex v0.0.0-20250611154800-78b82e9820e5/go.mod h1:GVzumIo3zR23/qGRN2AdnVkIPHcKMq/D89EGWZfMGQ0= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= From 5f8415655a4b8a055d3c837dbfec9096b982029d Mon Sep 17 00:00:00 2001 From: samliok Date: Thu, 12 Jun 2025 17:00:53 -0500 Subject: [PATCH 15/19] helper function + use testing in utils --- simplex/bls_test.go | 9 ++---- simplex/comm.go | 41 +++++++++++++++----------- simplex/comm_test.go | 14 ++++----- simplex/{test_util.go => util_test.go} | 27 ++++++++--------- 4 files changed, 43 insertions(+), 48 deletions(-) rename simplex/{test_util.go => util_test.go} (76%) diff --git a/simplex/bls_test.go b/simplex/bls_test.go index a4e9047b6348..ee6cd2f4a921 100644 --- a/simplex/bls_test.go +++ b/simplex/bls_test.go @@ -13,8 +13,7 @@ import ( ) func TestBLSSignVerify(t *testing.T) { - config, err := newEngineConfig(1) - require.NoError(t, err) + config := newEngineConfig(t, 1) signer, verifier := NewBLSAuth(config) @@ -28,8 +27,7 @@ func TestBLSSignVerify(t *testing.T) { } func TestSignerNotInMemberSet(t *testing.T) { - config, err := newEngineConfig(1) - require.NoError(t, err) + config := newEngineConfig(t, 1) signer, verifier := NewBLSAuth(config) msg := "Begin at the beginning, and go on till you come to the end: then stop" @@ -43,8 +41,7 @@ func TestSignerNotInMemberSet(t *testing.T) { } func TestSignerInvalidMessageEncoding(t *testing.T) { - config, err := newEngineConfig(1) - require.NoError(t, err) + config := newEngineConfig(t, 1) // sign a message with invalid encoding dummyMsg := []byte("dummy message") diff --git a/simplex/comm.go b/simplex/comm.go index 9f5d012e1acf..abca55b705be 100644 --- a/simplex/comm.go +++ b/simplex/comm.go @@ -82,6 +82,28 @@ func (c *Comm) ListNodes() []simplex.NodeID { } func (c *Comm) SendMessage(msg *simplex.Message, destination simplex.NodeID) { + outboundMsg, err := c.simplexMessageToOutboundMessage(msg) + if err != nil { + c.logger.Error("Failed creating message", zap.Error(err)) + return + } + + dest := ids.NodeID(destination) + + c.sender.Send(outboundMsg, common.SendConfig{NodeIDs: set.Of(dest)}, c.subnetID, subnets.NoOpAllower) +} + +func (c *Comm) Broadcast(msg *simplex.Message) { + for _, node := range c.nodes { + if node.Equals(c.nodeID) { + continue + } + + c.SendMessage(msg, node) + } +} + +func (c *Comm) simplexMessageToOutboundMessage(msg *simplex.Message) (message.OutboundMessage, error) { var outboundMessage message.OutboundMessage var err error switch { @@ -105,22 +127,5 @@ func (c *Comm) SendMessage(msg *simplex.Message, destination simplex.NodeID) { outboundMessage, err = c.msgBuilder.VerifiedReplicationResponse(c.chainID, msg.VerifiedReplicationResponse.Data, msg.VerifiedReplicationResponse.LatestRound) } - if err != nil { - c.logger.Error("Failed creating message", zap.Error(err)) - return - } - - dest := ids.NodeID(destination) - - c.sender.Send(outboundMessage, common.SendConfig{NodeIDs: set.Of(dest)}, c.subnetID, subnets.NoOpAllower) -} - -func (c *Comm) Broadcast(msg *simplex.Message) { - for _, node := range c.nodes { - if node.Equals(c.nodeID) { - continue - } - - c.SendMessage(msg, node) - } + return outboundMessage, err } diff --git a/simplex/comm_test.go b/simplex/comm_test.go index bd712da9095b..12ea94ea9c27 100644 --- a/simplex/comm_test.go +++ b/simplex/comm_test.go @@ -35,8 +35,7 @@ var testSimplexMessage = simplex.Message{ } func TestComm(t *testing.T) { - config, err := newEngineConfig(1) - require.NoError(t, err) + config := newEngineConfig(t, 1) destinationNodeID := ids.GenerateTestNodeID() @@ -60,8 +59,7 @@ func TestComm(t *testing.T) { // TestCommBroadcast tests the Broadcast method sends to all nodes in the subnet // not including the sending node. func TestCommBroadcast(t *testing.T) { - config, err := newEngineConfig(3) - require.NoError(t, err) + config := newEngineConfig(t, 3) ctrl := gomock.NewController(t) msgCreator := messagemock.NewOutboundMsgBuilder(ctrl) @@ -81,8 +79,7 @@ func TestCommBroadcast(t *testing.T) { } func TestCommFailsWithoutCurrentNode(t *testing.T) { - config, err := newEngineConfig(3) - require.NoError(t, err) + config := newEngineConfig(t, 3) ctrl := gomock.NewController(t) msgCreator := messagemock.NewOutboundMsgBuilder(ctrl) @@ -92,10 +89,9 @@ func TestCommFailsWithoutCurrentNode(t *testing.T) { config.Sender = sender // set the curNode to a different nodeID than the one in the config - vdrs, err := generateTestValidators(3) - require.NoError(t, err) + vdrs := generateTestValidators(t, 3) config.Validators = newTestValidators(vdrs) - _, err = NewComm(config) + _, err := NewComm(config) require.ErrorIs(t, err, errNodeNotFound) } diff --git a/simplex/test_util.go b/simplex/util_test.go similarity index 76% rename from simplex/test_util.go rename to simplex/util_test.go index 4a7cc991fe5f..0033686ccc0c 100644 --- a/simplex/test_util.go +++ b/simplex/util_test.go @@ -4,6 +4,10 @@ package simplex import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" @@ -18,15 +22,13 @@ func newTestValidators(allVds []validators.GetValidatorOutput) map[ids.NodeID]*v return vds } -func newEngineConfig(numNodes uint64) (*Config, error) { +func newEngineConfig(t *testing.T, numNodes uint64) *Config { if numNodes == 0 { - numNodes = 1 // Ensure at least one node for testing + panic("numNodes must be greater than 0") } ls, err := localsigner.New() - if err != nil { - return nil, err - } + require.NoError(t, err) nodeID := ids.GenerateTestNodeID() @@ -41,25 +43,20 @@ func newEngineConfig(numNodes uint64) (*Config, error) { PublicKey: ls.PublicKey(), } - validators, err := generateTestValidators(numNodes - 1) - if err != nil { - return nil, err - } + validators := generateTestValidators(t, numNodes-1) return &Config{ Ctx: simplexChainContext, Validators: newTestValidators(append(validators, nodeInfo)), SignBLS: ls.Sign, - }, nil + } } -func generateTestValidators(num uint64) ([]validators.GetValidatorOutput, error) { +func generateTestValidators(t *testing.T, num uint64) []validators.GetValidatorOutput { vds := make([]validators.GetValidatorOutput, num) for i := uint64(0); i < num; i++ { ls, err := localsigner.New() - if err != nil { - return nil, err - } + require.NoError(t, err) nodeID := ids.GenerateTestNodeID() vds[i] = validators.GetValidatorOutput{ @@ -67,5 +64,5 @@ func generateTestValidators(num uint64) ([]validators.GetValidatorOutput, error) PublicKey: ls.PublicKey(), } } - return vds, nil + return vds } From ebdbfc9133a1467e93fab47695fa30be1eac061d Mon Sep 17 00:00:00 2001 From: samliok Date: Wed, 18 Jun 2025 13:01:31 -0500 Subject: [PATCH 16/19] merge conflicts and cleanup --- simplex/bls_test.go | 5 ++--- simplex/comm.go | 14 +++----------- simplex/comm_test.go | 3 ++- simplex/config.go | 7 ++++++- simplex/test_util.go | 46 -------------------------------------------- simplex/util_test.go | 16 +++++++-------- 6 files changed, 21 insertions(+), 70 deletions(-) delete mode 100644 simplex/test_util.go diff --git a/simplex/bls_test.go b/simplex/bls_test.go index cc38dd6d918d..9222e86912c0 100644 --- a/simplex/bls_test.go +++ b/simplex/bls_test.go @@ -13,8 +13,7 @@ import ( ) func TestBLSVerifier(t *testing.T) { - config, err := newEngineConfig() - require.NoError(t, err) + config := newEngineConfig(t, 1) signer, verifier := NewBLSAuth(config) otherNodeID := ids.GenerateTestNodeID() @@ -81,7 +80,7 @@ func TestBLSVerifier(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err = verifier.Verify(msg, tt.sig, tt.nodeID) + err := verifier.Verify(msg, tt.sig, tt.nodeID) require.ErrorIs(t, err, tt.expectErr) }) } diff --git a/simplex/comm.go b/simplex/comm.go index abca55b705be..affb49d3de69 100644 --- a/simplex/comm.go +++ b/simplex/comm.go @@ -43,20 +43,12 @@ func NewComm(config *Config) (*Comm, error) { nodes = append(nodes, vd.NodeID[:]) } - sortedNodes := sortNodes(nodes) - - var found bool - for _, node := range sortedNodes { - if node.Equals(config.Ctx.NodeID[:]) { - found = true - break - } - } - - if !found { + if _, ok := config.Validators[config.Ctx.NodeID]; !ok { return nil, fmt.Errorf("%w: %s", errNodeNotFound, config.Ctx.NodeID) } + sortedNodes := sortNodes(nodes) + c := &Comm{ subnetID: config.Ctx.SubnetID, nodes: sortedNodes, diff --git a/simplex/comm_test.go b/simplex/comm_test.go index 12ea94ea9c27..eb6b5c82a2fc 100644 --- a/simplex/comm_test.go +++ b/simplex/comm_test.go @@ -34,7 +34,7 @@ var testSimplexMessage = simplex.Message{ }, } -func TestComm(t *testing.T) { +func TestCommSendMessage(t *testing.T) { config := newEngineConfig(t, 1) destinationNodeID := ids.GenerateTestNodeID() @@ -71,6 +71,7 @@ func TestCommBroadcast(t *testing.T) { comm, err := NewComm(config) require.NoError(t, err) + // should only send twice since the current node does not send to itself msgCreator.EXPECT().Vote(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, nil).Times(2) sender.EXPECT().Send(gomock.Any(), gomock.Any(), comm.subnetID, gomock.Any()).Times(2) diff --git a/simplex/config.go b/simplex/config.go index dcb714359712..fe1e70772b1b 100644 --- a/simplex/config.go +++ b/simplex/config.go @@ -5,7 +5,9 @@ package simplex import ( "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/message" + "github.com/ava-labs/avalanchego/snow/networking/sender" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/logging" ) @@ -31,9 +33,12 @@ type Config struct { type SimplexChainContext struct { // Network is the ID of the network this context exists within. NodeID ids.NodeID - + // ChainID is the ID of the chain this context exists within. ChainID ids.ID + + // SubnetID is the ID of the subnet this context exists within. + SubnetID ids.ID // NodeID is the ID of this node NetworkID uint32 diff --git a/simplex/test_util.go b/simplex/test_util.go deleted file mode 100644 index 5b167bd17e8d..000000000000 --- a/simplex/test_util.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package simplex - -import ( - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" -) - -func newTestValidatorInfo(allVds []validators.GetValidatorOutput) map[ids.NodeID]*validators.GetValidatorOutput { - vds := make(map[ids.NodeID]*validators.GetValidatorOutput, len(allVds)) - for _, vd := range allVds { - vds[vd.NodeID] = &vd - } - - return vds -} - -func newEngineConfig() (*Config, error) { - ls, err := localsigner.New() - if err != nil { - return nil, err - } - - nodeID := ids.GenerateTestNodeID() - - simplexChainContext := SimplexChainContext{ - NodeID: nodeID, - ChainID: ids.GenerateTestID(), - NetworkID: constants.UnitTestID, - } - - nodeInfo := validators.GetValidatorOutput{ - NodeID: nodeID, - PublicKey: ls.PublicKey(), - } - - return &Config{ - Ctx: simplexChainContext, - Validators: newTestValidatorInfo([]validators.GetValidatorOutput{nodeInfo}), - SignBLS: ls.Sign, - }, nil -} diff --git a/simplex/util_test.go b/simplex/util_test.go index 0033686ccc0c..2f789d376429 100644 --- a/simplex/util_test.go +++ b/simplex/util_test.go @@ -6,11 +6,11 @@ package simplex import ( "testing" - "github.com/stretchr/testify/require" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" + "github.com/stretchr/testify/require" ) func newTestValidators(allVds []validators.GetValidatorOutput) map[ids.NodeID]*validators.GetValidatorOutput { @@ -24,7 +24,7 @@ func newTestValidators(allVds []validators.GetValidatorOutput) map[ids.NodeID]*v func newEngineConfig(t *testing.T, numNodes uint64) *Config { if numNodes == 0 { - panic("numNodes must be greater than 0") + require.FailNow(t, "numNodes must be greater than 0") } ls, err := localsigner.New() @@ -33,9 +33,9 @@ func newEngineConfig(t *testing.T, numNodes uint64) *Config { nodeID := ids.GenerateTestNodeID() simplexChainContext := SimplexChainContext{ - NodeID: nodeID, - ChainID: ids.GenerateTestID(), - SubnetID: ids.GenerateTestID(), + NodeID: nodeID, + ChainID: ids.GenerateTestID(), + NetworkID: constants.UnitTestID, } nodeInfo := validators.GetValidatorOutput{ @@ -44,10 +44,10 @@ func newEngineConfig(t *testing.T, numNodes uint64) *Config { } validators := generateTestValidators(t, numNodes-1) - + validators = append(validators, nodeInfo) return &Config{ Ctx: simplexChainContext, - Validators: newTestValidators(append(validators, nodeInfo)), + Validators: newTestValidators(validators), SignBLS: ls.Sign, } } From 7a7e5e7815d6096314a033a2fc55817344e4f9d1 Mon Sep 17 00:00:00 2001 From: samliok Date: Wed, 18 Jun 2025 13:09:34 -0500 Subject: [PATCH 17/19] lint --- simplex/config.go | 5 ++--- simplex/util_test.go | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/simplex/config.go b/simplex/config.go index fe1e70772b1b..54ab79b35514 100644 --- a/simplex/config.go +++ b/simplex/config.go @@ -6,7 +6,6 @@ package simplex import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" - "github.com/ava-labs/avalanchego/snow/networking/sender" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/logging" @@ -33,10 +32,10 @@ type Config struct { type SimplexChainContext struct { // Network is the ID of the network this context exists within. NodeID ids.NodeID - + // ChainID is the ID of the chain this context exists within. ChainID ids.ID - + // SubnetID is the ID of the subnet this context exists within. SubnetID ids.ID diff --git a/simplex/util_test.go b/simplex/util_test.go index 2f789d376429..54cfe9a5fb69 100644 --- a/simplex/util_test.go +++ b/simplex/util_test.go @@ -6,11 +6,12 @@ package simplex import ( "testing" + "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" - "github.com/stretchr/testify/require" ) func newTestValidators(allVds []validators.GetValidatorOutput) map[ids.NodeID]*validators.GetValidatorOutput { From d9b8a2c5e8cca4cb807db4f5f8d79db18007d805 Mon Sep 17 00:00:00 2001 From: samliok Date: Wed, 18 Jun 2025 16:36:47 -0500 Subject: [PATCH 18/19] logs, and err clarification --- .../messagemock/outbound_message_builder.go | 24 +++++++++---------- message/simplex_outbound_msg_builder.go | 4 ++-- simplex/comm.go | 9 +++++-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/message/messagemock/outbound_message_builder.go b/message/messagemock/outbound_message_builder.go index dec1dffa8b4c..f869830b0f73 100644 --- a/message/messagemock/outbound_message_builder.go +++ b/message/messagemock/outbound_message_builder.go @@ -496,34 +496,34 @@ func (mr *OutboundMsgBuilderMockRecorder) ReplicationRequest(chainID, seqs, late return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplicationRequest", reflect.TypeOf((*OutboundMsgBuilder)(nil).ReplicationRequest), chainID, seqs, latestRound) } -// StateSummaryFrontier mocks base method. -func (m *OutboundMsgBuilder) StateSummaryFrontier(chainID ids.ID, requestID uint32, summary []byte) (message.OutboundMessage, error) { +// ReplicationResponse mocks base method. +func (m *OutboundMsgBuilder) ReplicationResponse(chainID ids.ID, data []simplex.VerifiedQuorumRound, latestRound *simplex.VerifiedQuorumRound) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateSummaryFrontier", chainID, requestID, summary) + ret := m.ctrl.Call(m, "ReplicationResponse", chainID, data, latestRound) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } -// StateSummaryFrontier indicates an expected call of StateSummaryFrontier. -func (mr *OutboundMsgBuilderMockRecorder) StateSummaryFrontier(chainID, requestID, summary any) *gomock.Call { +// ReplicationResponse indicates an expected call of ReplicationResponse. +func (mr *OutboundMsgBuilderMockRecorder) ReplicationResponse(chainID, data, latestRound any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSummaryFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).StateSummaryFrontier), chainID, requestID, summary) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplicationResponse", reflect.TypeOf((*OutboundMsgBuilder)(nil).ReplicationResponse), chainID, data, latestRound) } -// VerifiedReplicationResponse mocks base method. -func (m *OutboundMsgBuilder) VerifiedReplicationResponse(chainID ids.ID, data []simplex.VerifiedQuorumRound, latestRound *simplex.VerifiedQuorumRound) (message.OutboundMessage, error) { +// StateSummaryFrontier mocks base method. +func (m *OutboundMsgBuilder) StateSummaryFrontier(chainID ids.ID, requestID uint32, summary []byte) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VerifiedReplicationResponse", chainID, data, latestRound) + ret := m.ctrl.Call(m, "StateSummaryFrontier", chainID, requestID, summary) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } -// VerifiedReplicationResponse indicates an expected call of VerifiedReplicationResponse. -func (mr *OutboundMsgBuilderMockRecorder) VerifiedReplicationResponse(chainID, data, latestRound any) *gomock.Call { +// StateSummaryFrontier indicates an expected call of StateSummaryFrontier. +func (mr *OutboundMsgBuilderMockRecorder) StateSummaryFrontier(chainID, requestID, summary any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifiedReplicationResponse", reflect.TypeOf((*OutboundMsgBuilder)(nil).VerifiedReplicationResponse), chainID, data, latestRound) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSummaryFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).StateSummaryFrontier), chainID, requestID, summary) } // Vote mocks base method. diff --git a/message/simplex_outbound_msg_builder.go b/message/simplex_outbound_msg_builder.go index 8b6285ecd547..178bdef88bd4 100644 --- a/message/simplex_outbound_msg_builder.go +++ b/message/simplex_outbound_msg_builder.go @@ -59,7 +59,7 @@ type SimplexOutboundMessageBuilder interface { latestRound uint64, ) (OutboundMessage, error) - VerifiedReplicationResponse( + ReplicationResponse( chainID ids.ID, data []simplex.VerifiedQuorumRound, latestRound *simplex.VerifiedQuorumRound, @@ -273,7 +273,7 @@ func (b *outMsgBuilder) ReplicationRequest( ) } -func (b *outMsgBuilder) VerifiedReplicationResponse( +func (b *outMsgBuilder) ReplicationResponse( chainID ids.ID, data []simplex.VerifiedQuorumRound, latestRound *simplex.VerifiedQuorumRound, diff --git a/simplex/comm.go b/simplex/comm.go index affb49d3de69..a61bbd9e215a 100644 --- a/simplex/comm.go +++ b/simplex/comm.go @@ -44,7 +44,12 @@ func NewComm(config *Config) (*Comm, error) { } if _, ok := config.Validators[config.Ctx.NodeID]; !ok { - return nil, fmt.Errorf("%w: %s", errNodeNotFound, config.Ctx.NodeID) + config.Log.Warn("Node is not a validator for the subnet", + zap.String("nodeID", config.Ctx.NodeID.String()), + zap.String("chainID", config.Ctx.ChainID.String()), + zap.String("subnetID", config.Ctx.SubnetID.String()), + ) + return nil, fmt.Errorf("%w could not find our node: %s", errNodeNotFound, config.Ctx.NodeID) } sortedNodes := sortNodes(nodes) @@ -116,7 +121,7 @@ func (c *Comm) simplexMessageToOutboundMessage(msg *simplex.Message) (message.Ou case msg.ReplicationRequest != nil: outboundMessage, err = c.msgBuilder.ReplicationRequest(c.chainID, msg.ReplicationRequest.Seqs, msg.ReplicationRequest.LatestRound) case msg.VerifiedReplicationResponse != nil: - outboundMessage, err = c.msgBuilder.VerifiedReplicationResponse(c.chainID, msg.VerifiedReplicationResponse.Data, msg.VerifiedReplicationResponse.LatestRound) + outboundMessage, err = c.msgBuilder.ReplicationResponse(c.chainID, msg.VerifiedReplicationResponse.Data, msg.VerifiedReplicationResponse.LatestRound) } return outboundMessage, err From 12599d273e803c1fb1852b6935253c010f608081 Mon Sep 17 00:00:00 2001 From: samliok Date: Sun, 22 Jun 2025 23:48:42 -0400 Subject: [PATCH 19/19] add logging to config --- simplex/util_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/simplex/util_test.go b/simplex/util_test.go index 54cfe9a5fb69..14948d19c46a 100644 --- a/simplex/util_test.go +++ b/simplex/util_test.go @@ -12,6 +12,7 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" + "github.com/ava-labs/avalanchego/utils/logging" ) func newTestValidators(allVds []validators.GetValidatorOutput) map[ids.NodeID]*validators.GetValidatorOutput { @@ -36,6 +37,7 @@ func newEngineConfig(t *testing.T, numNodes uint64) *Config { simplexChainContext := SimplexChainContext{ NodeID: nodeID, ChainID: ids.GenerateTestID(), + SubnetID: ids.GenerateTestID(), NetworkID: constants.UnitTestID, } @@ -48,6 +50,7 @@ func newEngineConfig(t *testing.T, numNodes uint64) *Config { validators = append(validators, nodeInfo) return &Config{ Ctx: simplexChainContext, + Log: logging.NoLog{}, Validators: newTestValidators(validators), SignBLS: ls.Sign, }