From a1d7be0d605c0dd6adb62da0503405adff461c58 Mon Sep 17 00:00:00 2001 From: kevinssgh <79858682+kevinssgh@users.noreply.github.com> Date: Tue, 10 Oct 2023 21:26:04 -0400 Subject: [PATCH 1/2] fix: Blame index update (#1264) * initial commit * added queries and unit tests * added cli * fix parse error * fix parse error 2 * fix lint and test errors * ran make generate * update index for keygen * refactor query name * refactor key calculation * refactor lib name --- cmd/zetaclientd/keygen_tss.go | 3 +- docs/openapi/openapi.swagger.yaml | 34 ++ proto/observer/query.proto | 14 + x/observer/client/cli/query.go | 1 + x/observer/client/cli/query_blame.go | 45 ++ x/observer/keeper/blame.go | 29 ++ x/observer/keeper/blame_test.go | 47 ++ x/observer/types/keys.go | 8 + x/observer/types/query.pb.go | 650 ++++++++++++++++++++++----- x/observer/types/query.pb.gw.go | 123 +++++ zetaclient/btc_signer.go | 2 +- zetaclient/btc_test.go | 2 +- zetaclient/evm_signer.go | 6 +- zetaclient/signer.go | 4 +- zetaclient/tss_signer.go | 10 +- 15 files changed, 848 insertions(+), 130 deletions(-) create mode 100644 x/observer/keeper/blame_test.go diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 3b303450c3..5f76d7d512 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -134,7 +134,8 @@ func keygenTss(cfg *config.Config, tss *mc.TSS, keygenLogger zerolog.Logger) err if err != nil { return err } - zetaHash, err := tss.CoreBridge.PostBlameData(&res.Blame, common.ZetaChain().ChainId, digest) + index := fmt.Sprintf("keygen-%s-%d", digest, keyGen.BlockNumber) + zetaHash, err := tss.CoreBridge.PostBlameData(&res.Blame, common.ZetaChain().ChainId, index) if err != nil { keygenLogger.Error().Err(err).Msg("error sending blame data to core") return err diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index e7694c9585..39fa7d46df 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -27295,6 +27295,32 @@ paths: type: string tags: - Query + /zeta-chain/observer/blame_by_chain_and_nonce/{chain_id}/{nonce}: + get: + summary: Queries a list of VoterByIdentifier items. + operationId: Query_BlamesByChainAndNonce + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/observerQueryBlameByChainAndNonceResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + parameters: + - name: chain_id + in: path + required: true + type: string + format: int64 + - name: nonce + in: path + required: true + type: string + format: int64 + tags: + - Query /zeta-chain/observer/blame_by_identifier/{blame_identifier}: get: summary: Queries a list of VoterByIdentifier items. @@ -51119,6 +51145,14 @@ definitions: $ref: '#/definitions/observerObservationType' ballot_status: $ref: '#/definitions/observerBallotStatus' + observerQueryBlameByChainAndNonceResponse: + type: object + properties: + blame_info: + type: array + items: + type: object + $ref: '#/definitions/observerBlame' observerQueryBlameByIdentifierResponse: type: object properties: diff --git a/proto/observer/query.proto b/proto/observer/query.proto index fdd0733f04..1de4b9df30 100644 --- a/proto/observer/query.proto +++ b/proto/observer/query.proto @@ -80,6 +80,11 @@ service Query { option (google.api.http).get = "/zeta-chain/observer/get_all_blame_records"; } + // Queries a list of VoterByIdentifier items. + rpc BlamesByChainAndNonce(QueryBlameByChainAndNonceRequest) returns (QueryBlameByChainAndNonceResponse) { + option (google.api.http).get = "/zeta-chain/observer/blame_by_chain_and_nonce/{chain_id}/{nonce}"; + } + rpc GetAllBlockHeaders(QueryAllBlockHeaderRequest) returns (QueryAllBlockHeaderResponse) { option (google.api.http).get = "/zeta-chain/observer/get_all_block_headers"; } @@ -211,6 +216,15 @@ message QueryAllBlameRecordsResponse { repeated Blame blame_info = 1; } +message QueryBlameByChainAndNonceRequest { + int64 chain_id = 1; + int64 nonce = 2; +} + +message QueryBlameByChainAndNonceResponse { + repeated Blame blame_info = 1; +} + message QueryAllBlockHeaderRequest { cosmos.base.query.v1beta1.PageRequest pagination = 1; } diff --git a/x/observer/client/cli/query.go b/x/observer/client/cli/query.go index 1ea4d0d88b..47fd373eba 100644 --- a/x/observer/client/cli/query.go +++ b/x/observer/client/cli/query.go @@ -39,6 +39,7 @@ func GetQueryCmd(_ string) *cobra.Command { CmdShowObserverCount(), CmdBlameByIdentifier(), CmdGetAllBlameRecords(), + CmdGetBlameByChainAndNonce(), ) return cmd diff --git a/x/observer/client/cli/query_blame.go b/x/observer/client/cli/query_blame.go index aee13732b4..462c442279 100644 --- a/x/observer/client/cli/query_blame.go +++ b/x/observer/client/cli/query_blame.go @@ -1,6 +1,8 @@ package cli import ( + "strconv" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" @@ -69,3 +71,46 @@ func CmdGetAllBlameRecords() *cobra.Command { return cmd } + +func CmdGetBlameByChainAndNonce() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-blame-by-msg [chainId] [nonce]", + Short: "Query AllBlameRecords", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) (err error) { + chainID := args[0] + nonce := args[1] + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + chain, err := strconv.ParseInt(chainID, 10, 64) + if err != nil { + return err + } + nonceInt, err := strconv.ParseInt(nonce, 10, 64) + if err != nil { + return err + } + params := &types.QueryBlameByChainAndNonceRequest{ + ChainId: chain, + Nonce: nonceInt, + } + + res, err := queryClient.BlamesByChainAndNonce(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/observer/keeper/blame.go b/x/observer/keeper/blame.go index 6acab15c64..a72ae4335f 100644 --- a/x/observer/keeper/blame.go +++ b/x/observer/keeper/blame.go @@ -40,6 +40,21 @@ func (k Keeper) GetAllBlame(ctx sdk.Context) (BlameRecords []*types.Blame, found return } +func (k Keeper) GetBlamesByChainAndNonce(ctx sdk.Context, chainID int64, nonce int64) (BlameRecords []*types.Blame, found bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BlameKey)) + blamePrefix := types.GetBlamePrefix(chainID, nonce) + iterator := sdk.KVStorePrefixIterator(store, []byte(blamePrefix)) + defer iterator.Close() + found = false + for ; iterator.Valid(); iterator.Next() { + var val types.Blame + k.cdc.MustUnmarshal(iterator.Value(), &val) + BlameRecords = append(BlameRecords, &val) + found = true + } + return +} + // Query func (k Keeper) BlameByIdentifier(goCtx context.Context, request *types.QueryBlameByIdentifierRequest) (*types.QueryBlameByIdentifierResponse, error) { @@ -71,3 +86,17 @@ func (k Keeper) GetAllBlameRecords(goCtx context.Context, request *types.QueryAl BlameInfo: blameRecords, }, nil } + +func (k Keeper) BlamesByChainAndNonce(goCtx context.Context, request *types.QueryBlameByChainAndNonceRequest) (*types.QueryBlameByChainAndNonceResponse, error) { + if request == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(goCtx) + blameRecords, found := k.GetBlamesByChainAndNonce(ctx, request.ChainId, request.Nonce) + if !found { + return nil, status.Error(codes.NotFound, "blame info not found") + } + return &types.QueryBlameByChainAndNonceResponse{ + BlameInfo: blameRecords, + }, nil +} diff --git a/x/observer/keeper/blame_test.go b/x/observer/keeper/blame_test.go new file mode 100644 index 0000000000..d12d69b84a --- /dev/null +++ b/x/observer/keeper/blame_test.go @@ -0,0 +1,47 @@ +package keeper + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestKeeper_BlameByIdentifier(t *testing.T) { + keeper, ctx := SetupKeeper(t) + var chainId int64 = 97 + var nonce uint64 = 101 + digest := "85f5e10431f69bc2a14046a13aabaefc660103b6de7a84f75c4b96181d03f0b5" + + index := types.GetBlameIndex(chainId, nonce, digest, 123) + + keeper.SetBlame(ctx, &types.Blame{ + Index: index, + FailureReason: "failed to join party", + Nodes: nil, + }) + + blameRecords, found := keeper.GetBlame(ctx, index) + require.True(t, found) + require.Equal(t, index, blameRecords.Index) +} + +func TestKeeper_BlameByChainAndNonce(t *testing.T) { + keeper, ctx := SetupKeeper(t) + var chainId int64 = 97 + var nonce uint64 = 101 + digest := "85f5e10431f69bc2a14046a13aabaefc660103b6de7a84f75c4b96181d03f0b5" + + index := types.GetBlameIndex(chainId, nonce, digest, 123) + + keeper.SetBlame(ctx, &types.Blame{ + Index: index, + FailureReason: "failed to join party", + Nodes: nil, + }) + + blameRecords, found := keeper.GetBlamesByChainAndNonce(ctx, chainId, int64(nonce)) + require.True(t, found) + require.Equal(t, 1, len(blameRecords)) + require.Equal(t, index, blameRecords[0].Index) +} diff --git a/x/observer/types/keys.go b/x/observer/types/keys.go index 4a28380ed9..0195496735 100644 --- a/x/observer/types/keys.go +++ b/x/observer/types/keys.go @@ -50,3 +50,11 @@ const ( BallotListKey = "BallotList-value-" ) + +func GetBlameIndex(chainID int64, nonce uint64, digest string, height uint64) string { + return fmt.Sprintf("%d-%d-%s-%d", chainID, nonce, digest, height) +} + +func GetBlamePrefix(chainID int64, nonce int64) string { + return fmt.Sprintf("%d-%d", chainID, nonce) +} diff --git a/x/observer/types/query.pb.go b/x/observer/types/query.pb.go index 6917312022..16985b39b0 100644 --- a/x/observer/types/query.pb.go +++ b/x/observer/types/query.pb.go @@ -1406,6 +1406,102 @@ func (m *QueryAllBlameRecordsResponse) GetBlameInfo() []*Blame { return nil } +type QueryBlameByChainAndNonceRequest struct { + ChainId int64 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + Nonce int64 `protobuf:"varint,2,opt,name=nonce,proto3" json:"nonce,omitempty"` +} + +func (m *QueryBlameByChainAndNonceRequest) Reset() { *m = QueryBlameByChainAndNonceRequest{} } +func (m *QueryBlameByChainAndNonceRequest) String() string { return proto.CompactTextString(m) } +func (*QueryBlameByChainAndNonceRequest) ProtoMessage() {} +func (*QueryBlameByChainAndNonceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_dcb801e455adaee4, []int{31} +} +func (m *QueryBlameByChainAndNonceRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryBlameByChainAndNonceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryBlameByChainAndNonceRequest.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 *QueryBlameByChainAndNonceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryBlameByChainAndNonceRequest.Merge(m, src) +} +func (m *QueryBlameByChainAndNonceRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryBlameByChainAndNonceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryBlameByChainAndNonceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryBlameByChainAndNonceRequest proto.InternalMessageInfo + +func (m *QueryBlameByChainAndNonceRequest) GetChainId() int64 { + if m != nil { + return m.ChainId + } + return 0 +} + +func (m *QueryBlameByChainAndNonceRequest) GetNonce() int64 { + if m != nil { + return m.Nonce + } + return 0 +} + +type QueryBlameByChainAndNonceResponse struct { + BlameInfo []*Blame `protobuf:"bytes,1,rep,name=blame_info,json=blameInfo,proto3" json:"blame_info,omitempty"` +} + +func (m *QueryBlameByChainAndNonceResponse) Reset() { *m = QueryBlameByChainAndNonceResponse{} } +func (m *QueryBlameByChainAndNonceResponse) String() string { return proto.CompactTextString(m) } +func (*QueryBlameByChainAndNonceResponse) ProtoMessage() {} +func (*QueryBlameByChainAndNonceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_dcb801e455adaee4, []int{32} +} +func (m *QueryBlameByChainAndNonceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryBlameByChainAndNonceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryBlameByChainAndNonceResponse.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 *QueryBlameByChainAndNonceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryBlameByChainAndNonceResponse.Merge(m, src) +} +func (m *QueryBlameByChainAndNonceResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryBlameByChainAndNonceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryBlameByChainAndNonceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryBlameByChainAndNonceResponse proto.InternalMessageInfo + +func (m *QueryBlameByChainAndNonceResponse) GetBlameInfo() []*Blame { + if m != nil { + return m.BlameInfo + } + return nil +} + type QueryAllBlockHeaderRequest struct { Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -1414,7 +1510,7 @@ func (m *QueryAllBlockHeaderRequest) Reset() { *m = QueryAllBlockHeaderR func (m *QueryAllBlockHeaderRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllBlockHeaderRequest) ProtoMessage() {} func (*QueryAllBlockHeaderRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{31} + return fileDescriptor_dcb801e455adaee4, []int{33} } func (m *QueryAllBlockHeaderRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1459,7 +1555,7 @@ func (m *QueryAllBlockHeaderResponse) Reset() { *m = QueryAllBlockHeader func (m *QueryAllBlockHeaderResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllBlockHeaderResponse) ProtoMessage() {} func (*QueryAllBlockHeaderResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{32} + return fileDescriptor_dcb801e455adaee4, []int{34} } func (m *QueryAllBlockHeaderResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1510,7 +1606,7 @@ func (m *QueryGetBlockHeaderByHashRequest) Reset() { *m = QueryGetBlockH func (m *QueryGetBlockHeaderByHashRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetBlockHeaderByHashRequest) ProtoMessage() {} func (*QueryGetBlockHeaderByHashRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{33} + return fileDescriptor_dcb801e455adaee4, []int{35} } func (m *QueryGetBlockHeaderByHashRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1554,7 +1650,7 @@ func (m *QueryGetBlockHeaderByHashResponse) Reset() { *m = QueryGetBlock func (m *QueryGetBlockHeaderByHashResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetBlockHeaderByHashResponse) ProtoMessage() {} func (*QueryGetBlockHeaderByHashResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{34} + return fileDescriptor_dcb801e455adaee4, []int{36} } func (m *QueryGetBlockHeaderByHashResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1622,6 +1718,8 @@ func init() { proto.RegisterType((*QueryBlameByIdentifierResponse)(nil), "zetachain.zetacore.observer.QueryBlameByIdentifierResponse") proto.RegisterType((*QueryAllBlameRecordsRequest)(nil), "zetachain.zetacore.observer.QueryAllBlameRecordsRequest") proto.RegisterType((*QueryAllBlameRecordsResponse)(nil), "zetachain.zetacore.observer.QueryAllBlameRecordsResponse") + proto.RegisterType((*QueryBlameByChainAndNonceRequest)(nil), "zetachain.zetacore.observer.QueryBlameByChainAndNonceRequest") + proto.RegisterType((*QueryBlameByChainAndNonceResponse)(nil), "zetachain.zetacore.observer.QueryBlameByChainAndNonceResponse") proto.RegisterType((*QueryAllBlockHeaderRequest)(nil), "zetachain.zetacore.observer.QueryAllBlockHeaderRequest") proto.RegisterType((*QueryAllBlockHeaderResponse)(nil), "zetachain.zetacore.observer.QueryAllBlockHeaderResponse") proto.RegisterType((*QueryGetBlockHeaderByHashRequest)(nil), "zetachain.zetacore.observer.QueryGetBlockHeaderByHashRequest") @@ -1631,120 +1729,126 @@ func init() { func init() { proto.RegisterFile("observer/query.proto", fileDescriptor_dcb801e455adaee4) } var fileDescriptor_dcb801e455adaee4 = []byte{ - // 1798 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xcd, 0x4f, 0x1b, 0x49, - 0x16, 0xa7, 0x21, 0x38, 0xf0, 0x0c, 0x01, 0x0a, 0x92, 0x80, 0x01, 0xe3, 0x2d, 0x36, 0x89, 0x03, - 0x89, 0x1d, 0x1c, 0x29, 0x5f, 0x04, 0x22, 0x8c, 0xf2, 0x41, 0xbe, 0xd7, 0xd9, 0xcd, 0xae, 0x76, - 0xb5, 0x6b, 0xb5, 0xed, 0xc2, 0x38, 0x69, 0x5c, 0x4e, 0x77, 0x43, 0xf0, 0x46, 0x48, 0xab, 0x3d, - 0xcf, 0x48, 0x91, 0x46, 0x9a, 0xf3, 0x9c, 0xe6, 0x36, 0x73, 0xc8, 0x65, 0x0e, 0xd1, 0x5c, 0xe6, - 0x32, 0x39, 0x8d, 0x32, 0x1a, 0x69, 0x34, 0x73, 0x98, 0xd1, 0x28, 0x99, 0x3f, 0x64, 0xd4, 0xf5, - 0xd1, 0x2e, 0xb7, 0xbb, 0xed, 0x36, 0xca, 0x89, 0xae, 0x8f, 0xf7, 0xea, 0xf7, 0x7b, 0x55, 0xf5, - 0xde, 0xaf, 0x30, 0x4c, 0xd0, 0x82, 0x45, 0xcc, 0x5d, 0x62, 0xa6, 0x9f, 0xed, 0x10, 0xb3, 0x9e, - 0xaa, 0x99, 0xd4, 0xa6, 0x68, 0xfa, 0xbf, 0xc4, 0xd6, 0x8b, 0x5b, 0x7a, 0xa5, 0x9a, 0x62, 0x5f, - 0xd4, 0x24, 0x29, 0x39, 0x31, 0x36, 0x5e, 0xa4, 0xdb, 0xdb, 0xb4, 0x9a, 0xe6, 0x7f, 0xb8, 0x45, - 0x6c, 0xa1, 0x48, 0xad, 0x6d, 0x6a, 0xa5, 0x0b, 0xba, 0x45, 0xb8, 0xab, 0xf4, 0xee, 0x52, 0x81, - 0xd8, 0xfa, 0x52, 0xba, 0xa6, 0x97, 0x2b, 0x55, 0xdd, 0xae, 0xb8, 0x73, 0x27, 0xca, 0xb4, 0x4c, - 0xd9, 0x67, 0xda, 0xf9, 0x12, 0xbd, 0x33, 0x65, 0x4a, 0xcb, 0x06, 0x49, 0xeb, 0xb5, 0x4a, 0x5a, - 0xaf, 0x56, 0xa9, 0xcd, 0x4c, 0x2c, 0x31, 0x7a, 0xd4, 0xc5, 0x59, 0xd0, 0x0d, 0x83, 0xda, 0xd2, - 0x55, 0xa3, 0xdb, 0xd0, 0xb7, 0x89, 0xe8, 0x9d, 0x73, 0x7b, 0x8b, 0x26, 0xb5, 0x2c, 0x46, 0x24, - 0xbf, 0x69, 0xe8, 0xe5, 0x56, 0x6f, 0x4f, 0x49, 0xbd, 0x4c, 0x24, 0xb0, 0x69, 0xb7, 0xbb, 0x4a, - 0x4b, 0x24, 0xaf, 0x17, 0x8b, 0x74, 0xa7, 0x2a, 0x97, 0x3a, 0xee, 0x0e, 0xca, 0x8f, 0x16, 0x67, - 0x35, 0xdd, 0xd4, 0xb7, 0xc5, 0x1a, 0xf8, 0x73, 0x0d, 0xc6, 0xfe, 0xe2, 0x04, 0xe2, 0xa1, 0x49, - 0x77, 0x49, 0x8e, 0x3c, 0xdb, 0x21, 0x96, 0x8d, 0xa6, 0x60, 0x80, 0xc3, 0xa9, 0x94, 0x26, 0xb5, - 0x84, 0x96, 0x3c, 0x94, 0x3b, 0xcc, 0xda, 0x1b, 0x25, 0x74, 0x1c, 0x0e, 0xdb, 0x7b, 0xf9, 0x2d, - 0xdd, 0xda, 0x9a, 0xec, 0x4d, 0x68, 0xc9, 0xc1, 0x5c, 0xc4, 0xde, 0xbb, 0xa5, 0x5b, 0x5b, 0x68, - 0x1e, 0xfa, 0x6b, 0x26, 0xa5, 0x9b, 0x93, 0x7d, 0x09, 0x2d, 0x19, 0xcd, 0x0c, 0xa7, 0x44, 0xe4, - 0x1f, 0x3a, 0x9d, 0x39, 0x3e, 0x86, 0x66, 0x01, 0x0a, 0x06, 0x2d, 0x3e, 0xe5, 0x0e, 0x0e, 0x31, - 0x07, 0x83, 0xac, 0x87, 0xf9, 0x98, 0x82, 0x01, 0x7b, 0x2f, 0x5f, 0xa9, 0x96, 0xc8, 0xde, 0x64, - 0x7f, 0x42, 0x4b, 0xf6, 0xe5, 0x0e, 0xdb, 0x7b, 0x1b, 0x4e, 0x13, 0x2f, 0x00, 0x52, 0x71, 0x5a, - 0x35, 0x5a, 0xb5, 0x08, 0x9a, 0x80, 0xfe, 0x5d, 0xdd, 0x10, 0x28, 0x07, 0x72, 0xbc, 0x81, 0x27, - 0xe4, 0x5c, 0xc6, 0x54, 0x90, 0xc2, 0xff, 0x80, 0xf1, 0xa6, 0x5e, 0xe1, 0x62, 0x0d, 0x22, 0x3c, - 0x22, 0xcc, 0x47, 0x34, 0x33, 0x9f, 0x6a, 0x73, 0xac, 0x52, 0xdc, 0x38, 0x7b, 0xe8, 0xcd, 0xaf, - 0x73, 0x3d, 0x39, 0x61, 0x88, 0xef, 0x41, 0x9c, 0x79, 0xce, 0xb2, 0x4d, 0xcf, 0xd6, 0x37, 0x4a, - 0xa4, 0x6a, 0x57, 0x36, 0x2b, 0xc4, 0x94, 0x01, 0x5d, 0x84, 0x31, 0x7e, 0x22, 0xf2, 0x15, 0x77, - 0x8c, 0xad, 0x37, 0x98, 0x1b, 0xe5, 0x03, 0x0d, 0x1b, 0x6c, 0xc3, 0xe0, 0x63, 0x6a, 0x13, 0xf3, - 0x6e, 0xc5, 0xb2, 0xd1, 0x3c, 0x0c, 0xef, 0x3a, 0x8d, 0xbc, 0x5e, 0x2a, 0x99, 0xc4, 0xb2, 0x84, - 0xd5, 0x10, 0xeb, 0x5c, 0xe3, 0x7d, 0x28, 0x0b, 0x83, 0x4e, 0x3b, 0x6f, 0xd7, 0x6b, 0x84, 0x6d, - 0xcb, 0x91, 0xcc, 0x89, 0xb6, 0x34, 0x1c, 0xff, 0x7f, 0xad, 0xd7, 0x48, 0x6e, 0x60, 0x57, 0x7c, - 0xe1, 0xaf, 0x7a, 0x61, 0x2e, 0x90, 0x85, 0x88, 0x55, 0x37, 0x34, 0xd0, 0x2a, 0x44, 0x18, 0x48, - 0x6b, 0xb2, 0x37, 0xd1, 0x97, 0x8c, 0x66, 0x4e, 0x76, 0x44, 0xc4, 0x18, 0xe7, 0x84, 0x15, 0xfa, - 0x3b, 0x8c, 0xf2, 0x51, 0x76, 0xc5, 0x38, 0xb7, 0x3e, 0xc6, 0xed, 0x4c, 0x5b, 0x4f, 0x0f, 0x1a, - 0x46, 0x8c, 0xe2, 0x08, 0x6d, 0xee, 0x40, 0xf7, 0x61, 0x58, 0xb0, 0xb0, 0x6c, 0xdd, 0xde, 0xb1, - 0xd8, 0x39, 0x3c, 0x92, 0x39, 0xdd, 0xd6, 0x2b, 0x8f, 0xca, 0x23, 0x66, 0x90, 0x1b, 0x2a, 0x28, - 0x2d, 0x7c, 0x07, 0x66, 0x58, 0xe0, 0x1e, 0x88, 0xb9, 0x56, 0xb6, 0xbe, 0xee, 0x78, 0x51, 0x36, - 0x5f, 0x25, 0xc2, 0x56, 0x90, 0x51, 0x53, 0x06, 0x98, 0x0d, 0x5e, 0x81, 0xd9, 0x00, 0x67, 0x62, - 0x0f, 0x66, 0x60, 0x50, 0x82, 0x72, 0x0e, 0x43, 0x9f, 0x73, 0x83, 0xdc, 0x0e, 0x9c, 0x10, 0x47, - 0x71, 0xcd, 0x30, 0xa4, 0x87, 0x7b, 0x7a, 0xad, 0x46, 0x4c, 0xf7, 0x1a, 0xd4, 0xc5, 0x36, 0xfb, - 0xcd, 0x10, 0x4b, 0x3c, 0x96, 0x91, 0x27, 0x66, 0x7e, 0x9b, 0x8f, 0xb1, 0x95, 0xa2, 0x99, 0xc5, - 0x10, 0x91, 0x97, 0xfe, 0x64, 0xe0, 0x5d, 0xff, 0xf8, 0x18, 0x4c, 0xb0, 0xa5, 0x1f, 0xed, 0xd4, - 0x6a, 0xd4, 0xb4, 0x49, 0x89, 0x31, 0xb3, 0xf0, 0x75, 0x11, 0x40, 0x4f, 0xbf, 0x8b, 0xe7, 0x04, - 0x44, 0xd8, 0x92, 0x12, 0x85, 0x9b, 0x5b, 0x78, 0x64, 0xc4, 0x20, 0x5e, 0x85, 0x3f, 0x31, 0x37, - 0x37, 0x89, 0xbd, 0x4e, 0x4d, 0xc2, 0xaf, 0xea, 0x0d, 0x6a, 0x36, 0x6d, 0x86, 0x37, 0xb5, 0xf5, - 0xb9, 0xa9, 0x0d, 0x57, 0x01, 0xb7, 0xb3, 0x17, 0x60, 0x6e, 0x41, 0xd4, 0x61, 0x9d, 0x6f, 0x4a, - 0x1a, 0xa7, 0xda, 0xc6, 0xa5, 0xe1, 0x2d, 0x07, 0x45, 0xf7, 0x1b, 0x4f, 0xc3, 0x54, 0xeb, 0x7a, - 0x72, 0x9b, 0x9e, 0x40, 0xcc, 0x6f, 0x50, 0x80, 0xb8, 0xeb, 0x07, 0x62, 0x31, 0x24, 0x08, 0x76, - 0xcb, 0x54, 0x20, 0x99, 0xc6, 0x5a, 0xf7, 0x69, 0x89, 0xac, 0xf1, 0x8a, 0x22, 0x23, 0x36, 0x01, - 0xfd, 0x3c, 0x23, 0xf3, 0x23, 0xcb, 0x1b, 0xf8, 0x09, 0x4c, 0xfb, 0xda, 0x08, 0x80, 0x77, 0x60, - 0x48, 0xad, 0x4e, 0x02, 0x61, 0xb2, 0x2d, 0x42, 0xd5, 0x4f, 0xb4, 0xda, 0x68, 0xe0, 0x92, 0xc0, - 0xb7, 0x66, 0x18, 0x3e, 0xf8, 0x6e, 0x00, 0x34, 0x8a, 0xb7, 0x58, 0xe8, 0x64, 0x8a, 0x57, 0xfa, - 0x94, 0x53, 0xe9, 0x53, 0x5c, 0x34, 0x88, 0x4a, 0x9f, 0x7a, 0xa8, 0x97, 0x65, 0xa1, 0xcb, 0x29, - 0x96, 0xf8, 0x95, 0x26, 0x28, 0x79, 0x97, 0x11, 0x94, 0x6e, 0x43, 0x54, 0xe9, 0x16, 0x47, 0xb1, - 0x0b, 0x46, 0x4a, 0x03, 0xdd, 0x6c, 0xc2, 0xdc, 0x2b, 0xce, 0x50, 0x27, 0xcc, 0x1c, 0x48, 0x13, - 0x68, 0x79, 0xdf, 0x9d, 0x63, 0xe2, 0xaa, 0x88, 0x1b, 0x8e, 0x88, 0x90, 0x07, 0xe9, 0x7f, 0x9a, - 0xb8, 0xf0, 0x7e, 0x53, 0x04, 0xb5, 0x7f, 0xc3, 0xa8, 0x57, 0x83, 0x88, 0x40, 0xb6, 0x4f, 0xb5, - 0x1e, 0x7f, 0xa2, 0x2c, 0x8e, 0x14, 0x9b, 0xbb, 0xf1, 0x71, 0x38, 0x2a, 0x11, 0xdc, 0x61, 0x4a, - 0x46, 0x62, 0xfb, 0x1b, 0x1c, 0xf3, 0x0e, 0x08, 0x44, 0xcb, 0x10, 0xe1, 0xa2, 0x27, 0x54, 0x55, - 0x16, 0xc6, 0xc2, 0x04, 0xcf, 0x89, 0x1c, 0xfa, 0x68, 0x8b, 0x3e, 0x97, 0x39, 0x69, 0x5d, 0x39, - 0x32, 0x4e, 0x4c, 0xe2, 0x41, 0x33, 0x04, 0x80, 0xff, 0xc0, 0xb8, 0xa1, 0x5b, 0x76, 0xde, 0x4d, - 0x84, 0xea, 0x39, 0x4e, 0xb5, 0x45, 0x73, 0x57, 0xb7, 0xec, 0x66, 0xa7, 0x63, 0x86, 0xb7, 0x0b, - 0xdf, 0x16, 0x18, 0xb3, 0x8e, 0x22, 0xf4, 0x93, 0x0c, 0xa7, 0x61, 0x94, 0xa9, 0xc5, 0xd6, 0x52, - 0x3b, 0xc2, 0xfa, 0x15, 0xc1, 0x50, 0x94, 0xfa, 0xa3, 0xd5, 0x97, 0x2b, 0x72, 0x40, 0x38, 0xab, - 0x6e, 0x52, 0x41, 0x02, 0xb7, 0xaf, 0x77, 0xce, 0x74, 0x47, 0x9b, 0x39, 0x4b, 0x55, 0x37, 0x29, - 0x9e, 0x6d, 0xdc, 0x0e, 0x3e, 0x46, 0x8a, 0xd4, 0x2c, 0xb9, 0xc7, 0x4c, 0x17, 0x39, 0xbc, 0x65, - 0x38, 0x00, 0x41, 0x5f, 0xf7, 0x08, 0x94, 0x34, 0x90, 0x65, 0x92, 0x91, 0xe8, 0xa5, 0x46, 0xbc, - 0x3e, 0x54, 0x1a, 0xf8, 0x4c, 0x53, 0x89, 0x2a, 0xcb, 0x08, 0x22, 0x97, 0x60, 0x58, 0x48, 0x58, - 0xd6, 0x2f, 0x6b, 0xd2, 0xb8, 0xac, 0x49, 0xaa, 0xcd, 0x50, 0xa1, 0xd1, 0xb0, 0x3e, 0xdc, 0xa5, - 0x5f, 0x83, 0x84, 0xbc, 0x36, 0xca, 0x6a, 0xd9, 0xba, 0xa3, 0xa1, 0x65, 0x38, 0x9a, 0x95, 0xb6, - 0x13, 0x8e, 0x21, 0x45, 0x69, 0xe3, 0x7f, 0x35, 0x6a, 0xa5, 0x8f, 0x0b, 0x41, 0xf5, 0x02, 0x0c, - 0xa9, 0x54, 0x45, 0x50, 0x7d, 0x99, 0x46, 0x15, 0xa6, 0x99, 0x8f, 0xa7, 0xa0, 0x9f, 0x79, 0x47, - 0x2f, 0x35, 0x88, 0xf0, 0x22, 0x83, 0xd2, 0x6d, 0x37, 0xbb, 0x55, 0xaf, 0xc7, 0xce, 0x85, 0x37, - 0xe0, 0x78, 0xf1, 0xfc, 0xff, 0x7f, 0xf8, 0xfd, 0x93, 0xde, 0x59, 0x34, 0x9d, 0x76, 0xe6, 0x9f, - 0x65, 0xa6, 0x69, 0xcf, 0xbb, 0x07, 0xfd, 0xa8, 0x01, 0x6a, 0x95, 0xb8, 0x68, 0xb9, 0xf3, 0x6a, - 0x81, 0xf2, 0x3e, 0x76, 0xf5, 0x60, 0xc6, 0x02, 0xf6, 0x75, 0x06, 0xfb, 0x1a, 0x5a, 0xf1, 0x85, - 0x2d, 0xa4, 0x6a, 0xa1, 0xae, 0x24, 0x82, 0xf4, 0x8b, 0x16, 0x19, 0xbe, 0x8f, 0xbe, 0xd3, 0x60, - 0xd4, 0xab, 0x1a, 0xd1, 0xe5, 0xce, 0xc8, 0x02, 0x64, 0x6b, 0xec, 0xca, 0x41, 0x4c, 0x05, 0xa5, - 0x75, 0x46, 0x69, 0x05, 0x2d, 0xfb, 0x52, 0x72, 0xe5, 0xaa, 0xc3, 0x8a, 0x8f, 0xbd, 0x68, 0x51, - 0xc8, 0xfb, 0xe8, 0x1b, 0x0d, 0x50, 0xab, 0x4a, 0x0d, 0xb3, 0x53, 0x81, 0xea, 0x37, 0xcc, 0x4e, - 0x05, 0x0b, 0x63, 0xbc, 0xc4, 0x68, 0x2d, 0xa2, 0xd3, 0xbe, 0xb4, 0x74, 0xc3, 0xc8, 0x7b, 0x75, - 0x33, 0xfa, 0x42, 0x83, 0x11, 0x8f, 0xae, 0x45, 0x4b, 0x9d, 0x41, 0x78, 0x4c, 0x62, 0x97, 0xbb, - 0x36, 0x71, 0x41, 0x9f, 0x61, 0xa0, 0x4f, 0xa2, 0x3f, 0xfb, 0x82, 0xb6, 0x3c, 0xd8, 0x7e, 0xd1, - 0xe0, 0xa8, 0xaf, 0x00, 0x46, 0xab, 0x9d, 0x21, 0xb4, 0x53, 0xde, 0xb1, 0x6b, 0x07, 0xb6, 0x0f, - 0x75, 0xa8, 0xca, 0xc4, 0xce, 0x17, 0x8d, 0x0a, 0xa9, 0xda, 0x42, 0x15, 0xe7, 0x37, 0xa9, 0x29, - 0x4f, 0x97, 0x94, 0xfc, 0xfb, 0xe8, 0x4b, 0x0d, 0x86, 0x9b, 0x96, 0x41, 0x17, 0xba, 0xc4, 0x25, - 0xf9, 0x5c, 0xec, 0xda, 0x2e, 0xd4, 0x86, 0x30, 0x1e, 0x0d, 0x6d, 0x8f, 0x5e, 0x69, 0x4d, 0xba, - 0x13, 0x85, 0x5b, 0xb6, 0x55, 0x27, 0xc7, 0x2e, 0x75, 0x6f, 0x28, 0x00, 0x9f, 0x63, 0x80, 0x17, - 0x50, 0xd2, 0x17, 0xb0, 0xa2, 0xd4, 0xd3, 0x2f, 0xd8, 0xe3, 0x60, 0xdf, 0x39, 0xf5, 0x47, 0x14, - 0x4f, 0x6b, 0x86, 0x11, 0x06, 0xb7, 0xaf, 0xbe, 0x0f, 0x83, 0xdb, 0x5f, 0xb1, 0xe3, 0x24, 0xc3, - 0x8d, 0x51, 0xa2, 0x13, 0x6e, 0xf4, 0x5a, 0x83, 0x11, 0x8f, 0x98, 0x0d, 0x93, 0x67, 0x02, 0x55, - 0x77, 0x98, 0x3c, 0x13, 0xac, 0xc7, 0xf1, 0x59, 0x06, 0xfc, 0x14, 0x3a, 0xe1, 0x0b, 0xdc, 0x2b, - 0xd5, 0xd1, 0xa7, 0x1a, 0x44, 0xb8, 0x04, 0x46, 0x99, 0x50, 0xeb, 0x36, 0xa9, 0xf0, 0xd8, 0xf9, - 0xae, 0x6c, 0x42, 0xd5, 0x5a, 0x2e, 0xc4, 0xd1, 0xb7, 0x1a, 0x8c, 0xb5, 0x48, 0x6c, 0x14, 0xa2, - 0xb0, 0x04, 0x29, 0xf7, 0xd8, 0xf2, 0x81, 0x6c, 0x05, 0xe6, 0xcb, 0x0c, 0xf3, 0x79, 0xb4, 0xa4, - 0x62, 0x96, 0x5e, 0x94, 0x94, 0xb8, 0x45, 0x9f, 0x7b, 0x74, 0x3f, 0xfa, 0x5e, 0x83, 0xb1, 0x16, - 0x79, 0x1d, 0x86, 0x49, 0x90, 0xbe, 0x0f, 0xc3, 0x24, 0x50, 0xcf, 0x77, 0x48, 0x85, 0x5c, 0x68, - 0x7b, 0x15, 0x83, 0xe7, 0x31, 0xb1, 0x8f, 0xbe, 0xd6, 0x00, 0xdd, 0x24, 0xb6, 0x47, 0xb1, 0xa3, - 0x70, 0xf7, 0xcd, 0xe7, 0x0d, 0x10, 0xa6, 0x48, 0x05, 0x3c, 0x0f, 0x70, 0x86, 0x11, 0x3a, 0x83, - 0x16, 0x02, 0x73, 0xa2, 0x53, 0x5d, 0x39, 0x07, 0x53, 0x00, 0x7d, 0xad, 0xe0, 0x57, 0x64, 0xf6, - 0xc5, 0x90, 0x28, 0xbc, 0x2f, 0x88, 0xd8, 0xa5, 0xee, 0x0d, 0xbb, 0x44, 0xaf, 0x3c, 0x1b, 0xd0, - 0xcf, 0x1a, 0x4c, 0xf8, 0xa9, 0x6f, 0xb4, 0x12, 0xea, 0x3a, 0x06, 0x09, 0xff, 0xd8, 0xea, 0x41, - 0xcd, 0x05, 0x97, 0x2c, 0xe3, 0x72, 0x15, 0x5d, 0x09, 0xe4, 0xa2, 0xf2, 0x70, 0x4e, 0x99, 0xf3, - 0xc2, 0x70, 0xce, 0x97, 0x7c, 0x6d, 0xec, 0xa3, 0x8f, 0x34, 0xe8, 0x67, 0xff, 0xa8, 0x47, 0xa9, - 0x10, 0x22, 0x5e, 0xf9, 0xe5, 0x21, 0x96, 0x0e, 0x3d, 0x5f, 0xc0, 0xc5, 0x0c, 0xee, 0x0c, 0x8a, - 0xf9, 0x6b, 0x7e, 0x67, 0x6e, 0x76, 0xe3, 0xcd, 0xbb, 0xb8, 0xf6, 0xf6, 0x5d, 0x5c, 0xfb, 0xed, - 0x5d, 0x5c, 0x7b, 0xf9, 0x3e, 0xde, 0xf3, 0xf6, 0x7d, 0xbc, 0xe7, 0xa7, 0xf7, 0xf1, 0x9e, 0x7f, - 0xa6, 0xcb, 0x15, 0x7b, 0x6b, 0xa7, 0xe0, 0xbc, 0x68, 0x7c, 0x73, 0xc2, 0x5e, 0xc3, 0x95, 0x5d, - 0xaf, 0x11, 0xab, 0x10, 0x61, 0x3f, 0x9b, 0x9c, 0xff, 0x23, 0x00, 0x00, 0xff, 0xff, 0x50, 0x87, - 0x71, 0x20, 0x92, 0x1a, 0x00, 0x00, + // 1889 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xcf, 0x6f, 0x1b, 0xc7, + 0x15, 0xf6, 0x8a, 0x16, 0x6d, 0x3d, 0x4a, 0x96, 0x34, 0x92, 0x62, 0x79, 0x25, 0x51, 0xec, 0xa8, + 0x76, 0x68, 0xc9, 0xe1, 0x46, 0x34, 0x90, 0xd8, 0x51, 0xa4, 0x94, 0x14, 0x62, 0x59, 0xb1, 0xe3, + 0xb8, 0x54, 0x9b, 0x16, 0x2d, 0x5a, 0x62, 0x49, 0x8e, 0x28, 0x26, 0xab, 0x1d, 0x66, 0x77, 0xa5, + 0x88, 0x15, 0x04, 0x14, 0x3d, 0xf7, 0x10, 0xa0, 0x40, 0xcf, 0x3d, 0xf5, 0xd6, 0x1e, 0x72, 0xe9, + 0xa1, 0xe8, 0xa5, 0x97, 0xe6, 0x54, 0xa4, 0x28, 0x50, 0xb4, 0x87, 0x16, 0x81, 0xdd, 0x3f, 0xa0, + 0x7f, 0x42, 0x31, 0x3f, 0x76, 0x39, 0x5c, 0xee, 0x92, 0x4b, 0xc1, 0x27, 0x71, 0x67, 0xe6, 0xbd, + 0xf9, 0xbe, 0x37, 0x33, 0xef, 0xbd, 0x0f, 0x82, 0x79, 0x5a, 0x73, 0x89, 0x73, 0x4a, 0x1c, 0xe3, + 0xb3, 0x13, 0xe2, 0x74, 0x0a, 0x6d, 0x87, 0x7a, 0x14, 0x2d, 0xfd, 0x8c, 0x78, 0x66, 0xfd, 0xc8, + 0x6c, 0xd9, 0x05, 0xfe, 0x8b, 0x3a, 0xa4, 0xe0, 0x2f, 0xd4, 0xe7, 0xea, 0xf4, 0xf8, 0x98, 0xda, + 0x86, 0xf8, 0x23, 0x2c, 0xf4, 0xf5, 0x3a, 0x75, 0x8f, 0xa9, 0x6b, 0xd4, 0x4c, 0x97, 0x08, 0x57, + 0xc6, 0xe9, 0x66, 0x8d, 0x78, 0xe6, 0xa6, 0xd1, 0x36, 0x9b, 0x2d, 0xdb, 0xf4, 0x5a, 0xc1, 0xda, + 0xf9, 0x26, 0x6d, 0x52, 0xfe, 0xd3, 0x60, 0xbf, 0xe4, 0xe8, 0x72, 0x93, 0xd2, 0xa6, 0x45, 0x0c, + 0xb3, 0xdd, 0x32, 0x4c, 0xdb, 0xa6, 0x1e, 0x37, 0x71, 0xe5, 0xec, 0x42, 0x80, 0xb3, 0x66, 0x5a, + 0x16, 0xf5, 0x7c, 0x57, 0xdd, 0x61, 0xcb, 0x3c, 0x26, 0x72, 0x74, 0x35, 0x18, 0xad, 0x3b, 0xd4, + 0x75, 0x39, 0x91, 0xea, 0xa1, 0x65, 0x36, 0xfb, 0xbd, 0x7d, 0x4a, 0x3a, 0x4d, 0xe2, 0x03, 0x5b, + 0x0a, 0x86, 0x6d, 0xda, 0x20, 0x55, 0xb3, 0x5e, 0xa7, 0x27, 0xb6, 0xbf, 0xd5, 0xcd, 0x60, 0xd2, + 0xff, 0xd1, 0xe7, 0xac, 0x6d, 0x3a, 0xe6, 0xb1, 0xdc, 0x03, 0xff, 0x56, 0x83, 0xd9, 0xef, 0xb2, + 0x40, 0x3c, 0x77, 0xe8, 0x29, 0xa9, 0x90, 0xcf, 0x4e, 0x88, 0xeb, 0xa1, 0x5b, 0x70, 0x5d, 0xc0, + 0x69, 0x35, 0x16, 0xb5, 0x9c, 0x96, 0xbf, 0x5a, 0xb9, 0xc6, 0xbf, 0xf7, 0x1b, 0xe8, 0x26, 0x5c, + 0xf3, 0xce, 0xaa, 0x47, 0xa6, 0x7b, 0xb4, 0x38, 0x96, 0xd3, 0xf2, 0x13, 0x95, 0xb4, 0x77, 0xf6, + 0xd8, 0x74, 0x8f, 0xd0, 0x1a, 0x8c, 0xb7, 0x1d, 0x4a, 0x0f, 0x17, 0x53, 0x39, 0x2d, 0x9f, 0x29, + 0x4e, 0x15, 0x64, 0xe4, 0x9f, 0xb3, 0xc1, 0x8a, 0x98, 0x43, 0x2b, 0x00, 0x35, 0x8b, 0xd6, 0x3f, + 0x15, 0x0e, 0xae, 0x72, 0x07, 0x13, 0x7c, 0x84, 0xfb, 0xb8, 0x05, 0xd7, 0xbd, 0xb3, 0x6a, 0xcb, + 0x6e, 0x90, 0xb3, 0xc5, 0xf1, 0x9c, 0x96, 0x4f, 0x55, 0xae, 0x79, 0x67, 0xfb, 0xec, 0x13, 0xaf, + 0x03, 0x52, 0x71, 0xba, 0x6d, 0x6a, 0xbb, 0x04, 0xcd, 0xc3, 0xf8, 0xa9, 0x69, 0x49, 0x94, 0xd7, + 0x2b, 0xe2, 0x03, 0xcf, 0xfb, 0x6b, 0x39, 0x53, 0x49, 0x0a, 0xff, 0x10, 0xe6, 0x7a, 0x46, 0xa5, + 0x8b, 0x12, 0xa4, 0x45, 0x44, 0xb8, 0x8f, 0x4c, 0x71, 0xad, 0x30, 0xe0, 0x5a, 0x15, 0x84, 0x71, + 0xf9, 0xea, 0x57, 0xff, 0x59, 0xbd, 0x52, 0x91, 0x86, 0xf8, 0x43, 0xc8, 0x72, 0xcf, 0x65, 0x7e, + 0xe8, 0xe5, 0xce, 0x7e, 0x83, 0xd8, 0x5e, 0xeb, 0xb0, 0x45, 0x1c, 0x3f, 0xa0, 0x1b, 0x30, 0x2b, + 0x6e, 0x44, 0xb5, 0x15, 0xcc, 0xf1, 0xfd, 0x26, 0x2a, 0x33, 0x62, 0xa2, 0x6b, 0x83, 0x3d, 0x98, + 0xf8, 0x98, 0x7a, 0xc4, 0x79, 0xda, 0x72, 0x3d, 0xb4, 0x06, 0x53, 0xa7, 0xec, 0xa3, 0x6a, 0x36, + 0x1a, 0x0e, 0x71, 0x5d, 0x69, 0x35, 0xc9, 0x07, 0x4b, 0x62, 0x0c, 0x95, 0x61, 0x82, 0x7d, 0x57, + 0xbd, 0x4e, 0x9b, 0xf0, 0x63, 0xb9, 0x51, 0xbc, 0x3d, 0x90, 0x06, 0xf3, 0xff, 0xbd, 0x4e, 0x9b, + 0x54, 0xae, 0x9f, 0xca, 0x5f, 0xf8, 0x0f, 0x63, 0xb0, 0x1a, 0xcb, 0x42, 0xc6, 0x6a, 0x14, 0x1a, + 0x68, 0x07, 0xd2, 0x1c, 0xa4, 0xbb, 0x38, 0x96, 0x4b, 0xe5, 0x33, 0xc5, 0x3b, 0x43, 0x11, 0x71, + 0xc6, 0x15, 0x69, 0x85, 0x7e, 0x00, 0x33, 0x62, 0x96, 0x3f, 0x31, 0xc1, 0x2d, 0xc5, 0xb9, 0xdd, + 0x1b, 0xe8, 0xe9, 0xa3, 0xae, 0x11, 0xa7, 0x38, 0x4d, 0x7b, 0x07, 0xd0, 0x33, 0x98, 0x92, 0x2c, + 0x5c, 0xcf, 0xf4, 0x4e, 0x5c, 0x7e, 0x0f, 0x6f, 0x14, 0xef, 0x0e, 0xf4, 0x2a, 0xa2, 0x72, 0xc0, + 0x0d, 0x2a, 0x93, 0x35, 0xe5, 0x0b, 0x3f, 0x81, 0x65, 0x1e, 0xb8, 0x8f, 0xe4, 0x5a, 0xb7, 0xdc, + 0xd9, 0x65, 0x5e, 0x94, 0xc3, 0x57, 0x89, 0xf0, 0x1d, 0xfc, 0xa8, 0x29, 0x13, 0xdc, 0x06, 0x6f, + 0xc3, 0x4a, 0x8c, 0x33, 0x79, 0x06, 0xcb, 0x30, 0xe1, 0x83, 0x62, 0x97, 0x21, 0xc5, 0x5e, 0x50, + 0x30, 0x80, 0x73, 0xf2, 0x2a, 0x96, 0x2c, 0xcb, 0xf7, 0xf0, 0xa1, 0xd9, 0x6e, 0x13, 0x27, 0x78, + 0x06, 0x1d, 0x79, 0xcc, 0x51, 0x2b, 0xe4, 0x16, 0x1f, 0xfb, 0x91, 0x27, 0x4e, 0xf5, 0x58, 0xcc, + 0xf1, 0x9d, 0x32, 0xc5, 0x8d, 0x04, 0x91, 0xf7, 0xfd, 0xf9, 0x81, 0x0f, 0xfc, 0xe3, 0xd7, 0x60, + 0x9e, 0x6f, 0x7d, 0x70, 0xd2, 0x6e, 0x53, 0xc7, 0x23, 0x0d, 0xce, 0xcc, 0xc5, 0xef, 0xcb, 0x00, + 0x86, 0xc6, 0x03, 0x3c, 0xb7, 0x21, 0xcd, 0xb7, 0xf4, 0x51, 0x04, 0xb9, 0x45, 0x44, 0x46, 0x4e, + 0xe2, 0x1d, 0xf8, 0x16, 0x77, 0xb3, 0x47, 0xbc, 0x5d, 0xea, 0x10, 0xf1, 0x54, 0x1f, 0x51, 0xa7, + 0xe7, 0x30, 0xc2, 0xa9, 0x2d, 0x15, 0xa4, 0x36, 0x6c, 0x03, 0x1e, 0x64, 0x2f, 0xc1, 0x3c, 0x86, + 0x0c, 0x63, 0x5d, 0xed, 0x49, 0x1a, 0xaf, 0x0f, 0x8c, 0x4b, 0xd7, 0x5b, 0x05, 0xea, 0xc1, 0x6f, + 0xbc, 0x04, 0xb7, 0xfa, 0xf7, 0xf3, 0x8f, 0xe9, 0x13, 0xd0, 0xa3, 0x26, 0x25, 0x88, 0xa7, 0x51, + 0x20, 0x36, 0x12, 0x82, 0xe0, 0xaf, 0x4c, 0x05, 0x52, 0xec, 0xee, 0xf5, 0x8c, 0x36, 0x48, 0x49, + 0x54, 0x14, 0x3f, 0x62, 0xf3, 0x30, 0x2e, 0x32, 0xb2, 0xb8, 0xb2, 0xe2, 0x03, 0x7f, 0x02, 0x4b, + 0x91, 0x36, 0x12, 0xe0, 0x13, 0x98, 0x54, 0xab, 0x93, 0x44, 0x98, 0x1f, 0x88, 0x50, 0xf5, 0x93, + 0xb1, 0xbb, 0x1f, 0xb8, 0x21, 0xf1, 0x95, 0x2c, 0x2b, 0x02, 0xdf, 0x23, 0x80, 0x6e, 0xf1, 0x96, + 0x1b, 0xdd, 0x29, 0x88, 0x4a, 0x5f, 0x60, 0x95, 0xbe, 0x20, 0x9a, 0x06, 0x59, 0xe9, 0x0b, 0xcf, + 0xcd, 0xa6, 0x5f, 0xe8, 0x2a, 0x8a, 0x25, 0xfe, 0x52, 0x93, 0x94, 0xc2, 0xdb, 0x48, 0x4a, 0x1f, + 0x40, 0x46, 0x19, 0x96, 0x57, 0x71, 0x04, 0x46, 0xca, 0x07, 0xda, 0xeb, 0xc1, 0x3c, 0x26, 0xef, + 0xd0, 0x30, 0xcc, 0x02, 0x48, 0x0f, 0x68, 0xff, 0xbd, 0xb3, 0x6b, 0x12, 0x74, 0x11, 0x8f, 0x58, + 0x13, 0xe1, 0x5f, 0xa4, 0x9f, 0x6b, 0xf2, 0xc1, 0x47, 0x2d, 0x91, 0xd4, 0x7e, 0x02, 0x33, 0xe1, + 0x1e, 0x44, 0x06, 0x72, 0x70, 0xaa, 0x0d, 0xf9, 0x93, 0x65, 0x71, 0xba, 0xde, 0x3b, 0x8c, 0x6f, + 0xc2, 0x82, 0x8f, 0xe0, 0x09, 0xef, 0x64, 0x7c, 0x6c, 0xdf, 0x87, 0xd7, 0xc2, 0x13, 0x12, 0xd1, + 0x16, 0xa4, 0x45, 0xd3, 0x93, 0xa8, 0x2a, 0x4b, 0x63, 0x69, 0x82, 0x57, 0x65, 0x0e, 0x3d, 0x38, + 0xa2, 0x9f, 0xfb, 0x39, 0x69, 0x57, 0xb9, 0x32, 0x2c, 0x26, 0xd9, 0xb8, 0x15, 0x12, 0xc0, 0x4f, + 0x61, 0xce, 0x32, 0x5d, 0xaf, 0x1a, 0x24, 0x42, 0xf5, 0x1e, 0x17, 0x06, 0xa2, 0x79, 0x6a, 0xba, + 0x5e, 0xaf, 0xd3, 0x59, 0x2b, 0x3c, 0x84, 0x3f, 0x90, 0x18, 0xcb, 0xac, 0x23, 0x8c, 0x6a, 0x19, + 0xee, 0xc2, 0x0c, 0xef, 0x16, 0xfb, 0x4b, 0xed, 0x34, 0x1f, 0x57, 0x1a, 0x86, 0xba, 0xdf, 0x7f, + 0xf4, 0xfb, 0x0a, 0x9a, 0x1c, 0x90, 0xce, 0xec, 0x43, 0x2a, 0x49, 0xe0, 0xc1, 0xf5, 0x8e, 0x2d, + 0x67, 0xbd, 0x19, 0xdb, 0xca, 0x3e, 0xa4, 0x78, 0xa5, 0xfb, 0x3a, 0xc4, 0x1c, 0xa9, 0x53, 0xa7, + 0x11, 0x5c, 0x33, 0x53, 0xe6, 0xf0, 0xbe, 0xe9, 0x18, 0x04, 0xa9, 0xd1, 0x11, 0x1c, 0x40, 0x4e, + 0xa5, 0xc9, 0xd3, 0x72, 0xc9, 0x6e, 0x3c, 0xa3, 0x76, 0x9d, 0x0c, 0x4f, 0xef, 0x2c, 0x8f, 0xd9, + 0x6c, 0x29, 0x7f, 0x6e, 0xa9, 0x8a, 0xf8, 0xc0, 0x87, 0xb2, 0x68, 0x44, 0x3b, 0x7d, 0x75, 0xe0, + 0x95, 0x1c, 0x56, 0xe6, 0xfd, 0x2e, 0x31, 0x1b, 0xdd, 0xc3, 0x7e, 0x55, 0x39, 0xec, 0x37, 0x9a, + 0x7a, 0x4a, 0xca, 0x36, 0x92, 0xc8, 0x03, 0x98, 0x92, 0xfd, 0x37, 0x1f, 0xf7, 0x0b, 0xea, 0x9c, + 0x5f, 0x50, 0x55, 0x9b, 0xc9, 0x5a, 0xf7, 0xc3, 0x7d, 0x75, 0x19, 0xab, 0x24, 0x4f, 0x71, 0x8f, + 0x78, 0xca, 0x6e, 0xe5, 0x0e, 0x13, 0x00, 0x7e, 0x38, 0x7a, 0x65, 0x02, 0x0b, 0xc7, 0xa4, 0x22, + 0x13, 0xf0, 0x8f, 0xbb, 0x85, 0x3e, 0xc2, 0x85, 0xa4, 0xfa, 0x16, 0x4c, 0xaa, 0x54, 0x65, 0x50, + 0x23, 0x99, 0x66, 0x14, 0xa6, 0xc5, 0xff, 0xe9, 0x30, 0xce, 0xbd, 0xa3, 0x2f, 0x34, 0x48, 0x8b, + 0x0a, 0x89, 0x8c, 0x81, 0x87, 0xdd, 0x2f, 0x36, 0xf4, 0x37, 0x93, 0x1b, 0x08, 0xbc, 0x78, 0xed, + 0x17, 0x7f, 0xff, 0xef, 0xaf, 0xc6, 0x56, 0xd0, 0x92, 0xc1, 0xd6, 0xbf, 0xc1, 0x4d, 0x8d, 0x90, + 0x68, 0x43, 0xff, 0xd0, 0x00, 0xf5, 0xf7, 0xe7, 0x68, 0x6b, 0xf8, 0x6e, 0xb1, 0xda, 0x44, 0x7f, + 0xf7, 0x72, 0xc6, 0x12, 0xf6, 0xfb, 0x1c, 0xf6, 0x7b, 0x68, 0x3b, 0x12, 0xb6, 0xec, 0xb3, 0x6b, + 0x1d, 0x25, 0x8b, 0x19, 0xe7, 0x7d, 0x1a, 0xe2, 0x02, 0xfd, 0x55, 0x83, 0x99, 0x70, 0xcb, 0x8b, + 0x1e, 0x0e, 0x47, 0x16, 0xd3, 0x73, 0xeb, 0xef, 0x5c, 0xc6, 0x54, 0x52, 0xda, 0xe5, 0x94, 0xb6, + 0xd1, 0x56, 0x24, 0xa5, 0xa0, 0xd7, 0x66, 0xac, 0xc4, 0xdc, 0x79, 0x5f, 0x7b, 0x7f, 0x81, 0xfe, + 0xac, 0x01, 0xea, 0x6f, 0xb1, 0x93, 0x9c, 0x54, 0x6c, 0xeb, 0x9e, 0xe4, 0xa4, 0xe2, 0xbb, 0x7a, + 0xbc, 0xc9, 0x69, 0x6d, 0xa0, 0xbb, 0x91, 0xb4, 0x4c, 0xcb, 0xaa, 0x86, 0x9b, 0x7e, 0xf4, 0x3b, + 0x0d, 0xa6, 0x43, 0x4d, 0x39, 0xda, 0x1c, 0x0e, 0x22, 0x64, 0xa2, 0x3f, 0x1c, 0xd9, 0x24, 0x00, + 0x7d, 0x8f, 0x83, 0xbe, 0x83, 0xbe, 0x1d, 0x09, 0xda, 0x0d, 0x61, 0xfb, 0xb7, 0x06, 0x0b, 0x91, + 0xdd, 0x3b, 0xda, 0x19, 0x0e, 0x61, 0x90, 0x6c, 0xd0, 0xdf, 0xbb, 0xb4, 0x7d, 0xa2, 0x4b, 0xd5, + 0x24, 0x5e, 0xb5, 0x6e, 0xb5, 0x88, 0xed, 0xc9, 0x96, 0xbe, 0x7a, 0x48, 0x1d, 0xff, 0x76, 0xf9, + 0x05, 0xed, 0x02, 0xfd, 0x5e, 0x83, 0xa9, 0x9e, 0x6d, 0xd0, 0x5b, 0x23, 0xe2, 0xf2, 0xf9, 0xbc, + 0x3d, 0xb2, 0x5d, 0xa2, 0x03, 0xe1, 0x3c, 0xba, 0xc2, 0x04, 0x7d, 0xa9, 0xf5, 0x34, 0xcd, 0x28, + 0xd9, 0xb6, 0xfd, 0x4d, 0xbe, 0xfe, 0x60, 0x74, 0x43, 0x09, 0xf8, 0x4d, 0x0e, 0x78, 0x1d, 0xe5, + 0x23, 0x01, 0x2b, 0x32, 0xc3, 0x38, 0xe7, 0xca, 0xe6, 0x82, 0xdd, 0xfa, 0x1b, 0x8a, 0xa7, 0x92, + 0x65, 0x25, 0xc1, 0x1d, 0x29, 0x4e, 0x92, 0xe0, 0x8e, 0x96, 0x1b, 0x38, 0xcf, 0x71, 0x63, 0x94, + 0x1b, 0x86, 0x1b, 0xfd, 0x51, 0x83, 0xe9, 0x50, 0x27, 0x9e, 0x24, 0xcf, 0xc4, 0x4a, 0x86, 0x24, + 0x79, 0x26, 0x5e, 0x4c, 0xe0, 0x37, 0x38, 0xf0, 0xd7, 0xd1, 0xed, 0x48, 0xe0, 0x61, 0x9d, 0x81, + 0x7e, 0xad, 0x41, 0x5a, 0xf4, 0xef, 0xa8, 0x98, 0x68, 0xdf, 0x1e, 0x09, 0xa1, 0xdf, 0x1f, 0xc9, + 0x26, 0x51, 0xad, 0x15, 0x2a, 0x02, 0xfd, 0x45, 0x83, 0xd9, 0x3e, 0x7d, 0x80, 0x12, 0x14, 0x96, + 0x38, 0xd9, 0xa1, 0x6f, 0x5d, 0xca, 0x56, 0x62, 0x7e, 0xc8, 0x31, 0xdf, 0x47, 0x9b, 0x2a, 0x66, + 0xdf, 0x8b, 0x92, 0x12, 0x8f, 0xe8, 0xe7, 0x21, 0xd1, 0x82, 0xfe, 0xa6, 0xc1, 0x6c, 0x9f, 0x36, + 0x48, 0xc2, 0x24, 0x4e, 0x9c, 0x24, 0x61, 0x12, 0x2b, 0x46, 0x86, 0xa4, 0x42, 0xd1, 0x68, 0x87, + 0x3b, 0x86, 0x90, 0x12, 0xba, 0x40, 0x7f, 0xd2, 0x00, 0xed, 0x11, 0x2f, 0x24, 0x37, 0x50, 0xb2, + 0xf7, 0x16, 0x21, 0x60, 0x92, 0x14, 0xa9, 0x18, 0x6d, 0x83, 0x8b, 0x9c, 0xd0, 0x3d, 0xb4, 0x1e, + 0x9b, 0x13, 0x59, 0x75, 0x15, 0x1c, 0x1c, 0x09, 0xf4, 0x1b, 0x0d, 0x16, 0xb8, 0x33, 0x37, 0x24, + 0x3a, 0xd0, 0x76, 0xe2, 0xd8, 0x46, 0x29, 0x20, 0x7d, 0xe7, 0xb2, 0xe6, 0x92, 0xcc, 0x63, 0x4e, + 0xa6, 0x8c, 0xbe, 0x33, 0xf8, 0x74, 0xc4, 0x13, 0x36, 0xed, 0x46, 0x95, 0xeb, 0x28, 0xa5, 0x4a, + 0x19, 0xe7, 0x7c, 0xe4, 0x82, 0xe5, 0xa5, 0xe0, 0x88, 0x14, 0x25, 0xf1, 0x76, 0xc2, 0x40, 0x87, + 0x45, 0x92, 0xfe, 0x60, 0x74, 0xc3, 0x11, 0x0f, 0x48, 0x51, 0x46, 0xe8, 0x5f, 0x1a, 0xcc, 0x47, + 0x09, 0x8c, 0x24, 0xe7, 0x33, 0x40, 0xdb, 0xe8, 0x3b, 0x97, 0x35, 0x97, 0x5c, 0xca, 0x9c, 0xcb, + 0xbb, 0xe8, 0x9d, 0x58, 0x2e, 0x2a, 0x0f, 0x76, 0x54, 0x4c, 0x44, 0xb1, 0x27, 0xe4, 0x0b, 0xaa, + 0x0b, 0xf4, 0x4b, 0x0d, 0xc6, 0xf9, 0x3f, 0x52, 0x50, 0x21, 0x81, 0x4e, 0x51, 0xfe, 0x33, 0xa4, + 0x1b, 0x89, 0xd7, 0x4b, 0xb8, 0x98, 0xc3, 0x5d, 0x46, 0x7a, 0xb4, 0xac, 0x61, 0x6b, 0xcb, 0xfb, + 0x5f, 0xbd, 0xc8, 0x6a, 0x5f, 0xbf, 0xc8, 0x6a, 0xdf, 0xbc, 0xc8, 0x6a, 0x5f, 0xbc, 0xcc, 0x5e, + 0xf9, 0xfa, 0x65, 0xf6, 0xca, 0x3f, 0x5f, 0x66, 0xaf, 0xfc, 0xc8, 0x68, 0xb6, 0xbc, 0xa3, 0x93, + 0x1a, 0x13, 0x6d, 0x91, 0x69, 0xef, 0xac, 0xeb, 0xca, 0xeb, 0xb4, 0x89, 0x5b, 0x4b, 0xf3, 0x7f, + 0x6b, 0xdd, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, 0xd9, 0x94, 0x6c, 0x32, 0x1c, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1784,6 +1888,8 @@ type QueryClient interface { BlameByIdentifier(ctx context.Context, in *QueryBlameByIdentifierRequest, opts ...grpc.CallOption) (*QueryBlameByIdentifierResponse, error) // Queries a list of VoterByIdentifier items. GetAllBlameRecords(ctx context.Context, in *QueryAllBlameRecordsRequest, opts ...grpc.CallOption) (*QueryAllBlameRecordsResponse, error) + // Queries a list of VoterByIdentifier items. + BlamesByChainAndNonce(ctx context.Context, in *QueryBlameByChainAndNonceRequest, opts ...grpc.CallOption) (*QueryBlameByChainAndNonceResponse, error) GetAllBlockHeaders(ctx context.Context, in *QueryAllBlockHeaderRequest, opts ...grpc.CallOption) (*QueryAllBlockHeaderResponse, error) GetBlockHeaderByHash(ctx context.Context, in *QueryGetBlockHeaderByHashRequest, opts ...grpc.CallOption) (*QueryGetBlockHeaderByHashResponse, error) // merkle proof verification @@ -1924,6 +2030,15 @@ func (c *queryClient) GetAllBlameRecords(ctx context.Context, in *QueryAllBlameR return out, nil } +func (c *queryClient) BlamesByChainAndNonce(ctx context.Context, in *QueryBlameByChainAndNonceRequest, opts ...grpc.CallOption) (*QueryBlameByChainAndNonceResponse, error) { + out := new(QueryBlameByChainAndNonceResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/BlamesByChainAndNonce", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) GetAllBlockHeaders(ctx context.Context, in *QueryAllBlockHeaderRequest, opts ...grpc.CallOption) (*QueryAllBlockHeaderResponse, error) { out := new(QueryAllBlockHeaderResponse) err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/GetAllBlockHeaders", in, out, opts...) @@ -1978,6 +2093,8 @@ type QueryServer interface { BlameByIdentifier(context.Context, *QueryBlameByIdentifierRequest) (*QueryBlameByIdentifierResponse, error) // Queries a list of VoterByIdentifier items. GetAllBlameRecords(context.Context, *QueryAllBlameRecordsRequest) (*QueryAllBlameRecordsResponse, error) + // Queries a list of VoterByIdentifier items. + BlamesByChainAndNonce(context.Context, *QueryBlameByChainAndNonceRequest) (*QueryBlameByChainAndNonceResponse, error) GetAllBlockHeaders(context.Context, *QueryAllBlockHeaderRequest) (*QueryAllBlockHeaderResponse, error) GetBlockHeaderByHash(context.Context, *QueryGetBlockHeaderByHashRequest) (*QueryGetBlockHeaderByHashResponse, error) // merkle proof verification @@ -2030,6 +2147,9 @@ func (*UnimplementedQueryServer) BlameByIdentifier(ctx context.Context, req *Que func (*UnimplementedQueryServer) GetAllBlameRecords(ctx context.Context, req *QueryAllBlameRecordsRequest) (*QueryAllBlameRecordsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetAllBlameRecords not implemented") } +func (*UnimplementedQueryServer) BlamesByChainAndNonce(ctx context.Context, req *QueryBlameByChainAndNonceRequest) (*QueryBlameByChainAndNonceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BlamesByChainAndNonce not implemented") +} func (*UnimplementedQueryServer) GetAllBlockHeaders(ctx context.Context, req *QueryAllBlockHeaderRequest) (*QueryAllBlockHeaderResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetAllBlockHeaders not implemented") } @@ -2296,6 +2416,24 @@ func _Query_GetAllBlameRecords_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Query_BlamesByChainAndNonce_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryBlameByChainAndNonceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).BlamesByChainAndNonce(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.observer.Query/BlamesByChainAndNonce", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).BlamesByChainAndNonce(ctx, req.(*QueryBlameByChainAndNonceRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_GetAllBlockHeaders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryAllBlockHeaderRequest) if err := dec(in); err != nil { @@ -2410,6 +2548,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "GetAllBlameRecords", Handler: _Query_GetAllBlameRecords_Handler, }, + { + MethodName: "BlamesByChainAndNonce", + Handler: _Query_BlamesByChainAndNonce_Handler, + }, { MethodName: "GetAllBlockHeaders", Handler: _Query_GetAllBlockHeaders_Handler, @@ -3443,6 +3585,76 @@ func (m *QueryAllBlameRecordsResponse) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } +func (m *QueryBlameByChainAndNonceRequest) 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 *QueryBlameByChainAndNonceRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryBlameByChainAndNonceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Nonce != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Nonce)) + i-- + dAtA[i] = 0x10 + } + if m.ChainId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ChainId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryBlameByChainAndNonceResponse) 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 *QueryBlameByChainAndNonceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryBlameByChainAndNonceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.BlameInfo) > 0 { + for iNdEx := len(m.BlameInfo) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BlameInfo[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 *QueryAllBlockHeaderRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4011,6 +4223,36 @@ func (m *QueryAllBlameRecordsResponse) Size() (n int) { return n } +func (m *QueryBlameByChainAndNonceRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ChainId != 0 { + n += 1 + sovQuery(uint64(m.ChainId)) + } + if m.Nonce != 0 { + n += 1 + sovQuery(uint64(m.Nonce)) + } + return n +} + +func (m *QueryBlameByChainAndNonceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.BlameInfo) > 0 { + for _, e := range m.BlameInfo { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + func (m *QueryAllBlockHeaderRequest) Size() (n int) { if m == nil { return 0 @@ -6607,6 +6849,178 @@ func (m *QueryAllBlameRecordsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryBlameByChainAndNonceRequest) 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: QueryBlameByChainAndNonceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryBlameByChainAndNonceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + m.ChainId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Nonce", wireType) + } + m.Nonce = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Nonce |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryBlameByChainAndNonceResponse) 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: QueryBlameByChainAndNonceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryBlameByChainAndNonceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlameInfo", 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.BlameInfo = append(m.BlameInfo, &Blame{}) + if err := m.BlameInfo[len(m.BlameInfo)-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) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryAllBlockHeaderRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/observer/types/query.pb.gw.go b/x/observer/types/query.pb.gw.go index ecc350cdf6..232b97d9c7 100644 --- a/x/observer/types/query.pb.gw.go +++ b/x/observer/types/query.pb.gw.go @@ -483,6 +483,82 @@ func local_request_Query_GetAllBlameRecords_0(ctx context.Context, marshaler run } +func request_Query_BlamesByChainAndNonce_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryBlameByChainAndNonceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + val, ok = pathParams["nonce"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "nonce") + } + + protoReq.Nonce, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "nonce", err) + } + + msg, err := client.BlamesByChainAndNonce(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_BlamesByChainAndNonce_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryBlameByChainAndNonceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + val, ok = pathParams["nonce"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "nonce") + } + + protoReq.Nonce, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "nonce", err) + } + + msg, err := server.BlamesByChainAndNonce(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_Query_GetAllBlockHeaders_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -937,6 +1013,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_BlamesByChainAndNonce_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_BlamesByChainAndNonce_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_BlamesByChainAndNonce_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_GetAllBlockHeaders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1327,6 +1426,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_BlamesByChainAndNonce_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_BlamesByChainAndNonce_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_BlamesByChainAndNonce_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_GetAllBlockHeaders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1419,6 +1538,8 @@ var ( pattern_Query_GetAllBlameRecords_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "get_all_blame_records"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_BlamesByChainAndNonce_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"zeta-chain", "observer", "blame_by_chain_and_nonce", "chain_id", "nonce"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_GetAllBlockHeaders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "get_all_block_headers"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_GetBlockHeaderByHash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "observer", "get_block_header_by_hash", "block_hash"}, "", runtime.AssumeColonVerbOpt(false))) @@ -1455,6 +1576,8 @@ var ( forward_Query_GetAllBlameRecords_0 = runtime.ForwardResponseMessage + forward_Query_BlamesByChainAndNonce_0 = runtime.ForwardResponseMessage + forward_Query_GetAllBlockHeaders_0 = runtime.ForwardResponseMessage forward_Query_GetBlockHeaderByHash_0 = runtime.ForwardResponseMessage diff --git a/zetaclient/btc_signer.go b/zetaclient/btc_signer.go index a31f77bc85..625c4faef6 100644 --- a/zetaclient/btc_signer.go +++ b/zetaclient/btc_signer.go @@ -164,7 +164,7 @@ func (signer *BTCSigner) SignWithdrawTx(to *btcutil.AddressWitnessPubKeyHash, am if !ok { return nil, fmt.Errorf("tssSigner is not a TSS") } - sig65Bs, err := tss.SignBatch(witnessHashes, height, chain) + sig65Bs, err := tss.SignBatch(witnessHashes, height, nonce, chain) if err != nil { return nil, fmt.Errorf("SignBatch error: %v", err) } diff --git a/zetaclient/btc_test.go b/zetaclient/btc_test.go index cf6e2d8cd8..3144ffa927 100644 --- a/zetaclient/btc_test.go +++ b/zetaclient/btc_test.go @@ -146,7 +146,7 @@ func getTSSTX(tss *TestSigner, tx *wire.MsgTx, sigHashes *txscript.TxSigHashes, return "", err } - sig65B, err := tss.Sign(witnessHash, 10, &common.Chain{}, "") + sig65B, err := tss.Sign(witnessHash, 10, 10, &common.Chain{}, "") R := big.NewInt(0).SetBytes(sig65B[:32]) S := big.NewInt(0).SetBytes(sig65B[32:64]) sig := btcec.Signature{ diff --git a/zetaclient/evm_signer.go b/zetaclient/evm_signer.go index 3622a61ffd..a8c8c19292 100644 --- a/zetaclient/evm_signer.go +++ b/zetaclient/evm_signer.go @@ -84,7 +84,7 @@ func (signer *EVMSigner) Sign(data []byte, to ethcommon.Address, gasLimit uint64 tx := ethtypes.NewTransaction(nonce, to, big.NewInt(0), gasLimit, gasPrice, data) hashBytes := signer.ethSigner.Hash(tx).Bytes() - sig, err := signer.tssSigner.Sign(hashBytes, height, signer.chain, "") + sig, err := signer.tssSigner.Sign(hashBytes, height, nonce, signer.chain, "") if err != nil { return nil, nil, nil, err } @@ -178,7 +178,7 @@ func (signer *EVMSigner) SignRevertTx(sender ethcommon.Address, srcChainID *big. func (signer *EVMSigner) SignCancelTx(nonce uint64, gasPrice *big.Int, height uint64) (*ethtypes.Transaction, error) { tx := ethtypes.NewTransaction(nonce, signer.tssSigner.EVMAddress(), big.NewInt(0), 21000, gasPrice, nil) hashBytes := signer.ethSigner.Hash(tx).Bytes() - sig, err := signer.tssSigner.Sign(hashBytes, height, signer.chain, "") + sig, err := signer.tssSigner.Sign(hashBytes, height, nonce, signer.chain, "") if err != nil { return nil, err } @@ -199,7 +199,7 @@ func (signer *EVMSigner) SignCancelTx(nonce uint64, gasPrice *big.Int, height ui func (signer *EVMSigner) SignWithdrawTx(to ethcommon.Address, amount *big.Int, nonce uint64, gasPrice *big.Int, height uint64) (*ethtypes.Transaction, error) { tx := ethtypes.NewTransaction(nonce, to, amount, 21000, gasPrice, nil) hashBytes := signer.ethSigner.Hash(tx).Bytes() - sig, err := signer.tssSigner.Sign(hashBytes, height, signer.chain, "") + sig, err := signer.tssSigner.Sign(hashBytes, height, nonce, signer.chain, "") if err != nil { return nil, err } diff --git a/zetaclient/signer.go b/zetaclient/signer.go index c7ff9a87eb..5690a4693a 100644 --- a/zetaclient/signer.go +++ b/zetaclient/signer.go @@ -17,7 +17,7 @@ import ( type TSSSigner interface { Pubkey() []byte // Sign: Specify optionalPubkey to use a different pubkey than the current pubkey set during keygen - Sign(data []byte, height uint64, chain *common.Chain, optionalPubkey string) ([65]byte, error) + Sign(data []byte, height uint64, nonce uint64, chain *common.Chain, optionalPubkey string) ([65]byte, error) EVMAddress() ethcommon.Address BTCAddress() string BTCAddressWitnessPubkeyHash() *btcutil.AddressWitnessPubKeyHash @@ -31,7 +31,7 @@ type TestSigner struct { PrivKey *ecdsa.PrivateKey } -func (s TestSigner) Sign(digest []byte, _ uint64, _ *common.Chain, _ string) ([65]byte, error) { +func (s TestSigner) Sign(digest []byte, _ uint64, _ uint64, _ *common.Chain, _ string) ([65]byte, error) { sig, err := crypto.Sign(digest, s.PrivKey) if err != nil { return [65]byte{}, err diff --git a/zetaclient/tss_signer.go b/zetaclient/tss_signer.go index a52ea4adad..2302ad14e5 100644 --- a/zetaclient/tss_signer.go +++ b/zetaclient/tss_signer.go @@ -10,6 +10,8 @@ import ( "sort" "strings" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" + "github.com/zeta-chain/zetacore/zetaclient/metrics" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -94,7 +96,7 @@ func (tss *TSS) Pubkey() []byte { // digest should be Hashes of some data // Sign: Specify optionalPubkey to use a different pubkey than the current pubkey set during keygen -func (tss *TSS) Sign(digest []byte, height uint64, chain *common.Chain, optionalPubKey string) ([65]byte, error) { +func (tss *TSS) Sign(digest []byte, height uint64, nonce uint64, chain *common.Chain, optionalPubKey string) ([65]byte, error) { H := digest log.Debug().Msgf("hash of digest is %s", H) @@ -112,7 +114,7 @@ func (tss *TSS) Sign(digest []byte, height uint64, chain *common.Chain, optional log.Warn().Msgf("keysign status FAIL posting blame to core, blaming node(s): %#v", ksRes.Blame.BlameNodes) digest := hex.EncodeToString(digest) - index := fmt.Sprintf("%s-%d", digest, height) + index := observertypes.GetBlameIndex(chain.ChainId, nonce, digest, height) zetaHash, err := tss.CoreBridge.PostBlameData(&ksRes.Blame, chain.ChainId, index) if err != nil { @@ -167,7 +169,7 @@ func (tss *TSS) Sign(digest []byte, height uint64, chain *common.Chain, optional } // digest should be batch of Hashes of some data -func (tss *TSS) SignBatch(digests [][]byte, height uint64, chain *common.Chain) ([][65]byte, error) { +func (tss *TSS) SignBatch(digests [][]byte, height uint64, nonce uint64, chain *common.Chain) ([][65]byte, error) { tssPubkey := tss.CurrentPubkey digestBase64 := make([]string, len(digests)) for i, digest := range digests { @@ -184,7 +186,7 @@ func (tss *TSS) SignBatch(digests [][]byte, height uint64, chain *common.Chain) if ksRes.Status == thorcommon.Fail { log.Warn().Msg("keysign status FAIL posting blame to core") digest := combineDigests(digestBase64) - index := fmt.Sprintf("%s-%d", hex.EncodeToString(digest), height) + index := observertypes.GetBlameIndex(chain.ChainId, nonce, hex.EncodeToString(digest), height) zetaHash, err := tss.CoreBridge.PostBlameData(&ksRes.Blame, chain.ChainId, index) if err != nil { From f51f6e0cd34248f1fb160e4367a1b60dda9ae879 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Wed, 11 Oct 2023 11:40:40 -0500 Subject: [PATCH 2/2] fix: feed sataoshi/B to zetacore and check actual outTx size (#1243) * feed sataoshi/B to zetacore and check size limit * removed fee cap * replaced magic number 1000 with constant bytesPerKB * put lowerbound, upperbound limit on sizeLimit * use actual txSize for fee calculation --------- Co-authored-by: charliec --- zetaclient/bitcoin_client.go | 7 +++--- zetaclient/btc_signer.go | 43 +++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 72bce508cb..943ae8710b 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -73,6 +73,7 @@ const ( minConfirmations = 0 maxHeightDiff = 10000 dustOffset = 2000 + bytesPerKB = 1000 ) func (ob *BitcoinChainClient) SetCoreParams(params observertypes.CoreParams) { @@ -459,14 +460,14 @@ func (ob *BitcoinChainClient) PostGasPrice() error { if feeResult.Errors != nil || feeResult.FeeRate == nil { return fmt.Errorf("error getting gas price: %s", feeResult.Errors) } - gasPrice := big.NewFloat(0) - gasPriceU64, _ := gasPrice.Mul(big.NewFloat(*feeResult.FeeRate), big.NewFloat(1e8)).Uint64() + feeRate := new(big.Int).SetInt64(int64(*feeResult.FeeRate * 1e8)) + feeRatePerByte := new(big.Int).Div(feeRate, big.NewInt(bytesPerKB)) bn, err := ob.rpcClient.GetBlockCount() if err != nil { return err } // #nosec G701 always positive - zetaHash, err := ob.zetaClient.PostGasPrice(ob.chain, gasPriceU64, "100", uint64(bn)) + zetaHash, err := ob.zetaClient.PostGasPrice(ob.chain, feeRatePerByte.Uint64(), "100", uint64(bn)) if err != nil { ob.logger.WatchGasPrice.Err(err).Msg("PostGasPrice:") return err diff --git a/zetaclient/btc_signer.go b/zetaclient/btc_signer.go index 625c4faef6..07cf24df92 100644 --- a/zetaclient/btc_signer.go +++ b/zetaclient/btc_signer.go @@ -23,6 +23,13 @@ import ( const ( maxNoOfInputsPerTx = 20 + outTxBytesMin = 400 // 500B is a conservative estimate for a 2-input, 3-output SegWit tx + outTxBytesMax = 4_000 // 4KB is a conservative estimate for a 21-input, 3-output SegWit tx + outTxBytesCap = 10_000 // in case of accident + + // for ZRC20 configuration + bytesPerInput = 150 // each input is about 150 bytes + ZRC20GasLimit = outTxBytesMin + bytesPerInput*8 // 1600B a suggested ZRC20 GAS_LIMIT for a 10-input, 3-output SegWit tx ) type BTCSigner struct { @@ -59,9 +66,9 @@ func NewBTCSigner(cfg config.BTCConfig, tssSigner TSSSigner, logger zerolog.Logg } // SignWithdrawTx receives utxos sorted by value, amount in BTC, feeRate in BTC per Kb -func (signer *BTCSigner) SignWithdrawTx(to *btcutil.AddressWitnessPubKeyHash, amount float64, gasPrice *big.Int, btcClient *BitcoinChainClient, height uint64, nonce uint64, chain *common.Chain) (*wire.MsgTx, error) { - estimateFee := 0.0001 // 10,000 sats, should be good for testnet - minFee := 0.00005 +func (signer *BTCSigner) SignWithdrawTx(to *btcutil.AddressWitnessPubKeyHash, amount float64, gasPrice *big.Int, sizeLimit uint64, + btcClient *BitcoinChainClient, height uint64, nonce uint64, chain *common.Chain) (*wire.MsgTx, error) { + estimateFee := float64(gasPrice.Uint64()) * outTxBytesMax / 1e8 nonceMark := NonceMarkAmount(nonce) // refresh unspent UTXOs and continue with keysign regardless of error @@ -93,16 +100,25 @@ func (signer *BTCSigner) SignWithdrawTx(to *btcutil.AddressWitnessPubKeyHash, am return nil, err } - // fee checking - fees := new(big.Int).Mul(big.NewInt(int64(tx.SerializeSize())), gasPrice) - fees.Div(fees, big.NewInt(1000)) //FIXME: feeRate KB is 1000B or 1024B? - // #nosec G701 always in range - if fees.Int64() < int64(minFee*1e8) { - fmt.Printf("fees %d is less than minFee %f; use minFee", fees, minFee*1e8) - // #nosec G701 always in range - fees = big.NewInt(int64(minFee * 1e8)) + // size checking + txSize := uint64(tx.SerializeSize()) + if txSize > sizeLimit { // ZRC20 'withdraw' charged less fee from end user + signer.logger.Info().Msgf("sizeLimit %d is less than txSize %d for nonce %d", sizeLimit, txSize, nonce) + } + if txSize < outTxBytesMin { // outbound shouldn't be blocked a low sizeLimit + signer.logger.Warn().Msgf("sizeLimit %d is less than outTxBytesMin %d; use outTxBytesMin", sizeLimit, outTxBytesMin) + txSize = outTxBytesMin + } + if txSize > outTxBytesCap { // in case of accident + signer.logger.Warn().Msgf("sizeLimit %d is greater than outTxBytesCap %d; use outTxBytesCap", sizeLimit, outTxBytesCap) + txSize = outTxBytesCap } + // fee calculation + fees := new(big.Int).Mul(big.NewInt(int64(txSize)), gasPrice) + fees.Div(fees, big.NewInt(bytesPerKB)) + signer.logger.Info().Msgf("bitcoin outTx nonce %d gasPrice %s size %d fees %s", nonce, gasPrice.String(), txSize, fees.String()) + // calculate remaining btc to TSS self tssAddrWPKH := signer.tssSigner.BTCAddressWitnessPubkeyHash() payToSelf, err := payToWitnessPubKeyHashScript(tssAddrWPKH.WitnessProgram()) @@ -253,8 +269,9 @@ func (signer *BTCSigner) TryProcessOutTx(send *types.CrossChainTx, outTxMan *Out return } + sizelimit := params.OutboundTxGasLimit gasprice, ok := new(big.Int).SetString(params.OutboundTxGasPrice, 10) - if !ok { + if !ok || gasprice.Cmp(big.NewInt(0)) < 0 { logger.Error().Msgf("cannot convert gas price %s ", params.OutboundTxGasPrice) return } @@ -273,7 +290,7 @@ func (signer *BTCSigner) TryProcessOutTx(send *types.CrossChainTx, outTxMan *Out logger.Info().Msgf("SignWithdrawTx: to %s, value %d sats", addr.EncodeAddress(), params.Amount.Uint64()) logger.Info().Msgf("using utxos: %v", btcClient.utxos) - tx, err := signer.SignWithdrawTx(to, float64(params.Amount.Uint64())/1e8, gasprice, btcClient, height, + tx, err := signer.SignWithdrawTx(to, float64(params.Amount.Uint64())/1e8, gasprice, sizelimit, btcClient, height, outboundTxTssNonce, &btcClient.chain) if err != nil { logger.Warn().Err(err).Msgf("SignOutboundTx error: nonce %d chain %d", outboundTxTssNonce, params.ReceiverChainId)