diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d844156ac6..480bbd0dc67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ - [10211](https://github.com/vegaprotocol/vega/issues/10211) - Ensure infra fees don't get counted for vesting. - [10217](https://github.com/vegaprotocol/vega/issues/10217) - Game ID for reward entity should be optional - [10193](https://github.com/vegaprotocol/vega/issues/10193) - Denormalize `tx_results` to avoid joins with blocks when queried. +- [10215](https://github.com/vegaprotocol/vega/issues/10215) - Rework pagination to align with the natural reverse-chronological order of the block explorer. ## 0.73.0 diff --git a/blockexplorer/api/grpc/implementation.go b/blockexplorer/api/grpc/implementation.go index 812d0db190b..deef9753aa3 100644 --- a/blockexplorer/api/grpc/implementation.go +++ b/blockexplorer/api/grpc/implementation.go @@ -81,28 +81,12 @@ func (b *blockExplorerAPI) ListTransactions(ctx context.Context, req *pb.ListTra var before, after *entities.TxCursor var first, last uint32 - if req.First > 0 && req.Last > 0 { - return nil, apiError(codes.InvalidArgument, errors.New("cannot specify both first and last")) - } - - first = b.MaxPageSizeDefault - if req.First > 0 { - first = req.First - if req.After == nil && req.Before != nil { - return nil, apiError(codes.InvalidArgument, errors.New("cannot specify before when using first")) - } + if req.Before != nil && req.After != nil && (req.First > 0 || req.Last > 0) { + return nil, apiError(codes.InvalidArgument, errors.New("cannot use neither limits `first`, nor `last` when both cursors `before` and `after` are set")) } - if req.Last > 0 { - last = req.Last - if req.Before == nil && req.After != nil { - return nil, apiError(codes.InvalidArgument, errors.New("cannot specify after when using last")) - } - } - - // Temporary for now, until we have fully deprecated the limit field in the request. - if req.Limit > 0 && req.First == 0 && req.Last == 0 { - first = req.Limit + if req.First > 0 && req.Last > 0 { + return nil, apiError(codes.InvalidArgument, errors.New("cannot use both limits `first` and `last` within the same query")) } if req.Before != nil { @@ -111,6 +95,7 @@ func (b *blockExplorerAPI) ListTransactions(ctx context.Context, req *pb.ListTra return nil, apiError(codes.InvalidArgument, err) } before = &cursor + last = b.MaxPageSizeDefault } if req.After != nil { @@ -119,6 +104,37 @@ func (b *blockExplorerAPI) ListTransactions(ctx context.Context, req *pb.ListTra return nil, apiError(codes.InvalidArgument, err) } after = &cursor + first = b.MaxPageSizeDefault + } + + if before != nil && after != nil { + // The order of the parameters may seem odd, but this is expected as we have + // to keep in mind the natural order of the block-explorer is reverse-chronological. + // so, given transactions 4.2, 4.1, 3.2, 3.1, 2.2, when applying the window between + // 3.1 and 4.2, then we have to set after to 3.1 and before to 4.2. + // So effectively, after is the start and before is the end of the set. + if entities.AreValidCursorBoundaries(after, before) { + return nil, apiError(codes.InvalidArgument, errors.New("cursors `before` and `after` do not create a valid window")) + } + } + + if req.First > 0 { + if req.Before != nil { + return nil, apiError(codes.InvalidArgument, errors.New("cannot use cursor `before` when using limit `first`")) + } + first = req.First + } else if req.Last > 0 { + if req.After != nil { + return nil, apiError(codes.InvalidArgument, errors.New("cannot use cursor `after` when using limit `last`")) + } + last = req.Last + } + + // Entering this condition means there is no pagination set, so it defaults + // to listing the MaxPageSizeDefault newest transactions. + // Note, setting limits on a cursor window is not supported. + if !(before != nil && after != nil) && first == 0 && last == 0 { + first = b.MaxPageSizeDefault } transactions, err := b.store.ListTransactions(ctx, diff --git a/blockexplorer/entities/transaction.go b/blockexplorer/entities/transaction.go index 4979eb41d34..0b8652d5823 100644 --- a/blockexplorer/entities/transaction.go +++ b/blockexplorer/entities/transaction.go @@ -131,3 +131,13 @@ func TxCursorFromString(s string) (TxCursor, error) { func (c *TxCursor) String() string { return fmt.Sprintf("%d.%d", c.BlockNumber, c.TxIndex) } + +// AreValidCursorBoundaries checks if the start and end cursors creates valid +// set boundaries for cursors, as: [start, end] +func AreValidCursorBoundaries(start, end *TxCursor) bool { + if start.BlockNumber == end.BlockNumber { + return start.TxIndex < end.TxIndex + } + + return start.BlockNumber < end.BlockNumber +} diff --git a/blockexplorer/store/transactions.go b/blockexplorer/store/transactions.go index c4f88341024..9093f459409 100644 --- a/blockexplorer/store/transactions.go +++ b/blockexplorer/store/transactions.go @@ -71,33 +71,43 @@ func (s *Store) ListTransactions(ctx context.Context, args := []interface{}{} predicates := []string{} - // by default we want the most recent transactions so we'll set the limit to first - // and sort order to desc - limit := first + limit := uint32(0) + sortOrder := "desc" - // if we have a before cursor we want the results ordered earliest to latest - // so the limit will be set to last and sort order to asc + if first > 0 { + // We want the N most recent transactions, descending on block height and block + // index: 4.1, 3.2, 3.1, 2.2... + // The resulting query should already sort the rows in the right order. + limit = first + sortOrder = "desc" + } else if last > 0 { + // We want the N oldest transactions, ascending on block height and block + // index: 1.1, 1.2, 2.1, 2.2... + // The resulting query should sort the rows in the chronological order. But + // that's necessary to apply the LIMIT clause. It will be sorted in the + // reverse chronological order later on. + limit = last + sortOrder = "asc" + } + if before != nil { block := nextBindVar(&args, before.BlockNumber) index := nextBindVar(&args, before.TxIndex) - predicate := fmt.Sprintf("(t.block_height, t.index) > (%s, %s)", block, index) + predicate := fmt.Sprintf("(t.block_height, t.index) < (%s, %s)", block, index) predicates = append(predicates, predicate) - limit = last - sortOrder = "asc" + // We change the sorting order because we want the transactions right before + // the cursor, meaning older transactions. + sortOrder = "desc" } - if after != nil { block := nextBindVar(&args, after.BlockNumber) index := nextBindVar(&args, after.TxIndex) - predicate := fmt.Sprintf("(t.block_height, t.index) < (%s, %s)", block, index) + predicate := fmt.Sprintf("(t.block_height, t.index) > (%s, %s)", block, index) predicates = append(predicates, predicate) - } - - // just in case we have no before cursor, but we want to have the last N transactions in the data set - // i.e. the earliest transactions, sorting ascending - if last > 0 && first == 0 && after == nil && before == nil { - limit = last + // We change the sorting order because we want the transactions right after + // the cursor, meaning newer transaction. That's necessary to apply the + // LIMIT clause. sortOrder = "asc" } @@ -143,7 +153,9 @@ func (s *Store) ListTransactions(ctx context.Context, } query = fmt.Sprintf("%s ORDER BY t.block_height %s, t.index %s", query, sortOrder, sortOrder) - query = fmt.Sprintf("%s LIMIT %d", query, limit) + if limit != 0 { + query = fmt.Sprintf("%s LIMIT %d", query, limit) + } var rows []entities.TxResultRow if err := pgxscan.Select(ctx, s.pool, &rows, query, args...); err != nil { @@ -160,8 +172,10 @@ func (s *Store) ListTransactions(ctx context.Context, txs = append(txs, tx) } - // make sure the results are always order in the same direction, i.e. newest first, regardless of the order of the - // results from the database. + // Make sure the results are always order in the reverse chronological order, + // as required. + // This cannot be replaced by the `order by` in the request as it's used by the + // pagination system. sort.Slice(txs, func(i, j int) bool { if txs[i].Block == txs[j].Block { return txs[i].Index > txs[j].Index diff --git a/blockexplorer/store/transactions_test.go b/blockexplorer/store/transactions_test.go index 0b7ffa2bf80..3ad801ce779 100644 --- a/blockexplorer/store/transactions_test.go +++ b/blockexplorer/store/transactions_test.go @@ -123,8 +123,8 @@ func addTestTxResults(ctx context.Context, t *testing.T, txResults ...txResult) rows := make([]*pb.Transaction, 0, len(txResults)) blockIDs := make(map[int64]int64) - blockSQL := `insert into blocks (height, chain_id, created_at) values ($1, $2, $3) on conflict (height, chain_id) do update set created_at = EXCLUDED.created_at returning rowid` - resultSQL := `insert into tx_results (block_id, index, created_at, tx_hash, tx_result, submitter, cmd_type) values ($1, $2, $3, $4, $5, $6, $7) returning rowid` + blockSQL := `INSERT INTO blocks (height, chain_id, created_at) VALUES ($1, $2, $3) ON CONFLICT (height, chain_id) DO UPDATE SET created_at = EXCLUDED.created_at RETURNING rowid` + resultSQL := `INSERT INTO tx_results (block_id, index, created_at, tx_hash, tx_result, submitter, cmd_type) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING rowid` for _, txr := range txResults { var blockID int64 @@ -295,24 +295,39 @@ func TestStore_ListTransactions(t *testing.T) { }) t.Run("should return the transactions after the cursor when first is set", func(t *testing.T) { - first := entities.TxCursor{ - BlockNumber: 5, + after := entities.TxCursor{ + BlockNumber: 2, TxIndex: 1, } - got, err := s.ListTransactions(ctx, nil, nil, nil, nil, 2, &first, 0, nil) + got, err := s.ListTransactions(ctx, nil, nil, nil, nil, 2, &after, 0, nil) require.NoError(t, err) - want := []*pb.Transaction{inserted[7], inserted[6]} + want := []*pb.Transaction{inserted[5], inserted[4]} assert.Equal(t, want, got) }) t.Run("should return the transactions before the cursor when last is set", func(t *testing.T) { - first := entities.TxCursor{ + before := entities.TxCursor{ BlockNumber: 2, TxIndex: 1, } - got, err := s.ListTransactions(ctx, nil, nil, nil, nil, 2, &first, 0, nil) + got, err := s.ListTransactions(ctx, nil, nil, nil, nil, 0, nil, 2, &before) require.NoError(t, err) want := []*pb.Transaction{inserted[2], inserted[1]} assert.Equal(t, want, got) }) + + t.Run("should return the transactions before the cursor when last is set", func(t *testing.T) { + before := entities.TxCursor{ + BlockNumber: 5, + TxIndex: 1, + } + after := entities.TxCursor{ + BlockNumber: 2, + TxIndex: 2, + } + got, err := s.ListTransactions(ctx, nil, nil, nil, nil, 0, &after, 0, &before) + require.NoError(t, err) + want := []*pb.Transaction{inserted[7], inserted[6], inserted[5]} + assert.Equal(t, want, got) + }) } diff --git a/protos/blockexplorer/api/v1/blockexplorer.pb.go b/protos/blockexplorer/api/v1/blockexplorer.pb.go index c155bde9478..56fe26d1e31 100644 --- a/protos/blockexplorer/api/v1/blockexplorer.pb.go +++ b/protos/blockexplorer/api/v1/blockexplorer.pb.go @@ -220,14 +220,9 @@ type ListTransactionsRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Number of transactions to be returned from the blockchain. - // This is deprecated, use first and last instead. - // - // Deprecated: Do not use. - Limit uint32 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` - // Optional cursor to paginate the request + // Cursor to paginate the request. It can be used in conjunction with the `after` cursor. Before *string `protobuf:"bytes,2,opt,name=before,proto3,oneof" json:"before,omitempty"` - // Optional cursor to paginate the request + // Cursor to paginate the request. It can be used in conjunction with the `before` cursor. After *string `protobuf:"bytes,3,opt,name=after,proto3,oneof" json:"after,omitempty"` // Filters to apply to the request Filters map[string]string `protobuf:"bytes,4,rep,name=filters,proto3" json:"filters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` @@ -237,11 +232,17 @@ type ListTransactionsRequest struct { ExcludeCmdTypes []string `protobuf:"bytes,6,rep,name=exclude_cmd_types,json=excludeCmdTypes,proto3" json:"exclude_cmd_types,omitempty"` // Party IDs filter, can be sender or receiver Parties []string `protobuf:"bytes,7,rep,name=parties,proto3" json:"parties,omitempty"` - // Number of transactions to be returned from the blockchain. Use in conjunction with the `after` cursor to paginate forwards. - // On its own, this will return the first `first` transactions. + // Number of transactions to be returned from the blockchain. + // Use in conjunction with the `after` cursor to paginate forwards. Paginating forwards means toward the most recent + // transactions. + // It cannot be used in conjunction with the `before` cursor. + // On its own, this will return the `first` most recent transactions. First uint32 `protobuf:"varint,8,opt,name=first,proto3" json:"first,omitempty"` - // Number of transactions to be returned from the blockchain. Use in conjunction with the `before` cursor to paginate backwards. - // On its own, this will return the last `last` transactions. + // Number of transactions to be returned from the blockchain. + // Use in conjunction with the `before` cursor to paginate backwards. Paginating forwards means toward the least recent + // transactions. + // It cannot be used in conjunction with the `after` cursor. + // On its own, this will return the `last` oldest transactions. Last uint32 `protobuf:"varint,9,opt,name=last,proto3" json:"last,omitempty"` } @@ -277,14 +278,6 @@ func (*ListTransactionsRequest) Descriptor() ([]byte, []int) { return file_blockexplorer_api_v1_blockexplorer_proto_rawDescGZIP(), []int{4} } -// Deprecated: Do not use. -func (x *ListTransactionsRequest) GetLimit() uint32 { - if x != nil { - return x.Limit - } - return 0 -} - func (x *ListTransactionsRequest) GetBefore() string { if x != nil && x.Before != nil { return *x.Before @@ -577,97 +570,96 @@ var file_blockexplorer_api_v1_blockexplorer_proto_rawDesc = []byte{ 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0x9f, 0x03, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, + 0x69, 0x6f, 0x6e, 0x22, 0x8b, 0x03, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x18, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x02, - 0x18, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x62, 0x65, 0x66, - 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x62, 0x65, 0x66, - 0x6f, 0x72, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x88, 0x01, - 0x01, 0x12, 0x54, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, - 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6d, 0x64, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6d, 0x64, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, - 0x63, 0x6d, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x43, 0x6d, 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, - 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x07, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, - 0x72, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x69, 0x72, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, - 0x6c, 0x61, 0x73, 0x74, 0x1a, 0x3a, 0x0a, 0x0c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, - 0x61, 0x66, 0x74, 0x65, 0x72, 0x22, 0x61, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x45, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, - 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xc9, 0x03, 0x0a, 0x0b, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x14, - 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x75, 0x62, - 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, - 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x35, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, - 0x44, 0x61, 0x74, 0x61, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x39, 0x0a, - 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1b, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x41, 0x74, 0x12, 0x35, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x03, 0x70, 0x6f, 0x77, - 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4f, - 0x66, 0x57, 0x6f, 0x72, 0x6b, 0x52, 0x03, 0x70, 0x6f, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x32, 0xc9, 0x02, 0x0a, 0x14, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x78, - 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6d, 0x0a, - 0x0e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x2b, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x10, + 0x1b, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x05, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x54, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x2d, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2e, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x4d, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, - 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x62, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x0a, + 0x09, 0x63, 0x6d, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x6d, 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x78, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x63, 0x6d, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x43, 0x6d, + 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x72, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x66, 0x69, 0x72, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x1a, 0x3a, 0x0a, 0x0c, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x4a, 0x04, 0x08, 0x01, 0x10, + 0x02, 0x22, 0x61, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, + 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, + 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xc9, 0x03, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x68, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x74, 0x65, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x74, + 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x75, + 0x72, 0x73, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x75, 0x72, 0x73, + 0x6f, 0x72, 0x12, 0x35, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x44, 0x61, 0x74, 0x61, + 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, + 0x65, 0x67, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, + 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x35, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x1b, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x54, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x03, 0x70, 0x6f, 0x77, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4f, 0x66, 0x57, 0x6f, 0x72, + 0x6b, 0x52, 0x03, 0x70, 0x6f, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x32, 0xc9, 0x02, 0x0a, 0x14, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, + 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6d, 0x0a, 0x0e, 0x47, 0x65, 0x74, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2d, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x42, 0x7c, 0x5a, 0x35, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x65, 0x67, 0x61, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, - 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x92, 0x41, 0x42, 0x12, 0x27, 0x0a, 0x18, - 0x56, 0x65, 0x67, 0x61, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x65, 0x78, 0x70, 0x6c, 0x6f, - 0x72, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x73, 0x32, 0x0b, 0x76, 0x30, 0x2e, 0x37, 0x34, 0x2e, - 0x30, 0x2d, 0x64, 0x65, 0x76, 0x1a, 0x13, 0x6c, 0x62, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, - 0x74, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x2e, 0x78, 0x79, 0x7a, 0x2a, 0x02, 0x01, 0x02, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, + 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, + 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x7c, 0x5a, 0x35, + 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x65, 0x67, 0x61, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x65, 0x67, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, + 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x92, 0x41, 0x42, 0x12, 0x27, 0x0a, 0x18, 0x56, 0x65, 0x67, 0x61, + 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x20, + 0x41, 0x50, 0x49, 0x73, 0x32, 0x0b, 0x76, 0x30, 0x2e, 0x37, 0x34, 0x2e, 0x30, 0x2d, 0x64, 0x65, + 0x76, 0x1a, 0x13, 0x6c, 0x62, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x65, + 0x67, 0x61, 0x2e, 0x78, 0x79, 0x7a, 0x2a, 0x02, 0x01, 0x02, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/protos/blockexplorer/api/v1/blockexplorer_grpc.pb.go b/protos/blockexplorer/api/v1/blockexplorer_grpc.pb.go index 59b33c493c6..734a6b45219 100644 --- a/protos/blockexplorer/api/v1/blockexplorer_grpc.pb.go +++ b/protos/blockexplorer/api/v1/blockexplorer_grpc.pb.go @@ -28,7 +28,7 @@ type BlockExplorerServiceClient interface { GetTransaction(ctx context.Context, in *GetTransactionRequest, opts ...grpc.CallOption) (*GetTransactionResponse, error) // List transactions // - // List transactions from the Vega blockchain + // List transactions from the Vega blockchain from the newest to the oldest transactions. ListTransactions(ctx context.Context, in *ListTransactionsRequest, opts ...grpc.CallOption) (*ListTransactionsResponse, error) // Info // @@ -82,7 +82,7 @@ type BlockExplorerServiceServer interface { GetTransaction(context.Context, *GetTransactionRequest) (*GetTransactionResponse, error) // List transactions // - // List transactions from the Vega blockchain + // List transactions from the Vega blockchain from the newest to the oldest transactions. ListTransactions(context.Context, *ListTransactionsRequest) (*ListTransactionsResponse, error) // Info // diff --git a/protos/sources/blockexplorer/api/v1/blockexplorer.proto b/protos/sources/blockexplorer/api/v1/blockexplorer.proto index 88d8fe614e8..4d4cb369451 100644 --- a/protos/sources/blockexplorer/api/v1/blockexplorer.proto +++ b/protos/sources/blockexplorer/api/v1/blockexplorer.proto @@ -28,7 +28,7 @@ service BlockExplorerService { // List transactions // - // List transactions from the Vega blockchain + // List transactions from the Vega blockchain from the newest to the oldest transactions. rpc ListTransactions(ListTransactionsRequest) returns (ListTransactionsResponse) {} // Info @@ -59,12 +59,10 @@ message GetTransactionResponse { } message ListTransactionsRequest { - // Number of transactions to be returned from the blockchain. - // This is deprecated, use first and last instead. - uint32 limit = 1 [deprecated = true]; - // Optional cursor to paginate the request + reserved 1; + // Cursor to paginate the request. It can be used in conjunction with the `after` cursor. optional string before = 2; - // Optional cursor to paginate the request + // Cursor to paginate the request. It can be used in conjunction with the `before` cursor. optional string after = 3; // Filters to apply to the request map filters = 4; @@ -74,11 +72,17 @@ message ListTransactionsRequest { repeated string exclude_cmd_types = 6; // Party IDs filter, can be sender or receiver repeated string parties = 7; - // Number of transactions to be returned from the blockchain. Use in conjunction with the `after` cursor to paginate forwards. - // On its own, this will return the first `first` transactions. + // Number of transactions to be returned from the blockchain. + // Use in conjunction with the `after` cursor to paginate forwards. Paginating forwards means toward the most recent + // transactions. + // It cannot be used in conjunction with the `before` cursor. + // On its own, this will return the `first` most recent transactions. uint32 first = 8; - // Number of transactions to be returned from the blockchain. Use in conjunction with the `before` cursor to paginate backwards. - // On its own, this will return the last `last` transactions. + // Number of transactions to be returned from the blockchain. + // Use in conjunction with the `before` cursor to paginate backwards. Paginating forwards means toward the least recent + // transactions. + // It cannot be used in conjunction with the `after` cursor. + // On its own, this will return the `last` oldest transactions. uint32 last = 9; }