From 2324805b6197d3e4962d3dd87b8b7efa82fb8ae0 Mon Sep 17 00:00:00 2001 From: Christian Borst Date: Thu, 12 Aug 2021 12:06:31 -0400 Subject: [PATCH 1/2] Adding oracle attestations endpoint --- module/proto/gravity/v1/query.proto | 11 + module/x/gravity/keeper/attestation.go | 34 +- module/x/gravity/keeper/attestation_test.go | 51 ++ module/x/gravity/keeper/grpc_query.go | 16 + module/x/gravity/types/query.pb.go | 624 ++++++++++++++---- module/x/gravity/types/query.pb.gw.go | 83 +++ orchestrator/Cargo.lock | 3 + orchestrator/cosmos_gravity/src/query.rs | 15 + orchestrator/cosmos_gravity/src/send.rs | 6 +- orchestrator/gbt/src/client/cosmos_to_eth.rs | 12 +- .../gravity_proto/src/prost/gravity.v1.rs | 42 +- orchestrator/test_runner/Cargo.toml | 3 + orchestrator/test_runner/src/happy_path.rs | 155 ++++- orchestrator/test_runner/src/happy_path_v2.rs | 2 + orchestrator/test_runner/src/main.rs | 2 +- orchestrator/test_runner/src/relay_market.rs | 22 +- .../src/transaction_stress_test.rs | 12 +- .../test_runner/src/valset_rewards.rs | 2 +- orchestrator/test_runner/src/valset_stress.rs | 6 +- 19 files changed, 941 insertions(+), 160 deletions(-) create mode 100644 module/x/gravity/keeper/attestation_test.go diff --git a/module/proto/gravity/v1/query.proto b/module/proto/gravity/v1/query.proto index a77791776..42f2f5504 100644 --- a/module/proto/gravity/v1/query.proto +++ b/module/proto/gravity/v1/query.proto @@ -6,6 +6,7 @@ import "gravity/v1/types.proto"; import "gravity/v1/msgs.proto"; import "gravity/v1/pool.proto"; import "gravity/v1/batch.proto"; +import "gravity/v1/attestation.proto"; import "google/api/annotations.proto"; import "gogoproto/gogo.proto"; @@ -70,6 +71,9 @@ service Query { option (google.api.http).get = "/gravity/v1beta/cosmos_originated/denom_to_erc20"; } + rpc GetAttestations(QueryAttestationsRequest) returns (QueryAttestationsResponse) { + option (google.api.http).get = "/gravity/v1beta/query_attestations"; + } rpc GetDelegateKeyByValidator(QueryDelegateKeysByValidatorAddress) returns (QueryDelegateKeysByValidatorAddressResponse) { option (google.api.http).get = "/gravity/v1beta/query_delegate_keys_by_validator"; } @@ -205,6 +209,13 @@ message QueryDenomToERC20Response { bool cosmos_originated = 2; } +message QueryAttestationsRequest { + uint64 limit = 1; +} +message QueryAttestationsResponse { + repeated Attestation attestations = 1; +} + message QueryDelegateKeysByValidatorAddress { string validator_address = 1; } diff --git a/module/x/gravity/keeper/attestation.go b/module/x/gravity/keeper/attestation.go index 6a0ea2f49..224a7d21f 100644 --- a/module/x/gravity/keeper/attestation.go +++ b/module/x/gravity/keeper/attestation.go @@ -2,6 +2,7 @@ package keeper import ( "fmt" + "sort" "strconv" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -162,7 +163,7 @@ func (k Keeper) GetAttestation(ctx sdk.Context, eventNonce uint64, claimHash []b return &att } -// DeleteAttestation deletes an attestation given an event nonce and claim +// DeleteAttestation deletes the given attestation func (k Keeper) DeleteAttestation(ctx sdk.Context, att types.Attestation) { claim, err := k.UnpackAttestationClaim(&att) if err != nil { @@ -219,6 +220,37 @@ func (k Keeper) IterateAttestaions(ctx sdk.Context, cb func([]byte, types.Attest } } +// GetMostRecentAttestations returns sorted (by nonce) attestations up to a provided limit number of attestations +// Note: calls GetAttestationMapping in the hopes that there are potentially many attestations +// which are distributed between few nonces to minimize sorting time +func (k Keeper) GetMostRecentAttestations(ctx sdk.Context, limit uint64) []*types.Attestation { + attestationMapping := k.GetAttestationMapping(ctx) + attestations := make([]*types.Attestation, 0, limit) + + keys := make([]uint64, 0, len(attestationMapping)) + for k := range attestationMapping { + keys = append(keys, k) + } + sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] }) + + // Iterate the nonces and collect the attestations + count := 0 + for _, nonce := range keys { + if count >= int(limit) { + break + } + for _, att := range attestationMapping[nonce] { + if count >= int(limit) { + break + } + attestations = append(attestations, &att) + count++ + } + } + + return attestations +} + // GetLastObservedEventNonce returns the latest observed event nonce func (k Keeper) GetLastObservedEventNonce(ctx sdk.Context) uint64 { store := ctx.KVStore(k.storeKey) diff --git a/module/x/gravity/keeper/attestation_test.go b/module/x/gravity/keeper/attestation_test.go new file mode 100644 index 000000000..2bab5b590 --- /dev/null +++ b/module/x/gravity/keeper/attestation_test.go @@ -0,0 +1,51 @@ +package keeper + +import ( + "testing" + + "github.com/althea-net/cosmos-gravity-bridge/module/x/gravity/types" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdktypes "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +// Sets up 10 attestations and checks that they are returned in the correct order +func TestGetMostRecentAttestations(t *testing.T) { + input := CreateTestEnv(t) + k := input.GravityKeeper + ctx := input.Context + + lenth := 10 + msgs := make([]types.MsgSendToCosmosClaim, 0, lenth) + anys := make([]codectypes.Any, 0, lenth) + for i := 0; i < lenth; i++ { + nonce := uint64(1 + i) + msg := types.MsgSendToCosmosClaim{ + EventNonce: nonce, + BlockHeight: 1, + TokenContract: "0x00000000000000000001", + Amount: sdktypes.NewInt(10000000000 + int64(i)), + EthereumSender: "0x00000000000000000002", + CosmosReceiver: "0x00000000000000000003", + Orchestrator: "0x00000000000000000004", + } + msgs = append(msgs, msg) + + any, _ := codectypes.NewAnyWithValue(&msg) + anys = append(anys, *any) + att := &types.Attestation{ + Observed: false, + Height: uint64(ctx.BlockHeight()), + Claim: any, + } + k.SetAttestation(ctx, nonce, msg.ClaimHash(), att) + } + + recentAttestations := k.GetMostRecentAttestations(ctx, uint64(10)) + require.True(t, len(recentAttestations) == lenth, + "recentAttestations should have len %v but instead has %v", lenth, len(recentAttestations)) + for n, attest := range recentAttestations { + require.Equal(t, attest.Claim.GetCachedValue(), anys[n].GetCachedValue(), + "The %vth claim does not match our message: claim %v\n message %v", n, attest.Claim, msgs[n]) + } +} diff --git a/module/x/gravity/keeper/grpc_query.go b/module/x/gravity/keeper/grpc_query.go index b66a6edf1..a81699048 100644 --- a/module/x/gravity/keeper/grpc_query.go +++ b/module/x/gravity/keeper/grpc_query.go @@ -20,6 +20,8 @@ var _ types.QueryServer = Keeper{ AttestationHandler: nil, } +const QUERY_ATTESTATIONS_LIMIT uint64 = 1000 + // Params queries the params of the gravity module func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { var params types.Params @@ -270,6 +272,20 @@ func (k Keeper) ERC20ToDenom( return &ret, nil } +// GetAttestations queries the attestation map +func (k Keeper) GetAttestations( + c context.Context, + req *types.QueryAttestationsRequest) (*types.QueryAttestationsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + limit := req.Limit + if limit > QUERY_ATTESTATIONS_LIMIT { + limit = QUERY_ATTESTATIONS_LIMIT + } + attestations := k.GetMostRecentAttestations(ctx, limit) + + return &types.QueryAttestationsResponse{Attestations: attestations}, nil +} + func (k Keeper) GetDelegateKeyByValidator( c context.Context, req *types.QueryDelegateKeysByValidatorAddress) (*types.QueryDelegateKeysByValidatorAddressResponse, error) { diff --git a/module/x/gravity/types/query.pb.go b/module/x/gravity/types/query.pb.go index fb5a40fd8..535d48bc9 100644 --- a/module/x/gravity/types/query.pb.go +++ b/module/x/gravity/types/query.pb.go @@ -1633,6 +1633,94 @@ func (m *QueryDenomToERC20Response) GetCosmosOriginated() bool { return false } +type QueryAttestationsRequest struct { + Limit uint64 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` +} + +func (m *QueryAttestationsRequest) Reset() { *m = QueryAttestationsRequest{} } +func (m *QueryAttestationsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAttestationsRequest) ProtoMessage() {} +func (*QueryAttestationsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_29a9d4192703013c, []int{36} +} +func (m *QueryAttestationsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAttestationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAttestationsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAttestationsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAttestationsRequest.Merge(m, src) +} +func (m *QueryAttestationsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAttestationsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAttestationsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAttestationsRequest proto.InternalMessageInfo + +func (m *QueryAttestationsRequest) GetLimit() uint64 { + if m != nil { + return m.Limit + } + return 0 +} + +type QueryAttestationsResponse struct { + Attestations []*Attestation `protobuf:"bytes,1,rep,name=attestations,proto3" json:"attestations,omitempty"` +} + +func (m *QueryAttestationsResponse) Reset() { *m = QueryAttestationsResponse{} } +func (m *QueryAttestationsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAttestationsResponse) ProtoMessage() {} +func (*QueryAttestationsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_29a9d4192703013c, []int{37} +} +func (m *QueryAttestationsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAttestationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAttestationsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAttestationsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAttestationsResponse.Merge(m, src) +} +func (m *QueryAttestationsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAttestationsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAttestationsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAttestationsResponse proto.InternalMessageInfo + +func (m *QueryAttestationsResponse) GetAttestations() []*Attestation { + if m != nil { + return m.Attestations + } + return nil +} + type QueryDelegateKeysByValidatorAddress struct { ValidatorAddress string `protobuf:"bytes,1,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` } @@ -1641,7 +1729,7 @@ func (m *QueryDelegateKeysByValidatorAddress) Reset() { *m = QueryDelega func (m *QueryDelegateKeysByValidatorAddress) String() string { return proto.CompactTextString(m) } func (*QueryDelegateKeysByValidatorAddress) ProtoMessage() {} func (*QueryDelegateKeysByValidatorAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_29a9d4192703013c, []int{36} + return fileDescriptor_29a9d4192703013c, []int{38} } func (m *QueryDelegateKeysByValidatorAddress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1690,7 +1778,7 @@ func (m *QueryDelegateKeysByValidatorAddressResponse) String() string { } func (*QueryDelegateKeysByValidatorAddressResponse) ProtoMessage() {} func (*QueryDelegateKeysByValidatorAddressResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_29a9d4192703013c, []int{37} + return fileDescriptor_29a9d4192703013c, []int{39} } func (m *QueryDelegateKeysByValidatorAddressResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1741,7 +1829,7 @@ func (m *QueryDelegateKeysByEthAddress) Reset() { *m = QueryDelegateKeys func (m *QueryDelegateKeysByEthAddress) String() string { return proto.CompactTextString(m) } func (*QueryDelegateKeysByEthAddress) ProtoMessage() {} func (*QueryDelegateKeysByEthAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_29a9d4192703013c, []int{38} + return fileDescriptor_29a9d4192703013c, []int{40} } func (m *QueryDelegateKeysByEthAddress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1786,7 +1874,7 @@ func (m *QueryDelegateKeysByEthAddressResponse) Reset() { *m = QueryDele func (m *QueryDelegateKeysByEthAddressResponse) String() string { return proto.CompactTextString(m) } func (*QueryDelegateKeysByEthAddressResponse) ProtoMessage() {} func (*QueryDelegateKeysByEthAddressResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_29a9d4192703013c, []int{39} + return fileDescriptor_29a9d4192703013c, []int{41} } func (m *QueryDelegateKeysByEthAddressResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1839,7 +1927,7 @@ func (m *QueryDelegateKeysByOrchestratorAddress) Reset() { func (m *QueryDelegateKeysByOrchestratorAddress) String() string { return proto.CompactTextString(m) } func (*QueryDelegateKeysByOrchestratorAddress) ProtoMessage() {} func (*QueryDelegateKeysByOrchestratorAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_29a9d4192703013c, []int{40} + return fileDescriptor_29a9d4192703013c, []int{42} } func (m *QueryDelegateKeysByOrchestratorAddress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1888,7 +1976,7 @@ func (m *QueryDelegateKeysByOrchestratorAddressResponse) String() string { } func (*QueryDelegateKeysByOrchestratorAddressResponse) ProtoMessage() {} func (*QueryDelegateKeysByOrchestratorAddressResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_29a9d4192703013c, []int{41} + return fileDescriptor_29a9d4192703013c, []int{43} } func (m *QueryDelegateKeysByOrchestratorAddressResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1939,7 +2027,7 @@ func (m *QueryPendingSendToEth) Reset() { *m = QueryPendingSendToEth{} } func (m *QueryPendingSendToEth) String() string { return proto.CompactTextString(m) } func (*QueryPendingSendToEth) ProtoMessage() {} func (*QueryPendingSendToEth) Descriptor() ([]byte, []int) { - return fileDescriptor_29a9d4192703013c, []int{42} + return fileDescriptor_29a9d4192703013c, []int{44} } func (m *QueryPendingSendToEth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1984,7 +2072,7 @@ func (m *QueryPendingSendToEthResponse) Reset() { *m = QueryPendingSendT func (m *QueryPendingSendToEthResponse) String() string { return proto.CompactTextString(m) } func (*QueryPendingSendToEthResponse) ProtoMessage() {} func (*QueryPendingSendToEthResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_29a9d4192703013c, []int{43} + return fileDescriptor_29a9d4192703013c, []int{45} } func (m *QueryPendingSendToEthResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2064,6 +2152,8 @@ func init() { proto.RegisterType((*QueryERC20ToDenomResponse)(nil), "gravity.v1.QueryERC20ToDenomResponse") proto.RegisterType((*QueryDenomToERC20Request)(nil), "gravity.v1.QueryDenomToERC20Request") proto.RegisterType((*QueryDenomToERC20Response)(nil), "gravity.v1.QueryDenomToERC20Response") + proto.RegisterType((*QueryAttestationsRequest)(nil), "gravity.v1.QueryAttestationsRequest") + proto.RegisterType((*QueryAttestationsResponse)(nil), "gravity.v1.QueryAttestationsResponse") proto.RegisterType((*QueryDelegateKeysByValidatorAddress)(nil), "gravity.v1.QueryDelegateKeysByValidatorAddress") proto.RegisterType((*QueryDelegateKeysByValidatorAddressResponse)(nil), "gravity.v1.QueryDelegateKeysByValidatorAddressResponse") proto.RegisterType((*QueryDelegateKeysByEthAddress)(nil), "gravity.v1.QueryDelegateKeysByEthAddress") @@ -2077,119 +2167,124 @@ func init() { func init() { proto.RegisterFile("gravity/v1/query.proto", fileDescriptor_29a9d4192703013c) } var fileDescriptor_29a9d4192703013c = []byte{ - // 1789 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x99, 0xc9, 0x6f, 0xdc, 0x46, - 0x16, 0xc6, 0x45, 0x8d, 0x25, 0xd9, 0xcf, 0x7b, 0xa9, 0x65, 0xc8, 0x94, 0xd5, 0x2d, 0xd1, 0x23, - 0xdb, 0x5a, 0xa9, 0x65, 0xbc, 0xcc, 0x78, 0x30, 0x18, 0xb7, 0x2c, 0x7b, 0x0c, 0xdb, 0x23, 0x4f, - 0x8f, 0xc6, 0x83, 0xc4, 0x86, 0x09, 0x76, 0xb3, 0xc4, 0x26, 0xd2, 0x22, 0x65, 0x92, 0x6a, 0xa8, - 0x61, 0xd8, 0x40, 0x72, 0x48, 0xae, 0x01, 0xb2, 0x01, 0x39, 0xe5, 0x96, 0x9c, 0x72, 0x4c, 0x8e, - 0x01, 0x72, 0x32, 0x90, 0x8b, 0x81, 0x5c, 0x72, 0x0a, 0x02, 0x3b, 0x40, 0xfe, 0x8d, 0x80, 0x55, - 0x8f, 0x6c, 0x2e, 0xc5, 0x5e, 0x84, 0x9c, 0x2c, 0x15, 0xdf, 0x7b, 0xdf, 0xef, 0x55, 0x15, 0xab, - 0xf8, 0x59, 0x70, 0xc6, 0x74, 0xf5, 0xa6, 0xe5, 0xb7, 0xd4, 0xe6, 0x8a, 0xfa, 0x74, 0x8f, 0xba, - 0xad, 0xa5, 0x5d, 0xd7, 0xf1, 0x1d, 0x02, 0x38, 0xbe, 0xd4, 0x5c, 0x91, 0xc7, 0x63, 0x31, 0x26, - 0xb5, 0xa9, 0x67, 0x79, 0x3c, 0x4a, 0x8e, 0x67, 0xfb, 0xad, 0x5d, 0x1a, 0x8e, 0x8f, 0xc5, 0xc6, - 0x77, 0x3c, 0x53, 0x34, 0xbc, 0xeb, 0x38, 0x0d, 0x41, 0x95, 0xaa, 0xee, 0xd7, 0xea, 0x38, 0x7e, - 0xce, 0x74, 0x1c, 0xb3, 0x41, 0x55, 0x7d, 0xd7, 0x52, 0x75, 0xdb, 0x76, 0x7c, 0xdd, 0xb7, 0x1c, - 0x3b, 0x2c, 0x56, 0x30, 0x1d, 0xd3, 0x61, 0x3f, 0xaa, 0xc1, 0x4f, 0x7c, 0x54, 0x29, 0x00, 0xf9, - 0x4f, 0xd0, 0xc6, 0x03, 0xdd, 0xd5, 0x77, 0xbc, 0x0a, 0x7d, 0xba, 0x47, 0x3d, 0x5f, 0xb9, 0x0d, - 0xa3, 0x89, 0x51, 0x6f, 0xd7, 0xb1, 0x3d, 0x4a, 0x96, 0x61, 0x78, 0x97, 0x8d, 0x8c, 0x4b, 0x53, - 0xd2, 0xa5, 0xa3, 0xab, 0x64, 0xa9, 0xdd, 0xf5, 0x12, 0x8f, 0x2d, 0x1f, 0x7a, 0xf9, 0x73, 0x69, - 0xa0, 0x82, 0x71, 0xca, 0x04, 0x9c, 0x65, 0x85, 0xd6, 0xf7, 0x5c, 0x97, 0xda, 0xfe, 0x43, 0xbd, - 0xe1, 0x51, 0x3f, 0x54, 0xf9, 0x17, 0xc8, 0xa2, 0x87, 0x28, 0x36, 0x07, 0xc3, 0x4d, 0x36, 0x22, - 0x12, 0xc3, 0x58, 0x8c, 0x50, 0x56, 0x50, 0x26, 0x51, 0x1f, 0xff, 0x21, 0x05, 0x18, 0xb2, 0x1d, - 0xbb, 0x46, 0x59, 0x9d, 0x43, 0x15, 0xfe, 0x4b, 0x24, 0x9e, 0x4a, 0x39, 0x80, 0xf8, 0xdd, 0x84, - 0xf8, 0xba, 0x63, 0x6f, 0x5b, 0xee, 0x4e, 0x47, 0x71, 0x32, 0x0e, 0x23, 0xba, 0x61, 0xb8, 0xd4, - 0xf3, 0xc6, 0x07, 0xa7, 0xa4, 0x4b, 0x47, 0x2a, 0xe1, 0xaf, 0xca, 0x56, 0x02, 0x2b, 0x2a, 0x86, - 0x58, 0x57, 0x60, 0xa4, 0xc6, 0x87, 0x90, 0xeb, 0x5c, 0x9c, 0xeb, 0xbe, 0x67, 0x26, 0xd3, 0xc2, - 0x60, 0xe5, 0xaf, 0x30, 0x9d, 0xad, 0xea, 0x95, 0x5b, 0xff, 0x0e, 0x68, 0x3a, 0xcf, 0xd3, 0x13, - 0x50, 0x3a, 0xa5, 0x22, 0xd8, 0x35, 0x38, 0x8c, 0x5a, 0xc1, 0xde, 0xf8, 0x53, 0x57, 0xb2, 0x28, - 0x5a, 0x99, 0x82, 0x22, 0xab, 0x7f, 0x4f, 0xf7, 0x92, 0xdb, 0x23, 0xda, 0x8c, 0x9b, 0x50, 0xca, - 0x8d, 0x40, 0xf9, 0x05, 0x18, 0xe1, 0x8b, 0x11, 0xaa, 0x8b, 0xd6, 0x2b, 0x0c, 0x51, 0x6e, 0xc1, - 0x5c, 0x54, 0xf0, 0x01, 0xb5, 0x0d, 0xcb, 0x36, 0x13, 0x75, 0xcb, 0xad, 0x1b, 0x86, 0xe1, 0x86, - 0xd3, 0x12, 0x5b, 0x2b, 0x29, 0xb9, 0x56, 0x8f, 0x60, 0xbe, 0xa7, 0x3a, 0x07, 0x82, 0x3c, 0x03, - 0x05, 0x56, 0xbc, 0x1c, 0xbc, 0xe0, 0xb7, 0x68, 0xb8, 0x4a, 0xca, 0x7d, 0x18, 0x4b, 0x8d, 0x63, - 0xf9, 0xbf, 0x00, 0xb0, 0xc3, 0x40, 0xdb, 0xa6, 0x34, 0x54, 0x18, 0x8b, 0x2b, 0x84, 0x19, 0x5e, - 0xe5, 0x48, 0x35, 0xfc, 0x51, 0xd9, 0x80, 0xd9, 0x74, 0x0f, 0x2c, 0xae, 0xcf, 0xa9, 0xd0, 0xb2, - 0x53, 0x2a, 0x2a, 0x83, 0xa8, 0x2b, 0x30, 0xc4, 0x08, 0x70, 0x13, 0x4f, 0xc4, 0x29, 0x37, 0xf7, - 0x7c, 0xd3, 0xb1, 0x6c, 0x73, 0x6b, 0x9f, 0x17, 0xe0, 0x91, 0x4a, 0x19, 0x2e, 0xa4, 0x05, 0xee, - 0x39, 0xa6, 0x55, 0x5b, 0xd7, 0x1b, 0x8d, 0x5e, 0x21, 0x1f, 0xc3, 0xc5, 0xae, 0x35, 0x22, 0xc2, - 0x43, 0x35, 0xbd, 0xd1, 0x40, 0xc0, 0x49, 0x11, 0x60, 0x94, 0x5a, 0x61, 0xa1, 0x4a, 0x09, 0x26, - 0x59, 0xf5, 0x54, 0x03, 0x34, 0xda, 0xc7, 0xff, 0xc7, 0x9d, 0x2e, 0x08, 0x40, 0xd5, 0xcb, 0x30, - 0x52, 0xe5, 0x43, 0xb8, 0x7e, 0x1d, 0x67, 0x26, 0x8c, 0x8d, 0x5e, 0xa1, 0x0c, 0x59, 0x24, 0xfd, - 0x10, 0x5f, 0x21, 0x51, 0x04, 0x6a, 0xaf, 0xc1, 0x50, 0xd0, 0x46, 0xa8, 0xdc, 0xa5, 0x65, 0x1e, - 0xab, 0x54, 0xb1, 0x6e, 0x72, 0xad, 0xbb, 0x9f, 0x2a, 0x64, 0x16, 0x4e, 0xd5, 0x1c, 0xdb, 0x77, - 0xf5, 0x9a, 0xaf, 0x25, 0x4f, 0xc2, 0x93, 0xe1, 0xf8, 0x0d, 0x5c, 0xb5, 0xff, 0xc1, 0x54, 0xbe, - 0xc6, 0xc1, 0x37, 0xd4, 0x63, 0x3c, 0xb5, 0xd9, 0x60, 0x78, 0xac, 0xfd, 0x81, 0xd0, 0xb2, 0xa8, - 0x3a, 0xe2, 0x5e, 0xcd, 0x9c, 0x96, 0x13, 0xa9, 0xd3, 0x12, 0x53, 0x38, 0x71, 0xfb, 0xb0, 0xf4, - 0x10, 0x9a, 0x2f, 0x44, 0x0a, 0xfa, 0x22, 0x9c, 0xb4, 0xec, 0xa6, 0xde, 0xb0, 0x0c, 0x76, 0xef, - 0x6b, 0x96, 0xc1, 0xf0, 0x8f, 0x55, 0x4e, 0xc4, 0x87, 0xef, 0x18, 0x64, 0x11, 0x48, 0x22, 0x90, - 0xb7, 0x3a, 0xc8, 0x5a, 0x3d, 0x1d, 0x7f, 0xc2, 0x26, 0x59, 0x79, 0x0b, 0x7b, 0x49, 0x89, 0x62, - 0x2f, 0xd7, 0x33, 0xbd, 0x94, 0xc4, 0xbd, 0xb4, 0x37, 0x4f, 0xbb, 0x9f, 0xbf, 0xe3, 0xda, 0x06, - 0x6f, 0xe4, 0x46, 0x93, 0xda, 0x3e, 0x53, 0xec, 0xf5, 0x7d, 0xbe, 0x89, 0xb7, 0x9a, 0x38, 0x1b, - 0xf9, 0x4a, 0x70, 0x94, 0x06, 0xcf, 0xb4, 0xf8, 0x82, 0x02, 0x8d, 0xc2, 0x95, 0x65, 0x18, 0x67, - 0x55, 0x36, 0x2a, 0xeb, 0xab, 0xcb, 0x5b, 0xce, 0x4d, 0x6a, 0x3b, 0xf1, 0xdb, 0x9b, 0xba, 0xb5, - 0xd5, 0x65, 0x54, 0xe6, 0xbf, 0x28, 0x4f, 0x70, 0x15, 0x92, 0x19, 0xa8, 0x57, 0x80, 0x21, 0x23, - 0x18, 0x08, 0x53, 0xd8, 0x2f, 0x64, 0x1e, 0x4e, 0xd7, 0x1c, 0x6f, 0xc7, 0xf1, 0x34, 0xc7, 0xb5, - 0x4c, 0xcb, 0xd6, 0x7d, 0x6a, 0xb0, 0x19, 0x3f, 0x5c, 0x39, 0xc5, 0x1f, 0x6c, 0x46, 0xe3, 0x11, - 0x11, 0x2b, 0xbc, 0xe5, 0x30, 0x99, 0x18, 0x51, 0xb6, 0x7c, 0x44, 0x94, 0xcc, 0x68, 0x13, 0x65, - 0x9b, 0xe8, 0x8f, 0xa8, 0x02, 0xe7, 0xb1, 0x7e, 0x83, 0x9a, 0xba, 0x4f, 0xef, 0xd2, 0x96, 0x57, - 0x0e, 0x3e, 0x09, 0x82, 0x8d, 0xe2, 0xb8, 0xb8, 0xeb, 0x83, 0x9a, 0xcd, 0x70, 0x4c, 0x4b, 0x2e, - 0xda, 0xa9, 0x66, 0x2a, 0x58, 0x79, 0x57, 0xc2, 0xeb, 0xb3, 0x73, 0xd1, 0xc4, 0x42, 0xfa, 0xf5, - 0x54, 0x59, 0xa0, 0x7e, 0x3d, 0x54, 0x5f, 0x81, 0x82, 0xe3, 0x06, 0x07, 0xa2, 0xef, 0x26, 0x00, - 0xf8, 0x2b, 0x3a, 0x1a, 0x7f, 0x16, 0x32, 0xfc, 0x13, 0xcf, 0xec, 0x24, 0xc2, 0x46, 0xbb, 0x66, - 0x37, 0x51, 0xe5, 0x03, 0x09, 0x66, 0x3a, 0x96, 0x88, 0xf8, 0xfb, 0x99, 0x9c, 0x83, 0xf4, 0xf2, - 0x08, 0x6f, 0xc8, 0x24, 0xc8, 0x66, 0x36, 0x32, 0xb7, 0xb8, 0x94, 0x5f, 0xfc, 0x05, 0x2c, 0xf5, - 0x56, 0xfc, 0x60, 0xed, 0xa6, 0xa6, 0x79, 0x30, 0x33, 0xcd, 0xff, 0xc0, 0xaf, 0x1e, 0xbc, 0xb6, - 0xff, 0x4b, 0x6d, 0x63, 0xcb, 0xd9, 0xf0, 0xeb, 0x64, 0x06, 0x4e, 0x78, 0xd4, 0x36, 0x68, 0x5a, - 0xe3, 0x38, 0x1f, 0x0d, 0xf3, 0xbf, 0x97, 0x70, 0xa5, 0xd3, 0x05, 0x22, 0xde, 0x07, 0x50, 0xf0, - 0x5d, 0xdd, 0xf6, 0xb6, 0xa9, 0xeb, 0x69, 0x96, 0xad, 0x25, 0x2f, 0xe2, 0xa2, 0xf0, 0x46, 0xc1, - 0xf8, 0xad, 0xfd, 0x0a, 0x89, 0x72, 0xef, 0xd8, 0x78, 0xab, 0x93, 0x4d, 0x18, 0xdd, 0xb3, 0x79, - 0x19, 0x43, 0x8b, 0x9e, 0x8f, 0x0f, 0xf6, 0x56, 0x30, 0x4a, 0x0d, 0x07, 0xbd, 0xd5, 0xdf, 0x64, - 0x18, 0x62, 0x4d, 0x10, 0x0b, 0x86, 0xb9, 0xdd, 0x22, 0x89, 0x3a, 0x59, 0x27, 0x27, 0x97, 0x72, - 0x9f, 0xf3, 0xbe, 0x95, 0xe2, 0x7b, 0x3f, 0xfe, 0xfa, 0xd1, 0xe0, 0x38, 0x39, 0xa3, 0xb6, 0x5d, - 0x65, 0x95, 0xfa, 0xba, 0xca, 0x1d, 0x1c, 0x79, 0x5f, 0x82, 0xe3, 0x09, 0x83, 0x46, 0x66, 0x32, - 0x25, 0x45, 0xee, 0x4e, 0xbe, 0xd0, 0x2d, 0x0c, 0x01, 0x2e, 0x30, 0x80, 0x29, 0x52, 0x4c, 0x03, - 0xf0, 0x2f, 0x61, 0xb5, 0xc6, 0xb3, 0xc8, 0x0b, 0x38, 0x9e, 0x10, 0x10, 0x70, 0x88, 0xec, 0x9f, - 0x80, 0x43, 0x68, 0xf9, 0xf2, 0x27, 0x82, 0x73, 0xb0, 0x89, 0x48, 0x98, 0x98, 0x5c, 0x80, 0xa4, - 0x05, 0xcc, 0x05, 0x48, 0x99, 0xbb, 0xee, 0x13, 0x81, 0xb2, 0x5f, 0x48, 0x30, 0x26, 0x74, 0x63, - 0x64, 0xb1, 0xb3, 0x52, 0xca, 0xf0, 0xc9, 0x4b, 0xbd, 0x86, 0x23, 0xe0, 0x25, 0x06, 0xa8, 0x90, - 0xa9, 0x34, 0x60, 0x78, 0x9f, 0xab, 0xcf, 0xd8, 0x25, 0xfb, 0x9c, 0x7c, 0x2a, 0x01, 0xc9, 0xda, - 0x35, 0x32, 0x97, 0x11, 0xcc, 0x75, 0x7d, 0xf2, 0x7c, 0x4f, 0xb1, 0x48, 0x76, 0x91, 0x91, 0x4d, - 0x93, 0x52, 0xce, 0xd4, 0xb9, 0x21, 0xc1, 0x37, 0x12, 0x14, 0x3b, 0xdb, 0x35, 0x72, 0x45, 0x28, - 0xdc, 0xd5, 0x27, 0xca, 0x57, 0xfb, 0xce, 0x43, 0xf8, 0xf3, 0x0c, 0x7e, 0x92, 0x4c, 0xe4, 0xc0, - 0x37, 0x74, 0xcf, 0x27, 0xdf, 0x4a, 0x30, 0xd9, 0xd1, 0x5c, 0x91, 0xcb, 0x9d, 0xf4, 0x73, 0x3d, - 0x9d, 0x7c, 0xa5, 0xdf, 0xb4, 0x6e, 0x53, 0xce, 0x8e, 0x2d, 0xf5, 0x19, 0x1e, 0xc7, 0xcf, 0xc9, - 0xd7, 0x12, 0xc8, 0xf9, 0x8e, 0x8b, 0xac, 0x76, 0xd2, 0x17, 0x5b, 0x3c, 0x79, 0xad, 0xaf, 0x9c, - 0x6e, 0xc0, 0x8d, 0x20, 0x21, 0x06, 0xfc, 0x95, 0x04, 0x05, 0xd1, 0x27, 0x25, 0x59, 0x10, 0xca, - 0xe6, 0x7c, 0xb7, 0xca, 0x8b, 0x3d, 0x46, 0x23, 0xde, 0x1a, 0xc3, 0x5b, 0x24, 0xf3, 0x69, 0x3c, - 0xc7, 0xd5, 0x6b, 0x0d, 0xaa, 0xb2, 0x2f, 0x56, 0xf6, 0x7a, 0xc5, 0x50, 0x3d, 0x38, 0x12, 0xb9, - 0x7a, 0x32, 0x95, 0x11, 0x4c, 0xfd, 0xdf, 0x81, 0x3c, 0xdd, 0x21, 0x02, 0x31, 0xa6, 0x19, 0xc6, - 0x04, 0x39, 0x2b, 0x5c, 0xd6, 0xed, 0x40, 0xe7, 0x63, 0x09, 0x4e, 0x67, 0x3c, 0x2c, 0x99, 0xcd, - 0xd4, 0xce, 0x33, 0xc2, 0xf2, 0x5c, 0x2f, 0xa1, 0xdd, 0xce, 0x1c, 0xbe, 0xcd, 0x1c, 0x4c, 0xf4, - 0xf7, 0xc9, 0xe7, 0x12, 0x90, 0xac, 0xbf, 0x25, 0xf9, 0x62, 0x19, 0x9b, 0x2c, 0x38, 0x73, 0xf2, - 0x0d, 0xb3, 0x32, 0xcf, 0xc8, 0x66, 0xc8, 0xf9, 0xce, 0x64, 0x6c, 0x77, 0x91, 0xcf, 0x24, 0x18, - 0x15, 0x18, 0x58, 0x32, 0x2f, 0x5e, 0x11, 0xa1, 0x95, 0x96, 0x17, 0x7a, 0x0b, 0x46, 0xbe, 0x19, - 0xc6, 0x57, 0x22, 0x93, 0x39, 0x2f, 0x28, 0x1e, 0xd5, 0xc1, 0xb5, 0x96, 0x70, 0xa9, 0x82, 0x6b, - 0x4d, 0xe4, 0x91, 0x05, 0xd7, 0x9a, 0xd0, 0xec, 0xe6, 0x5f, 0x6b, 0x9c, 0x23, 0xbc, 0x3b, 0x18, - 0x48, 0xc2, 0x62, 0x0a, 0x40, 0x44, 0xbe, 0x57, 0x00, 0x22, 0x74, 0xaa, 0xf9, 0x20, 0xfc, 0x00, - 0x88, 0x40, 0x3e, 0x91, 0xe0, 0x58, 0xdc, 0xda, 0x91, 0x3f, 0x67, 0x04, 0x04, 0x5e, 0x51, 0x9e, - 0xe9, 0x12, 0x85, 0x14, 0xd7, 0x18, 0xc5, 0x2a, 0x59, 0xce, 0x5e, 0xa2, 0x29, 0x37, 0xa6, 0x32, - 0xa3, 0xa6, 0xf9, 0x8e, 0xc6, 0x3d, 0x64, 0xc0, 0x15, 0x37, 0x78, 0x02, 0x2e, 0x81, 0x63, 0x14, - 0x70, 0x89, 0x5c, 0x62, 0x3f, 0x5c, 0x0c, 0x27, 0xe0, 0xe2, 0x4e, 0xf2, 0x3b, 0x09, 0xce, 0xde, - 0xa6, 0x7e, 0xcc, 0x1a, 0xc4, 0x5c, 0x1c, 0x51, 0x05, 0xf2, 0x9d, 0xfc, 0x9e, 0xe0, 0x1e, 0xed, - 0xcd, 0x20, 0xe6, 0x77, 0xc0, 0xfe, 0x4e, 0xa3, 0x19, 0x58, 0x45, 0x7b, 0x87, 0xb6, 0x3c, 0xad, - 0xda, 0xd2, 0x22, 0x17, 0x42, 0xbe, 0x94, 0x60, 0x34, 0xdd, 0x41, 0x60, 0x2e, 0x66, 0xbb, 0xa0, - 0xb4, 0x5d, 0x9e, 0xbc, 0xd2, 0x73, 0x68, 0xc4, 0xbb, 0xca, 0x78, 0x17, 0xc8, 0x5c, 0x8f, 0xbc, - 0xd4, 0xaf, 0x93, 0x1f, 0x24, 0x38, 0x97, 0x26, 0x8d, 0xbb, 0x30, 0xc1, 0x75, 0xda, 0xd5, 0xb2, - 0xc9, 0x7f, 0xeb, 0x3f, 0x27, 0x6a, 0xe2, 0x3a, 0x6b, 0xe2, 0x32, 0x59, 0xeb, 0xb1, 0x89, 0xb8, - 0xb9, 0x0c, 0x3e, 0x13, 0x83, 0x79, 0xcf, 0x98, 0xba, 0xec, 0x3d, 0x95, 0x0e, 0x91, 0x67, 0xbb, - 0x86, 0x44, 0x88, 0x2b, 0x0c, 0x71, 0x9e, 0xcc, 0x8a, 0x11, 0x77, 0x79, 0x9e, 0x16, 0x18, 0x46, - 0xb6, 0xa9, 0xfd, 0x7a, 0xf9, 0xf1, 0xcb, 0xd7, 0x45, 0xe9, 0xd5, 0xeb, 0xa2, 0xf4, 0xcb, 0xeb, - 0xa2, 0xf4, 0xe1, 0x9b, 0xe2, 0xc0, 0xab, 0x37, 0xc5, 0x81, 0x9f, 0xde, 0x14, 0x07, 0xde, 0x2e, - 0x9b, 0x96, 0x5f, 0xdf, 0xab, 0x2e, 0xd5, 0x9c, 0x1d, 0x55, 0x6f, 0xf8, 0x75, 0xaa, 0x2f, 0xda, - 0xec, 0xdb, 0x3c, 0x78, 0x49, 0x16, 0x51, 0x60, 0xb1, 0xea, 0x5a, 0x86, 0x49, 0xd5, 0x1d, 0xc7, - 0xd8, 0x6b, 0x50, 0x75, 0x3f, 0x12, 0x66, 0x7f, 0xf3, 0xab, 0x0e, 0xb3, 0x3f, 0xbd, 0xad, 0xfd, - 0x1e, 0x00, 0x00, 0xff, 0xff, 0x24, 0x7a, 0x80, 0xfb, 0x4c, 0x1c, 0x00, 0x00, + // 1871 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x99, 0x49, 0x6f, 0x1b, 0xc9, + 0x15, 0xc7, 0xd5, 0x8a, 0x25, 0xd9, 0xcf, 0x7b, 0x89, 0x72, 0xe4, 0x96, 0x45, 0x4a, 0x6d, 0xcb, + 0xb6, 0xd6, 0xd6, 0x12, 0x2f, 0x89, 0x83, 0x20, 0xa6, 0x2c, 0x3b, 0x86, 0xed, 0xc8, 0x61, 0x14, + 0x67, 0xb1, 0xe1, 0x46, 0x93, 0x5d, 0x22, 0x1b, 0xa1, 0xba, 0xe5, 0xee, 0x12, 0x21, 0xc2, 0xb0, + 0x81, 0xe4, 0x90, 0x00, 0x39, 0x05, 0xc8, 0x06, 0xe4, 0x34, 0xb7, 0x99, 0xd3, 0x1c, 0x67, 0x8e, + 0x03, 0xcc, 0xc9, 0xc0, 0x5c, 0x0c, 0xcc, 0x65, 0x4e, 0x83, 0x81, 0x3d, 0x1f, 0x61, 0x3e, 0xc0, + 0xa0, 0xab, 0x5e, 0x37, 0x7b, 0xa9, 0x26, 0x29, 0x61, 0x4e, 0x22, 0x5f, 0xbf, 0xe5, 0xf7, 0xaa, + 0xaa, 0xab, 0xea, 0x2f, 0xc2, 0xb9, 0xba, 0x67, 0xb6, 0x6c, 0xd6, 0xd6, 0x5b, 0x2b, 0xfa, 0x8b, + 0x3d, 0xea, 0xb5, 0x97, 0x76, 0x3d, 0x97, 0xb9, 0x04, 0xd0, 0xbe, 0xd4, 0x5a, 0x51, 0xc7, 0x63, + 0x3e, 0x75, 0xea, 0x50, 0xdf, 0xf6, 0x85, 0x97, 0x1a, 0x8f, 0x66, 0xed, 0x5d, 0x1a, 0xda, 0xc7, + 0x62, 0xf6, 0x1d, 0xbf, 0x2e, 0x33, 0xef, 0xba, 0x6e, 0x53, 0x92, 0xa5, 0x6a, 0xb2, 0x5a, 0x03, + 0xed, 0x17, 0x62, 0x76, 0x93, 0x31, 0xea, 0x33, 0x93, 0xd9, 0xae, 0x13, 0x3d, 0x75, 0xdd, 0x7a, + 0x93, 0xea, 0xe6, 0xae, 0xad, 0x9b, 0x8e, 0xe3, 0x8a, 0x87, 0x61, 0xa9, 0x42, 0xdd, 0xad, 0xbb, + 0xfc, 0xa3, 0x1e, 0x7c, 0x12, 0x56, 0xad, 0x00, 0xe4, 0x37, 0x41, 0x93, 0x8f, 0x4d, 0xcf, 0xdc, + 0xf1, 0x2b, 0xf4, 0xc5, 0x1e, 0xf5, 0x99, 0x76, 0x0f, 0x46, 0x13, 0x56, 0x7f, 0xd7, 0x75, 0x7c, + 0x4a, 0x96, 0x61, 0x78, 0x97, 0x5b, 0xc6, 0x95, 0x29, 0xe5, 0xea, 0xf1, 0x55, 0xb2, 0xd4, 0x19, + 0x93, 0x25, 0xe1, 0x5b, 0x3e, 0xf2, 0xe6, 0xeb, 0xd2, 0x40, 0x05, 0xfd, 0xb4, 0x09, 0x38, 0xcf, + 0x13, 0xad, 0xef, 0x79, 0x1e, 0x75, 0xd8, 0x13, 0xb3, 0xe9, 0x53, 0x16, 0x56, 0xf9, 0x15, 0xa8, + 0xb2, 0x87, 0x58, 0x6c, 0x0e, 0x86, 0x5b, 0xdc, 0x22, 0x2b, 0x86, 0xbe, 0xe8, 0xa1, 0xad, 0x60, + 0x99, 0x44, 0x7e, 0xfc, 0x43, 0x0a, 0x30, 0xe4, 0xb8, 0x4e, 0x8d, 0xf2, 0x3c, 0x47, 0x2a, 0xe2, + 0x4b, 0x54, 0x3c, 0x15, 0x72, 0x88, 0xe2, 0x0f, 0x12, 0xc5, 0xd7, 0x5d, 0x67, 0xdb, 0xf6, 0x76, + 0xba, 0x16, 0x27, 0xe3, 0x30, 0x62, 0x5a, 0x96, 0x47, 0x7d, 0x7f, 0x7c, 0x70, 0x4a, 0xb9, 0x7a, + 0xac, 0x12, 0x7e, 0xd5, 0xb6, 0x12, 0x58, 0x51, 0x32, 0xc4, 0xba, 0x0e, 0x23, 0x35, 0x61, 0x42, + 0xae, 0x0b, 0x71, 0xae, 0x47, 0x7e, 0x3d, 0x19, 0x16, 0x3a, 0x6b, 0x3f, 0x85, 0xe9, 0x6c, 0x56, + 0xbf, 0xdc, 0xfe, 0x75, 0x40, 0xd3, 0x7d, 0x9c, 0x9e, 0x83, 0xd6, 0x2d, 0x14, 0xc1, 0x6e, 0xc2, + 0x51, 0xac, 0x15, 0xac, 0x8d, 0x1f, 0xf5, 0x24, 0x8b, 0xbc, 0xb5, 0x29, 0x28, 0xf2, 0xfc, 0x0f, + 0x4d, 0x3f, 0xb9, 0x3c, 0xa2, 0xc5, 0xb8, 0x09, 0xa5, 0x5c, 0x0f, 0x2c, 0xbf, 0x00, 0x23, 0x62, + 0x32, 0xc2, 0xea, 0xb2, 0xf9, 0x0a, 0x5d, 0xb4, 0xbb, 0x30, 0x17, 0x25, 0x7c, 0x4c, 0x1d, 0xcb, + 0x76, 0xea, 0x89, 0xbc, 0xe5, 0xf6, 0x6d, 0xcb, 0xf2, 0xc2, 0x61, 0x89, 0xcd, 0x95, 0x92, 0x9c, + 0xab, 0xa7, 0x30, 0xdf, 0x57, 0x9e, 0x43, 0x41, 0x9e, 0x83, 0x02, 0x4f, 0x5e, 0x0e, 0x5e, 0xff, + 0xbb, 0x34, 0x9c, 0x25, 0xed, 0x11, 0x8c, 0xa5, 0xec, 0x98, 0xfe, 0x27, 0x00, 0x7c, 0xab, 0x30, + 0xb6, 0x29, 0x0d, 0x2b, 0x8c, 0xc5, 0x2b, 0x84, 0x11, 0x7e, 0xe5, 0x58, 0x35, 0xfc, 0xa8, 0x6d, + 0xc0, 0x6c, 0xba, 0x07, 0xee, 0x77, 0xc0, 0xa1, 0x30, 0xb2, 0x43, 0x2a, 0x4b, 0x83, 0xa8, 0x2b, + 0x30, 0xc4, 0x09, 0x70, 0x11, 0x4f, 0xc4, 0x29, 0x37, 0xf7, 0x58, 0xdd, 0xb5, 0x9d, 0xfa, 0xd6, + 0xbe, 0x48, 0x20, 0x3c, 0xb5, 0x32, 0x5c, 0x4e, 0x17, 0x78, 0xe8, 0xd6, 0xed, 0xda, 0xba, 0xd9, + 0x6c, 0xf6, 0x0b, 0xf9, 0x0c, 0xae, 0xf4, 0xcc, 0x11, 0x11, 0x1e, 0xa9, 0x99, 0xcd, 0x26, 0x02, + 0x4e, 0xca, 0x00, 0xa3, 0xd0, 0x0a, 0x77, 0xd5, 0x4a, 0x30, 0xc9, 0xb3, 0xa7, 0x1a, 0xa0, 0xd1, + 0x3a, 0xfe, 0x3d, 0xae, 0x74, 0x89, 0x03, 0x56, 0xbd, 0x06, 0x23, 0x55, 0x61, 0xc2, 0xf9, 0xeb, + 0x3a, 0x32, 0xa1, 0x6f, 0xf4, 0x0a, 0x65, 0xc8, 0xa2, 0xd2, 0x4f, 0xf0, 0x15, 0x92, 0x79, 0x60, + 0xed, 0x35, 0x18, 0x0a, 0xda, 0x08, 0x2b, 0xf7, 0x68, 0x59, 0xf8, 0x6a, 0x55, 0xcc, 0x9b, 0x9c, + 0xeb, 0xde, 0xbb, 0x0a, 0x99, 0x85, 0x33, 0x35, 0xd7, 0x61, 0x9e, 0x59, 0x63, 0x46, 0x72, 0x27, + 0x3c, 0x1d, 0xda, 0x6f, 0xe3, 0xac, 0xfd, 0x0e, 0xa6, 0xf2, 0x6b, 0x1c, 0x7e, 0x41, 0x3d, 0xc3, + 0x5d, 0x9b, 0x1b, 0xc3, 0x6d, 0xed, 0x07, 0x84, 0x56, 0x65, 0xd9, 0x11, 0xf7, 0x46, 0x66, 0xb7, + 0x9c, 0x48, 0xed, 0x96, 0x18, 0x22, 0x88, 0x3b, 0x9b, 0xa5, 0x8f, 0xd0, 0x62, 0x22, 0x52, 0xd0, + 0x57, 0xe0, 0xb4, 0xed, 0xb4, 0xcc, 0xa6, 0x6d, 0xf1, 0x73, 0xdf, 0xb0, 0x2d, 0x8e, 0x7f, 0xa2, + 0x72, 0x2a, 0x6e, 0xbe, 0x6f, 0x91, 0x45, 0x20, 0x09, 0x47, 0xd1, 0xea, 0x20, 0x6f, 0xf5, 0x6c, + 0xfc, 0x09, 0x1f, 0x64, 0xed, 0x8f, 0xd8, 0x4b, 0xaa, 0x28, 0xf6, 0x72, 0x2b, 0xd3, 0x4b, 0x49, + 0xde, 0x4b, 0x67, 0xf1, 0x74, 0xfa, 0xf9, 0x39, 0xce, 0x6d, 0xf0, 0x46, 0x6e, 0xb4, 0xa8, 0xc3, + 0x78, 0xc5, 0x7e, 0xdf, 0xe7, 0x3b, 0x78, 0xaa, 0xc9, 0xa3, 0x91, 0xaf, 0x04, 0xc7, 0x69, 0xf0, + 0xcc, 0x88, 0x4f, 0x28, 0xd0, 0xc8, 0x5d, 0x5b, 0x86, 0x71, 0x9e, 0x65, 0xa3, 0xb2, 0xbe, 0xba, + 0xbc, 0xe5, 0xde, 0xa1, 0x8e, 0x1b, 0x3f, 0xbd, 0xa9, 0x57, 0x5b, 0x5d, 0xc6, 0xca, 0xe2, 0x8b, + 0xf6, 0x1c, 0x67, 0x21, 0x19, 0x81, 0xf5, 0x0a, 0x30, 0x64, 0x05, 0x86, 0x30, 0x84, 0x7f, 0x21, + 0xf3, 0x70, 0xb6, 0xe6, 0xfa, 0x3b, 0xae, 0x6f, 0xb8, 0x9e, 0x5d, 0xb7, 0x1d, 0x93, 0x51, 0x8b, + 0x8f, 0xf8, 0xd1, 0xca, 0x19, 0xf1, 0x60, 0x33, 0xb2, 0x47, 0x44, 0x3c, 0xf1, 0x96, 0xcb, 0xcb, + 0xc4, 0x88, 0xb2, 0xe9, 0x23, 0xa2, 0x64, 0x44, 0x87, 0x28, 0xdb, 0xc4, 0xe1, 0x88, 0x6e, 0x77, + 0xee, 0x9c, 0xf1, 0x77, 0xa5, 0x69, 0xef, 0xd8, 0x2c, 0x7c, 0x57, 0xf8, 0x17, 0xed, 0x0f, 0x48, + 0x94, 0x8c, 0x88, 0xd6, 0xcc, 0x89, 0xd8, 0xed, 0x35, 0x5c, 0x37, 0x3f, 0x8e, 0xaf, 0x9b, 0x58, + 0x5c, 0x25, 0xe1, 0xac, 0x55, 0xe0, 0x22, 0xf6, 0xda, 0xa4, 0x75, 0x93, 0xd1, 0x07, 0xb4, 0xed, + 0x97, 0x83, 0xeb, 0x49, 0xb0, 0x68, 0x5d, 0x0f, 0xdf, 0xc0, 0xa0, 0xbf, 0x56, 0x68, 0x33, 0x92, + 0x0b, 0xe8, 0x4c, 0x2b, 0xe5, 0xac, 0xfd, 0x45, 0xc1, 0xa3, 0xbc, 0x7b, 0xd2, 0xc4, 0xa2, 0x62, + 0x8d, 0x54, 0x5a, 0xa0, 0xac, 0x11, 0x56, 0x5f, 0x81, 0x82, 0xeb, 0x05, 0x9b, 0x33, 0xf3, 0x12, + 0x00, 0x62, 0xbb, 0x18, 0x8d, 0x3f, 0x0b, 0x19, 0x7e, 0x89, 0xe7, 0x47, 0x12, 0x61, 0xa3, 0x93, + 0xb3, 0x57, 0x51, 0xed, 0xef, 0x0a, 0xcc, 0x74, 0x4d, 0x11, 0xf1, 0x1f, 0x64, 0x70, 0x0e, 0xd3, + 0xcb, 0x53, 0x3c, 0xad, 0x93, 0x20, 0x9b, 0x59, 0xcf, 0xdc, 0xe4, 0x4a, 0x7e, 0xf2, 0xd7, 0xb0, + 0xd4, 0x5f, 0xf2, 0xc3, 0xb5, 0x9b, 0x1a, 0xe6, 0xc1, 0xcc, 0x30, 0xff, 0x02, 0x6f, 0x60, 0x78, + 0x85, 0xf8, 0x2d, 0x75, 0xac, 0x2d, 0x77, 0x83, 0x35, 0xc8, 0x0c, 0x9c, 0xf2, 0xa9, 0x63, 0xd1, + 0x74, 0x8d, 0x93, 0xc2, 0x1a, 0xc6, 0x7f, 0xae, 0xe0, 0x4c, 0xa7, 0x13, 0x44, 0xbc, 0x8f, 0xa1, + 0xc0, 0x3c, 0xd3, 0xf1, 0xb7, 0xa9, 0xe7, 0x1b, 0xb6, 0x63, 0x24, 0x2f, 0x05, 0x45, 0xe9, 0xe9, + 0x86, 0xfe, 0x5b, 0xfb, 0x15, 0x12, 0xc5, 0xde, 0x77, 0xf0, 0x86, 0x41, 0x36, 0x61, 0x74, 0xcf, + 0x11, 0x69, 0x2c, 0x23, 0x7a, 0x3e, 0x3e, 0xd8, 0x5f, 0xc2, 0x28, 0x34, 0x34, 0xfa, 0xab, 0xdf, + 0x4d, 0xc0, 0x10, 0x6f, 0x82, 0xd8, 0x30, 0x2c, 0xa4, 0x1f, 0x49, 0xe4, 0xc9, 0xaa, 0x4a, 0xb5, + 0x94, 0xfb, 0x5c, 0xf4, 0xad, 0x15, 0xff, 0xfa, 0xe5, 0xb7, 0xff, 0x1a, 0x1c, 0x27, 0xe7, 0xf4, + 0x8e, 0xce, 0xad, 0x52, 0x66, 0xea, 0x42, 0x4d, 0x92, 0xbf, 0x29, 0x70, 0x32, 0x21, 0x16, 0xc9, + 0x4c, 0x26, 0xa5, 0x4c, 0x69, 0xaa, 0x97, 0x7b, 0xb9, 0x21, 0xc0, 0x65, 0x0e, 0x30, 0x45, 0x8a, + 0x69, 0x00, 0x71, 0x2b, 0xd7, 0x6b, 0x22, 0x8a, 0xbc, 0x86, 0x93, 0x89, 0x02, 0x12, 0x0e, 0x99, + 0x14, 0x95, 0x70, 0x48, 0xe5, 0x67, 0xfe, 0x40, 0x08, 0x0e, 0x3e, 0x10, 0x09, 0x41, 0x95, 0x0b, + 0x90, 0x94, 0xa3, 0xb9, 0x00, 0x29, 0xa1, 0xd9, 0x7b, 0x20, 0xb0, 0xec, 0x07, 0x0a, 0x8c, 0x49, + 0x95, 0x21, 0x59, 0xec, 0x5e, 0x29, 0x25, 0x3e, 0xd5, 0xa5, 0x7e, 0xdd, 0x11, 0xf0, 0x2a, 0x07, + 0xd4, 0xc8, 0x54, 0x1a, 0x30, 0xbc, 0x5b, 0xe8, 0x2f, 0xf9, 0x81, 0xff, 0x8a, 0xfc, 0x57, 0x01, + 0x92, 0x95, 0x8e, 0x64, 0x2e, 0x53, 0x30, 0x57, 0x81, 0xaa, 0xf3, 0x7d, 0xf9, 0x22, 0xd9, 0x15, + 0x4e, 0x36, 0x4d, 0x4a, 0x39, 0x43, 0xe7, 0x85, 0x04, 0x9f, 0x28, 0x50, 0xec, 0x2e, 0x1d, 0xc9, + 0x75, 0x69, 0xe1, 0x9e, 0x9a, 0x55, 0xbd, 0x71, 0xe0, 0x38, 0x84, 0xbf, 0xc8, 0xe1, 0x27, 0xc9, + 0x44, 0x0e, 0x7c, 0xd3, 0xf4, 0x19, 0xf9, 0x54, 0x81, 0xc9, 0xae, 0x42, 0x8f, 0x5c, 0xeb, 0x56, + 0x3f, 0x57, 0x5f, 0xaa, 0xd7, 0x0f, 0x1a, 0xd6, 0x6b, 0xc8, 0xf9, 0xb6, 0xa5, 0xbf, 0xc4, 0xed, + 0xf8, 0x15, 0xf9, 0x58, 0x01, 0x35, 0x5f, 0xfd, 0x91, 0xd5, 0x6e, 0xf5, 0xe5, 0x72, 0x53, 0x5d, + 0x3b, 0x50, 0x4c, 0x2f, 0xe0, 0x66, 0x10, 0x10, 0x03, 0xfe, 0x48, 0x81, 0x82, 0xec, 0x7a, 0x4b, + 0x16, 0xa4, 0x65, 0x73, 0xee, 0xd0, 0xea, 0x62, 0x9f, 0xde, 0x88, 0xb7, 0xc6, 0xf1, 0x16, 0xc9, + 0x7c, 0x1a, 0xcf, 0xf5, 0xcc, 0x5a, 0x93, 0xea, 0xfc, 0xf6, 0xcc, 0x5f, 0xaf, 0x18, 0xaa, 0x0f, + 0xc7, 0xa2, 0xff, 0x30, 0x90, 0xa9, 0x4c, 0xc1, 0xd4, 0xff, 0x31, 0xd4, 0xe9, 0x2e, 0x1e, 0x88, + 0x31, 0xcd, 0x31, 0x26, 0xc8, 0x79, 0xe9, 0xb4, 0x6e, 0x07, 0x75, 0xfe, 0xad, 0xc0, 0xd9, 0x8c, + 0x9e, 0x26, 0xb3, 0x99, 0xdc, 0x79, 0xa2, 0x5c, 0x9d, 0xeb, 0xc7, 0xb5, 0xd7, 0x9e, 0x23, 0x96, + 0x99, 0x8b, 0x81, 0x6c, 0x9f, 0xfc, 0x5f, 0x01, 0x92, 0xd5, 0xda, 0x24, 0xbf, 0x58, 0x46, 0xb2, + 0x4b, 0xf6, 0x9c, 0x7c, 0xf1, 0xae, 0xcd, 0x73, 0xb2, 0x19, 0x72, 0xb1, 0x3b, 0x19, 0x5f, 0x5d, + 0xe4, 0x7f, 0x0a, 0x8c, 0x4a, 0xc4, 0x34, 0x99, 0x97, 0xcf, 0x88, 0x54, 0xd6, 0xab, 0x0b, 0xfd, + 0x39, 0x23, 0xdf, 0x0c, 0xe7, 0x2b, 0x91, 0xc9, 0x9c, 0x17, 0x14, 0xb7, 0xea, 0xe0, 0x58, 0x4b, + 0x28, 0x66, 0xc9, 0xb1, 0x26, 0xd3, 0xeb, 0x92, 0x63, 0x4d, 0x2a, 0xbc, 0xf3, 0x8f, 0x35, 0xc1, + 0x11, 0x9e, 0x1d, 0x1c, 0x24, 0x21, 0x77, 0x25, 0x20, 0x32, 0x0d, 0x2e, 0x01, 0x91, 0xaa, 0xe6, + 0x7c, 0x10, 0xb1, 0x01, 0x44, 0x20, 0xff, 0x51, 0xe0, 0x44, 0x5c, 0x66, 0x92, 0x4b, 0x99, 0x02, + 0x12, 0xdd, 0xaa, 0xce, 0xf4, 0xf0, 0x42, 0x8a, 0x9b, 0x9c, 0x62, 0x95, 0x2c, 0x67, 0x0f, 0xd1, + 0x94, 0x32, 0xd4, 0xb9, 0x68, 0x34, 0x98, 0x6b, 0x08, 0x3d, 0x1b, 0x70, 0xc5, 0xc5, 0xa6, 0x84, + 0x4b, 0xa2, 0x5e, 0x25, 0x5c, 0x32, 0xc5, 0x7a, 0x10, 0x2e, 0x8e, 0x13, 0x70, 0x09, 0x55, 0xfb, + 0x0f, 0x05, 0x4e, 0xdf, 0xa3, 0x2c, 0xae, 0x3a, 0x25, 0x68, 0x12, 0x19, 0x2b, 0x41, 0x93, 0x49, + 0x57, 0x6d, 0x8e, 0xa3, 0x5d, 0x22, 0x5a, 0x1a, 0x8d, 0xff, 0x54, 0x64, 0xc4, 0x95, 0x2a, 0xf9, + 0x4c, 0x81, 0xf3, 0xf7, 0x28, 0x8b, 0xe9, 0x94, 0x98, 0xa4, 0x24, 0xba, 0x64, 0x2c, 0xba, 0x89, + 0x4f, 0xc9, 0xa1, 0xde, 0x9f, 0x5a, 0xcd, 0x1f, 0x4e, 0xc1, 0x6c, 0x61, 0x16, 0xe3, 0xcf, 0xb4, + 0xed, 0x1b, 0xd5, 0xb6, 0x11, 0x49, 0x22, 0xf2, 0xa1, 0x02, 0xa3, 0xe9, 0x0e, 0x02, 0xa5, 0x33, + 0xdb, 0x03, 0xa5, 0x23, 0x39, 0xd5, 0x95, 0xbe, 0x5d, 0x23, 0xde, 0x55, 0xce, 0xbb, 0x40, 0xe6, + 0xfa, 0xe4, 0xa5, 0xac, 0x41, 0xbe, 0x50, 0xe0, 0x42, 0x9a, 0x34, 0x2e, 0x09, 0x25, 0x67, 0x7b, + 0x4f, 0xfd, 0xa8, 0xfe, 0xec, 0xe0, 0x31, 0x51, 0x13, 0xb7, 0x78, 0x13, 0xd7, 0xc8, 0x5a, 0x9f, + 0x4d, 0xc4, 0x95, 0x6e, 0x70, 0x67, 0x0d, 0xc6, 0x3d, 0xa3, 0x30, 0xb3, 0x87, 0x66, 0xda, 0x45, + 0x9d, 0xed, 0xe9, 0x12, 0x21, 0xae, 0x70, 0xc4, 0x79, 0x32, 0x2b, 0x47, 0xdc, 0x15, 0x71, 0x46, + 0xa0, 0x5e, 0xf9, 0x1b, 0xc6, 0x1a, 0xe5, 0x67, 0x6f, 0xde, 0x15, 0x95, 0xb7, 0xef, 0x8a, 0xca, + 0x37, 0xef, 0x8a, 0xca, 0x3f, 0xdf, 0x17, 0x07, 0xde, 0xbe, 0x2f, 0x0e, 0x7c, 0xf5, 0xbe, 0x38, + 0xf0, 0xa7, 0x72, 0xdd, 0x66, 0x8d, 0xbd, 0xea, 0x52, 0xcd, 0xdd, 0xd1, 0xcd, 0x26, 0x6b, 0x50, + 0x73, 0xd1, 0xe1, 0x42, 0x21, 0x78, 0x63, 0x17, 0xb1, 0xc0, 0x62, 0xd5, 0xb3, 0xad, 0x3a, 0xd5, + 0x77, 0x5c, 0x6b, 0xaf, 0x49, 0xf5, 0xfd, 0xa8, 0x30, 0xff, 0xa9, 0xb4, 0x3a, 0xcc, 0x7f, 0x93, + 0x5c, 0xfb, 0x3e, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x23, 0x8f, 0x54, 0x83, 0x1d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2223,6 +2318,7 @@ type QueryClient interface { LogicConfirms(ctx context.Context, in *QueryLogicConfirmsRequest, opts ...grpc.CallOption) (*QueryLogicConfirmsResponse, error) ERC20ToDenom(ctx context.Context, in *QueryERC20ToDenomRequest, opts ...grpc.CallOption) (*QueryERC20ToDenomResponse, error) DenomToERC20(ctx context.Context, in *QueryDenomToERC20Request, opts ...grpc.CallOption) (*QueryDenomToERC20Response, error) + GetAttestations(ctx context.Context, in *QueryAttestationsRequest, opts ...grpc.CallOption) (*QueryAttestationsResponse, error) GetDelegateKeyByValidator(ctx context.Context, in *QueryDelegateKeysByValidatorAddress, opts ...grpc.CallOption) (*QueryDelegateKeysByValidatorAddressResponse, error) GetDelegateKeyByEth(ctx context.Context, in *QueryDelegateKeysByEthAddress, opts ...grpc.CallOption) (*QueryDelegateKeysByEthAddressResponse, error) GetDelegateKeyByOrchestrator(ctx context.Context, in *QueryDelegateKeysByOrchestratorAddress, opts ...grpc.CallOption) (*QueryDelegateKeysByOrchestratorAddressResponse, error) @@ -2399,6 +2495,15 @@ func (c *queryClient) DenomToERC20(ctx context.Context, in *QueryDenomToERC20Req return out, nil } +func (c *queryClient) GetAttestations(ctx context.Context, in *QueryAttestationsRequest, opts ...grpc.CallOption) (*QueryAttestationsResponse, error) { + out := new(QueryAttestationsResponse) + err := c.cc.Invoke(ctx, "/gravity.v1.Query/GetAttestations", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) GetDelegateKeyByValidator(ctx context.Context, in *QueryDelegateKeysByValidatorAddress, opts ...grpc.CallOption) (*QueryDelegateKeysByValidatorAddressResponse, error) { out := new(QueryDelegateKeysByValidatorAddressResponse) err := c.cc.Invoke(ctx, "/gravity.v1.Query/GetDelegateKeyByValidator", in, out, opts...) @@ -2456,6 +2561,7 @@ type QueryServer interface { LogicConfirms(context.Context, *QueryLogicConfirmsRequest) (*QueryLogicConfirmsResponse, error) ERC20ToDenom(context.Context, *QueryERC20ToDenomRequest) (*QueryERC20ToDenomResponse, error) DenomToERC20(context.Context, *QueryDenomToERC20Request) (*QueryDenomToERC20Response, error) + GetAttestations(context.Context, *QueryAttestationsRequest) (*QueryAttestationsResponse, error) GetDelegateKeyByValidator(context.Context, *QueryDelegateKeysByValidatorAddress) (*QueryDelegateKeysByValidatorAddressResponse, error) GetDelegateKeyByEth(context.Context, *QueryDelegateKeysByEthAddress) (*QueryDelegateKeysByEthAddressResponse, error) GetDelegateKeyByOrchestrator(context.Context, *QueryDelegateKeysByOrchestratorAddress) (*QueryDelegateKeysByOrchestratorAddressResponse, error) @@ -2520,6 +2626,9 @@ func (*UnimplementedQueryServer) ERC20ToDenom(ctx context.Context, req *QueryERC func (*UnimplementedQueryServer) DenomToERC20(ctx context.Context, req *QueryDenomToERC20Request) (*QueryDenomToERC20Response, error) { return nil, status.Errorf(codes.Unimplemented, "method DenomToERC20 not implemented") } +func (*UnimplementedQueryServer) GetAttestations(ctx context.Context, req *QueryAttestationsRequest) (*QueryAttestationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAttestations not implemented") +} func (*UnimplementedQueryServer) GetDelegateKeyByValidator(ctx context.Context, req *QueryDelegateKeysByValidatorAddress) (*QueryDelegateKeysByValidatorAddressResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetDelegateKeyByValidator not implemented") } @@ -2861,6 +2970,24 @@ func _Query_DenomToERC20_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _Query_GetAttestations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAttestationsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetAttestations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gravity.v1.Query/GetAttestations", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetAttestations(ctx, req.(*QueryAttestationsRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_GetDelegateKeyByValidator_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryDelegateKeysByValidatorAddress) if err := dec(in); err != nil { @@ -3009,6 +3136,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "DenomToERC20", Handler: _Query_DenomToERC20_Handler, }, + { + MethodName: "GetAttestations", + Handler: _Query_GetAttestations_Handler, + }, { MethodName: "GetDelegateKeyByValidator", Handler: _Query_GetDelegateKeyByValidator_Handler, @@ -4191,6 +4322,71 @@ func (m *QueryDenomToERC20Response) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } +func (m *QueryAttestationsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAttestationsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAttestationsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Limit != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Limit)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryAttestationsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAttestationsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAttestationsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Attestations) > 0 { + for iNdEx := len(m.Attestations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Attestations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *QueryDelegateKeysByValidatorAddress) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4957,6 +5153,33 @@ func (m *QueryDenomToERC20Response) Size() (n int) { return n } +func (m *QueryAttestationsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Limit != 0 { + n += 1 + sovQuery(uint64(m.Limit)) + } + return n +} + +func (m *QueryAttestationsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Attestations) > 0 { + for _, e := range m.Attestations { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + func (m *QueryDelegateKeysByValidatorAddress) Size() (n int) { if m == nil { return 0 @@ -8075,6 +8298,165 @@ func (m *QueryDenomToERC20Response) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryAttestationsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAttestationsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAttestationsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAttestationsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAttestationsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAttestationsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Attestations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Attestations = append(m.Attestations, &Attestation{}) + if err := m.Attestations[len(m.Attestations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryDelegateKeysByValidatorAddress) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/module/x/gravity/types/query.pb.gw.go b/module/x/gravity/types/query.pb.gw.go index d5d4494dd..348d0229a 100644 --- a/module/x/gravity/types/query.pb.gw.go +++ b/module/x/gravity/types/query.pb.gw.go @@ -681,6 +681,42 @@ func local_request_Query_DenomToERC20_0(ctx context.Context, marshaler runtime.M } +var ( + filter_Query_GetAttestations_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_GetAttestations_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAttestationsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GetAttestations_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetAttestations(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetAttestations_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAttestationsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GetAttestations_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetAttestations(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_Query_GetDelegateKeyByValidator_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -1245,6 +1281,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_GetAttestations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetAttestations_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetAttestations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_GetDelegateKeyByValidator_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1738,6 +1797,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_GetAttestations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetAttestations_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetAttestations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_GetDelegateKeyByValidator_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1858,6 +1937,8 @@ var ( pattern_Query_DenomToERC20_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"gravity", "v1beta", "cosmos_originated", "denom_to_erc20"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_GetAttestations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"gravity", "v1beta", "query_attestations"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_GetDelegateKeyByValidator_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"gravity", "v1beta", "query_delegate_keys_by_validator"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_GetDelegateKeyByEth_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"gravity", "v1beta", "query_delegate_keys_by_eth"}, "", runtime.AssumeColonVerbOpt(true))) @@ -1904,6 +1985,8 @@ var ( forward_Query_DenomToERC20_0 = runtime.ForwardResponseMessage + forward_Query_GetAttestations_0 = runtime.ForwardResponseMessage + forward_Query_GetDelegateKeyByValidator_0 = runtime.ForwardResponseMessage forward_Query_GetDelegateKeyByEth_0 = runtime.ForwardResponseMessage diff --git a/orchestrator/Cargo.lock b/orchestrator/Cargo.lock index 911964269..11ab2f45e 100644 --- a/orchestrator/Cargo.lock +++ b/orchestrator/Cargo.lock @@ -2866,6 +2866,7 @@ dependencies = [ "actix", "actix-rt 2.2.0", "actix-web", + "bytes 1.0.1", "clarity", "cosmos_gravity", "deep_space", @@ -2879,6 +2880,8 @@ dependencies = [ "log", "num256", "orchestrator", + "prost", + "prost-types", "rand 0.8.4", "serde", "serde_derive", diff --git a/orchestrator/cosmos_gravity/src/query.rs b/orchestrator/cosmos_gravity/src/query.rs index fa1572636..39111aa55 100644 --- a/orchestrator/cosmos_gravity/src/query.rs +++ b/orchestrator/cosmos_gravity/src/query.rs @@ -1,7 +1,9 @@ use clarity::Address as EthAddress; use deep_space::address::Address; use gravity_proto::gravity::query_client::QueryClient as GravityQueryClient; +use gravity_proto::gravity::Attestation; use gravity_proto::gravity::Params; +use gravity_proto::gravity::QueryAttestationsRequest; use gravity_proto::gravity::QueryBatchConfirmsRequest; use gravity_proto::gravity::QueryCurrentValsetRequest; use gravity_proto::gravity::QueryLastEventNonceByAddrRequest; @@ -224,3 +226,16 @@ pub async fn get_oldest_unsigned_logic_call( None => Ok(None), } } + +pub async fn get_attestations( + client: &mut GravityQueryClient, + limit: Option, +) -> Result, GravityError> { + let request = client + .get_attestations(QueryAttestationsRequest { + limit: limit.or(Some(1000u64)).unwrap(), + }) + .await?; + let attestations = request.into_inner().attestations; + Ok(attestations) +} diff --git a/orchestrator/cosmos_gravity/src/send.rs b/orchestrator/cosmos_gravity/src/send.rs index b138bd0b2..dfdf0fec9 100644 --- a/orchestrator/cosmos_gravity/src/send.rs +++ b/orchestrator/cosmos_gravity/src/send.rs @@ -430,6 +430,7 @@ pub async fn send_request_batch( denom: String, fee: Coin, contact: &Contact, + timeout: Option, ) -> Result { let our_address = private_key.to_address(&contact.get_prefix()).unwrap(); @@ -456,5 +457,8 @@ pub async fn send_request_batch( .send_transaction(msg_bytes, BroadcastMode::Sync) .await?; - contact.wait_for_tx(response, TIMEOUT).await + match timeout { + Some(duration) => contact.wait_for_tx(response, duration).await, + None => Ok(response), + } } diff --git a/orchestrator/gbt/src/client/cosmos_to_eth.rs b/orchestrator/gbt/src/client/cosmos_to_eth.rs index 1705eecbd..7d4c0d1c3 100644 --- a/orchestrator/gbt/src/client/cosmos_to_eth.rs +++ b/orchestrator/gbt/src/client/cosmos_to_eth.rs @@ -98,9 +98,15 @@ pub async fn cosmos_to_eth(args: CosmosToEthOpts, address_prefix: String) { if !no_batch { info!("Requesting a batch to push transaction along immediately"); - send_request_batch(cosmos_key, gravity_coin.denom, bridge_fee, &contact) - .await - .expect("Failed to request batch"); + send_request_batch( + cosmos_key, + gravity_coin.denom, + bridge_fee, + &contact, + Some(TIMEOUT), + ) + .await + .expect("Failed to request batch"); } else { info!("--no-batch specified, your transfer will wait until someone requests a batch for this token type") } diff --git a/orchestrator/gravity_proto/src/prost/gravity.v1.rs b/orchestrator/gravity_proto/src/prost/gravity.v1.rs index 5c8c9faa3..3ad360525 100644 --- a/orchestrator/gravity_proto/src/prost/gravity.v1.rs +++ b/orchestrator/gravity_proto/src/prost/gravity.v1.rs @@ -49,19 +49,6 @@ pub enum ClaimType { LogicCallExecuted = 4, ValsetUpdated = 5, } -/// IDSet represents a set of IDs -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct IdSet { - #[prost(uint64, repeated, tag="1")] - pub ids: ::prost::alloc::vec::Vec, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct BatchFees { - #[prost(string, tag="1")] - pub token: ::prost::alloc::string::String, - #[prost(string, tag="2")] - pub total_fees: ::prost::alloc::string::String, -} /// OutgoingTxBatch represents a batch of transactions going from gravity to ETH #[derive(Clone, PartialEq, ::prost::Message)] pub struct OutgoingTxBatch { @@ -441,11 +428,26 @@ pub struct MsgSubmitBadSignatureEvidence { pub subject: ::core::option::Option<::prost_types::Any>, #[prost(string, tag="2")] pub signature: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub sender: ::prost::alloc::string::String, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct MsgSubmitBadSignatureEvidenceResponse { } -# [doc = r" Generated client implementations."] pub mod msg_client { # ! [allow (unused_variables , dead_code , missing_docs)] use tonic :: codegen :: * ; # [doc = " Msg defines the state transitions possible within gravity"] pub struct MsgClient < T > { inner : tonic :: client :: Grpc < T > , } impl MsgClient < tonic :: transport :: Channel > { # [doc = r" Attempt to create a new client by connecting to a given endpoint."] pub async fn connect < D > (dst : D) -> Result < Self , tonic :: transport :: Error > where D : std :: convert :: TryInto < tonic :: transport :: Endpoint > , D :: Error : Into < StdError > , { let conn = tonic :: transport :: Endpoint :: new (dst) ? . connect () . await ? ; Ok (Self :: new (conn)) } } impl < T > MsgClient < T > where T : tonic :: client :: GrpcService < tonic :: body :: BoxBody > , T :: ResponseBody : Body + HttpBody + Send + 'static , T :: Error : Into < StdError > , < T :: ResponseBody as HttpBody > :: Error : Into < StdError > + Send , { pub fn new (inner : T) -> Self { let inner = tonic :: client :: Grpc :: new (inner) ; Self { inner } } pub fn with_interceptor (inner : T , interceptor : impl Into < tonic :: Interceptor >) -> Self { let inner = tonic :: client :: Grpc :: with_interceptor (inner , interceptor) ; Self { inner } } pub async fn valset_confirm (& mut self , request : impl tonic :: IntoRequest < super :: MsgValsetConfirm > ,) -> Result < tonic :: Response < super :: MsgValsetConfirmResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/ValsetConfirm") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn send_to_eth (& mut self , request : impl tonic :: IntoRequest < super :: MsgSendToEth > ,) -> Result < tonic :: Response < super :: MsgSendToEthResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/SendToEth") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn request_batch (& mut self , request : impl tonic :: IntoRequest < super :: MsgRequestBatch > ,) -> Result < tonic :: Response < super :: MsgRequestBatchResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/RequestBatch") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn confirm_batch (& mut self , request : impl tonic :: IntoRequest < super :: MsgConfirmBatch > ,) -> Result < tonic :: Response < super :: MsgConfirmBatchResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/ConfirmBatch") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn confirm_logic_call (& mut self , request : impl tonic :: IntoRequest < super :: MsgConfirmLogicCall > ,) -> Result < tonic :: Response < super :: MsgConfirmLogicCallResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/ConfirmLogicCall") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn send_to_cosmos_claim (& mut self , request : impl tonic :: IntoRequest < super :: MsgSendToCosmosClaim > ,) -> Result < tonic :: Response < super :: MsgSendToCosmosClaimResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/SendToCosmosClaim") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn batch_send_to_eth_claim (& mut self , request : impl tonic :: IntoRequest < super :: MsgBatchSendToEthClaim > ,) -> Result < tonic :: Response < super :: MsgBatchSendToEthClaimResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/BatchSendToEthClaim") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn valset_update_claim (& mut self , request : impl tonic :: IntoRequest < super :: MsgValsetUpdatedClaim > ,) -> Result < tonic :: Response < super :: MsgValsetUpdatedClaimResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/ValsetUpdateClaim") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn erc20_deployed_claim (& mut self , request : impl tonic :: IntoRequest < super :: MsgErc20DeployedClaim > ,) -> Result < tonic :: Response < super :: MsgErc20DeployedClaimResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/ERC20DeployedClaim") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn logic_call_executed_claim (& mut self , request : impl tonic :: IntoRequest < super :: MsgLogicCallExecutedClaim > ,) -> Result < tonic :: Response < super :: MsgLogicCallExecutedClaimResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/LogicCallExecutedClaim") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn set_orchestrator_address (& mut self , request : impl tonic :: IntoRequest < super :: MsgSetOrchestratorAddress > ,) -> Result < tonic :: Response < super :: MsgSetOrchestratorAddressResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/SetOrchestratorAddress") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn cancel_send_to_eth (& mut self , request : impl tonic :: IntoRequest < super :: MsgCancelSendToEth > ,) -> Result < tonic :: Response < super :: MsgCancelSendToEthResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/CancelSendToEth") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn submit_bad_signature_evidence (& mut self , request : impl tonic :: IntoRequest < super :: MsgSubmitBadSignatureEvidence > ,) -> Result < tonic :: Response < super :: MsgSubmitBadSignatureEvidenceResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/SubmitBadSignatureEvidence") ; self . inner . unary (request . into_request () , path , codec) . await } } impl < T : Clone > Clone for MsgClient < T > { fn clone (& self) -> Self { Self { inner : self . inner . clone () , } } } impl < T > std :: fmt :: Debug for MsgClient < T > { fn fmt (& self , f : & mut std :: fmt :: Formatter < '_ >) -> std :: fmt :: Result { write ! (f , "MsgClient {{ ... }}") } } }// Params represent the Gravity genesis and store parameters +# [doc = r" Generated client implementations."] pub mod msg_client { # ! [allow (unused_variables , dead_code , missing_docs)] use tonic :: codegen :: * ; # [doc = " Msg defines the state transitions possible within gravity"] pub struct MsgClient < T > { inner : tonic :: client :: Grpc < T > , } impl MsgClient < tonic :: transport :: Channel > { # [doc = r" Attempt to create a new client by connecting to a given endpoint."] pub async fn connect < D > (dst : D) -> Result < Self , tonic :: transport :: Error > where D : std :: convert :: TryInto < tonic :: transport :: Endpoint > , D :: Error : Into < StdError > , { let conn = tonic :: transport :: Endpoint :: new (dst) ? . connect () . await ? ; Ok (Self :: new (conn)) } } impl < T > MsgClient < T > where T : tonic :: client :: GrpcService < tonic :: body :: BoxBody > , T :: ResponseBody : Body + HttpBody + Send + 'static , T :: Error : Into < StdError > , < T :: ResponseBody as HttpBody > :: Error : Into < StdError > + Send , { pub fn new (inner : T) -> Self { let inner = tonic :: client :: Grpc :: new (inner) ; Self { inner } } pub fn with_interceptor (inner : T , interceptor : impl Into < tonic :: Interceptor >) -> Self { let inner = tonic :: client :: Grpc :: with_interceptor (inner , interceptor) ; Self { inner } } pub async fn valset_confirm (& mut self , request : impl tonic :: IntoRequest < super :: MsgValsetConfirm > ,) -> Result < tonic :: Response < super :: MsgValsetConfirmResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/ValsetConfirm") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn send_to_eth (& mut self , request : impl tonic :: IntoRequest < super :: MsgSendToEth > ,) -> Result < tonic :: Response < super :: MsgSendToEthResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/SendToEth") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn request_batch (& mut self , request : impl tonic :: IntoRequest < super :: MsgRequestBatch > ,) -> Result < tonic :: Response < super :: MsgRequestBatchResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/RequestBatch") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn confirm_batch (& mut self , request : impl tonic :: IntoRequest < super :: MsgConfirmBatch > ,) -> Result < tonic :: Response < super :: MsgConfirmBatchResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/ConfirmBatch") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn confirm_logic_call (& mut self , request : impl tonic :: IntoRequest < super :: MsgConfirmLogicCall > ,) -> Result < tonic :: Response < super :: MsgConfirmLogicCallResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/ConfirmLogicCall") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn send_to_cosmos_claim (& mut self , request : impl tonic :: IntoRequest < super :: MsgSendToCosmosClaim > ,) -> Result < tonic :: Response < super :: MsgSendToCosmosClaimResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/SendToCosmosClaim") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn batch_send_to_eth_claim (& mut self , request : impl tonic :: IntoRequest < super :: MsgBatchSendToEthClaim > ,) -> Result < tonic :: Response < super :: MsgBatchSendToEthClaimResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/BatchSendToEthClaim") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn valset_update_claim (& mut self , request : impl tonic :: IntoRequest < super :: MsgValsetUpdatedClaim > ,) -> Result < tonic :: Response < super :: MsgValsetUpdatedClaimResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/ValsetUpdateClaim") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn erc20_deployed_claim (& mut self , request : impl tonic :: IntoRequest < super :: MsgErc20DeployedClaim > ,) -> Result < tonic :: Response < super :: MsgErc20DeployedClaimResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/ERC20DeployedClaim") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn logic_call_executed_claim (& mut self , request : impl tonic :: IntoRequest < super :: MsgLogicCallExecutedClaim > ,) -> Result < tonic :: Response < super :: MsgLogicCallExecutedClaimResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/LogicCallExecutedClaim") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn set_orchestrator_address (& mut self , request : impl tonic :: IntoRequest < super :: MsgSetOrchestratorAddress > ,) -> Result < tonic :: Response < super :: MsgSetOrchestratorAddressResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/SetOrchestratorAddress") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn cancel_send_to_eth (& mut self , request : impl tonic :: IntoRequest < super :: MsgCancelSendToEth > ,) -> Result < tonic :: Response < super :: MsgCancelSendToEthResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/CancelSendToEth") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn submit_bad_signature_evidence (& mut self , request : impl tonic :: IntoRequest < super :: MsgSubmitBadSignatureEvidence > ,) -> Result < tonic :: Response < super :: MsgSubmitBadSignatureEvidenceResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Msg/SubmitBadSignatureEvidence") ; self . inner . unary (request . into_request () , path , codec) . await } } impl < T : Clone > Clone for MsgClient < T > { fn clone (& self) -> Self { Self { inner : self . inner . clone () , } } } impl < T > std :: fmt :: Debug for MsgClient < T > { fn fmt (& self , f : & mut std :: fmt :: Formatter < '_ >) -> std :: fmt :: Result { write ! (f , "MsgClient {{ ... }}") } } }/// IDSet represents a set of IDs +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IdSet { + #[prost(uint64, repeated, tag="1")] + pub ids: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BatchFees { + #[prost(string, tag="1")] + pub token: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub total_fees: ::prost::alloc::string::String, +} +// Params represent the Gravity genesis and store parameters // gravity_id: // a random 32 byte value to prevent signature reuse, for example if the // cosmos validators decided to use the same Ethereum keys for another chain @@ -767,6 +769,16 @@ pub struct QueryDenomToErc20Response { pub cosmos_originated: bool, } #[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryAttestationsRequest { + #[prost(uint64, tag="1")] + pub limit: u64, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryAttestationsResponse { + #[prost(message, repeated, tag="1")] + pub attestations: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryDelegateKeysByValidatorAddress { #[prost(string, tag="1")] pub validator_address: ::prost::alloc::string::String, @@ -814,4 +826,4 @@ pub struct QueryPendingSendToEthResponse { #[prost(message, repeated, tag="2")] pub unbatched_transfers: ::prost::alloc::vec::Vec, } -# [doc = r" Generated client implementations."] pub mod query_client { # ! [allow (unused_variables , dead_code , missing_docs)] use tonic :: codegen :: * ; # [doc = " Query defines the gRPC querier service"] pub struct QueryClient < T > { inner : tonic :: client :: Grpc < T > , } impl QueryClient < tonic :: transport :: Channel > { # [doc = r" Attempt to create a new client by connecting to a given endpoint."] pub async fn connect < D > (dst : D) -> Result < Self , tonic :: transport :: Error > where D : std :: convert :: TryInto < tonic :: transport :: Endpoint > , D :: Error : Into < StdError > , { let conn = tonic :: transport :: Endpoint :: new (dst) ? . connect () . await ? ; Ok (Self :: new (conn)) } } impl < T > QueryClient < T > where T : tonic :: client :: GrpcService < tonic :: body :: BoxBody > , T :: ResponseBody : Body + HttpBody + Send + 'static , T :: Error : Into < StdError > , < T :: ResponseBody as HttpBody > :: Error : Into < StdError > + Send , { pub fn new (inner : T) -> Self { let inner = tonic :: client :: Grpc :: new (inner) ; Self { inner } } pub fn with_interceptor (inner : T , interceptor : impl Into < tonic :: Interceptor >) -> Self { let inner = tonic :: client :: Grpc :: with_interceptor (inner , interceptor) ; Self { inner } } # [doc = " Deployments queries deployments"] pub async fn params (& mut self , request : impl tonic :: IntoRequest < super :: QueryParamsRequest > ,) -> Result < tonic :: Response < super :: QueryParamsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/Params") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn current_valset (& mut self , request : impl tonic :: IntoRequest < super :: QueryCurrentValsetRequest > ,) -> Result < tonic :: Response < super :: QueryCurrentValsetResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/CurrentValset") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn valset_request (& mut self , request : impl tonic :: IntoRequest < super :: QueryValsetRequestRequest > ,) -> Result < tonic :: Response < super :: QueryValsetRequestResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/ValsetRequest") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn valset_confirm (& mut self , request : impl tonic :: IntoRequest < super :: QueryValsetConfirmRequest > ,) -> Result < tonic :: Response < super :: QueryValsetConfirmResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/ValsetConfirm") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn valset_confirms_by_nonce (& mut self , request : impl tonic :: IntoRequest < super :: QueryValsetConfirmsByNonceRequest > ,) -> Result < tonic :: Response < super :: QueryValsetConfirmsByNonceResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/ValsetConfirmsByNonce") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn last_valset_requests (& mut self , request : impl tonic :: IntoRequest < super :: QueryLastValsetRequestsRequest > ,) -> Result < tonic :: Response < super :: QueryLastValsetRequestsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LastValsetRequests") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn last_pending_valset_request_by_addr (& mut self , request : impl tonic :: IntoRequest < super :: QueryLastPendingValsetRequestByAddrRequest > ,) -> Result < tonic :: Response < super :: QueryLastPendingValsetRequestByAddrResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LastPendingValsetRequestByAddr") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn last_pending_batch_request_by_addr (& mut self , request : impl tonic :: IntoRequest < super :: QueryLastPendingBatchRequestByAddrRequest > ,) -> Result < tonic :: Response < super :: QueryLastPendingBatchRequestByAddrResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LastPendingBatchRequestByAddr") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn last_pending_logic_call_by_addr (& mut self , request : impl tonic :: IntoRequest < super :: QueryLastPendingLogicCallByAddrRequest > ,) -> Result < tonic :: Response < super :: QueryLastPendingLogicCallByAddrResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LastPendingLogicCallByAddr") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn last_event_nonce_by_addr (& mut self , request : impl tonic :: IntoRequest < super :: QueryLastEventNonceByAddrRequest > ,) -> Result < tonic :: Response < super :: QueryLastEventNonceByAddrResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LastEventNonceByAddr") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn batch_fees (& mut self , request : impl tonic :: IntoRequest < super :: QueryBatchFeeRequest > ,) -> Result < tonic :: Response < super :: QueryBatchFeeResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/BatchFees") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn outgoing_tx_batches (& mut self , request : impl tonic :: IntoRequest < super :: QueryOutgoingTxBatchesRequest > ,) -> Result < tonic :: Response < super :: QueryOutgoingTxBatchesResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/OutgoingTxBatches") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn outgoing_logic_calls (& mut self , request : impl tonic :: IntoRequest < super :: QueryOutgoingLogicCallsRequest > ,) -> Result < tonic :: Response < super :: QueryOutgoingLogicCallsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/OutgoingLogicCalls") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn batch_request_by_nonce (& mut self , request : impl tonic :: IntoRequest < super :: QueryBatchRequestByNonceRequest > ,) -> Result < tonic :: Response < super :: QueryBatchRequestByNonceResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/BatchRequestByNonce") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn batch_confirms (& mut self , request : impl tonic :: IntoRequest < super :: QueryBatchConfirmsRequest > ,) -> Result < tonic :: Response < super :: QueryBatchConfirmsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/BatchConfirms") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn logic_confirms (& mut self , request : impl tonic :: IntoRequest < super :: QueryLogicConfirmsRequest > ,) -> Result < tonic :: Response < super :: QueryLogicConfirmsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LogicConfirms") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn erc20_to_denom (& mut self , request : impl tonic :: IntoRequest < super :: QueryErc20ToDenomRequest > ,) -> Result < tonic :: Response < super :: QueryErc20ToDenomResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/ERC20ToDenom") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn denom_to_erc20 (& mut self , request : impl tonic :: IntoRequest < super :: QueryDenomToErc20Request > ,) -> Result < tonic :: Response < super :: QueryDenomToErc20Response > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/DenomToERC20") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn get_delegate_key_by_validator (& mut self , request : impl tonic :: IntoRequest < super :: QueryDelegateKeysByValidatorAddress > ,) -> Result < tonic :: Response < super :: QueryDelegateKeysByValidatorAddressResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/GetDelegateKeyByValidator") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn get_delegate_key_by_eth (& mut self , request : impl tonic :: IntoRequest < super :: QueryDelegateKeysByEthAddress > ,) -> Result < tonic :: Response < super :: QueryDelegateKeysByEthAddressResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/GetDelegateKeyByEth") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn get_delegate_key_by_orchestrator (& mut self , request : impl tonic :: IntoRequest < super :: QueryDelegateKeysByOrchestratorAddress > ,) -> Result < tonic :: Response < super :: QueryDelegateKeysByOrchestratorAddressResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/GetDelegateKeyByOrchestrator") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn get_pending_send_to_eth (& mut self , request : impl tonic :: IntoRequest < super :: QueryPendingSendToEth > ,) -> Result < tonic :: Response < super :: QueryPendingSendToEthResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/GetPendingSendToEth") ; self . inner . unary (request . into_request () , path , codec) . await } } impl < T : Clone > Clone for QueryClient < T > { fn clone (& self) -> Self { Self { inner : self . inner . clone () , } } } impl < T > std :: fmt :: Debug for QueryClient < T > { fn fmt (& self , f : & mut std :: fmt :: Formatter < '_ >) -> std :: fmt :: Result { write ! (f , "QueryClient {{ ... }}") } } } \ No newline at end of file +# [doc = r" Generated client implementations."] pub mod query_client { # ! [allow (unused_variables , dead_code , missing_docs)] use tonic :: codegen :: * ; # [doc = " Query defines the gRPC querier service"] pub struct QueryClient < T > { inner : tonic :: client :: Grpc < T > , } impl QueryClient < tonic :: transport :: Channel > { # [doc = r" Attempt to create a new client by connecting to a given endpoint."] pub async fn connect < D > (dst : D) -> Result < Self , tonic :: transport :: Error > where D : std :: convert :: TryInto < tonic :: transport :: Endpoint > , D :: Error : Into < StdError > , { let conn = tonic :: transport :: Endpoint :: new (dst) ? . connect () . await ? ; Ok (Self :: new (conn)) } } impl < T > QueryClient < T > where T : tonic :: client :: GrpcService < tonic :: body :: BoxBody > , T :: ResponseBody : Body + HttpBody + Send + 'static , T :: Error : Into < StdError > , < T :: ResponseBody as HttpBody > :: Error : Into < StdError > + Send , { pub fn new (inner : T) -> Self { let inner = tonic :: client :: Grpc :: new (inner) ; Self { inner } } pub fn with_interceptor (inner : T , interceptor : impl Into < tonic :: Interceptor >) -> Self { let inner = tonic :: client :: Grpc :: with_interceptor (inner , interceptor) ; Self { inner } } # [doc = " Deployments queries deployments"] pub async fn params (& mut self , request : impl tonic :: IntoRequest < super :: QueryParamsRequest > ,) -> Result < tonic :: Response < super :: QueryParamsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/Params") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn current_valset (& mut self , request : impl tonic :: IntoRequest < super :: QueryCurrentValsetRequest > ,) -> Result < tonic :: Response < super :: QueryCurrentValsetResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/CurrentValset") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn valset_request (& mut self , request : impl tonic :: IntoRequest < super :: QueryValsetRequestRequest > ,) -> Result < tonic :: Response < super :: QueryValsetRequestResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/ValsetRequest") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn valset_confirm (& mut self , request : impl tonic :: IntoRequest < super :: QueryValsetConfirmRequest > ,) -> Result < tonic :: Response < super :: QueryValsetConfirmResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/ValsetConfirm") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn valset_confirms_by_nonce (& mut self , request : impl tonic :: IntoRequest < super :: QueryValsetConfirmsByNonceRequest > ,) -> Result < tonic :: Response < super :: QueryValsetConfirmsByNonceResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/ValsetConfirmsByNonce") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn last_valset_requests (& mut self , request : impl tonic :: IntoRequest < super :: QueryLastValsetRequestsRequest > ,) -> Result < tonic :: Response < super :: QueryLastValsetRequestsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LastValsetRequests") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn last_pending_valset_request_by_addr (& mut self , request : impl tonic :: IntoRequest < super :: QueryLastPendingValsetRequestByAddrRequest > ,) -> Result < tonic :: Response < super :: QueryLastPendingValsetRequestByAddrResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LastPendingValsetRequestByAddr") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn last_pending_batch_request_by_addr (& mut self , request : impl tonic :: IntoRequest < super :: QueryLastPendingBatchRequestByAddrRequest > ,) -> Result < tonic :: Response < super :: QueryLastPendingBatchRequestByAddrResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LastPendingBatchRequestByAddr") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn last_pending_logic_call_by_addr (& mut self , request : impl tonic :: IntoRequest < super :: QueryLastPendingLogicCallByAddrRequest > ,) -> Result < tonic :: Response < super :: QueryLastPendingLogicCallByAddrResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LastPendingLogicCallByAddr") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn last_event_nonce_by_addr (& mut self , request : impl tonic :: IntoRequest < super :: QueryLastEventNonceByAddrRequest > ,) -> Result < tonic :: Response < super :: QueryLastEventNonceByAddrResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LastEventNonceByAddr") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn batch_fees (& mut self , request : impl tonic :: IntoRequest < super :: QueryBatchFeeRequest > ,) -> Result < tonic :: Response < super :: QueryBatchFeeResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/BatchFees") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn outgoing_tx_batches (& mut self , request : impl tonic :: IntoRequest < super :: QueryOutgoingTxBatchesRequest > ,) -> Result < tonic :: Response < super :: QueryOutgoingTxBatchesResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/OutgoingTxBatches") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn outgoing_logic_calls (& mut self , request : impl tonic :: IntoRequest < super :: QueryOutgoingLogicCallsRequest > ,) -> Result < tonic :: Response < super :: QueryOutgoingLogicCallsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/OutgoingLogicCalls") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn batch_request_by_nonce (& mut self , request : impl tonic :: IntoRequest < super :: QueryBatchRequestByNonceRequest > ,) -> Result < tonic :: Response < super :: QueryBatchRequestByNonceResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/BatchRequestByNonce") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn batch_confirms (& mut self , request : impl tonic :: IntoRequest < super :: QueryBatchConfirmsRequest > ,) -> Result < tonic :: Response < super :: QueryBatchConfirmsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/BatchConfirms") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn logic_confirms (& mut self , request : impl tonic :: IntoRequest < super :: QueryLogicConfirmsRequest > ,) -> Result < tonic :: Response < super :: QueryLogicConfirmsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/LogicConfirms") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn erc20_to_denom (& mut self , request : impl tonic :: IntoRequest < super :: QueryErc20ToDenomRequest > ,) -> Result < tonic :: Response < super :: QueryErc20ToDenomResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/ERC20ToDenom") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn denom_to_erc20 (& mut self , request : impl tonic :: IntoRequest < super :: QueryDenomToErc20Request > ,) -> Result < tonic :: Response < super :: QueryDenomToErc20Response > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/DenomToERC20") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn get_attestations (& mut self , request : impl tonic :: IntoRequest < super :: QueryAttestationsRequest > ,) -> Result < tonic :: Response < super :: QueryAttestationsResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/GetAttestations") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn get_delegate_key_by_validator (& mut self , request : impl tonic :: IntoRequest < super :: QueryDelegateKeysByValidatorAddress > ,) -> Result < tonic :: Response < super :: QueryDelegateKeysByValidatorAddressResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/GetDelegateKeyByValidator") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn get_delegate_key_by_eth (& mut self , request : impl tonic :: IntoRequest < super :: QueryDelegateKeysByEthAddress > ,) -> Result < tonic :: Response < super :: QueryDelegateKeysByEthAddressResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/GetDelegateKeyByEth") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn get_delegate_key_by_orchestrator (& mut self , request : impl tonic :: IntoRequest < super :: QueryDelegateKeysByOrchestratorAddress > ,) -> Result < tonic :: Response < super :: QueryDelegateKeysByOrchestratorAddressResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/GetDelegateKeyByOrchestrator") ; self . inner . unary (request . into_request () , path , codec) . await } pub async fn get_pending_send_to_eth (& mut self , request : impl tonic :: IntoRequest < super :: QueryPendingSendToEth > ,) -> Result < tonic :: Response < super :: QueryPendingSendToEthResponse > , tonic :: Status > { self . inner . ready () . await . map_err (| e | { tonic :: Status :: new (tonic :: Code :: Unknown , format ! ("Service was not ready: {}" , e . into ())) }) ? ; let codec = tonic :: codec :: ProstCodec :: default () ; let path = http :: uri :: PathAndQuery :: from_static ("/gravity.v1.Query/GetPendingSendToEth") ; self . inner . unary (request . into_request () , path , codec) . await } } impl < T : Clone > Clone for QueryClient < T > { fn clone (& self) -> Self { Self { inner : self . inner . clone () , } } } impl < T > std :: fmt :: Debug for QueryClient < T > { fn fmt (& self , f : & mut std :: fmt :: Formatter < '_ >) -> std :: fmt :: Result { write ! (f , "QueryClient {{ ... }}") } } } \ No newline at end of file diff --git a/orchestrator/test_runner/Cargo.toml b/orchestrator/test_runner/Cargo.toml index 07a2c10ca..983ebb3b0 100644 --- a/orchestrator/test_runner/Cargo.toml +++ b/orchestrator/test_runner/Cargo.toml @@ -16,6 +16,9 @@ gravity_utils = {path = "../gravity_utils"} gravity_proto = {path = "../gravity_proto/"} orchestrator = {path = "../orchestrator/"} +bytes = "1" +prost = "0.7" +prost-types = "0.7" deep_space = "2.4" serde_derive = "1.0" clarity = "0.4" diff --git a/orchestrator/test_runner/src/happy_path.rs b/orchestrator/test_runner/src/happy_path.rs index 1ff470029..b6d73ab84 100644 --- a/orchestrator/test_runner/src/happy_path.rs +++ b/orchestrator/test_runner/src/happy_path.rs @@ -3,22 +3,31 @@ use crate::utils::*; use crate::ADDRESS_PREFIX; use crate::MINER_ADDRESS; use crate::MINER_PRIVATE_KEY; +use crate::OPERATION_TIMEOUT; use crate::STAKING_TOKEN; use crate::STARTING_STAKE_PER_VALIDATOR; use crate::TOTAL_TIMEOUT; +use bytes::BytesMut; use clarity::PrivateKey as EthPrivateKey; use clarity::{Address as EthAddress, Uint256}; +use cosmos_gravity::query::get_attestations; use cosmos_gravity::send::{send_request_batch, send_to_eth}; use cosmos_gravity::{query::get_oldest_unsigned_transaction_batch, send::send_ethereum_claims}; use deep_space::address::Address as CosmosAddress; use deep_space::coin::Coin; use deep_space::private_key::PrivateKey as CosmosPrivateKey; use deep_space::Contact; +use ethereum_gravity::utils::get_event_nonce; use ethereum_gravity::utils::get_valset_nonce; use ethereum_gravity::{send_to_cosmos::send_to_cosmos, utils::get_tx_batch_nonce}; use gravity_proto::gravity::query_client::QueryClient as GravityQueryClient; +use gravity_proto::gravity::MsgSendToCosmosClaim; +use gravity_proto::gravity::MsgValsetUpdatedClaim; use gravity_utils::types::SendToCosmosEvent; +use prost::Message; use rand::Rng; +use std::any::type_name; +use std::thread::sleep; use std::time::Duration; use std::time::Instant; use tokio::time::sleep as delay_for; @@ -57,7 +66,7 @@ pub async fn happy_path_test( // with the first block) is successfully updated if !validator_out { for _ in 0u32..2 { - test_valset_update(web30, contact, &keys, gravity_address).await; + test_valset_update(web30, contact, &mut grpc_client, &keys, gravity_address).await; } } else { wait_for_nonzero_valset(web30, gravity_address).await; @@ -80,6 +89,7 @@ pub async fn happy_path_test( test_erc20_deposit( web30, contact, + &mut grpc_client, dest_cosmos_address, gravity_address, erc20_address, @@ -88,12 +98,16 @@ pub async fn happy_path_test( .await; } + let event_nonce = get_event_nonce(gravity_address, *MINER_ADDRESS, web30) + .await + .unwrap(); + // We are going to submit a duplicate tx with nonce 1 // This had better not increase the balance again // this test may have false positives if the timeout is not // long enough. TODO check for an error on the cosmos send response submit_duplicate_erc20_send( - 1u64, + event_nonce, // Duplicate the current nonce contact, erc20_address, 1u64.into(), @@ -116,6 +130,51 @@ pub async fn happy_path_test( .await; } +// Iterates each attestation known by the grpc endpoint by calling `get_attestations()` +// Executes the input closure `f` against each attestation's decoded claim +// This is useful for testing that certain attestations exist in the oracle, +// see the consumers of this function (check_valset_update_attestation(), +// check_send_to_cosmos_attestation(), etc.) for examples of usage +// +// `F` is the type of the closure, a state mutating function which may be called multiple times +// `F` functions take a single parameter of type `T`, which is some sort of `Message` +// The type `T` is very important as it dictates how we decode the message +pub async fn iterate_attestations( + grpc_client: &mut GravityQueryClient, + f: &mut F, +) { + let attestations = get_attestations(grpc_client, None) + .await + .expect("Something happened while getting attestations after delegating to validator"); + for (i, att) in attestations.into_iter().enumerate() { + let claim = att.clone().claim; + trace!("Processing attestation {}", i); + if claim.is_none() { + trace!("Attestation returned with no claim: {:?}", att); + continue; + } + let claim = claim.unwrap(); + let mut buf = BytesMut::with_capacity(claim.value.len()); + buf.extend_from_slice(&claim.value); + + // Here we use the `T` type to decode whatever type of message this attestation holds + // for use in the `f` function + let decoded = T::decode(buf); + + // Decoding errors indicate there is some other attestation we don't care about + if decoded.is_err() { + debug!( + "Found an attestation which is not a {}: {:?}", + type_name::(), + att, + ); + continue; + } + let decoded = decoded.unwrap(); + f(decoded); + } +} + pub async fn wait_for_nonzero_valset(web30: &Web3, gravity_address: EthAddress) { let start = Instant::now(); let mut current_eth_valset_nonce = get_valset_nonce(gravity_address, *MINER_ADDRESS, web30) @@ -137,6 +196,7 @@ pub async fn wait_for_nonzero_valset(web30: &Web3, gravity_address: EthAddress) pub async fn test_valset_update( web30: &Web3, contact: &Contact, + grpc_client: &mut GravityQueryClient, keys: &[ValidatorKeys], gravity_address: EthAddress, ) { @@ -148,6 +208,7 @@ pub async fn test_valset_update( .await .expect("Incorrect Gravity Address or otherwise unable to contact Gravity"); + let mut grpc_client = grpc_client.clone(); // if we don't do this the orchestrators may run ahead of us and we'll be stuck here after // getting credit for two loops when we did one let starting_eth_valset_nonce = get_valset_nonce(gravity_address, *MINER_ADDRESS, web30) @@ -192,6 +253,8 @@ pub async fn test_valset_update( .await .unwrap(); + check_valset_update_attestation(&mut grpc_client, keys).await; + let mut current_eth_valset_nonce = get_valset_nonce(gravity_address, *MINER_ADDRESS, web30) .await .expect("Failed to get current eth valset"); @@ -213,10 +276,41 @@ pub async fn test_valset_update( info!("Validator set successfully updated!"); } +// Checks for a MsgValsetUpdatedClaim attestation where every validator is represented +async fn check_valset_update_attestation( + grpc_client: &mut GravityQueryClient, + keys: &[ValidatorKeys], +) { + let mut found = true; + iterate_attestations(grpc_client, &mut |decoded: MsgValsetUpdatedClaim| { + // Check that each bridge validator is one of the addresses in our keys + for bridge_val in decoded.members { + let found_val = keys.iter().any(|key: &ValidatorKeys| { + let eth_pub_key = key.eth_key.to_public_key().unwrap().to_string(); + bridge_val.ethereum_address == eth_pub_key + }); + if !found_val { + warn!( + "Could not find BridgeValidator eth pub key {} in keys", + bridge_val.ethereum_address + ); + } + found &= found_val; + } + }) + .await; + assert!( + found, + "Could not find the valset updated attestation we were looking for!" + ); + info!("Found the expected MsgValsetUpdatedClaim attestation"); +} + /// this function tests Ethereum -> Cosmos pub async fn test_erc20_deposit( web30: &Web3, contact: &Contact, + grpc_client: &mut GravityQueryClient, dest: CosmosAddress, gravity_address: EthAddress, erc20_address: EthAddress, @@ -226,6 +320,7 @@ pub async fn test_erc20_deposit( .await .expect("Incorrect Gravity Address or otherwise unable to contact Gravity"); + let mut grpc_client = grpc_client.clone(); let start_coin = check_cosmos_balance("gravity", dest, contact).await; info!( "Sending to Cosmos from {} to {} with amount {}", @@ -238,7 +333,7 @@ pub async fn test_erc20_deposit( amount.clone(), dest, *MINER_PRIVATE_KEY, - Some(TOTAL_TIMEOUT), + None, web30, vec![], ) @@ -246,6 +341,13 @@ pub async fn test_erc20_deposit( .expect("Failed to send tokens to Cosmos"); info!("Send to Cosmos txid: {:#066x}", tx_id); + check_send_to_cosmos_attestation(&mut grpc_client, erc20_address, dest, *MINER_ADDRESS).await; + + let _tx_res = web30 + .wait_for_transaction(tx_id, OPERATION_TIMEOUT, None) + .await + .expect("Send to cosmos transaction failed to be included into ethereum side"); + let start = Instant::now(); while Instant::now() - start < TOTAL_TIMEOUT { match ( @@ -282,6 +384,34 @@ pub async fn test_erc20_deposit( panic!("Failed to bridge ERC20!") } +// Tries up to TOTAL_TIMEOUT time to find a MsgSendToCosmosClaim attestation created in the +// test_erc20_deposit test +async fn check_send_to_cosmos_attestation( + grpc_client: &mut GravityQueryClient, + erc20_address: EthAddress, + receiver: CosmosAddress, + sender: EthAddress, +) { + let start = Instant::now(); + let mut found = false; + loop { + iterate_attestations(grpc_client, &mut |decoded: MsgSendToCosmosClaim| { + let right_contract = decoded.token_contract == erc20_address.to_string(); + let right_destination = decoded.cosmos_receiver == receiver.to_string(); + let right_sender = decoded.ethereum_sender == sender.to_string(); + found = right_contract && right_destination && right_sender; + }) + .await; + if found { + break; + } else if Instant::now() - start > TOTAL_TIMEOUT { + panic!("Could not find the send_to_cosmos attestation we were looking for!"); + } + sleep(Duration::from_secs(5)) + } + info!("Found the expected MsgSendToCosmosClaim attestation"); +} + #[allow(clippy::too_many_arguments)] async fn test_batch( contact: &Contact, @@ -297,6 +427,7 @@ async fn test_batch( .await .expect("Incorrect Gravity Address or otherwise unable to contact Gravity"); + let mut grpc_client = grpc_client.clone(); let dest_cosmos_address = dest_cosmos_private_key .to_address(&contact.get_prefix()) .unwrap(); @@ -315,6 +446,7 @@ async fn test_batch( "Sending {}{} from {} on Cosmos back to Ethereum", amount, token_name, dest_cosmos_address ); + let res = send_to_eth( dest_cosmos_private_key, dest_eth_address, @@ -336,6 +468,7 @@ async fn test_batch( token_name.clone(), get_fee(), contact, + None, ) .await .unwrap(); @@ -344,9 +477,13 @@ async fn test_batch( let requester_address = requester_cosmos_private_key .to_address(&contact.get_prefix()) .unwrap(); - get_oldest_unsigned_transaction_batch(grpc_client, requester_address, contact.get_prefix()) - .await - .expect("Failed to get batch to sign"); + get_oldest_unsigned_transaction_batch( + &mut grpc_client, + requester_address, + contact.get_prefix(), + ) + .await + .expect("Failed to get batch to sign"); let mut current_eth_batch_nonce = get_tx_batch_nonce(gravity_address, erc20_contract, *MINER_ADDRESS, web30) @@ -431,7 +568,7 @@ async fn submit_duplicate_erc20_send( // iterate through all validators and try to send an event with duplicate nonce for k in keys.iter() { - let c_key = k.validator_key; + let c_key = k.orch_key; let res = send_ethereum_claims( contact, c_key, @@ -444,9 +581,11 @@ async fn submit_duplicate_erc20_send( ) .await .unwrap(); - trace!("Submitted duplicate sendToCosmos event: {:?}", res); + info!("Submitted duplicate sendToCosmos event: {:?}", res); } + contact.wait_for_next_block(TOTAL_TIMEOUT).await.unwrap(); + if let Some(end_coin) = check_cosmos_balance("gravity", receiver, contact).await { if start_coin.amount == end_coin.amount && start_coin.denom == end_coin.denom { info!("Successfully failed to duplicate ERC20!"); diff --git a/orchestrator/test_runner/src/happy_path_v2.rs b/orchestrator/test_runner/src/happy_path_v2.rs index ea98a865e..6065733e7 100644 --- a/orchestrator/test_runner/src/happy_path_v2.rs +++ b/orchestrator/test_runner/src/happy_path_v2.rs @@ -8,6 +8,7 @@ use crate::TOTAL_TIMEOUT; use crate::{get_fee, utils::ValidatorKeys}; use clarity::Address as EthAddress; use clarity::Uint256; +use cosmos_gravity::send::TIMEOUT; use cosmos_gravity::send::{send_request_batch, send_to_eth}; use deep_space::coin::Coin; use deep_space::Contact; @@ -112,6 +113,7 @@ pub async fn happy_path_test_v2( token_to_send_to_eth.clone(), get_fee(), contact, + Some(TIMEOUT), ) .await .unwrap(); diff --git a/orchestrator/test_runner/src/main.rs b/orchestrator/test_runner/src/main.rs index fc63b3ee1..8ce8e7633 100644 --- a/orchestrator/test_runner/src/main.rs +++ b/orchestrator/test_runner/src/main.rs @@ -191,7 +191,7 @@ pub async fn main() { return; } else if test_type == "VALSET_STRESS" { info!("Starting Valset update stress test"); - validator_set_stress_test(&web30, &contact, keys, gravity_address).await; + validator_set_stress_test(&web30, grpc_client, &contact, keys, gravity_address).await; return; } else if test_type == "VALSET_REWARDS" { info!("Starting Valset rewards test"); diff --git a/orchestrator/test_runner/src/relay_market.rs b/orchestrator/test_runner/src/relay_market.rs index 570ab71fb..4c9e522cf 100644 --- a/orchestrator/test_runner/src/relay_market.rs +++ b/orchestrator/test_runner/src/relay_market.rs @@ -11,7 +11,7 @@ use crate::{one_eth, MINER_ADDRESS}; use crate::{ADDRESS_PREFIX, OPERATION_TIMEOUT}; use clarity::PrivateKey as EthPrivateKey; use clarity::{Address as EthAddress, Uint256}; -use cosmos_gravity::send::send_to_eth; +use cosmos_gravity::send::{send_to_eth, TIMEOUT}; use cosmos_gravity::{query::get_oldest_unsigned_transaction_batch, send::send_request_batch}; use deep_space::coin::Coin; use deep_space::private_key::PrivateKey as CosmosPrivateKey; @@ -73,7 +73,9 @@ async fn setup_batch_test( gravity_address: EthAddress, erc20_contract: EthAddress, bridge_fee_amount: Uint256, + grpc_client: &mut GravityQueryClient, ) -> (Coin, Uint256, CosmosPrivateKey, Address, EthAddress) { + let mut grpc_client = grpc_client.clone(); // Acquire 10,000 WETH let weth_acquired = web30 .wrap_eth(one_eth() * 10000u16.into(), *MINER_PRIVATE_KEY, None) @@ -118,6 +120,7 @@ async fn setup_batch_test( test_erc20_deposit( web30, contact, + &mut grpc_client, dest_cosmos_address, gravity_address, erc20_contract, @@ -134,6 +137,7 @@ async fn setup_batch_test( test_erc20_deposit( web30, contact, + &mut grpc_client, requester_address, gravity_address, erc20_contract, @@ -187,7 +191,7 @@ async fn wait_for_batch( expect_batch: bool, web30: &Web3, contact: &Contact, - grpc_client: &mut GravityQueryClient, + mut grpc_client: &mut GravityQueryClient, requester_address: Address, erc20_contract: EthAddress, gravity_address: EthAddress, @@ -197,9 +201,13 @@ async fn wait_for_batch( .await .unwrap(); - get_oldest_unsigned_transaction_batch(grpc_client, requester_address, contact.get_prefix()) - .await - .expect("Failed to get batch to sign"); + get_oldest_unsigned_transaction_batch( + &mut grpc_client, + requester_address, + contact.get_prefix(), + ) + .await + .expect("Failed to get batch to sign"); let mut current_eth_batch_nonce = get_tx_batch_nonce(gravity_address, erc20_contract, *MINER_ADDRESS, web30) @@ -253,6 +261,7 @@ async fn test_good_batch( gravity_address, erc20_contract, bridge_fee_amount, + grpc_client, ) .await; @@ -267,6 +276,7 @@ async fn test_good_batch( request_batch_fee.denom.clone(), request_batch_fee, contact, + Some(TIMEOUT), ) .await .unwrap(); @@ -334,6 +344,7 @@ async fn test_bad_batch( gravity_address, erc20_contract, bridge_fee_amount, + grpc_client, ) .await; @@ -348,6 +359,7 @@ async fn test_bad_batch( request_batch_fee.denom.clone(), request_batch_fee, contact, + Some(TIMEOUT), ) .await .unwrap(); diff --git a/orchestrator/test_runner/src/transaction_stress_test.rs b/orchestrator/test_runner/src/transaction_stress_test.rs index fc51892af..df83b9482 100644 --- a/orchestrator/test_runner/src/transaction_stress_test.rs +++ b/orchestrator/test_runner/src/transaction_stress_test.rs @@ -176,9 +176,15 @@ pub async fn transaction_stress_test( for denom in denoms { info!("Requesting batch for {}", denom); - let res = send_request_batch(keys[0].validator_key, denom, get_fee(), contact) - .await - .unwrap(); + let res = send_request_batch( + keys[0].validator_key, + denom, + get_fee(), + contact, + Some(TIMEOUT), + ) + .await + .unwrap(); info!("batch request response is {:?}", res); } diff --git a/orchestrator/test_runner/src/valset_rewards.rs b/orchestrator/test_runner/src/valset_rewards.rs index 9511a61c6..0a369eb60 100644 --- a/orchestrator/test_runner/src/valset_rewards.rs +++ b/orchestrator/test_runner/src/valset_rewards.rs @@ -96,7 +96,7 @@ pub async fn valset_rewards_test( assert_eq!(params.bridge_ethereum_address, gravity_address.to_string()); // trigger a valset update - test_valset_update(web30, contact, &keys, gravity_address).await; + test_valset_update(web30, contact, &mut grpc_client, &keys, gravity_address).await; // check that one of the relayers has footoken now let mut found = false; diff --git a/orchestrator/test_runner/src/valset_stress.rs b/orchestrator/test_runner/src/valset_stress.rs index aee93190c..bb7864bcd 100644 --- a/orchestrator/test_runner/src/valset_stress.rs +++ b/orchestrator/test_runner/src/valset_stress.rs @@ -4,18 +4,22 @@ use crate::utils::start_orchestrators; use crate::utils::ValidatorKeys; use clarity::Address as EthAddress; use deep_space::Contact; +use gravity_proto::gravity::query_client::QueryClient as GravityQueryClient; +use tonic::transport::Channel; use web30::client::Web3; pub async fn validator_set_stress_test( web30: &Web3, + grpc_client: GravityQueryClient, contact: &Contact, keys: Vec, gravity_address: EthAddress, ) { + let mut grpc_client = grpc_client.clone(); let no_relay_market_config = create_default_test_config(); start_orchestrators(keys.clone(), gravity_address, false, no_relay_market_config).await; for _ in 0u32..10 { - test_valset_update(web30, contact, &keys, gravity_address).await; + test_valset_update(web30, contact, &mut grpc_client, &keys, gravity_address).await; } } From 87a431f259bca17b069cc32c818b51998ab4d2d4 Mon Sep 17 00:00:00 2001 From: Justin Kilpatrick Date: Mon, 30 Aug 2021 09:10:54 -0400 Subject: [PATCH 2/2] Add event pruning cutoff The addition of a new endpoint for browsing oracle events made clear the problem that as events execute they get pruned immediately, preventing the endpoint from being useful for debugging or for frontend visualization. This patch adds a cutoff to event pruning that allows for some recent events to be kept around. --- module/x/gravity/abci.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/module/x/gravity/abci.go b/module/x/gravity/abci.go index 96364657f..3bb88b77b 100644 --- a/module/x/gravity/abci.go +++ b/module/x/gravity/abci.go @@ -361,6 +361,18 @@ func pruneAttestations(ctx sdk.Context, k keeper.Keeper) { // Then we sort it sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] }) + // we delete all attestations earlier than the current event nonce + // minus some buffer value. This buffer value is purely to allow + // frontends and other UI components to view recent oracle history + const eventsToKeep = 1000 + lastNonce := uint64(k.GetLastObservedEventNonce(ctx)) + var cutoff uint64 + if lastNonce <= eventsToKeep { + return + } else { + cutoff = lastNonce - eventsToKeep + } + // This iterates over all keys (event nonces) in the attestation mapping. Each value contains // a slice with one or more attestations at that event nonce. There can be multiple attestations // at one event nonce when validators disagree about what event happened at that nonce. @@ -369,8 +381,8 @@ func pruneAttestations(ctx sdk.Context, k keeper.Keeper) { // They are ordered by when the first attestation at the event nonce was received. // This order is not important. for _, att := range attmap[nonce] { - // we delete all attestations earlier than the current event nonce - if nonce < uint64(k.GetLastObservedEventNonce(ctx)) { + // delete all before the cutoff + if nonce < cutoff { k.DeleteAttestation(ctx, att) } }