From abfe125743b5abdcd1d531ccd224bd0d1dcd09a2 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Sun, 17 Nov 2024 13:13:48 -0300 Subject: [PATCH 01/19] Implement `GET /v2/blocks` Currently using the exact same implementation as https://github.com/AlgoNode/indexer-api-cdb/pull/10 --- api/converter_utils.go | 233 ++++++++++++++ api/error_messages.go | 2 + api/generated/common/routes.go | 369 +++++++++++----------- api/generated/common/types.go | 26 ++ api/generated/v2/routes.go | 544 +++++++++++++++++++-------------- api/generated/v2/types.go | 62 ++++ api/handlers.go | 94 ++++++ api/indexer.oas2.json | 158 +++++++++- api/indexer.oas3.yml | 311 +++++++++++++++++++ api/server.go | 10 + cmd/algorand-indexer/daemon.go | 9 + idb/dummy/dummy.go | 5 + idb/idb.go | 45 +++ idb/postgres/postgres.go | 268 ++++++++++++++++ 14 files changed, 1722 insertions(+), 414 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index 8b4081acd..105321b0d 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -34,6 +34,15 @@ func decodeDigest(str *string, field string, errorArr []string) (string, []strin return "", errorArr } +// decodeSdkAddress returns the sdk.Address representation of the input string, or appends an error to errorArr +func decodeSdkAddress(str string, field string, errorArr []string) (sdk.Address, []string) { + addr, err := sdk.DecodeAddress(str) + if err != nil { + return sdk.ZeroAddress, append(errorArr, fmt.Sprintf("%s '%s': %v", errUnableToParseAddress, field, err)) + } + return addr, errorArr +} + // decodeAddress returns the byte representation of the input string, or appends an error to errorArr func decodeAddress(str *string, field string, errorArr []string) ([]byte, []string) { if str != nil { @@ -298,6 +307,94 @@ func txnRowToTransaction(row idb.TxnRow) (generated.Transaction, error) { return txn, nil } +func rowToBlock(blockHeader *sdk.BlockHeader) generated.Block { + + rewards := generated.BlockRewards{ + FeeSink: blockHeader.FeeSink.String(), + RewardsCalculationRound: uint64(blockHeader.RewardsRecalculationRound), + RewardsLevel: blockHeader.RewardsLevel, + RewardsPool: blockHeader.RewardsPool.String(), + RewardsRate: blockHeader.RewardsRate, + RewardsResidue: blockHeader.RewardsResidue, + } + + upgradeState := generated.BlockUpgradeState{ + CurrentProtocol: string(blockHeader.CurrentProtocol), + NextProtocol: strPtr(string(blockHeader.NextProtocol)), + NextProtocolApprovals: uint64Ptr(blockHeader.NextProtocolApprovals), + NextProtocolSwitchOn: uint64Ptr(uint64(blockHeader.NextProtocolSwitchOn)), + NextProtocolVoteBefore: uint64Ptr(uint64(blockHeader.NextProtocolVoteBefore)), + } + + upgradeVote := generated.BlockUpgradeVote{ + UpgradeApprove: boolPtr(blockHeader.UpgradeApprove), + UpgradeDelay: uint64Ptr(uint64(blockHeader.UpgradeDelay)), + UpgradePropose: strPtr(string(blockHeader.UpgradePropose)), + } + + var partUpdates *generated.ParticipationUpdates = &generated.ParticipationUpdates{} + if len(blockHeader.ExpiredParticipationAccounts) > 0 { + addrs := make([]string, len(blockHeader.ExpiredParticipationAccounts)) + for i := 0; i < len(addrs); i++ { + addrs[i] = blockHeader.ExpiredParticipationAccounts[i].String() + } + partUpdates.ExpiredParticipationAccounts = strArrayPtr(addrs) + } + if len(blockHeader.AbsentParticipationAccounts) > 0 { + addrs := make([]string, len(blockHeader.AbsentParticipationAccounts)) + for i := 0; i < len(addrs); i++ { + addrs[i] = blockHeader.AbsentParticipationAccounts[i].String() + } + partUpdates.AbsentParticipationAccounts = strArrayPtr(addrs) + } + if *partUpdates == (generated.ParticipationUpdates{}) { + partUpdates = nil + } + + // order these so they're deterministic + orderedTrackingTypes := make([]sdk.StateProofType, len(blockHeader.StateProofTracking)) + trackingArray := make([]generated.StateProofTracking, len(blockHeader.StateProofTracking)) + elems := 0 + for key := range blockHeader.StateProofTracking { + orderedTrackingTypes[elems] = key + elems++ + } + sort.Slice(orderedTrackingTypes, func(i, j int) bool { return orderedTrackingTypes[i] < orderedTrackingTypes[j] }) + for i := 0; i < len(orderedTrackingTypes); i++ { + stpfTracking := blockHeader.StateProofTracking[orderedTrackingTypes[i]] + thing1 := generated.StateProofTracking{ + NextRound: uint64Ptr(uint64(stpfTracking.StateProofNextRound)), + Type: uint64Ptr(uint64(orderedTrackingTypes[i])), + VotersCommitment: byteSliceOmitZeroPtr(stpfTracking.StateProofVotersCommitment), + OnlineTotalWeight: uint64Ptr(uint64(stpfTracking.StateProofOnlineTotalWeight)), + } + trackingArray[orderedTrackingTypes[i]] = thing1 + } + + ret := generated.Block{ + Bonus: uint64PtrOrNil(uint64(blockHeader.Bonus)), + FeesCollected: uint64PtrOrNil(uint64(blockHeader.FeesCollected)), + GenesisHash: blockHeader.GenesisHash[:], + GenesisId: blockHeader.GenesisID, + ParticipationUpdates: partUpdates, + PreviousBlockHash: blockHeader.Branch[:], + Proposer: addrPtr(blockHeader.Proposer), + ProposerPayout: uint64PtrOrNil(uint64(blockHeader.ProposerPayout)), + Rewards: &rewards, + Round: uint64(blockHeader.Round), + Seed: blockHeader.Seed[:], + StateProofTracking: &trackingArray, + Timestamp: uint64(blockHeader.TimeStamp), + Transactions: nil, + TransactionsRoot: blockHeader.TxnCommitments.NativeSha512_256Commitment[:], + TransactionsRootSha256: blockHeader.TxnCommitments.Sha256Commitment[:], + TxnCounter: uint64Ptr(blockHeader.TxnCounter), + UpgradeState: &upgradeState, + UpgradeVote: &upgradeVote, + } + return ret +} + func signedTxnWithAdToTransaction(stxn *sdk.SignedTxnWithAD, extra rowData) (generated.Transaction, error) { var payment *generated.TransactionPayment var keyreg *generated.TransactionKeyreg @@ -749,6 +846,142 @@ func (si *ServerImplementation) transactionParamsToTransactionFilter(params gene return } +func (si *ServerImplementation) blockParamsToBlockFilter(params generated.SearchForBlocksParams) (filter idb.BlockFilter, err error) { + var errorArr []string + + // Integer + filter.Limit = min(uintOrDefaultValue(params.Limit, si.opts.DefaultBlocksLimit), si.opts.MaxBlocksLimit) + // If min/max are mixed up + // + // This check is performed here instead of in validateBlockFilter because + // when converting params into a filter, the next token is merged with params.MinRound. + if params.MinRound != nil && params.MaxRound != nil && *params.MinRound > *params.MaxRound { + errorArr = append(errorArr, errInvalidRoundMinMax) + } + filter.MaxRound = params.MaxRound + filter.MinRound = params.MinRound + + // String + if params.Next != nil { + n, err := idb.DecodeBlockRowNext(*params.Next) + if err != nil { + errorArr = append(errorArr, fmt.Sprintf("%s: %v", errUnableToParseNext, err)) + } + // Set the MinRound + if filter.MinRound == nil { + filter.MinRound = uint64Ptr(n + 1) + } else { + filter.MinRound = uint64Ptr(max(*filter.MinRound, n+1)) + } + } + + // Time + if params.AfterTime != nil { + filter.AfterTime = *params.AfterTime + } + if params.BeforeTime != nil { + filter.BeforeTime = *params.BeforeTime + } + + // Address list + { + // Make sure at most one of the participation parameters is set + numParticipationFilters := 0 + if params.Proposer != nil { + numParticipationFilters++ + } + if params.Expired != nil { + numParticipationFilters++ + } + if params.Absent != nil { + numParticipationFilters++ + } + if params.Updates != nil { + numParticipationFilters++ + } + if params.Participation != nil { + numParticipationFilters++ + } + if numParticipationFilters > 1 { + errorArr = append(errorArr, "only one of `proposer`, `expired`, `absent`, `updates`, or `participation` can be specified") + } + + // Validate the number of items in the participation account lists + if params.Proposer != nil && uint64(len(*params.Proposer)) > si.opts.MaxAccountListSize { + errorArr = append(errorArr, fmt.Sprintf("proposer list too long, max size is %d", si.opts.MaxAccountListSize)) + } + if params.Expired != nil && uint64(len(*params.Expired)) > si.opts.MaxAccountListSize { + errorArr = append(errorArr, fmt.Sprintf("expired list too long, max size is %d", si.opts.MaxAccountListSize)) + } + if params.Absent != nil && uint64(len(*params.Absent)) > si.opts.MaxAccountListSize { + errorArr = append(errorArr, fmt.Sprintf("absent list too long, max size is %d", si.opts.MaxAccountListSize)) + } + if params.Updates != nil && uint64(len(*params.Updates)) > si.opts.MaxAccountListSize { + errorArr = append(errorArr, fmt.Sprintf("updates list too long, max size is %d", si.opts.MaxAccountListSize)) + } + if params.Participation != nil && uint64(len(*params.Participation)) > si.opts.MaxAccountListSize { + errorArr = append(errorArr, fmt.Sprintf("participation list too long, max size is %d", si.opts.MaxAccountListSize)) + } + + filter.Proposers = make(map[sdk.Address]struct{}, 0) + if params.Proposer != nil { + for _, s := range *params.Proposer { + var addr sdk.Address + addr, errorArr = decodeSdkAddress(s, "proposer", errorArr) + filter.Proposers[addr] = struct{}{} + } + } + + filter.ExpiredParticipationAccounts = make(map[sdk.Address]struct{}, 0) + if params.Expired != nil { + for _, s := range *params.Expired { + var addr sdk.Address + addr, errorArr = decodeSdkAddress(s, "expired", errorArr) + filter.ExpiredParticipationAccounts[addr] = struct{}{} + } + } + + filter.AbsentParticipationAccounts = make(map[sdk.Address]struct{}, 0) + if params.Absent != nil { + for _, s := range *params.Absent { + var addr sdk.Address + addr, errorArr = decodeSdkAddress(s, "absent", errorArr) + filter.AbsentParticipationAccounts[addr] = struct{}{} + } + } + + // Updates = absent || expired + if params.Updates != nil { + for _, s := range *params.Updates { + var addr sdk.Address + addr, errorArr = decodeSdkAddress(s, "updates", errorArr) + filter.AbsentParticipationAccounts[addr] = struct{}{} + filter.ExpiredParticipationAccounts[addr] = struct{}{} + } + } + + // Participation = proposer || absent || expired + if params.Participation != nil { + for _, s := range *params.Participation { + var addr sdk.Address + addr, errorArr = decodeSdkAddress(s, "participation", errorArr) + filter.Proposers[addr] = struct{}{} + filter.AbsentParticipationAccounts[addr] = struct{}{} + filter.ExpiredParticipationAccounts[addr] = struct{}{} + } + } + } + + // If there were any errorArr while setting up the BlockFilter, return now. + if len(errorArr) > 0 { + err = errors.New("invalid input: " + strings.Join(errorArr, ", ")) + + // clear out the intermediates. + filter = idb.BlockFilter{} + } + return +} + func (si *ServerImplementation) maxAccountsErrorToAccountsErrorResponse(maxErr idb.MaxAPIResourcesPerAccountError) generated.ErrorResponse { addr := maxErr.Address.String() max := uint64(si.opts.MaxAPIResourcesPerAccount) diff --git a/api/error_messages.go b/api/error_messages.go index a1bfbfbc2..cd364ab46 100644 --- a/api/error_messages.go +++ b/api/error_messages.go @@ -11,6 +11,7 @@ import ( const ( errInvalidRoundAndMinMax = "cannot specify round and min-round/max-round" errInvalidRoundMinMax = "min-round must be less than max-round" + errInvalidTimeMinMax = "after-time must be less than before-time" errUnableToParseAddress = "unable to parse address" errInvalidCreatorAddress = "found an invalid creator address" errUnableToParseBase64 = "unable to parse base64 data" @@ -38,6 +39,7 @@ const ( ErrFailedLookingUpBoxes = "failed while looking up application boxes" errRewindingAccountNotSupported = "rewinding account is no longer supported, please remove the `round=` query parameter and try again" errLookingUpBlockForRound = "error while looking up block for round" + errBlockHeaderSearch = "error while searching for block headers" errTransactionSearch = "error while searching for transaction" errZeroAddressCloseRemainderToRole = "searching transactions by zero address with close address role is not supported" errZeroAddressAssetSenderRole = "searching transactions by zero address with asset sender role is not supported" diff --git a/api/generated/common/routes.go b/api/generated/common/routes.go index bf1f44d7f..97e6bed82 100644 --- a/api/generated/common/routes.go +++ b/api/generated/common/routes.go @@ -72,189 +72,192 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "+ge3+k7gAAA=", + "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", + "6AAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/common/types.go b/api/generated/common/types.go index 3a0e083ca..b532222f5 100644 --- a/api/generated/common/types.go +++ b/api/generated/common/types.go @@ -1144,6 +1144,9 @@ type TransactionStateProof struct { StateProofType *uint64 `json:"state-proof-type,omitempty"` } +// Absent defines model for absent. +type Absent = []string + // AccountId defines model for account-id. type AccountId = string @@ -1183,6 +1186,9 @@ type Exclude = []string // ExcludeCloseTo defines model for exclude-close-to. type ExcludeCloseTo = bool +// Expired defines model for expired. +type Expired = []string + // HeaderOnly defines model for header-only. type HeaderOnly = bool @@ -1204,6 +1210,12 @@ type Next = string // NotePrefix defines model for note-prefix. type NotePrefix = string +// Participation defines model for participation. +type Participation = []string + +// Proposer defines model for proposer. +type Proposer = []string + // RekeyTo defines model for rekey-to. type RekeyTo = bool @@ -1225,6 +1237,9 @@ type TxType string // Txid defines model for txid. type Txid = string +// Updates defines model for updates. +type Updates = []string + // AccountResponse defines model for AccountResponse. type AccountResponse struct { // Account Account information at a given round. @@ -1340,6 +1355,17 @@ type AssetsResponse struct { // data/bookkeeping/block.go : Block type BlockResponse = Block +// BlocksResponse defines model for BlocksResponse. +type BlocksResponse struct { + Blocks []Block `json:"blocks"` + + // CurrentRound Round at which the results were computed. + CurrentRound uint64 `json:"current-round"` + + // NextToken Used for pagination, when making another request provide this token with the next parameter. + NextToken *string `json:"next-token,omitempty"` +} + // BoxResponse Box name and its content. type BoxResponse = Box diff --git a/api/generated/v2/routes.go b/api/generated/v2/routes.go index 6b9f38d0d..d787979a1 100644 --- a/api/generated/v2/routes.go +++ b/api/generated/v2/routes.go @@ -69,6 +69,9 @@ type ServerInterface interface { // (GET /v2/assets/{asset-id}/transactions) LookupAssetTransactions(ctx echo.Context, assetId uint64, params LookupAssetTransactionsParams) error + // (GET /v2/blocks) + SearchForBlocks(ctx echo.Context, params SearchForBlocksParams) error + // (GET /v2/blocks/{round-number}) LookupBlock(ctx echo.Context, roundNumber uint64, params LookupBlockParams) error @@ -974,6 +977,94 @@ func (w *ServerInterfaceWrapper) LookupAssetTransactions(ctx echo.Context) error return err } +// SearchForBlocks converts echo context to params. +func (w *ServerInterfaceWrapper) SearchForBlocks(ctx echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params SearchForBlocksParams + // ------------- Optional query parameter "limit" ------------- + + err = runtime.BindQueryParameter("form", true, false, "limit", ctx.QueryParams(), ¶ms.Limit) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter limit: %s", err)) + } + + // ------------- Optional query parameter "next" ------------- + + err = runtime.BindQueryParameter("form", true, false, "next", ctx.QueryParams(), ¶ms.Next) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter next: %s", err)) + } + + // ------------- Optional query parameter "min-round" ------------- + + err = runtime.BindQueryParameter("form", true, false, "min-round", ctx.QueryParams(), ¶ms.MinRound) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter min-round: %s", err)) + } + + // ------------- Optional query parameter "max-round" ------------- + + err = runtime.BindQueryParameter("form", true, false, "max-round", ctx.QueryParams(), ¶ms.MaxRound) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter max-round: %s", err)) + } + + // ------------- Optional query parameter "before-time" ------------- + + err = runtime.BindQueryParameter("form", true, false, "before-time", ctx.QueryParams(), ¶ms.BeforeTime) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter before-time: %s", err)) + } + + // ------------- Optional query parameter "after-time" ------------- + + err = runtime.BindQueryParameter("form", true, false, "after-time", ctx.QueryParams(), ¶ms.AfterTime) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter after-time: %s", err)) + } + + // ------------- Optional query parameter "proposer" ------------- + + err = runtime.BindQueryParameter("form", false, false, "proposer", ctx.QueryParams(), ¶ms.Proposer) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter proposer: %s", err)) + } + + // ------------- Optional query parameter "expired" ------------- + + err = runtime.BindQueryParameter("form", false, false, "expired", ctx.QueryParams(), ¶ms.Expired) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter expired: %s", err)) + } + + // ------------- Optional query parameter "absent" ------------- + + err = runtime.BindQueryParameter("form", false, false, "absent", ctx.QueryParams(), ¶ms.Absent) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter absent: %s", err)) + } + + // ------------- Optional query parameter "updates" ------------- + + err = runtime.BindQueryParameter("form", false, false, "updates", ctx.QueryParams(), ¶ms.Updates) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter updates: %s", err)) + } + + // ------------- Optional query parameter "participation" ------------- + + err = runtime.BindQueryParameter("form", false, false, "participation", ctx.QueryParams(), ¶ms.Participation) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter participation: %s", err)) + } + + // Invoke the callback with all the unmarshalled arguments + err = w.Handler.SearchForBlocks(ctx, params) + return err +} + // LookupBlock converts echo context to params. func (w *ServerInterfaceWrapper) LookupBlock(ctx echo.Context) error { var err error @@ -1203,6 +1294,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL router.GET(baseURL+"/v2/assets/:asset-id", wrapper.LookupAssetByID, m...) router.GET(baseURL+"/v2/assets/:asset-id/balances", wrapper.LookupAssetBalances, m...) router.GET(baseURL+"/v2/assets/:asset-id/transactions", wrapper.LookupAssetTransactions, m...) + router.GET(baseURL+"/v2/blocks", wrapper.SearchForBlocks, m...) router.GET(baseURL+"/v2/blocks/:round-number", wrapper.LookupBlock, m...) router.GET(baseURL+"/v2/transactions", wrapper.SearchForTransactions, m...) router.GET(baseURL+"/v2/transactions/:txid", wrapper.LookupTransaction, m...) @@ -1212,229 +1304,235 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "lrsEplHBUCfD7ulxPOC1avkiYIHke/RC2D+7HX2PFvGo89WCm6H57LfJ/UcLnsK/TuFfJ9H0Pr0H4JDP", - "//DXc7/HAFzzMUnObcPx0mRcsfzkK3CnvgJA5sbSwntMKg1TnsjNSZn3abs6dCnm+YyWVORsr0YOWW9t", - "QA3t6/aslxIIisuHDwRmJ0X1k51ko5NsdCpddwpsGhvYdDSm67jcSEw8R0lpr7ngp2ydqVdv1jwNJ5Ht", - "z8SAHJLqomWeAF2so0+78l1glgv7pGLmi50y3ynbxSnbxSnbxSnbxSnbxcexRp/yUpzyUpzEt3/vvBRj", - "PE6cEdMCKgVDV+ZWY3z+B7mQu3ZC6S3qmVzNuGCNAORX0BQLNdIeFDRaUhPeYd/QSKKDl8GedWVKlgPv", - "KzjhgFCcM34N/50rxn5nmaHKMtdj3tvWajyAUBozmj+ujXnQ2ixTjAo34vOBaFdGVa0gDa0JuWoJJX4l", - "U8snb2VN1nBZSn4F/V1dTbvpKyjI2qnRaiQxqh40TrvuGcCzN/PI9D4MQKckKqckKqckKn8CbcislPmV", - "Pv8DjjpDPcJeIzZ0GlJiPLUf9yku8DLidOm0UDFAtyRqPzBaMEWkffTnJV2ckX/Yywm3D1xLjafQ00Zn", - "A2skhWSoC3EKgC4PoAfo3xKmzOyUd0sCd0arwEmcAsM/4+s5SjUZeYaOzcDb1Uh6dj3NNnIN7HiXaQ9i", - "4mG5fYOX6knTedJ0njSdJ03nSdN5yut70p+e9Kcn/elJf3rSn570p3euP/2YOs+7rxV60qqetKontc1H", - "DQuKj/b8DysT7Q8MIlZ8LFsv5JCKNca6MdFBTii7vxxq90hCou066LKOv5ynGJoTeflUtMIfphPN1LW/", - "67UqJxeTpTGVvjg/Zxu6qkp2lsvVOSSpcP3/CHy/XK3goQq/uJGjXxwps903mVTcvr1lptd0sWAqszMj", - "zI/PHk0+/J8AAAD//3BbS4jifQEA", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/v2/types.go b/api/generated/v2/types.go index 36d8da56d..63dc39fe3 100644 --- a/api/generated/v2/types.go +++ b/api/generated/v2/types.go @@ -1232,6 +1232,9 @@ type TransactionStateProof struct { StateProofType *uint64 `json:"state-proof-type,omitempty"` } +// Absent defines model for absent. +type Absent = []string + // AccountId defines model for account-id. type AccountId = string @@ -1271,6 +1274,9 @@ type Exclude = []string // ExcludeCloseTo defines model for exclude-close-to. type ExcludeCloseTo = bool +// Expired defines model for expired. +type Expired = []string + // HeaderOnly defines model for header-only. type HeaderOnly = bool @@ -1292,6 +1298,12 @@ type Next = string // NotePrefix defines model for note-prefix. type NotePrefix = string +// Participation defines model for participation. +type Participation = []string + +// Proposer defines model for proposer. +type Proposer = []string + // RekeyTo defines model for rekey-to. type RekeyTo = bool @@ -1313,6 +1325,9 @@ type TxType string // Txid defines model for txid. type Txid = string +// Updates defines model for updates. +type Updates = []string + // AccountResponse defines model for AccountResponse. type AccountResponse struct { // Account Account information at a given round. @@ -1428,6 +1443,17 @@ type AssetsResponse struct { // data/bookkeeping/block.go : Block type BlockResponse = Block +// BlocksResponse defines model for BlocksResponse. +type BlocksResponse struct { + Blocks []Block `json:"blocks"` + + // CurrentRound Round at which the results were computed. + CurrentRound uint64 `json:"current-round"` + + // NextToken Used for pagination, when making another request provide this token with the next parameter. + NextToken *string `json:"next-token,omitempty"` +} + // BoxResponse Box name and its content. type BoxResponse = Box @@ -1811,6 +1837,42 @@ type LookupAssetTransactionsParamsSigType string // LookupAssetTransactionsParamsAddressRole defines parameters for LookupAssetTransactions. type LookupAssetTransactionsParamsAddressRole string +// SearchForBlocksParams defines parameters for SearchForBlocks. +type SearchForBlocksParams struct { + // Limit Maximum number of results to return. There could be additional pages even if the limit is not reached. + Limit *uint64 `form:"limit,omitempty" json:"limit,omitempty"` + + // Next The next page of results. Use the next token provided by the previous results. + Next *string `form:"next,omitempty" json:"next,omitempty"` + + // MinRound Include results at or after the specified min-round. + MinRound *uint64 `form:"min-round,omitempty" json:"min-round,omitempty"` + + // MaxRound Include results at or before the specified max-round. + MaxRound *uint64 `form:"max-round,omitempty" json:"max-round,omitempty"` + + // BeforeTime Include results before the given time. Must be an RFC 3339 formatted string. + BeforeTime *time.Time `form:"before-time,omitempty" json:"before-time,omitempty"` + + // AfterTime Include results after the given time. Must be an RFC 3339 formatted string. + AfterTime *time.Time `form:"after-time,omitempty" json:"after-time,omitempty"` + + // Proposer Account(s) marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses. + Proposer *[]string `form:"proposer,omitempty" json:"proposer,omitempty"` + + // Expired Account(s) marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses. + Expired *[]string `form:"expired,omitempty" json:"expired,omitempty"` + + // Absent Account(s) marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses. + Absent *[]string `form:"absent,omitempty" json:"absent,omitempty"` + + // Updates Account(s) marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses. + Updates *[]string `form:"updates,omitempty" json:"updates,omitempty"` + + // Participation Account(s) marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses. + Participation *[]string `form:"participation,omitempty" json:"participation,omitempty"` +} + // LookupBlockParams defines parameters for LookupBlock. type LookupBlockParams struct { // HeaderOnly Header only flag. When this is set to true, returned block does not contain the transactions diff --git a/api/handlers.go b/api/handlers.go index 76d40f9c0..70a24eca8 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -45,6 +45,27 @@ type ServerImplementation struct { // Helper functions // ////////////////////// +func validateBlockFilter(filter *idb.BlockFilter) error { + var errorArr = make([]string, 0) + + // Int64 overflows + if (filter.MaxRound != nil && *filter.MaxRound > math.MaxInt64) || + (filter.MinRound != nil && *filter.MinRound > math.MaxInt64) { + errorArr = append(errorArr, errValueExceedingInt64) + } + + // Time + if !filter.AfterTime.IsZero() && !filter.BeforeTime.IsZero() && filter.AfterTime.After(filter.BeforeTime) { + errorArr = append(errorArr, errInvalidTimeMinMax) + } + + if len(errorArr) > 0 { + return errors.New("invalid input: " + strings.Join(errorArr, ", ")) + } + + return nil +} + func validateTransactionFilter(filter *idb.TransactionFilter) error { var errorArr = make([]string, 0) @@ -981,6 +1002,79 @@ func (si *ServerImplementation) LookupTransaction(ctx echo.Context, txid string) return ctx.JSON(http.StatusOK, response) } +// SearchForBlocks returns block headers matching the provided parameters +// (GET /v2/blocks) +func (si *ServerImplementation) SearchForBlocks(ctx echo.Context, params generated.SearchForBlocksParams) error { + // Validate query parameters + if err := si.verifyHandler("SearchForBlocks", ctx); err != nil { + return badRequest(ctx, err.Error()) + } + + // Convert query params into a filter + filter, err := si.blockParamsToBlockFilter(params) + if err != nil { + return badRequest(ctx, err.Error()) + } + err = validateBlockFilter(&filter) + if err != nil { + return badRequest(ctx, err.Error()) + } + + // Fetch the block headers + blockHeaders, next, round, err := si.fetchBlockHeaders(ctx.Request().Context(), filter) + if err != nil { + return indexerError(ctx, fmt.Errorf("%s: %w", errBlockHeaderSearch, err)) + } + + // Populate the response model and render it + response := generated.BlocksResponse{ + CurrentRound: round, + NextToken: strPtr(next), + Blocks: blockHeaders, + } + return ctx.JSON(http.StatusOK, response) +} + +// fetchBlockHeaders is used to query the backend for block headers, and compute the next token +func (si *ServerImplementation) fetchBlockHeaders(ctx context.Context, bf idb.BlockFilter) ([]generated.Block, string, uint64 /*round*/, error) { + + var round uint64 + var nextToken string + results := make([]generated.Block, 0) + err := callWithTimeout(ctx, si.log, si.timeout, func(ctx context.Context) error { + + // Open a channel from which result rows will be received + var rows <-chan idb.BlockRow + rows, round = si.db.Blocks(ctx, bf) + + // Iterate receieved rows, converting each to a generated.Block + var lastRow idb.BlockRow + for row := range rows { + if row.Error != nil { + return row.Error + } + + results = append(results, rowToBlock(&row.BlockHeader)) + lastRow = row + } + + // No next token if there were no results. + if len(results) == 0 { + return nil + } + + // Generate the next token and return + var err error + nextToken, err = lastRow.Next() + return err + }) + if err != nil { + return nil, "", 0, err + } + + return results, nextToken, round, nil +} + // SearchForTransactions returns transactions matching the provided parameters // (GET /v2/transactions) func (si *ServerImplementation) SearchForTransactions(ctx echo.Context, params generated.SearchForTransactionsParams) error { diff --git a/api/indexer.oas2.json b/api/indexer.oas2.json index 76c11d21d..e2dfad0e0 100644 --- a/api/indexer.oas2.json +++ b/api/indexer.oas2.json @@ -853,6 +853,67 @@ } } }, + "/v2/blocks": { + "get": { + "description": "Search for blocks. Blocks are returned in ascending round order. Transactions are not included in the output.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "search" + ], + "operationId": "searchForBlocks", + "parameters": [ + { + "$ref": "#/parameters/limit" + }, + { + "$ref": "#/parameters/next" + }, + { + "$ref": "#/parameters/min-round" + }, + { + "$ref": "#/parameters/max-round" + }, + { + "$ref": "#/parameters/before-time" + }, + { + "$ref": "#/parameters/after-time" + }, + { + "$ref": "#/parameters/proposer" + }, + { + "$ref": "#/parameters/expired" + }, + { + "$ref": "#/parameters/absent" + }, + { + "$ref": "#/parameters/updates" + }, + { + "$ref": "#/parameters/participation" + } + ], + "responses": { + "200": { + "$ref": "#/responses/BlocksResponse" + }, + "404": { + "$ref": "#/responses/ErrorResponse" + }, + "500": { + "$ref": "#/responses/ErrorResponse" + } + } + } + }, "/v2/blocks/{round-number}": { "get": { "description": "Lookup block.", @@ -1753,7 +1814,7 @@ "Box": { "description": "Box name and its content.", "required": [ - "name", + "name", "value", "round" ], @@ -2595,10 +2656,10 @@ "StateProofParticipant": { "type": "object", "properties": { - "verifier": { - "description": "\\[p\\]", - "$ref": "#/definitions/StateProofVerifier" - }, + "verifier": { + "description": "\\[p\\]", + "$ref": "#/definitions/StateProofVerifier" + }, "weight": { "description": "\\[w\\]", "type": "integer", @@ -2677,6 +2738,61 @@ } }, "parameters": { + "proposer": { + "type": "array", + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "description": "Account(s) marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "name": "proposer", + "in": "query", + "required": false + }, + "absent": { + "type": "array", + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "description": "Account(s) marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "name": "absent", + "in": "query", + "required": false + }, + "expired": { + "type": "array", + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "description": "Account(s) marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "name": "expired", + "in": "query", + "required": false + }, + "updates": { + "type": "array", + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "description": "Account(s) marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "name": "updates", + "in": "query", + "required": false + }, + "participation": { + "type": "array", + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "description": "Account(s) marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "name": "participation", + "in": "query", + "required": false + }, "account-id": { "type": "string", "description": "account string", @@ -3103,7 +3219,7 @@ "schema": { "type": "object", "required": [ - "application-id", + "application-id", "boxes" ], "properties": { @@ -3132,7 +3248,7 @@ }, "ErrorResponse": { "description": "Response for errors", - "schema":{ + "schema": { "type": "object", "required": [ "message" @@ -3179,6 +3295,32 @@ "$ref": "#/definitions/Block" } }, + "BlocksResponse": { + "description": "(empty)", + "schema": { + "type": "object", + "required": [ + "current-round", + "blocks" + ], + "properties": { + "current-round": { + "description": "Round at which the results were computed.", + "type": "integer" + }, + "next-token": { + "description": "Used for pagination, when making another request provide this token with the next parameter.", + "type": "string" + }, + "blocks": { + "type": "array", + "items": { + "$ref": "#/definitions/Block" + } + } + } + } + }, "HealthCheckResponse": { "description": "(empty)", "schema": { @@ -3242,4 +3384,4 @@ "name": "search" } ] -} +} \ No newline at end of file diff --git a/api/indexer.oas3.yml b/api/indexer.oas3.yml index 9a425b354..96fcc87e1 100644 --- a/api/indexer.oas3.yml +++ b/api/indexer.oas3.yml @@ -1,6 +1,20 @@ { "components": { "parameters": { + "absent": { + "description": "Account(s) marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "absent", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, "account-id": { "description": "account string", "in": "path", @@ -135,6 +149,20 @@ "type": "boolean" } }, + "expired": { + "description": "Account(s) marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "expired", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, "header-only": { "description": "Header only flag. When this is set to true, returned block does not contain the transactions", "in": "query", @@ -193,6 +221,34 @@ }, "x-algorand-format": "base64" }, + "participation": { + "description": "Account(s) marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "participation", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, + "proposer": { + "description": "Account(s) marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "proposer", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, "rekey-to": { "description": "Include results which include the rekey-to field.", "in": "query", @@ -264,6 +320,20 @@ "schema": { "type": "string" } + }, + "updates": { + "description": "Account(s) marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "updates", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" } }, "responses": { @@ -559,6 +629,36 @@ }, "description": "(empty)" }, + "BlocksResponse": { + "content": { + "application/json": { + "schema": { + "properties": { + "blocks": { + "items": { + "$ref": "#/components/schemas/Block" + }, + "type": "array" + }, + "current-round": { + "description": "Round at which the results were computed.", + "type": "integer" + }, + "next-token": { + "description": "Used for pagination, when making another request provide this token with the next parameter.", + "type": "string" + } + }, + "required": [ + "blocks", + "current-round" + ], + "type": "object" + } + } + }, + "description": "(empty)" + }, "BoxResponse": { "content": { "application/json": { @@ -4763,6 +4863,217 @@ ] } }, + "/v2/blocks": { + "get": { + "description": "Search for blocks. Blocks are returned in ascending round order. Transactions are not included in the output.", + "operationId": "searchForBlocks", + "parameters": [ + { + "description": "Maximum number of results to return. There could be additional pages even if the limit is not reached.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer" + } + }, + { + "description": "The next page of results. Use the next token provided by the previous results.", + "in": "query", + "name": "next", + "schema": { + "type": "string" + } + }, + { + "description": "Include results at or after the specified min-round.", + "in": "query", + "name": "min-round", + "schema": { + "type": "integer" + } + }, + { + "description": "Include results at or before the specified max-round.", + "in": "query", + "name": "max-round", + "schema": { + "type": "integer" + } + }, + { + "description": "Include results before the given time. Must be an RFC 3339 formatted string.", + "in": "query", + "name": "before-time", + "schema": { + "format": "date-time", + "type": "string", + "x-algorand-format": "RFC3339 String" + }, + "x-algorand-format": "RFC3339 String" + }, + { + "description": "Include results after the given time. Must be an RFC 3339 formatted string.", + "in": "query", + "name": "after-time", + "schema": { + "format": "date-time", + "type": "string", + "x-algorand-format": "RFC3339 String" + }, + "x-algorand-format": "RFC3339 String" + }, + { + "description": "Account(s) marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "proposer", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, + { + "description": "Account(s) marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "expired", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, + { + "description": "Account(s) marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "absent", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, + { + "description": "Account(s) marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "updates", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, + { + "description": "Account(s) marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "participation", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "properties": { + "blocks": { + "items": { + "$ref": "#/components/schemas/Block" + }, + "type": "array" + }, + "current-round": { + "description": "Round at which the results were computed.", + "type": "integer" + }, + "next-token": { + "description": "Used for pagination, when making another request provide this token with the next parameter.", + "type": "string" + } + }, + "required": [ + "blocks", + "current-round" + ], + "type": "object" + } + } + }, + "description": "(empty)" + }, + "404": { + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "properties": {}, + "type": "object" + }, + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + }, + "description": "Response for errors" + }, + "500": { + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "properties": {}, + "type": "object" + }, + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + }, + "description": "Response for errors" + } + }, + "tags": [ + "search" + ] + } + }, "/v2/blocks/{round-number}": { "get": { "description": "Lookup block.", diff --git a/api/server.go b/api/server.go index c8f21531e..75e7558b6 100644 --- a/api/server.go +++ b/api/server.go @@ -47,10 +47,20 @@ type ExtraOptions struct { // If an address exceeds this number, a 400 error is returned. Zero means unlimited. MaxAPIResourcesPerAccount uint64 + // MaxAccountListSize is the maximum number of items that can be passed in query parameter account lists. + // (e.g.: GET /v2/blocks?proposer=A,B,C) + // + // Zero means unlimited. + MaxAccountListSize uint64 + ///////////////////// // Limit Constants // ///////////////////// + // Blocks + MaxBlocksLimit uint64 + DefaultBlocksLimit uint64 + // Transactions MaxTransactionsLimit uint64 DefaultTransactionsLimit uint64 diff --git a/cmd/algorand-indexer/daemon.go b/cmd/algorand-indexer/daemon.go index 421bfd4fb..213f21892 100644 --- a/cmd/algorand-indexer/daemon.go +++ b/cmd/algorand-indexer/daemon.go @@ -33,6 +33,9 @@ type daemonConfig struct { readTimeout time.Duration maxConn uint32 maxAPIResourcesPerAccount uint32 + maxAccountListSize uint32 + maxBlocksLimit uint32 + defaultBlocksLimit uint32 maxTransactionsLimit uint32 defaultTransactionsLimit uint32 maxAccountsLimit uint32 @@ -81,6 +84,9 @@ func DaemonCmd() *cobra.Command { cfg.flags.StringVar(&cfg.suppliedAPIConfigFile, "api-config-file", "", "supply an API config file to enable/disable parameters") cfg.flags.BoolVar(&cfg.enableAllParameters, "enable-all-parameters", false, "override default configuration and enable all parameters. Can't be used with --api-config-file") cfg.flags.Uint32VarP(&cfg.maxAPIResourcesPerAccount, "max-api-resources-per-account", "", 1000, "set the maximum total number of resources (created assets, created apps, asset holdings, and application local state) per account that will be allowed in REST API lookupAccountByID and searchForAccounts responses before returning a 400 Bad Request. Set zero for no limit") + cfg.flags.Uint32VarP(&cfg.maxAccountListSize, "max-account-list-size", "", 50, "set the maximum number of items for query parameters that accept account lists. Set zero for no limit") + cfg.flags.Uint32VarP(&cfg.maxBlocksLimit, "max-blocks-limit", "", 1000, "set the maximum allowed Limit parameter for querying blocks") + cfg.flags.Uint32VarP(&cfg.defaultBlocksLimit, "default-blocks-limit", "", 100, "set the default Limit parameter for querying blocks, if none is provided") cfg.flags.Uint32VarP(&cfg.maxTransactionsLimit, "max-transactions-limit", "", 10000, "set the maximum allowed Limit parameter for querying transactions") cfg.flags.Uint32VarP(&cfg.defaultTransactionsLimit, "default-transactions-limit", "", 1000, "set the default Limit parameter for querying transactions, if none is provided") cfg.flags.Uint32VarP(&cfg.maxAccountsLimit, "max-accounts-limit", "", 1000, "set the maximum allowed Limit parameter for querying accounts") @@ -322,6 +328,9 @@ func makeOptions(daemonConfig *daemonConfig) (options api.ExtraOptions) { options.ReadTimeout = daemonConfig.readTimeout options.MaxAPIResourcesPerAccount = uint64(daemonConfig.maxAPIResourcesPerAccount) + options.MaxAccountListSize = uint64(daemonConfig.maxAccountListSize) + options.MaxBlocksLimit = uint64(daemonConfig.maxBlocksLimit) + options.DefaultBlocksLimit = uint64(daemonConfig.defaultBlocksLimit) options.MaxTransactionsLimit = uint64(daemonConfig.maxTransactionsLimit) options.DefaultTransactionsLimit = uint64(daemonConfig.defaultTransactionsLimit) options.MaxAccountsLimit = uint64(daemonConfig.maxAccountsLimit) diff --git a/idb/dummy/dummy.go b/idb/dummy/dummy.go index 19e276e8b..29552c4c3 100644 --- a/idb/dummy/dummy.go +++ b/idb/dummy/dummy.go @@ -53,6 +53,11 @@ func (db *dummyIndexerDb) GetBlock(ctx context.Context, round uint64, options id return sdk.BlockHeader{}, nil, nil } +// Blocks is part of idb.IndexerDB +func (db *dummyIndexerDb) Blocks(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { + return nil, 0 +} + // Transactions is part of idb.IndexerDB func (db *dummyIndexerDb) Transactions(ctx context.Context, tf idb.TransactionFilter) (<-chan idb.TxnRow, uint64) { return nil, 0 diff --git a/idb/idb.go b/idb/idb.go index a4c58c948..037a6819d 100644 --- a/idb/idb.go +++ b/idb/idb.go @@ -15,6 +15,23 @@ import ( sdk "github.com/algorand/go-algorand-sdk/v2/types" ) +// BlockRow is metadata relating to one block in a block query. +type BlockRow struct { + BlockHeader sdk.BlockHeader + + // Error indicates that there was an internal problem processing the expected block. + Error error +} + +// Next returns what should be an opaque string to be used with the next query to resume where a previous limit left off. +func (br BlockRow) Next() (string, error) { + + var b [8]byte + binary.LittleEndian.PutUint64(b[:8], uint64(br.BlockHeader.Round)) + + return base64.URLEncoding.EncodeToString(b[:]), nil +} + // TxnRow is metadata relating to one transaction in a transaction query. type TxnRow struct { // Round is the round where the transaction was committed. @@ -99,6 +116,21 @@ func DecodeTxnRowNext(s string) (uint64 /*round*/, uint32 /*intra*/, error) { return round, intra, nil } +// DecodeBlockRowNext unpacks opaque string returned from BlockRow.Next() +func DecodeBlockRowNext(s string) (uint64 /*round*/, error) { + b, err := base64.URLEncoding.DecodeString(s) + if err != nil { + return 0, fmt.Errorf("DecodeBlockRowNext() decode err: %w", err) + } + + if len(b) != 8 { + return 0, fmt.Errorf("DecodeBlockRowNext() bad next token b: %x", b) + } + + round := binary.LittleEndian.Uint64(b[:8]) + return round, nil +} + // OptionalUint wraps bool and uint. It has a custom marshaller below. type OptionalUint struct { Present bool @@ -173,6 +205,7 @@ type IndexerDb interface { // The next multiple functions return a channel with results as well as the latest round // accounted. + Blocks(ctx context.Context, bf BlockFilter) (<-chan BlockRow, uint64) Transactions(ctx context.Context, tf TransactionFilter) (<-chan TxnRow, uint64) GetAccounts(ctx context.Context, opts AccountQueryOptions) (<-chan AccountRow, uint64) Assets(ctx context.Context, filter AssetsQuery) (<-chan AssetRow, uint64) @@ -195,6 +228,18 @@ type GetBlockOptions struct { MaxTransactionsLimit uint64 } +// BlockFilter is a parameter object with all the block filter options. +type BlockFilter struct { + Limit uint64 + MaxRound *uint64 + MinRound *uint64 + AfterTime time.Time + BeforeTime time.Time + Proposers map[sdk.Address]struct{} + ExpiredParticipationAccounts map[sdk.Address]struct{} + AbsentParticipationAccounts map[sdk.Address]struct{} +} + // TransactionFilter is a parameter object with all the transaction filter options. type TransactionFilter struct { // SkipOptimization is used for testing to ensure the parameters are not modified. diff --git a/idb/postgres/postgres.go b/idb/postgres/postgres.go index 1a6850ccb..ab4b1ae64 100644 --- a/idb/postgres/postgres.go +++ b/idb/postgres/postgres.go @@ -949,6 +949,274 @@ finish: } } +// buildBlockFilters generates filters based on a block's round and/or timestamp. +// +// Filters related to participation are generated elsewhere. +// +// Some of the filters are meant to be used as boolean conditions in the WHERE clause. +// Others, for performance reasons, have to be used as INNER JOIN terms in the FROM clause. +func buildBlockFilters(bf idb.BlockFilter) (whereTerms []string, joinTerms []string) { + + // Round-based filters + if bf.MaxRound != nil { + whereTerms = append( + whereTerms, + fmt.Sprintf("bh.round <= %d", *bf.MaxRound), + ) + } + if bf.MinRound != nil { + whereTerms = append( + whereTerms, + fmt.Sprintf("bh.round >= %d", *bf.MinRound), + ) + } + + // Timestamp-based filters + // + // Converting the timestamp into a round usually results in faster execution plans + // (compared to the execution plans that would result from using the `block_header.realtime` column directly) + // + // Unfortunately, writing this condition in the WHERE clause results in poor execution plans. + // Expressing the filter as an INNER JOIN results in an efficient query execution plan. + if !bf.AfterTime.IsZero() { + tmpl := ` + INNER JOIN ( + SELECT COALESCE(tmp.round, 0) AS round + FROM block_header tmp + WHERE tmp.realtime > (to_timestamp(%d) AT TIME ZONE 'UTC') + ORDER BY tmp.realtime ASC, tmp.round ASC + LIMIT 1 + ) bh_at ON bh.round >= bh_at.round + ` + joinTerms = append( + joinTerms, + fmt.Sprintf(tmpl, bf.AfterTime.UTC().Unix()), + ) + } + if !bf.BeforeTime.IsZero() { + tmpl := ` + INNER JOIN ( + SELECT COALESCE(tmp.round, 0) AS round + FROM block_header tmp + WHERE tmp.realtime < (to_timestamp(%d) AT TIME ZONE 'UTC') + ORDER BY tmp.realtime DESC, tmp.round DESC + LIMIT 1 + ) bh_bt ON bh.round <= bh_bt.round + ` + joinTerms = append( + joinTerms, + fmt.Sprintf(tmpl, bf.BeforeTime.UTC().Unix()), + ) + } + + return whereTerms, joinTerms +} + +func buildBlockQuery(bf idb.BlockFilter) (query string, err error) { + + // helper function to build CTEs + buildCte := func(cteName string, whereTerms []string, joinTerms []string) string { + tmpl := `%s AS ( + SELECT bh.round, bh.header + FROM block_header bh + %s + WHERE %s + ORDER BY bh.round ASC + LIMIT %d + )` + return fmt.Sprintf(tmpl, cteName, strings.Join(joinTerms, "\n"), strings.Join(whereTerms, " AND "), bf.Limit) + } + + // Build auxiliary CTEs for participation-related parameters. + // + // Using CTEs in this way turned out to be necessary to lead CockroachDB's query optimizer + // into using the execution plan we want. + // + // If we were to put the CTE filters in the main query's WHERE clause, that would result + // in a sub-optimal execution plan. At least this was the case at the time of writing. + var CTEs []string + var CteNames []string + { + if len(bf.Proposers) > 0 { + whereTerms, joinTerms := buildBlockFilters(bf) + var proposersStr []string + for addr := range bf.Proposers { + proposersStr = append(proposersStr, `'"`+addr.String()+`"'`) + } + whereTerms = append( + whereTerms, + fmt.Sprintf("( (bh.header->'prp') IS NOT NULL AND ((bh.header->'prp')::TEXT IN (%s)) )", strings.Join(proposersStr, ",")), + ) + + cteName := "prp" + cte := buildCte(cteName, whereTerms, joinTerms) + CTEs = append(CTEs, cte) + CteNames = append(CteNames, cteName) + + } + if len(bf.ExpiredParticipationAccounts) > 0 { + whereTerms, joinTerms := buildBlockFilters(bf) + var expiredStr []string + for addr := range bf.ExpiredParticipationAccounts { + expiredStr = append(expiredStr, `'`+addr.String()+`'`) + } + whereTerms = append( + whereTerms, + fmt.Sprintf("( (bh.header->'partupdrmv') IS NOT NULL AND (bh.header->'partupdrmv') ?| array[%s] )", strings.Join(expiredStr, ",")), + ) + + cteName := "expired" + CTE := buildCte(cteName, whereTerms, joinTerms) + CTEs = append(CTEs, CTE) + CteNames = append(CteNames, "expired") + + } + if len(bf.AbsentParticipationAccounts) > 0 { + whereTerms, joinTerms := buildBlockFilters(bf) + var absentStr []string + for addr := range bf.AbsentParticipationAccounts { + absentStr = append(absentStr, `'`+addr.String()+`'`) + } + whereTerms = append( + whereTerms, + fmt.Sprintf("( (bh.header->'partupdabs') IS NOT NULL AND (bh.header->'partupdabs') ?| array[%s] )", strings.Join(absentStr, ",")), + ) + + cteName := "absent" + CTE := buildCte(cteName, whereTerms, joinTerms) + CTEs = append(CTEs, CTE) + CteNames = append(CteNames, cteName) + } + if len(CteNames) > 0 { + var selects []string + for _, cteName := range CteNames { + selects = append(selects, fmt.Sprintf("SELECT * FROM %s", cteName)) + } + CTE := "tmp AS (" + strings.Join(selects, " UNION ") + ")" + CTEs = append(CTEs, CTE) + } + } + + // Build the main query. It uses the CTEs, if any. + { + var withClause string + if len(CTEs) > 0 { + withClause = "WITH " + strings.Join(CTEs, ",\n") + } + + var fromTable string + if len(CTEs) > 0 { + fromTable = "tmp bh" + } else { + fromTable = "block_header bh" + } + + var whereClause string + var joinClause string + if len(CTEs) == 0 { + whereTerms, joinTerms := buildBlockFilters(bf) + if len(whereTerms) > 0 { + whereClause = "WHERE " + strings.Join(whereTerms, " AND ") + "\n" + } + if len(joinTerms) > 0 { + joinClause = strings.Join(joinTerms, "\n") + } + } + + tmpl := ` + %s + SELECT bh.header + FROM %s + %s + %s + ORDER BY bh.round ASC + LIMIT %d` + + query = fmt.Sprintf(tmpl, withClause, fromTable, joinClause, whereClause, bf.Limit) + } + + return query, nil +} + +// This function blocks. `tx` must be non-nil. +func (db *IndexerDb) yieldBlocks(ctx context.Context, tx pgx.Tx, bf idb.BlockFilter, out chan<- idb.BlockRow) { + + query, err := buildBlockQuery(bf) + if err != nil { + err = fmt.Errorf("block query err %v", err) + out <- idb.BlockRow{Error: err} + return + } + + rows, err := tx.Query(ctx, query) + if err != nil { + err = fmt.Errorf("block query %#v err %v", query, err) + out <- idb.BlockRow{Error: err} + return + } + db.yieldBlocksThreadSimple(rows, out) +} + +// Blocks is part of idb.IndexerDB +func (db *IndexerDb) Blocks(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { + out := make(chan idb.BlockRow, 1) + + tx, err := db.db.BeginTx(ctx, readonlyRepeatableRead) + if err != nil { + out <- idb.BlockRow{Error: err} + close(out) + return out, 0 + } + + round, err := db.getMaxRoundAccounted(ctx, tx) + if err != nil { + out <- idb.BlockRow{Error: err} + close(out) + if rerr := tx.Rollback(ctx); rerr != nil { + db.log.Printf("rollback error: %s", rerr) + } + return out, round + } + + go func() { + db.yieldBlocks(ctx, tx, bf, out) + // Because we return a channel into a "callWithTimeout" function, + // We need to make sure that rollback is called before close() + // otherwise we can end up with a situation where "callWithTimeout" + // will cancel our context, resulting in connection pool churn + if rerr := tx.Rollback(ctx); rerr != nil { + db.log.Printf("rollback error: %s", rerr) + } + close(out) + }() + + return out, round +} + +func (db *IndexerDb) yieldBlocksThreadSimple(rows pgx.Rows, results chan<- idb.BlockRow) { + defer rows.Close() + + for rows.Next() { + var row idb.BlockRow + + var blockheaderjson []byte + err := rows.Scan(&blockheaderjson) + if err != nil { + row.Error = err + } else { + row.BlockHeader, err = encoding.DecodeBlockHeader(blockheaderjson) + if err != nil { + row.Error = fmt.Errorf("failed to decode block header: %w", err) + } + } + + results <- row + } + if err := rows.Err(); err != nil { + results <- idb.BlockRow{Error: err} + } +} + var statusStrings = []string{"Offline", "Online", "NotParticipating"} const offlineStatusIdx = 0 From bf0e2a457e304e524a0d49a106a7565fcdbd288e Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Mon, 18 Nov 2024 15:04:04 -0300 Subject: [PATCH 02/19] Rename function --- api/converter_utils.go | 11 ++++++----- api/handlers.go | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index 105321b0d..42a7d881a 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -40,11 +40,12 @@ func decodeSdkAddress(str string, field string, errorArr []string) (sdk.Address, if err != nil { return sdk.ZeroAddress, append(errorArr, fmt.Sprintf("%s '%s': %v", errUnableToParseAddress, field, err)) } + // Pass through return addr, errorArr } -// decodeAddress returns the byte representation of the input string, or appends an error to errorArr -func decodeAddress(str *string, field string, errorArr []string) ([]byte, []string) { +// decodeAddressToBytes returns the byte representation of the input string, or appends an error to errorArr +func decodeAddressToBytes(str *string, field string, errorArr []string) ([]byte, []string) { if str != nil { addr, err := sdk.DecodeAddress(*str) if err != nil { @@ -737,7 +738,7 @@ func edIndexToAddress(index uint64, txn sdk.Transaction, shared []sdk.Address) ( } func (si *ServerImplementation) assetParamsToAssetQuery(params generated.SearchForAssetsParams) (idb.AssetsQuery, error) { - creator, errorArr := decodeAddress(params.Creator, "creator", make([]string, 0)) + creator, errorArr := decodeAddressToBytes(params.Creator, "creator", make([]string, 0)) if len(errorArr) != 0 { return idb.AssetsQuery{}, errors.New(errUnableToParseAddress) } @@ -766,7 +767,7 @@ func (si *ServerImplementation) assetParamsToAssetQuery(params generated.SearchF } func (si *ServerImplementation) appParamsToApplicationQuery(params generated.SearchForApplicationsParams) (idb.ApplicationQuery, error) { - addr, errorArr := decodeAddress(params.Creator, "creator", make([]string, 0)) + addr, errorArr := decodeAddressToBytes(params.Creator, "creator", make([]string, 0)) if len(errorArr) != 0 { return idb.ApplicationQuery{}, errors.New(errUnableToParseAddress) } @@ -805,7 +806,7 @@ func (si *ServerImplementation) transactionParamsToTransactionFilter(params gene filter.NextToken = strOrDefault(params.Next) // Address - filter.Address, errorArr = decodeAddress(params.Address, "address", errorArr) + filter.Address, errorArr = decodeAddressToBytes(params.Address, "address", errorArr) filter.Txid, errorArr = decodeDigest(params.Txid, "txid", errorArr) // Byte array diff --git a/api/handlers.go b/api/handlers.go index 70a24eca8..ea40e583a 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -214,7 +214,7 @@ func (si *ServerImplementation) LookupAccountByID(ctx echo.Context, accountID st return badRequest(ctx, errRewindingAccountNotSupported) } - addr, decodeErrors := decodeAddress(&accountID, "account-id", make([]string, 0)) + addr, decodeErrors := decodeAddressToBytes(&accountID, "account-id", make([]string, 0)) if len(decodeErrors) != 0 { return badRequest(ctx, decodeErrors[0]) } @@ -314,7 +314,7 @@ func (si *ServerImplementation) LookupAccountAssets(ctx echo.Context, accountID return notFound(ctx, errValueExceedingInt64) } - addr, errors := decodeAddress(&accountID, "account-id", make([]string, 0)) + addr, errors := decodeAddressToBytes(&accountID, "account-id", make([]string, 0)) if len(errors) != 0 { return badRequest(ctx, errors[0]) } @@ -408,7 +408,7 @@ func (si *ServerImplementation) SearchForAccounts(ctx echo.Context, params gener return badRequest(ctx, errRewindingAccountNotSupported) } - spendingAddr, decodeErrors := decodeAddress(params.AuthAddr, "account-id", make([]string, 0)) + spendingAddr, decodeErrors := decodeAddressToBytes(params.AuthAddr, "account-id", make([]string, 0)) if len(decodeErrors) != 0 { return badRequest(ctx, decodeErrors[0]) } @@ -487,7 +487,7 @@ func (si *ServerImplementation) LookupAccountTransactions(ctx echo.Context, acco return notFound(ctx, errValueExceedingInt64) } // Check that a valid account was provided - _, errors := decodeAddress(strPtr(accountID), "account-id", make([]string, 0)) + _, errors := decodeAddressToBytes(strPtr(accountID), "account-id", make([]string, 0)) if len(errors) != 0 { return badRequest(ctx, errors[0]) } From 996ebba835bb31f4024e69d27ff4fbe560cc20a1 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Mon, 18 Nov 2024 15:04:31 -0300 Subject: [PATCH 03/19] Rename function --- api/converter_utils.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index 42a7d881a..e6adda9b5 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -34,8 +34,8 @@ func decodeDigest(str *string, field string, errorArr []string) (string, []strin return "", errorArr } -// decodeSdkAddress returns the sdk.Address representation of the input string, or appends an error to errorArr -func decodeSdkAddress(str string, field string, errorArr []string) (sdk.Address, []string) { +// decodeAddress returns the sdk.Address representation of the input string, or appends an error to errorArr +func decodeAddress(str string, field string, errorArr []string) (sdk.Address, []string) { addr, err := sdk.DecodeAddress(str) if err != nil { return sdk.ZeroAddress, append(errorArr, fmt.Sprintf("%s '%s': %v", errUnableToParseAddress, field, err)) @@ -928,7 +928,7 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search if params.Proposer != nil { for _, s := range *params.Proposer { var addr sdk.Address - addr, errorArr = decodeSdkAddress(s, "proposer", errorArr) + addr, errorArr = decodeAddress(s, "proposer", errorArr) filter.Proposers[addr] = struct{}{} } } @@ -937,7 +937,7 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search if params.Expired != nil { for _, s := range *params.Expired { var addr sdk.Address - addr, errorArr = decodeSdkAddress(s, "expired", errorArr) + addr, errorArr = decodeAddress(s, "expired", errorArr) filter.ExpiredParticipationAccounts[addr] = struct{}{} } } @@ -946,7 +946,7 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search if params.Absent != nil { for _, s := range *params.Absent { var addr sdk.Address - addr, errorArr = decodeSdkAddress(s, "absent", errorArr) + addr, errorArr = decodeAddress(s, "absent", errorArr) filter.AbsentParticipationAccounts[addr] = struct{}{} } } @@ -955,7 +955,7 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search if params.Updates != nil { for _, s := range *params.Updates { var addr sdk.Address - addr, errorArr = decodeSdkAddress(s, "updates", errorArr) + addr, errorArr = decodeAddress(s, "updates", errorArr) filter.AbsentParticipationAccounts[addr] = struct{}{} filter.ExpiredParticipationAccounts[addr] = struct{}{} } @@ -965,7 +965,7 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search if params.Participation != nil { for _, s := range *params.Participation { var addr sdk.Address - addr, errorArr = decodeSdkAddress(s, "participation", errorArr) + addr, errorArr = decodeAddress(s, "participation", errorArr) filter.Proposers[addr] = struct{}{} filter.AbsentParticipationAccounts[addr] = struct{}{} filter.ExpiredParticipationAccounts[addr] = struct{}{} From f17423ba2ad117cd23ff7d9eba49a7c5cc9ee3ee Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Mon, 18 Nov 2024 15:56:34 -0300 Subject: [PATCH 04/19] Fix compiler error --- idb/mocks/IndexerDb.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/idb/mocks/IndexerDb.go b/idb/mocks/IndexerDb.go index 15b508e10..e53cb399b 100644 --- a/idb/mocks/IndexerDb.go +++ b/idb/mocks/IndexerDb.go @@ -424,6 +424,36 @@ func (_m *IndexerDb) SetNetworkState(genesis v2types.Digest) error { return r0 } +// Blocks provides a mock function with given fields: ctx, bf +func (_m *IndexerDb) Blocks(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { + ret := _m.Called(ctx, bf) + + if len(ret) == 0 { + panic("no return value specified for Blocks") + } + + var r0 <-chan idb.BlockRow + var r1 uint64 + if rf, ok := ret.Get(0).(func(context.Context, idb.BlockFilter) (<-chan idb.BlockRow, uint64)); ok { + return rf(ctx, bf) + } + if rf, ok := ret.Get(0).(func(context.Context, idb.BlockFilter) <-chan idb.BlockRow); ok { + r0 = rf(ctx, bf) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan idb.BlockRow) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, idb.BlockFilter) uint64); ok { + r1 = rf(ctx, bf) + } else { + r1 = ret.Get(1).(uint64) + } + + return r0, r1 +} + // Transactions provides a mock function with given fields: ctx, tf func (_m *IndexerDb) Transactions(ctx context.Context, tf idb.TransactionFilter) (<-chan idb.TxnRow, uint64) { ret := _m.Called(ctx, tf) From a1904b4d5c76152440d3043bc62226290a143b49 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Mon, 18 Nov 2024 16:20:14 -0300 Subject: [PATCH 05/19] Revert f17423ba2ad117cd23ff7d9eba49a7c5cc9ee3ee --- idb/mocks/IndexerDb.go | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/idb/mocks/IndexerDb.go b/idb/mocks/IndexerDb.go index e53cb399b..15b508e10 100644 --- a/idb/mocks/IndexerDb.go +++ b/idb/mocks/IndexerDb.go @@ -424,36 +424,6 @@ func (_m *IndexerDb) SetNetworkState(genesis v2types.Digest) error { return r0 } -// Blocks provides a mock function with given fields: ctx, bf -func (_m *IndexerDb) Blocks(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { - ret := _m.Called(ctx, bf) - - if len(ret) == 0 { - panic("no return value specified for Blocks") - } - - var r0 <-chan idb.BlockRow - var r1 uint64 - if rf, ok := ret.Get(0).(func(context.Context, idb.BlockFilter) (<-chan idb.BlockRow, uint64)); ok { - return rf(ctx, bf) - } - if rf, ok := ret.Get(0).(func(context.Context, idb.BlockFilter) <-chan idb.BlockRow); ok { - r0 = rf(ctx, bf) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(<-chan idb.BlockRow) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, idb.BlockFilter) uint64); ok { - r1 = rf(ctx, bf) - } else { - r1 = ret.Get(1).(uint64) - } - - return r0, r1 -} - // Transactions provides a mock function with given fields: ctx, tf func (_m *IndexerDb) Transactions(ctx context.Context, tf idb.TransactionFilter) (<-chan idb.TxnRow, uint64) { ret := _m.Called(ctx, tf) From 286787a2c11252e5739d677798ffb27290be7b94 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Mon, 18 Nov 2024 16:27:59 -0300 Subject: [PATCH 06/19] Update file generated by mockery --- idb/mocks/IndexerDb.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/idb/mocks/IndexerDb.go b/idb/mocks/IndexerDb.go index 15b508e10..d5b4e9957 100644 --- a/idb/mocks/IndexerDb.go +++ b/idb/mocks/IndexerDb.go @@ -186,6 +186,36 @@ func (_m *IndexerDb) Assets(ctx context.Context, filter idb.AssetsQuery) (<-chan return r0, r1 } +// Blocks provides a mock function with given fields: ctx, bf +func (_m *IndexerDb) Blocks(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { + ret := _m.Called(ctx, bf) + + if len(ret) == 0 { + panic("no return value specified for Blocks") + } + + var r0 <-chan idb.BlockRow + var r1 uint64 + if rf, ok := ret.Get(0).(func(context.Context, idb.BlockFilter) (<-chan idb.BlockRow, uint64)); ok { + return rf(ctx, bf) + } + if rf, ok := ret.Get(0).(func(context.Context, idb.BlockFilter) <-chan idb.BlockRow); ok { + r0 = rf(ctx, bf) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan idb.BlockRow) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, idb.BlockFilter) uint64); ok { + r1 = rf(ctx, bf) + } else { + r1 = ret.Get(1).(uint64) + } + + return r0, r1 +} + // Close provides a mock function with given fields: func (_m *IndexerDb) Close() { _m.Called() From f7121b52a726e147010c10c7ce1939f68e3382c7 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 13:59:11 -0300 Subject: [PATCH 07/19] Fix typo --- api/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/handlers.go b/api/handlers.go index ea40e583a..f81f3aaf2 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -1047,7 +1047,7 @@ func (si *ServerImplementation) fetchBlockHeaders(ctx context.Context, bf idb.Bl var rows <-chan idb.BlockRow rows, round = si.db.Blocks(ctx, bf) - // Iterate receieved rows, converting each to a generated.Block + // Iterate received rows, converting each to a generated.Block var lastRow idb.BlockRow for row := range rows { if row.Error != nil { From fbab2c80561b6686cfe176d9c9100bd5c62dd266 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 14:00:48 -0300 Subject: [PATCH 08/19] Improve parameter descriptions --- api/indexer.oas2.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api/indexer.oas2.json b/api/indexer.oas2.json index e2dfad0e0..0f7ca657f 100644 --- a/api/indexer.oas2.json +++ b/api/indexer.oas2.json @@ -2744,7 +2744,7 @@ "type": "string", "x-algorand-format": "Address" }, - "description": "Account(s) marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "name": "proposer", "in": "query", "required": false @@ -2755,7 +2755,7 @@ "type": "string", "x-algorand-format": "Address" }, - "description": "Account(s) marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "name": "absent", "in": "query", "required": false @@ -2766,7 +2766,7 @@ "type": "string", "x-algorand-format": "Address" }, - "description": "Account(s) marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "name": "expired", "in": "query", "required": false @@ -2777,7 +2777,7 @@ "type": "string", "x-algorand-format": "Address" }, - "description": "Account(s) marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "name": "updates", "in": "query", "required": false @@ -2788,7 +2788,7 @@ "type": "string", "x-algorand-format": "Address" }, - "description": "Account(s) marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "name": "participation", "in": "query", "required": false From a302e5b9948fa1dace8f77f2b31bfeb8227d0bac Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 18:48:29 -0300 Subject: [PATCH 09/19] Change route to `GET /v2/block-headers` --- api/converter_utils.go | 2 +- api/generated/common/routes.go | 370 +++++++++++++------------- api/generated/common/types.go | 16 +- api/generated/v2/routes.go | 468 ++++++++++++++++----------------- api/generated/v2/types.go | 30 +-- api/handlers.go | 8 +- api/indexer.oas2.json | 10 +- api/indexer.oas3.yml | 48 ++-- idb/dummy/dummy.go | 2 +- idb/idb.go | 2 +- idb/mocks/IndexerDb.go | 6 +- idb/postgres/postgres.go | 10 +- 12 files changed, 486 insertions(+), 486 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index e6adda9b5..b9d7d2f9c 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -847,7 +847,7 @@ func (si *ServerImplementation) transactionParamsToTransactionFilter(params gene return } -func (si *ServerImplementation) blockParamsToBlockFilter(params generated.SearchForBlocksParams) (filter idb.BlockFilter, err error) { +func (si *ServerImplementation) blockParamsToBlockFilter(params generated.SearchForBlockHeadersParams) (filter idb.BlockFilter, err error) { var errorArr []string // Integer diff --git a/api/generated/common/routes.go b/api/generated/common/routes.go index 97e6bed82..18c19b70d 100644 --- a/api/generated/common/routes.go +++ b/api/generated/common/routes.go @@ -73,191 +73,191 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL var swaggerSpec = []string{ "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", - "6AAA", + "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", + "AA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/common/types.go b/api/generated/common/types.go index b532222f5..90b8a1c83 100644 --- a/api/generated/common/types.go +++ b/api/generated/common/types.go @@ -1349,14 +1349,8 @@ type AssetsResponse struct { NextToken *string `json:"next-token,omitempty"` } -// BlockResponse Block information. -// -// Definition: -// data/bookkeeping/block.go : Block -type BlockResponse = Block - -// BlocksResponse defines model for BlocksResponse. -type BlocksResponse struct { +// BlockHeadersResponse defines model for BlockHeadersResponse. +type BlockHeadersResponse struct { Blocks []Block `json:"blocks"` // CurrentRound Round at which the results were computed. @@ -1366,6 +1360,12 @@ type BlocksResponse struct { NextToken *string `json:"next-token,omitempty"` } +// BlockResponse Block information. +// +// Definition: +// data/bookkeeping/block.go : Block +type BlockResponse = Block + // BoxResponse Box name and its content. type BoxResponse = Box diff --git a/api/generated/v2/routes.go b/api/generated/v2/routes.go index d787979a1..7a4ac1b61 100644 --- a/api/generated/v2/routes.go +++ b/api/generated/v2/routes.go @@ -69,8 +69,8 @@ type ServerInterface interface { // (GET /v2/assets/{asset-id}/transactions) LookupAssetTransactions(ctx echo.Context, assetId uint64, params LookupAssetTransactionsParams) error - // (GET /v2/blocks) - SearchForBlocks(ctx echo.Context, params SearchForBlocksParams) error + // (GET /v2/block-headers) + SearchForBlockHeaders(ctx echo.Context, params SearchForBlockHeadersParams) error // (GET /v2/blocks/{round-number}) LookupBlock(ctx echo.Context, roundNumber uint64, params LookupBlockParams) error @@ -977,12 +977,12 @@ func (w *ServerInterfaceWrapper) LookupAssetTransactions(ctx echo.Context) error return err } -// SearchForBlocks converts echo context to params. -func (w *ServerInterfaceWrapper) SearchForBlocks(ctx echo.Context) error { +// SearchForBlockHeaders converts echo context to params. +func (w *ServerInterfaceWrapper) SearchForBlockHeaders(ctx echo.Context) error { var err error // Parameter object where we will unmarshal all parameters from the context - var params SearchForBlocksParams + var params SearchForBlockHeadersParams // ------------- Optional query parameter "limit" ------------- err = runtime.BindQueryParameter("form", true, false, "limit", ctx.QueryParams(), ¶ms.Limit) @@ -1061,7 +1061,7 @@ func (w *ServerInterfaceWrapper) SearchForBlocks(ctx echo.Context) error { } // Invoke the callback with all the unmarshalled arguments - err = w.Handler.SearchForBlocks(ctx, params) + err = w.Handler.SearchForBlockHeaders(ctx, params) return err } @@ -1294,7 +1294,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL router.GET(baseURL+"/v2/assets/:asset-id", wrapper.LookupAssetByID, m...) router.GET(baseURL+"/v2/assets/:asset-id/balances", wrapper.LookupAssetBalances, m...) router.GET(baseURL+"/v2/assets/:asset-id/transactions", wrapper.LookupAssetTransactions, m...) - router.GET(baseURL+"/v2/blocks", wrapper.SearchForBlocks, m...) + router.GET(baseURL+"/v2/block-headers", wrapper.SearchForBlockHeaders, m...) router.GET(baseURL+"/v2/blocks/:round-number", wrapper.LookupBlock, m...) router.GET(baseURL+"/v2/transactions", wrapper.SearchForTransactions, m...) router.GET(baseURL+"/v2/transactions/:txid", wrapper.LookupTransaction, m...) @@ -1306,233 +1306,233 @@ var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/v2/types.go b/api/generated/v2/types.go index 63dc39fe3..0918237eb 100644 --- a/api/generated/v2/types.go +++ b/api/generated/v2/types.go @@ -1437,14 +1437,8 @@ type AssetsResponse struct { NextToken *string `json:"next-token,omitempty"` } -// BlockResponse Block information. -// -// Definition: -// data/bookkeeping/block.go : Block -type BlockResponse = Block - -// BlocksResponse defines model for BlocksResponse. -type BlocksResponse struct { +// BlockHeadersResponse defines model for BlockHeadersResponse. +type BlockHeadersResponse struct { Blocks []Block `json:"blocks"` // CurrentRound Round at which the results were computed. @@ -1454,6 +1448,12 @@ type BlocksResponse struct { NextToken *string `json:"next-token,omitempty"` } +// BlockResponse Block information. +// +// Definition: +// data/bookkeeping/block.go : Block +type BlockResponse = Block + // BoxResponse Box name and its content. type BoxResponse = Box @@ -1837,8 +1837,8 @@ type LookupAssetTransactionsParamsSigType string // LookupAssetTransactionsParamsAddressRole defines parameters for LookupAssetTransactions. type LookupAssetTransactionsParamsAddressRole string -// SearchForBlocksParams defines parameters for SearchForBlocks. -type SearchForBlocksParams struct { +// SearchForBlockHeadersParams defines parameters for SearchForBlockHeaders. +type SearchForBlockHeadersParams struct { // Limit Maximum number of results to return. There could be additional pages even if the limit is not reached. Limit *uint64 `form:"limit,omitempty" json:"limit,omitempty"` @@ -1857,19 +1857,19 @@ type SearchForBlocksParams struct { // AfterTime Include results after the given time. Must be an RFC 3339 formatted string. AfterTime *time.Time `form:"after-time,omitempty" json:"after-time,omitempty"` - // Proposer Account(s) marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses. + // Proposer Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses. Proposer *[]string `form:"proposer,omitempty" json:"proposer,omitempty"` - // Expired Account(s) marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses. + // Expired Accounts marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses. Expired *[]string `form:"expired,omitempty" json:"expired,omitempty"` - // Absent Account(s) marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses. + // Absent Accounts marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses. Absent *[]string `form:"absent,omitempty" json:"absent,omitempty"` - // Updates Account(s) marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses. + // Updates Accounts marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses. Updates *[]string `form:"updates,omitempty" json:"updates,omitempty"` - // Participation Account(s) marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses. + // Participation Accounts marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses. Participation *[]string `form:"participation,omitempty" json:"participation,omitempty"` } diff --git a/api/handlers.go b/api/handlers.go index f81f3aaf2..58287ca37 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -1004,9 +1004,9 @@ func (si *ServerImplementation) LookupTransaction(ctx echo.Context, txid string) // SearchForBlocks returns block headers matching the provided parameters // (GET /v2/blocks) -func (si *ServerImplementation) SearchForBlocks(ctx echo.Context, params generated.SearchForBlocksParams) error { +func (si *ServerImplementation) SearchForBlockHeaders(ctx echo.Context, params generated.SearchForBlockHeadersParams) error { // Validate query parameters - if err := si.verifyHandler("SearchForBlocks", ctx); err != nil { + if err := si.verifyHandler("SearchForBlockHeaders", ctx); err != nil { return badRequest(ctx, err.Error()) } @@ -1027,7 +1027,7 @@ func (si *ServerImplementation) SearchForBlocks(ctx echo.Context, params generat } // Populate the response model and render it - response := generated.BlocksResponse{ + response := generated.BlockHeadersResponse{ CurrentRound: round, NextToken: strPtr(next), Blocks: blockHeaders, @@ -1045,7 +1045,7 @@ func (si *ServerImplementation) fetchBlockHeaders(ctx context.Context, bf idb.Bl // Open a channel from which result rows will be received var rows <-chan idb.BlockRow - rows, round = si.db.Blocks(ctx, bf) + rows, round = si.db.BlockHeaders(ctx, bf) // Iterate received rows, converting each to a generated.Block var lastRow idb.BlockRow diff --git a/api/indexer.oas2.json b/api/indexer.oas2.json index 0f7ca657f..ac377eb61 100644 --- a/api/indexer.oas2.json +++ b/api/indexer.oas2.json @@ -853,9 +853,9 @@ } } }, - "/v2/blocks": { + "/v2/block-headers": { "get": { - "description": "Search for blocks. Blocks are returned in ascending round order. Transactions are not included in the output.", + "description": "Search for block headers. Block headers are returned in ascending round order. Transactions are not included in the output.", "consumes": [ "application/json" ], @@ -865,7 +865,7 @@ "tags": [ "search" ], - "operationId": "searchForBlocks", + "operationId": "searchForBlockHeaders", "parameters": [ { "$ref": "#/parameters/limit" @@ -903,7 +903,7 @@ ], "responses": { "200": { - "$ref": "#/responses/BlocksResponse" + "$ref": "#/responses/BlockHeadersResponse" }, "404": { "$ref": "#/responses/ErrorResponse" @@ -3295,7 +3295,7 @@ "$ref": "#/definitions/Block" } }, - "BlocksResponse": { + "BlockHeadersResponse": { "description": "(empty)", "schema": { "type": "object", diff --git a/api/indexer.oas3.yml b/api/indexer.oas3.yml index 96fcc87e1..f1c215a4f 100644 --- a/api/indexer.oas3.yml +++ b/api/indexer.oas3.yml @@ -2,7 +2,7 @@ "components": { "parameters": { "absent": { - "description": "Account(s) marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", "name": "absent", @@ -150,7 +150,7 @@ } }, "expired": { - "description": "Account(s) marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", "name": "expired", @@ -222,7 +222,7 @@ "x-algorand-format": "base64" }, "participation": { - "description": "Account(s) marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", "name": "participation", @@ -236,7 +236,7 @@ "style": "form" }, "proposer": { - "description": "Account(s) marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", "name": "proposer", @@ -322,7 +322,7 @@ } }, "updates": { - "description": "Account(s) marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", "name": "updates", @@ -619,17 +619,7 @@ }, "description": "(empty)" }, - "BlockResponse": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Block" - } - } - }, - "description": "(empty)" - }, - "BlocksResponse": { + "BlockHeadersResponse": { "content": { "application/json": { "schema": { @@ -659,6 +649,16 @@ }, "description": "(empty)" }, + "BlockResponse": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Block" + } + } + }, + "description": "(empty)" + }, "BoxResponse": { "content": { "application/json": { @@ -4863,10 +4863,10 @@ ] } }, - "/v2/blocks": { + "/v2/block-headers": { "get": { - "description": "Search for blocks. Blocks are returned in ascending round order. Transactions are not included in the output.", - "operationId": "searchForBlocks", + "description": "Search for block headers. Block headers are returned in ascending round order. Transactions are not included in the output.", + "operationId": "searchForBlockHeaders", "parameters": [ { "description": "Maximum number of results to return. There could be additional pages even if the limit is not reached.", @@ -4923,7 +4923,7 @@ "x-algorand-format": "RFC3339 String" }, { - "description": "Account(s) marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", "name": "proposer", @@ -4937,7 +4937,7 @@ "style": "form" }, { - "description": "Account(s) marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", "name": "expired", @@ -4951,7 +4951,7 @@ "style": "form" }, { - "description": "Account(s) marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", "name": "absent", @@ -4965,7 +4965,7 @@ "style": "form" }, { - "description": "Account(s) marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", "name": "updates", @@ -4979,7 +4979,7 @@ "style": "form" }, { - "description": "Account(s) marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "description": "Accounts marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", "name": "participation", diff --git a/idb/dummy/dummy.go b/idb/dummy/dummy.go index 29552c4c3..e7763f1da 100644 --- a/idb/dummy/dummy.go +++ b/idb/dummy/dummy.go @@ -54,7 +54,7 @@ func (db *dummyIndexerDb) GetBlock(ctx context.Context, round uint64, options id } // Blocks is part of idb.IndexerDB -func (db *dummyIndexerDb) Blocks(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { +func (db *dummyIndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { return nil, 0 } diff --git a/idb/idb.go b/idb/idb.go index 037a6819d..91db9145c 100644 --- a/idb/idb.go +++ b/idb/idb.go @@ -205,7 +205,7 @@ type IndexerDb interface { // The next multiple functions return a channel with results as well as the latest round // accounted. - Blocks(ctx context.Context, bf BlockFilter) (<-chan BlockRow, uint64) + BlockHeaders(ctx context.Context, bf BlockFilter) (<-chan BlockRow, uint64) Transactions(ctx context.Context, tf TransactionFilter) (<-chan TxnRow, uint64) GetAccounts(ctx context.Context, opts AccountQueryOptions) (<-chan AccountRow, uint64) Assets(ctx context.Context, filter AssetsQuery) (<-chan AssetRow, uint64) diff --git a/idb/mocks/IndexerDb.go b/idb/mocks/IndexerDb.go index d5b4e9957..57fa6187e 100644 --- a/idb/mocks/IndexerDb.go +++ b/idb/mocks/IndexerDb.go @@ -186,12 +186,12 @@ func (_m *IndexerDb) Assets(ctx context.Context, filter idb.AssetsQuery) (<-chan return r0, r1 } -// Blocks provides a mock function with given fields: ctx, bf -func (_m *IndexerDb) Blocks(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { +// BlockHeaders provides a mock function with given fields: ctx, bf +func (_m *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { ret := _m.Called(ctx, bf) if len(ret) == 0 { - panic("no return value specified for Blocks") + panic("no return value specified for BlockHeaders") } var r0 <-chan idb.BlockRow diff --git a/idb/postgres/postgres.go b/idb/postgres/postgres.go index ab4b1ae64..949e0239b 100644 --- a/idb/postgres/postgres.go +++ b/idb/postgres/postgres.go @@ -1012,7 +1012,7 @@ func buildBlockFilters(bf idb.BlockFilter) (whereTerms []string, joinTerms []str return whereTerms, joinTerms } -func buildBlockQuery(bf idb.BlockFilter) (query string, err error) { +func buildBlockHeadersQuery(bf idb.BlockFilter) (query string, err error) { // helper function to build CTEs buildCte := func(cteName string, whereTerms []string, joinTerms []string) string { @@ -1139,9 +1139,9 @@ func buildBlockQuery(bf idb.BlockFilter) (query string, err error) { } // This function blocks. `tx` must be non-nil. -func (db *IndexerDb) yieldBlocks(ctx context.Context, tx pgx.Tx, bf idb.BlockFilter, out chan<- idb.BlockRow) { +func (db *IndexerDb) yieldBlockHeaders(ctx context.Context, tx pgx.Tx, bf idb.BlockFilter, out chan<- idb.BlockRow) { - query, err := buildBlockQuery(bf) + query, err := buildBlockHeadersQuery(bf) if err != nil { err = fmt.Errorf("block query err %v", err) out <- idb.BlockRow{Error: err} @@ -1158,7 +1158,7 @@ func (db *IndexerDb) yieldBlocks(ctx context.Context, tx pgx.Tx, bf idb.BlockFil } // Blocks is part of idb.IndexerDB -func (db *IndexerDb) Blocks(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { +func (db *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { out := make(chan idb.BlockRow, 1) tx, err := db.db.BeginTx(ctx, readonlyRepeatableRead) @@ -1179,7 +1179,7 @@ func (db *IndexerDb) Blocks(ctx context.Context, bf idb.BlockFilter) (<-chan idb } go func() { - db.yieldBlocks(ctx, tx, bf, out) + db.yieldBlockHeaders(ctx, tx, bf, out) // Because we return a channel into a "callWithTimeout" function, // We need to make sure that rollback is called before close() // otherwise we can end up with a situation where "callWithTimeout" From 8cb90c11876a9bc8fa70f42c0b7321a6625bdfba Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 19:40:50 -0300 Subject: [PATCH 10/19] Remove the `updates` and `participation` params Remove the `updates` and `participation` parameters from `GET /v2/block-headers`. The underlying SQL code is now simpler. --- api/converter_utils.go | 35 +-- api/generated/common/routes.go | 325 +++++++++++++------------ api/generated/common/types.go | 6 - api/generated/v2/routes.go | 425 ++++++++++++++++----------------- api/generated/v2/types.go | 12 - api/indexer.oas2.json | 28 --- api/indexer.oas3.yml | 56 ----- idb/postgres/postgres.go | 223 ++++++----------- 8 files changed, 435 insertions(+), 675 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index b9d7d2f9c..966a7ea26 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -897,14 +897,8 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search if params.Absent != nil { numParticipationFilters++ } - if params.Updates != nil { - numParticipationFilters++ - } - if params.Participation != nil { - numParticipationFilters++ - } if numParticipationFilters > 1 { - errorArr = append(errorArr, "only one of `proposer`, `expired`, `absent`, `updates`, or `participation` can be specified") + errorArr = append(errorArr, "only one of `proposer`, `expired`, or `absent` can be specified") } // Validate the number of items in the participation account lists @@ -917,12 +911,6 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search if params.Absent != nil && uint64(len(*params.Absent)) > si.opts.MaxAccountListSize { errorArr = append(errorArr, fmt.Sprintf("absent list too long, max size is %d", si.opts.MaxAccountListSize)) } - if params.Updates != nil && uint64(len(*params.Updates)) > si.opts.MaxAccountListSize { - errorArr = append(errorArr, fmt.Sprintf("updates list too long, max size is %d", si.opts.MaxAccountListSize)) - } - if params.Participation != nil && uint64(len(*params.Participation)) > si.opts.MaxAccountListSize { - errorArr = append(errorArr, fmt.Sprintf("participation list too long, max size is %d", si.opts.MaxAccountListSize)) - } filter.Proposers = make(map[sdk.Address]struct{}, 0) if params.Proposer != nil { @@ -950,27 +938,6 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search filter.AbsentParticipationAccounts[addr] = struct{}{} } } - - // Updates = absent || expired - if params.Updates != nil { - for _, s := range *params.Updates { - var addr sdk.Address - addr, errorArr = decodeAddress(s, "updates", errorArr) - filter.AbsentParticipationAccounts[addr] = struct{}{} - filter.ExpiredParticipationAccounts[addr] = struct{}{} - } - } - - // Participation = proposer || absent || expired - if params.Participation != nil { - for _, s := range *params.Participation { - var addr sdk.Address - addr, errorArr = decodeAddress(s, "participation", errorArr) - filter.Proposers[addr] = struct{}{} - filter.AbsentParticipationAccounts[addr] = struct{}{} - filter.ExpiredParticipationAccounts[addr] = struct{}{} - } - } } // If there were any errorArr while setting up the BlockFilter, return now. diff --git a/api/generated/common/routes.go b/api/generated/common/routes.go index 18c19b70d..9d4846e55 100644 --- a/api/generated/common/routes.go +++ b/api/generated/common/routes.go @@ -95,169 +95,168 @@ var swaggerSpec = []string{ "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", - "AA==", + "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", + "SouVkI6qt3y1Ap31+M7/DwAA///TTGMQxeUAAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/common/types.go b/api/generated/common/types.go index 90b8a1c83..7d5e140c8 100644 --- a/api/generated/common/types.go +++ b/api/generated/common/types.go @@ -1210,9 +1210,6 @@ type Next = string // NotePrefix defines model for note-prefix. type NotePrefix = string -// Participation defines model for participation. -type Participation = []string - // Proposer defines model for proposer. type Proposer = []string @@ -1237,9 +1234,6 @@ type TxType string // Txid defines model for txid. type Txid = string -// Updates defines model for updates. -type Updates = []string - // AccountResponse defines model for AccountResponse. type AccountResponse struct { // Account Account information at a given round. diff --git a/api/generated/v2/routes.go b/api/generated/v2/routes.go index 7a4ac1b61..e32354051 100644 --- a/api/generated/v2/routes.go +++ b/api/generated/v2/routes.go @@ -1046,20 +1046,6 @@ func (w *ServerInterfaceWrapper) SearchForBlockHeaders(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter absent: %s", err)) } - // ------------- Optional query parameter "updates" ------------- - - err = runtime.BindQueryParameter("form", false, false, "updates", ctx.QueryParams(), ¶ms.Updates) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter updates: %s", err)) - } - - // ------------- Optional query parameter "participation" ------------- - - err = runtime.BindQueryParameter("form", false, false, "participation", ctx.QueryParams(), ¶ms.Participation) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter participation: %s", err)) - } - // Invoke the callback with all the unmarshalled arguments err = w.Handler.SearchForBlockHeaders(ctx, params) return err @@ -1327,212 +1313,211 @@ var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/v2/types.go b/api/generated/v2/types.go index 0918237eb..b352c80d9 100644 --- a/api/generated/v2/types.go +++ b/api/generated/v2/types.go @@ -1298,9 +1298,6 @@ type Next = string // NotePrefix defines model for note-prefix. type NotePrefix = string -// Participation defines model for participation. -type Participation = []string - // Proposer defines model for proposer. type Proposer = []string @@ -1325,9 +1322,6 @@ type TxType string // Txid defines model for txid. type Txid = string -// Updates defines model for updates. -type Updates = []string - // AccountResponse defines model for AccountResponse. type AccountResponse struct { // Account Account information at a given round. @@ -1865,12 +1859,6 @@ type SearchForBlockHeadersParams struct { // Absent Accounts marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses. Absent *[]string `form:"absent,omitempty" json:"absent,omitempty"` - - // Updates Accounts marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses. - Updates *[]string `form:"updates,omitempty" json:"updates,omitempty"` - - // Participation Accounts marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses. - Participation *[]string `form:"participation,omitempty" json:"participation,omitempty"` } // LookupBlockParams defines parameters for LookupBlock. diff --git a/api/indexer.oas2.json b/api/indexer.oas2.json index ac377eb61..09895a510 100644 --- a/api/indexer.oas2.json +++ b/api/indexer.oas2.json @@ -893,12 +893,6 @@ }, { "$ref": "#/parameters/absent" - }, - { - "$ref": "#/parameters/updates" - }, - { - "$ref": "#/parameters/participation" } ], "responses": { @@ -2771,28 +2765,6 @@ "in": "query", "required": false }, - "updates": { - "type": "array", - "items": { - "type": "string", - "x-algorand-format": "Address" - }, - "description": "Accounts marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", - "name": "updates", - "in": "query", - "required": false - }, - "participation": { - "type": "array", - "items": { - "type": "string", - "x-algorand-format": "Address" - }, - "description": "Accounts marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", - "name": "participation", - "in": "query", - "required": false - }, "account-id": { "type": "string", "description": "account string", diff --git a/api/indexer.oas3.yml b/api/indexer.oas3.yml index f1c215a4f..761643bc3 100644 --- a/api/indexer.oas3.yml +++ b/api/indexer.oas3.yml @@ -221,20 +221,6 @@ }, "x-algorand-format": "base64" }, - "participation": { - "description": "Accounts marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", - "explode": false, - "in": "query", - "name": "participation", - "schema": { - "items": { - "type": "string", - "x-algorand-format": "Address" - }, - "type": "array" - }, - "style": "form" - }, "proposer": { "description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, @@ -320,20 +306,6 @@ "schema": { "type": "string" } - }, - "updates": { - "description": "Accounts marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", - "explode": false, - "in": "query", - "name": "updates", - "schema": { - "items": { - "type": "string", - "x-algorand-format": "Address" - }, - "type": "array" - }, - "style": "form" } }, "responses": { @@ -4963,34 +4935,6 @@ "type": "array" }, "style": "form" - }, - { - "description": "Accounts marked as expired or absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", - "explode": false, - "in": "query", - "name": "updates", - "schema": { - "items": { - "type": "string", - "x-algorand-format": "Address" - }, - "type": "array" - }, - "style": "form" - }, - { - "description": "Accounts marked as expired, absent or as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", - "explode": false, - "in": "query", - "name": "participation", - "schema": { - "items": { - "type": "string", - "x-algorand-format": "Address" - }, - "type": "array" - }, - "style": "form" } ], "responses": { diff --git a/idb/postgres/postgres.go b/idb/postgres/postgres.go index 949e0239b..83d324f7a 100644 --- a/idb/postgres/postgres.go +++ b/idb/postgres/postgres.go @@ -949,191 +949,102 @@ finish: } } -// buildBlockFilters generates filters based on a block's round and/or timestamp. -// -// Filters related to participation are generated elsewhere. -// -// Some of the filters are meant to be used as boolean conditions in the WHERE clause. -// Others, for performance reasons, have to be used as INNER JOIN terms in the FROM clause. -func buildBlockFilters(bf idb.BlockFilter) (whereTerms []string, joinTerms []string) { - - // Round-based filters - if bf.MaxRound != nil { - whereTerms = append( - whereTerms, - fmt.Sprintf("bh.round <= %d", *bf.MaxRound), - ) - } - if bf.MinRound != nil { - whereTerms = append( - whereTerms, - fmt.Sprintf("bh.round >= %d", *bf.MinRound), - ) - } - - // Timestamp-based filters - // - // Converting the timestamp into a round usually results in faster execution plans - // (compared to the execution plans that would result from using the `block_header.realtime` column directly) - // - // Unfortunately, writing this condition in the WHERE clause results in poor execution plans. - // Expressing the filter as an INNER JOIN results in an efficient query execution plan. - if !bf.AfterTime.IsZero() { - tmpl := ` - INNER JOIN ( - SELECT COALESCE(tmp.round, 0) AS round - FROM block_header tmp - WHERE tmp.realtime > (to_timestamp(%d) AT TIME ZONE 'UTC') - ORDER BY tmp.realtime ASC, tmp.round ASC - LIMIT 1 - ) bh_at ON bh.round >= bh_at.round - ` - joinTerms = append( - joinTerms, - fmt.Sprintf(tmpl, bf.AfterTime.UTC().Unix()), - ) - } - if !bf.BeforeTime.IsZero() { - tmpl := ` - INNER JOIN ( - SELECT COALESCE(tmp.round, 0) AS round +func buildBlockHeadersQuery(bf idb.BlockFilter) (query string, err error) { + + // Build the terms for the WHERE clause based on the input parameters + var whereTerms []string + { + // Round-based filters + if bf.MaxRound != nil { + whereTerms = append( + whereTerms, + fmt.Sprintf("bh.round <= %d", *bf.MaxRound), + ) + } + if bf.MinRound != nil { + whereTerms = append( + whereTerms, + fmt.Sprintf("bh.round >= %d", *bf.MinRound), + ) + } + + // Timestamp-based filters + // + // Converting the timestamp into a round usually results in faster execution plans + // (compared to the execution plans that would result from using the `block_header.realtime` column directly) + if !bf.AfterTime.IsZero() { + tmpl := `bh.round >= ( + SELECT tmp.round + FROM block_header tmp + WHERE tmp.realtime > (to_timestamp(%d) AT TIME ZONE 'UTC') + ORDER BY tmp.realtime ASC, tmp.round ASC + LIMIT 1 + )` + whereTerms = append( + whereTerms, + fmt.Sprintf(tmpl, bf.AfterTime.UTC().Unix()), + ) + } + if !bf.BeforeTime.IsZero() { + tmpl := `bh.round <= ( + SELECT tmp.round FROM block_header tmp WHERE tmp.realtime < (to_timestamp(%d) AT TIME ZONE 'UTC') ORDER BY tmp.realtime DESC, tmp.round DESC LIMIT 1 - ) bh_bt ON bh.round <= bh_bt.round - ` - joinTerms = append( - joinTerms, - fmt.Sprintf(tmpl, bf.BeforeTime.UTC().Unix()), - ) - } - - return whereTerms, joinTerms -} - -func buildBlockHeadersQuery(bf idb.BlockFilter) (query string, err error) { + )` + whereTerms = append( + whereTerms, + fmt.Sprintf(tmpl, bf.BeforeTime.UTC().Unix()), + ) + } - // helper function to build CTEs - buildCte := func(cteName string, whereTerms []string, joinTerms []string) string { - tmpl := `%s AS ( - SELECT bh.round, bh.header - FROM block_header bh - %s - WHERE %s - ORDER BY bh.round ASC - LIMIT %d - )` - return fmt.Sprintf(tmpl, cteName, strings.Join(joinTerms, "\n"), strings.Join(whereTerms, " AND "), bf.Limit) - } - - // Build auxiliary CTEs for participation-related parameters. - // - // Using CTEs in this way turned out to be necessary to lead CockroachDB's query optimizer - // into using the execution plan we want. - // - // If we were to put the CTE filters in the main query's WHERE clause, that would result - // in a sub-optimal execution plan. At least this was the case at the time of writing. - var CTEs []string - var CteNames []string - { + // Participation-based filters if len(bf.Proposers) > 0 { - whereTerms, joinTerms := buildBlockFilters(bf) - var proposersStr []string + var ps []string for addr := range bf.Proposers { - proposersStr = append(proposersStr, `'"`+addr.String()+`"'`) + ps = append(ps, `'"`+addr.String()+`"'`) } whereTerms = append( whereTerms, - fmt.Sprintf("( (bh.header->'prp') IS NOT NULL AND ((bh.header->'prp')::TEXT IN (%s)) )", strings.Join(proposersStr, ",")), + fmt.Sprintf("( (bh.header->'prp') IS NOT NULL AND ((bh.header->'prp')::TEXT IN (%s)) )", strings.Join(ps, ",")), ) - - cteName := "prp" - cte := buildCte(cteName, whereTerms, joinTerms) - CTEs = append(CTEs, cte) - CteNames = append(CteNames, cteName) - } if len(bf.ExpiredParticipationAccounts) > 0 { - whereTerms, joinTerms := buildBlockFilters(bf) - var expiredStr []string + var es []string for addr := range bf.ExpiredParticipationAccounts { - expiredStr = append(expiredStr, `'`+addr.String()+`'`) + es = append(es, `'`+addr.String()+`'`) } whereTerms = append( whereTerms, - fmt.Sprintf("( (bh.header->'partupdrmv') IS NOT NULL AND (bh.header->'partupdrmv') ?| array[%s] )", strings.Join(expiredStr, ",")), + fmt.Sprintf("( (bh.header->'partupdrmv') IS NOT NULL AND (bh.header->'partupdrmv') ?| array[%s] )", strings.Join(es, ",")), ) - - cteName := "expired" - CTE := buildCte(cteName, whereTerms, joinTerms) - CTEs = append(CTEs, CTE) - CteNames = append(CteNames, "expired") - } if len(bf.AbsentParticipationAccounts) > 0 { - whereTerms, joinTerms := buildBlockFilters(bf) - var absentStr []string + var as []string for addr := range bf.AbsentParticipationAccounts { - absentStr = append(absentStr, `'`+addr.String()+`'`) + as = append(as, `'`+addr.String()+`'`) } whereTerms = append( whereTerms, - fmt.Sprintf("( (bh.header->'partupdabs') IS NOT NULL AND (bh.header->'partupdabs') ?| array[%s] )", strings.Join(absentStr, ",")), + fmt.Sprintf("( (bh.header->'partupdabs') IS NOT NULL AND (bh.header->'partupdabs') ?| array[%s] )", strings.Join(as, ",")), ) - - cteName := "absent" - CTE := buildCte(cteName, whereTerms, joinTerms) - CTEs = append(CTEs, CTE) - CteNames = append(CteNames, cteName) } - if len(CteNames) > 0 { - var selects []string - for _, cteName := range CteNames { - selects = append(selects, fmt.Sprintf("SELECT * FROM %s", cteName)) - } - CTE := "tmp AS (" + strings.Join(selects, " UNION ") + ")" - CTEs = append(CTEs, CTE) - } - } - // Build the main query. It uses the CTEs, if any. - { - var withClause string - if len(CTEs) > 0 { - withClause = "WITH " + strings.Join(CTEs, ",\n") - } - - var fromTable string - if len(CTEs) > 0 { - fromTable = "tmp bh" - } else { - fromTable = "block_header bh" - } - - var whereClause string - var joinClause string - if len(CTEs) == 0 { - whereTerms, joinTerms := buildBlockFilters(bf) - if len(whereTerms) > 0 { - whereClause = "WHERE " + strings.Join(whereTerms, " AND ") + "\n" - } - if len(joinTerms) > 0 { - joinClause = strings.Join(joinTerms, "\n") - } - } - - tmpl := ` - %s - SELECT bh.header - FROM %s - %s - %s - ORDER BY bh.round ASC - LIMIT %d` + } - query = fmt.Sprintf(tmpl, withClause, fromTable, joinClause, whereClause, bf.Limit) + // Build the full SQL query + var whereClause string + if len(whereTerms) > 0 { + whereClause = "WHERE " + strings.Join(whereTerms, " AND ") } + tmpl := ` + SELECT bh.header + FROM block_header bh + %s + ORDER BY bh.round ASC + LIMIT %d` + query = fmt.Sprintf(tmpl, whereClause, bf.Limit) return query, nil } From 0fa808b442679c8c874787d5912c1fcd4a277984 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 20:25:37 -0300 Subject: [PATCH 11/19] Lints --- api/handlers.go | 2 +- idb/postgres/postgres.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/handlers.go b/api/handlers.go index 58287ca37..ede26984d 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -1002,7 +1002,7 @@ func (si *ServerImplementation) LookupTransaction(ctx echo.Context, txid string) return ctx.JSON(http.StatusOK, response) } -// SearchForBlocks returns block headers matching the provided parameters +// SearchForBlockHeaders returns block headers matching the provided parameters // (GET /v2/blocks) func (si *ServerImplementation) SearchForBlockHeaders(ctx echo.Context, params generated.SearchForBlockHeadersParams) error { // Validate query parameters diff --git a/idb/postgres/postgres.go b/idb/postgres/postgres.go index 83d324f7a..ad3243068 100644 --- a/idb/postgres/postgres.go +++ b/idb/postgres/postgres.go @@ -1068,7 +1068,7 @@ func (db *IndexerDb) yieldBlockHeaders(ctx context.Context, tx pgx.Tx, bf idb.Bl db.yieldBlocksThreadSimple(rows, out) } -// Blocks is part of idb.IndexerDB +// BlockHeaders is part of idb.IndexerDB func (db *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { out := make(chan idb.BlockRow, 1) From 42669136054394c925a3d5d0912552fff242bdfe Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 20:29:27 -0300 Subject: [PATCH 12/19] Rename struct --- api/converter_utils.go | 4 ++-- api/handlers.go | 4 ++-- idb/dummy/dummy.go | 2 +- idb/idb.go | 6 +++--- idb/mocks/IndexerDb.go | 8 ++++---- idb/postgres/postgres.go | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index 966a7ea26..e41fb6b59 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -847,7 +847,7 @@ func (si *ServerImplementation) transactionParamsToTransactionFilter(params gene return } -func (si *ServerImplementation) blockParamsToBlockFilter(params generated.SearchForBlockHeadersParams) (filter idb.BlockFilter, err error) { +func (si *ServerImplementation) blockParamsToBlockFilter(params generated.SearchForBlockHeadersParams) (filter idb.BlockHeaderFilter, err error) { var errorArr []string // Integer @@ -945,7 +945,7 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search err = errors.New("invalid input: " + strings.Join(errorArr, ", ")) // clear out the intermediates. - filter = idb.BlockFilter{} + filter = idb.BlockHeaderFilter{} } return } diff --git a/api/handlers.go b/api/handlers.go index ede26984d..e595cfd72 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -45,7 +45,7 @@ type ServerImplementation struct { // Helper functions // ////////////////////// -func validateBlockFilter(filter *idb.BlockFilter) error { +func validateBlockFilter(filter *idb.BlockHeaderFilter) error { var errorArr = make([]string, 0) // Int64 overflows @@ -1036,7 +1036,7 @@ func (si *ServerImplementation) SearchForBlockHeaders(ctx echo.Context, params g } // fetchBlockHeaders is used to query the backend for block headers, and compute the next token -func (si *ServerImplementation) fetchBlockHeaders(ctx context.Context, bf idb.BlockFilter) ([]generated.Block, string, uint64 /*round*/, error) { +func (si *ServerImplementation) fetchBlockHeaders(ctx context.Context, bf idb.BlockHeaderFilter) ([]generated.Block, string, uint64 /*round*/, error) { var round uint64 var nextToken string diff --git a/idb/dummy/dummy.go b/idb/dummy/dummy.go index e7763f1da..459e9d8db 100644 --- a/idb/dummy/dummy.go +++ b/idb/dummy/dummy.go @@ -54,7 +54,7 @@ func (db *dummyIndexerDb) GetBlock(ctx context.Context, round uint64, options id } // Blocks is part of idb.IndexerDB -func (db *dummyIndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { +func (db *dummyIndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockHeaderFilter) (<-chan idb.BlockRow, uint64) { return nil, 0 } diff --git a/idb/idb.go b/idb/idb.go index 91db9145c..3381045ac 100644 --- a/idb/idb.go +++ b/idb/idb.go @@ -205,7 +205,7 @@ type IndexerDb interface { // The next multiple functions return a channel with results as well as the latest round // accounted. - BlockHeaders(ctx context.Context, bf BlockFilter) (<-chan BlockRow, uint64) + BlockHeaders(ctx context.Context, bf BlockHeaderFilter) (<-chan BlockRow, uint64) Transactions(ctx context.Context, tf TransactionFilter) (<-chan TxnRow, uint64) GetAccounts(ctx context.Context, opts AccountQueryOptions) (<-chan AccountRow, uint64) Assets(ctx context.Context, filter AssetsQuery) (<-chan AssetRow, uint64) @@ -228,8 +228,8 @@ type GetBlockOptions struct { MaxTransactionsLimit uint64 } -// BlockFilter is a parameter object with all the block filter options. -type BlockFilter struct { +// BlockHeaderFilter is a parameter object with all the block filter options. +type BlockHeaderFilter struct { Limit uint64 MaxRound *uint64 MinRound *uint64 diff --git a/idb/mocks/IndexerDb.go b/idb/mocks/IndexerDb.go index 57fa6187e..f7b03c408 100644 --- a/idb/mocks/IndexerDb.go +++ b/idb/mocks/IndexerDb.go @@ -187,7 +187,7 @@ func (_m *IndexerDb) Assets(ctx context.Context, filter idb.AssetsQuery) (<-chan } // BlockHeaders provides a mock function with given fields: ctx, bf -func (_m *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { +func (_m *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockHeaderFilter) (<-chan idb.BlockRow, uint64) { ret := _m.Called(ctx, bf) if len(ret) == 0 { @@ -196,10 +196,10 @@ func (_m *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockFilter) (<-ch var r0 <-chan idb.BlockRow var r1 uint64 - if rf, ok := ret.Get(0).(func(context.Context, idb.BlockFilter) (<-chan idb.BlockRow, uint64)); ok { + if rf, ok := ret.Get(0).(func(context.Context, idb.BlockHeaderFilter) (<-chan idb.BlockRow, uint64)); ok { return rf(ctx, bf) } - if rf, ok := ret.Get(0).(func(context.Context, idb.BlockFilter) <-chan idb.BlockRow); ok { + if rf, ok := ret.Get(0).(func(context.Context, idb.BlockHeaderFilter) <-chan idb.BlockRow); ok { r0 = rf(ctx, bf) } else { if ret.Get(0) != nil { @@ -207,7 +207,7 @@ func (_m *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockFilter) (<-ch } } - if rf, ok := ret.Get(1).(func(context.Context, idb.BlockFilter) uint64); ok { + if rf, ok := ret.Get(1).(func(context.Context, idb.BlockHeaderFilter) uint64); ok { r1 = rf(ctx, bf) } else { r1 = ret.Get(1).(uint64) diff --git a/idb/postgres/postgres.go b/idb/postgres/postgres.go index ad3243068..7e41128eb 100644 --- a/idb/postgres/postgres.go +++ b/idb/postgres/postgres.go @@ -949,7 +949,7 @@ finish: } } -func buildBlockHeadersQuery(bf idb.BlockFilter) (query string, err error) { +func buildBlockHeadersQuery(bf idb.BlockHeaderFilter) (query string, err error) { // Build the terms for the WHERE clause based on the input parameters var whereTerms []string @@ -1050,7 +1050,7 @@ func buildBlockHeadersQuery(bf idb.BlockFilter) (query string, err error) { } // This function blocks. `tx` must be non-nil. -func (db *IndexerDb) yieldBlockHeaders(ctx context.Context, tx pgx.Tx, bf idb.BlockFilter, out chan<- idb.BlockRow) { +func (db *IndexerDb) yieldBlockHeaders(ctx context.Context, tx pgx.Tx, bf idb.BlockHeaderFilter, out chan<- idb.BlockRow) { query, err := buildBlockHeadersQuery(bf) if err != nil { @@ -1069,7 +1069,7 @@ func (db *IndexerDb) yieldBlockHeaders(ctx context.Context, tx pgx.Tx, bf idb.Bl } // BlockHeaders is part of idb.IndexerDB -func (db *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockFilter) (<-chan idb.BlockRow, uint64) { +func (db *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockHeaderFilter) (<-chan idb.BlockRow, uint64) { out := make(chan idb.BlockRow, 1) tx, err := db.db.BeginTx(ctx, readonlyRepeatableRead) From 500d881f6d6973493a288bb2c2aab069c05e0243 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 20:31:56 -0300 Subject: [PATCH 13/19] Fix outdated comment --- api/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/server.go b/api/server.go index 75e7558b6..aadd58420 100644 --- a/api/server.go +++ b/api/server.go @@ -48,7 +48,7 @@ type ExtraOptions struct { MaxAPIResourcesPerAccount uint64 // MaxAccountListSize is the maximum number of items that can be passed in query parameter account lists. - // (e.g.: GET /v2/blocks?proposer=A,B,C) + // (e.g.: GET /v2/block-headers?proposer=A,B,C) // // Zero means unlimited. MaxAccountListSize uint64 From 82e864bfb760ebec9056d80c83d63f7929f1eb65 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 20:49:24 -0300 Subject: [PATCH 14/19] Use faster/simpler sorting function --- api/converter_utils.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index e41fb6b59..b12ebcd09 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "errors" "fmt" + "slices" "sort" "strconv" "strings" @@ -360,7 +361,7 @@ func rowToBlock(blockHeader *sdk.BlockHeader) generated.Block { orderedTrackingTypes[elems] = key elems++ } - sort.Slice(orderedTrackingTypes, func(i, j int) bool { return orderedTrackingTypes[i] < orderedTrackingTypes[j] }) + slices.Sort(orderedTrackingTypes) for i := 0; i < len(orderedTrackingTypes); i++ { stpfTracking := blockHeader.StateProofTracking[orderedTrackingTypes[i]] thing1 := generated.StateProofTracking{ From eaefec7e83a256b20b77ab63ac75fd63e5874fca Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 20:58:05 -0300 Subject: [PATCH 15/19] Use a more descriptive name for func `rowToBlock` --- api/converter_utils.go | 2 +- api/handlers.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index b12ebcd09..5e47caaef 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -309,7 +309,7 @@ func txnRowToTransaction(row idb.TxnRow) (generated.Transaction, error) { return txn, nil } -func rowToBlock(blockHeader *sdk.BlockHeader) generated.Block { +func hdrRowToBlock(blockHeader *sdk.BlockHeader) generated.Block { rewards := generated.BlockRewards{ FeeSink: blockHeader.FeeSink.String(), diff --git a/api/handlers.go b/api/handlers.go index e595cfd72..be4bc93c3 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -1054,7 +1054,7 @@ func (si *ServerImplementation) fetchBlockHeaders(ctx context.Context, bf idb.Bl return row.Error } - results = append(results, rowToBlock(&row.BlockHeader)) + results = append(results, hdrRowToBlock(&row.BlockHeader)) lastRow = row } From 7f26e0fbc48bfd655fcb0cc1cf6b3fced7e7fc8c Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 22:20:46 -0300 Subject: [PATCH 16/19] Remove decodeAddress / decodeAddressToBytes Remove the functions `decodeAddress` and `decodeAddressToBytes`. Also, add more context information to the errors being returned. --- api/converter_utils.go | 110 ++++++++++++++++++++--------------------- api/handlers.go | 33 +++++++------ 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index 5e47caaef..09b8ebff0 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -35,29 +35,6 @@ func decodeDigest(str *string, field string, errorArr []string) (string, []strin return "", errorArr } -// decodeAddress returns the sdk.Address representation of the input string, or appends an error to errorArr -func decodeAddress(str string, field string, errorArr []string) (sdk.Address, []string) { - addr, err := sdk.DecodeAddress(str) - if err != nil { - return sdk.ZeroAddress, append(errorArr, fmt.Sprintf("%s '%s': %v", errUnableToParseAddress, field, err)) - } - // Pass through - return addr, errorArr -} - -// decodeAddressToBytes returns the byte representation of the input string, or appends an error to errorArr -func decodeAddressToBytes(str *string, field string, errorArr []string) ([]byte, []string) { - if str != nil { - addr, err := sdk.DecodeAddress(*str) - if err != nil { - return nil, append(errorArr, fmt.Sprintf("%s '%s': %v", errUnableToParseAddress, field, err)) - } - return addr[:], errorArr - } - // Pass through - return nil, errorArr -} - // decodeAddress converts the role information into a bitmask, or appends an error to errorArr func decodeAddressRole(role *string, excludeCloseTo *bool, errorArr []string) (idb.AddressRole, []string) { // If the string is nil, return early. @@ -739,9 +716,14 @@ func edIndexToAddress(index uint64, txn sdk.Transaction, shared []sdk.Address) ( } func (si *ServerImplementation) assetParamsToAssetQuery(params generated.SearchForAssetsParams) (idb.AssetsQuery, error) { - creator, errorArr := decodeAddressToBytes(params.Creator, "creator", make([]string, 0)) - if len(errorArr) != 0 { - return idb.AssetsQuery{}, errors.New(errUnableToParseAddress) + + var creatorAddressBytes []byte + if params.Creator != nil { + creator, err := sdk.DecodeAddress(*params.Creator) + if err != nil { + return idb.AssetsQuery{}, fmt.Errorf("unable to parse creator address: %w", err) + } + creatorAddressBytes = creator[:] } var assetGreaterThan *uint64 @@ -756,7 +738,7 @@ func (si *ServerImplementation) assetParamsToAssetQuery(params generated.SearchF query := idb.AssetsQuery{ AssetID: params.AssetId, AssetIDGreaterThan: assetGreaterThan, - Creator: creator, + Creator: creatorAddressBytes, Name: strOrDefault(params.Name), Unit: strOrDefault(params.Unit), Query: "", @@ -768,9 +750,14 @@ func (si *ServerImplementation) assetParamsToAssetQuery(params generated.SearchF } func (si *ServerImplementation) appParamsToApplicationQuery(params generated.SearchForApplicationsParams) (idb.ApplicationQuery, error) { - addr, errorArr := decodeAddressToBytes(params.Creator, "creator", make([]string, 0)) - if len(errorArr) != 0 { - return idb.ApplicationQuery{}, errors.New(errUnableToParseAddress) + + var creatorAddressBytes []byte + if params.Creator != nil { + addr, err := sdk.DecodeAddress(*params.Creator) + if err != nil { + return idb.ApplicationQuery{}, fmt.Errorf("unable to parse creator address: %w", err) + } + creatorAddressBytes = addr[:] } var appGreaterThan *uint64 @@ -785,7 +772,7 @@ func (si *ServerImplementation) appParamsToApplicationQuery(params generated.Sea return idb.ApplicationQuery{ ApplicationID: params.ApplicationId, ApplicationIDGreaterThan: appGreaterThan, - Address: addr, + Address: creatorAddressBytes, IncludeDeleted: boolOrDefault(params.IncludeAll), Limit: min(uintOrDefaultValue(params.Limit, si.opts.DefaultApplicationsLimit), si.opts.MaxApplicationsLimit), }, nil @@ -807,7 +794,15 @@ func (si *ServerImplementation) transactionParamsToTransactionFilter(params gene filter.NextToken = strOrDefault(params.Next) // Address - filter.Address, errorArr = decodeAddressToBytes(params.Address, "address", errorArr) + if params.Address != nil { + addr, err := sdk.DecodeAddress(*params.Address) + if err != nil { + errorArr = append(errorArr, fmt.Sprintf("%s: %v", errUnableToParseAddress, err)) + } + filter.Address = addr[:] + } + + // Txid filter.Txid, errorArr = decodeDigest(params.Txid, "txid", errorArr) // Byte array @@ -849,7 +844,8 @@ func (si *ServerImplementation) transactionParamsToTransactionFilter(params gene } func (si *ServerImplementation) blockParamsToBlockFilter(params generated.SearchForBlockHeadersParams) (filter idb.BlockHeaderFilter, err error) { - var errorArr []string + + var errs []error // Integer filter.Limit = min(uintOrDefaultValue(params.Limit, si.opts.DefaultBlocksLimit), si.opts.MaxBlocksLimit) @@ -858,7 +854,7 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search // This check is performed here instead of in validateBlockFilter because // when converting params into a filter, the next token is merged with params.MinRound. if params.MinRound != nil && params.MaxRound != nil && *params.MinRound > *params.MaxRound { - errorArr = append(errorArr, errInvalidRoundMinMax) + errs = append(errs, errors.New(errInvalidRoundMinMax)) } filter.MaxRound = params.MaxRound filter.MinRound = params.MinRound @@ -867,7 +863,7 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search if params.Next != nil { n, err := idb.DecodeBlockRowNext(*params.Next) if err != nil { - errorArr = append(errorArr, fmt.Sprintf("%s: %v", errUnableToParseNext, err)) + errs = append(errs, fmt.Errorf("%s: %w", errUnableToParseNext, err)) } // Set the MinRound if filter.MinRound == nil { @@ -899,56 +895,58 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search numParticipationFilters++ } if numParticipationFilters > 1 { - errorArr = append(errorArr, "only one of `proposer`, `expired`, or `absent` can be specified") + errs = append(errs, errors.New("only one of `proposer`, `expired`, or `absent` can be specified")) } // Validate the number of items in the participation account lists if params.Proposer != nil && uint64(len(*params.Proposer)) > si.opts.MaxAccountListSize { - errorArr = append(errorArr, fmt.Sprintf("proposer list too long, max size is %d", si.opts.MaxAccountListSize)) + errs = append(errs, fmt.Errorf("proposer list too long, max size is %d", si.opts.MaxAccountListSize)) } if params.Expired != nil && uint64(len(*params.Expired)) > si.opts.MaxAccountListSize { - errorArr = append(errorArr, fmt.Sprintf("expired list too long, max size is %d", si.opts.MaxAccountListSize)) + errs = append(errs, fmt.Errorf("expired list too long, max size is %d", si.opts.MaxAccountListSize)) } if params.Absent != nil && uint64(len(*params.Absent)) > si.opts.MaxAccountListSize { - errorArr = append(errorArr, fmt.Sprintf("absent list too long, max size is %d", si.opts.MaxAccountListSize)) + errs = append(errs, fmt.Errorf("absent list too long, max size is %d", si.opts.MaxAccountListSize)) } filter.Proposers = make(map[sdk.Address]struct{}, 0) if params.Proposer != nil { for _, s := range *params.Proposer { - var addr sdk.Address - addr, errorArr = decodeAddress(s, "proposer", errorArr) - filter.Proposers[addr] = struct{}{} + addr, err := sdk.DecodeAddress(s) + if err != nil { + errs = append(errs, fmt.Errorf("unable to parse proposer address `%s`: %w", s, err)) + } else { + filter.Proposers[addr] = struct{}{} + } } } filter.ExpiredParticipationAccounts = make(map[sdk.Address]struct{}, 0) if params.Expired != nil { for _, s := range *params.Expired { - var addr sdk.Address - addr, errorArr = decodeAddress(s, "expired", errorArr) - filter.ExpiredParticipationAccounts[addr] = struct{}{} + addr, err := sdk.DecodeAddress(s) + if err != nil { + errs = append(errs, fmt.Errorf("unable to parse expired address `%s`: %w", s, err)) + } else { + filter.ExpiredParticipationAccounts[addr] = struct{}{} + } } } filter.AbsentParticipationAccounts = make(map[sdk.Address]struct{}, 0) if params.Absent != nil { for _, s := range *params.Absent { - var addr sdk.Address - addr, errorArr = decodeAddress(s, "absent", errorArr) - filter.AbsentParticipationAccounts[addr] = struct{}{} + addr, err := sdk.DecodeAddress(s) + if err != nil { + errs = append(errs, fmt.Errorf("unable to parse absent address `%s`: %w", s, err)) + } else { + filter.AbsentParticipationAccounts[addr] = struct{}{} + } } } } - // If there were any errorArr while setting up the BlockFilter, return now. - if len(errorArr) > 0 { - err = errors.New("invalid input: " + strings.Join(errorArr, ", ")) - - // clear out the intermediates. - filter = idb.BlockHeaderFilter{} - } - return + return filter, errors.Join(errs...) } func (si *ServerImplementation) maxAccountsErrorToAccountsErrorResponse(maxErr idb.MaxAPIResourcesPerAccountError) generated.ErrorResponse { diff --git a/api/handlers.go b/api/handlers.go index be4bc93c3..933d160fa 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -214,9 +214,9 @@ func (si *ServerImplementation) LookupAccountByID(ctx echo.Context, accountID st return badRequest(ctx, errRewindingAccountNotSupported) } - addr, decodeErrors := decodeAddressToBytes(&accountID, "account-id", make([]string, 0)) - if len(decodeErrors) != 0 { - return badRequest(ctx, decodeErrors[0]) + addr, err := sdk.DecodeAddress(accountID) + if err != nil { + return badRequest(ctx, fmt.Sprintf("%s: %v", errUnableToParseAddress, err)) } options := idb.AccountQueryOptions{ @@ -314,9 +314,9 @@ func (si *ServerImplementation) LookupAccountAssets(ctx echo.Context, accountID return notFound(ctx, errValueExceedingInt64) } - addr, errors := decodeAddressToBytes(&accountID, "account-id", make([]string, 0)) - if len(errors) != 0 { - return badRequest(ctx, errors[0]) + addr, err := sdk.DecodeAddress(accountID) + if err != nil { + return badRequest(ctx, fmt.Sprintf("%s: %v", errUnableToParseAddress, err)) } var assetGreaterThan *uint64 @@ -329,7 +329,7 @@ func (si *ServerImplementation) LookupAccountAssets(ctx echo.Context, accountID } query := idb.AssetBalanceQuery{ - Address: addr, + Address: addr[:], AssetID: params.AssetId, AssetIDGT: assetGreaterThan, IncludeDeleted: boolOrDefault(params.IncludeAll), @@ -408,9 +408,13 @@ func (si *ServerImplementation) SearchForAccounts(ctx echo.Context, params gener return badRequest(ctx, errRewindingAccountNotSupported) } - spendingAddr, decodeErrors := decodeAddressToBytes(params.AuthAddr, "account-id", make([]string, 0)) - if len(decodeErrors) != 0 { - return badRequest(ctx, decodeErrors[0]) + var spendingAddrBytes []byte + if params.AuthAddr != nil { + spendingAddr, err := sdk.DecodeAddress(*params.AuthAddr) + if err != nil { + return badRequest(ctx, fmt.Sprintf("unable to parse auth addr: %v", err)) + } + spendingAddrBytes = spendingAddr[:] } options := idb.AccountQueryOptions{ @@ -421,7 +425,7 @@ func (si *ServerImplementation) SearchForAccounts(ctx echo.Context, params gener Limit: min(uintOrDefaultValue(params.Limit, si.opts.DefaultAccountsLimit), si.opts.MaxAccountsLimit), HasAssetID: uintOrDefault(params.AssetId), HasAppID: uintOrDefault(params.ApplicationId), - EqualToAuthAddr: spendingAddr[:], + EqualToAuthAddr: spendingAddrBytes, IncludeDeleted: boolOrDefault(params.IncludeAll), MaxResources: si.opts.MaxAPIResourcesPerAccount, } @@ -486,10 +490,11 @@ func (si *ServerImplementation) LookupAccountTransactions(ctx echo.Context, acco if (params.AssetId != nil && uint64(*params.AssetId) > math.MaxInt64) || (params.Round != nil && uint64(*params.Round) > math.MaxInt64) { return notFound(ctx, errValueExceedingInt64) } + // Check that a valid account was provided - _, errors := decodeAddressToBytes(strPtr(accountID), "account-id", make([]string, 0)) - if len(errors) != 0 { - return badRequest(ctx, errors[0]) + _, err := sdk.DecodeAddress(accountID) + if err != nil { + return badRequest(ctx, fmt.Sprintf("%s: %v", errUnableToParseAddress, err)) } searchParams := generated.SearchForTransactionsParams{ From 99c47395b8986ca69cc0bd1a152bb0acec5bfdb7 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Thu, 21 Nov 2024 22:39:24 -0300 Subject: [PATCH 17/19] Attempt at fixing broken test Attempt at fixing `TestTimeouts/LookupAccountTransactions` --- api/handlers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/handlers_test.go b/api/handlers_test.go index a64aa31e0..c18323513 100644 --- a/api/handlers_test.go +++ b/api/handlers_test.go @@ -846,7 +846,7 @@ func TestTimeouts(t *testing.T) { errString: errTransactionSearch, mockCall: transactionFunc, callHandler: func(ctx echo.Context, si ServerImplementation) error { - return si.LookupAccountTransactions(ctx, "", generated.LookupAccountTransactionsParams{}) + return si.LookupAccountTransactions(ctx, "MONEYMBRSMUAM2NGL6PCEQEDVHFWAQB6DU47NUS6P5DJM4OJFN7E7DSVBA", generated.LookupAccountTransactionsParams{}) }, }, { From 8924c97009a56066562086b499273a822bbd4261 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Fri, 22 Nov 2024 09:06:31 -0300 Subject: [PATCH 18/19] Change function `hdrRowToBlock` signature Change function `hdrRowToBlock` signature to be in line with other similar functions. --- api/converter_utils.go | 76 +++++++++++++++++++++--------------------- api/handlers.go | 2 +- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index 09b8ebff0..c22da32a9 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -286,43 +286,43 @@ func txnRowToTransaction(row idb.TxnRow) (generated.Transaction, error) { return txn, nil } -func hdrRowToBlock(blockHeader *sdk.BlockHeader) generated.Block { +func hdrRowToBlock(row idb.BlockRow) generated.Block { rewards := generated.BlockRewards{ - FeeSink: blockHeader.FeeSink.String(), - RewardsCalculationRound: uint64(blockHeader.RewardsRecalculationRound), - RewardsLevel: blockHeader.RewardsLevel, - RewardsPool: blockHeader.RewardsPool.String(), - RewardsRate: blockHeader.RewardsRate, - RewardsResidue: blockHeader.RewardsResidue, + FeeSink: row.BlockHeader.FeeSink.String(), + RewardsCalculationRound: uint64(row.BlockHeader.RewardsRecalculationRound), + RewardsLevel: row.BlockHeader.RewardsLevel, + RewardsPool: row.BlockHeader.RewardsPool.String(), + RewardsRate: row.BlockHeader.RewardsRate, + RewardsResidue: row.BlockHeader.RewardsResidue, } upgradeState := generated.BlockUpgradeState{ - CurrentProtocol: string(blockHeader.CurrentProtocol), - NextProtocol: strPtr(string(blockHeader.NextProtocol)), - NextProtocolApprovals: uint64Ptr(blockHeader.NextProtocolApprovals), - NextProtocolSwitchOn: uint64Ptr(uint64(blockHeader.NextProtocolSwitchOn)), - NextProtocolVoteBefore: uint64Ptr(uint64(blockHeader.NextProtocolVoteBefore)), + CurrentProtocol: string(row.BlockHeader.CurrentProtocol), + NextProtocol: strPtr(string(row.BlockHeader.NextProtocol)), + NextProtocolApprovals: uint64Ptr(row.BlockHeader.NextProtocolApprovals), + NextProtocolSwitchOn: uint64Ptr(uint64(row.BlockHeader.NextProtocolSwitchOn)), + NextProtocolVoteBefore: uint64Ptr(uint64(row.BlockHeader.NextProtocolVoteBefore)), } upgradeVote := generated.BlockUpgradeVote{ - UpgradeApprove: boolPtr(blockHeader.UpgradeApprove), - UpgradeDelay: uint64Ptr(uint64(blockHeader.UpgradeDelay)), - UpgradePropose: strPtr(string(blockHeader.UpgradePropose)), + UpgradeApprove: boolPtr(row.BlockHeader.UpgradeApprove), + UpgradeDelay: uint64Ptr(uint64(row.BlockHeader.UpgradeDelay)), + UpgradePropose: strPtr(string(row.BlockHeader.UpgradePropose)), } var partUpdates *generated.ParticipationUpdates = &generated.ParticipationUpdates{} - if len(blockHeader.ExpiredParticipationAccounts) > 0 { - addrs := make([]string, len(blockHeader.ExpiredParticipationAccounts)) + if len(row.BlockHeader.ExpiredParticipationAccounts) > 0 { + addrs := make([]string, len(row.BlockHeader.ExpiredParticipationAccounts)) for i := 0; i < len(addrs); i++ { - addrs[i] = blockHeader.ExpiredParticipationAccounts[i].String() + addrs[i] = row.BlockHeader.ExpiredParticipationAccounts[i].String() } partUpdates.ExpiredParticipationAccounts = strArrayPtr(addrs) } - if len(blockHeader.AbsentParticipationAccounts) > 0 { - addrs := make([]string, len(blockHeader.AbsentParticipationAccounts)) + if len(row.BlockHeader.AbsentParticipationAccounts) > 0 { + addrs := make([]string, len(row.BlockHeader.AbsentParticipationAccounts)) for i := 0; i < len(addrs); i++ { - addrs[i] = blockHeader.AbsentParticipationAccounts[i].String() + addrs[i] = row.BlockHeader.AbsentParticipationAccounts[i].String() } partUpdates.AbsentParticipationAccounts = strArrayPtr(addrs) } @@ -331,16 +331,16 @@ func hdrRowToBlock(blockHeader *sdk.BlockHeader) generated.Block { } // order these so they're deterministic - orderedTrackingTypes := make([]sdk.StateProofType, len(blockHeader.StateProofTracking)) - trackingArray := make([]generated.StateProofTracking, len(blockHeader.StateProofTracking)) + orderedTrackingTypes := make([]sdk.StateProofType, len(row.BlockHeader.StateProofTracking)) + trackingArray := make([]generated.StateProofTracking, len(row.BlockHeader.StateProofTracking)) elems := 0 - for key := range blockHeader.StateProofTracking { + for key := range row.BlockHeader.StateProofTracking { orderedTrackingTypes[elems] = key elems++ } slices.Sort(orderedTrackingTypes) for i := 0; i < len(orderedTrackingTypes); i++ { - stpfTracking := blockHeader.StateProofTracking[orderedTrackingTypes[i]] + stpfTracking := row.BlockHeader.StateProofTracking[orderedTrackingTypes[i]] thing1 := generated.StateProofTracking{ NextRound: uint64Ptr(uint64(stpfTracking.StateProofNextRound)), Type: uint64Ptr(uint64(orderedTrackingTypes[i])), @@ -351,23 +351,23 @@ func hdrRowToBlock(blockHeader *sdk.BlockHeader) generated.Block { } ret := generated.Block{ - Bonus: uint64PtrOrNil(uint64(blockHeader.Bonus)), - FeesCollected: uint64PtrOrNil(uint64(blockHeader.FeesCollected)), - GenesisHash: blockHeader.GenesisHash[:], - GenesisId: blockHeader.GenesisID, + Bonus: uint64PtrOrNil(uint64(row.BlockHeader.Bonus)), + FeesCollected: uint64PtrOrNil(uint64(row.BlockHeader.FeesCollected)), + GenesisHash: row.BlockHeader.GenesisHash[:], + GenesisId: row.BlockHeader.GenesisID, ParticipationUpdates: partUpdates, - PreviousBlockHash: blockHeader.Branch[:], - Proposer: addrPtr(blockHeader.Proposer), - ProposerPayout: uint64PtrOrNil(uint64(blockHeader.ProposerPayout)), + PreviousBlockHash: row.BlockHeader.Branch[:], + Proposer: addrPtr(row.BlockHeader.Proposer), + ProposerPayout: uint64PtrOrNil(uint64(row.BlockHeader.ProposerPayout)), Rewards: &rewards, - Round: uint64(blockHeader.Round), - Seed: blockHeader.Seed[:], + Round: uint64(row.BlockHeader.Round), + Seed: row.BlockHeader.Seed[:], StateProofTracking: &trackingArray, - Timestamp: uint64(blockHeader.TimeStamp), + Timestamp: uint64(row.BlockHeader.TimeStamp), Transactions: nil, - TransactionsRoot: blockHeader.TxnCommitments.NativeSha512_256Commitment[:], - TransactionsRootSha256: blockHeader.TxnCommitments.Sha256Commitment[:], - TxnCounter: uint64Ptr(blockHeader.TxnCounter), + TransactionsRoot: row.BlockHeader.TxnCommitments.NativeSha512_256Commitment[:], + TransactionsRootSha256: row.BlockHeader.TxnCommitments.Sha256Commitment[:], + TxnCounter: uint64Ptr(row.BlockHeader.TxnCounter), UpgradeState: &upgradeState, UpgradeVote: &upgradeVote, } diff --git a/api/handlers.go b/api/handlers.go index 933d160fa..6449c3d69 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -1059,7 +1059,7 @@ func (si *ServerImplementation) fetchBlockHeaders(ctx context.Context, bf idb.Bl return row.Error } - results = append(results, hdrRowToBlock(&row.BlockHeader)) + results = append(results, hdrRowToBlock(row)) lastRow = row } From dff12aac53f9157752d87e54c0b2acd763bae609 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Wed, 4 Dec 2024 21:41:19 -0300 Subject: [PATCH 19/19] Rename `proposer` parameter to `proposers` In `GET /v2/block-headers`, rename the `proposer` parameter to `proposers` to follow conventions through the rest of the API. --- api/converter_utils.go | 10 +- api/generated/common/routes.go | 324 ++++++++++++------------- api/generated/common/types.go | 4 +- api/generated/v2/routes.go | 416 ++++++++++++++++----------------- api/generated/v2/types.go | 8 +- api/indexer.oas2.json | 6 +- api/indexer.oas3.yml | 6 +- 7 files changed, 387 insertions(+), 387 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index c22da32a9..8a854c231 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -885,7 +885,7 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search { // Make sure at most one of the participation parameters is set numParticipationFilters := 0 - if params.Proposer != nil { + if params.Proposers != nil { numParticipationFilters++ } if params.Expired != nil { @@ -899,8 +899,8 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search } // Validate the number of items in the participation account lists - if params.Proposer != nil && uint64(len(*params.Proposer)) > si.opts.MaxAccountListSize { - errs = append(errs, fmt.Errorf("proposer list too long, max size is %d", si.opts.MaxAccountListSize)) + if params.Proposers != nil && uint64(len(*params.Proposers)) > si.opts.MaxAccountListSize { + errs = append(errs, fmt.Errorf("proposers list too long, max size is %d", si.opts.MaxAccountListSize)) } if params.Expired != nil && uint64(len(*params.Expired)) > si.opts.MaxAccountListSize { errs = append(errs, fmt.Errorf("expired list too long, max size is %d", si.opts.MaxAccountListSize)) @@ -910,8 +910,8 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search } filter.Proposers = make(map[sdk.Address]struct{}, 0) - if params.Proposer != nil { - for _, s := range *params.Proposer { + if params.Proposers != nil { + for _, s := range *params.Proposers { addr, err := sdk.DecodeAddress(s) if err != nil { errs = append(errs, fmt.Errorf("unable to parse proposer address `%s`: %w", s, err)) diff --git a/api/generated/common/routes.go b/api/generated/common/routes.go index 9d4846e55..e70663e5b 100644 --- a/api/generated/common/routes.go +++ b/api/generated/common/routes.go @@ -95,168 +95,168 @@ var swaggerSpec = []string{ "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", - "SouVkI6qt3y1Ap31+M7/DwAA///TTGMQxeUAAA==", + "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", + "ZUqLlZCOqrd8tQKd9fjO/w8AAP//62VeisflAAA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/common/types.go b/api/generated/common/types.go index 7d5e140c8..a7c59f989 100644 --- a/api/generated/common/types.go +++ b/api/generated/common/types.go @@ -1210,8 +1210,8 @@ type Next = string // NotePrefix defines model for note-prefix. type NotePrefix = string -// Proposer defines model for proposer. -type Proposer = []string +// Proposers defines model for proposers. +type Proposers = []string // RekeyTo defines model for rekey-to. type RekeyTo = bool diff --git a/api/generated/v2/routes.go b/api/generated/v2/routes.go index e32354051..ae2f05591 100644 --- a/api/generated/v2/routes.go +++ b/api/generated/v2/routes.go @@ -1025,11 +1025,11 @@ func (w *ServerInterfaceWrapper) SearchForBlockHeaders(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter after-time: %s", err)) } - // ------------- Optional query parameter "proposer" ------------- + // ------------- Optional query parameter "proposers" ------------- - err = runtime.BindQueryParameter("form", false, false, "proposer", ctx.QueryParams(), ¶ms.Proposer) + err = runtime.BindQueryParameter("form", false, false, "proposers", ctx.QueryParams(), ¶ms.Proposers) if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter proposer: %s", err)) + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter proposers: %s", err)) } // ------------- Optional query parameter "expired" ------------- @@ -1313,211 +1313,211 @@ var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/v2/types.go b/api/generated/v2/types.go index b352c80d9..4916b726c 100644 --- a/api/generated/v2/types.go +++ b/api/generated/v2/types.go @@ -1298,8 +1298,8 @@ type Next = string // NotePrefix defines model for note-prefix. type NotePrefix = string -// Proposer defines model for proposer. -type Proposer = []string +// Proposers defines model for proposers. +type Proposers = []string // RekeyTo defines model for rekey-to. type RekeyTo = bool @@ -1851,8 +1851,8 @@ type SearchForBlockHeadersParams struct { // AfterTime Include results after the given time. Must be an RFC 3339 formatted string. AfterTime *time.Time `form:"after-time,omitempty" json:"after-time,omitempty"` - // Proposer Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses. - Proposer *[]string `form:"proposer,omitempty" json:"proposer,omitempty"` + // Proposers Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses. + Proposers *[]string `form:"proposers,omitempty" json:"proposers,omitempty"` // Expired Accounts marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses. Expired *[]string `form:"expired,omitempty" json:"expired,omitempty"` diff --git a/api/indexer.oas2.json b/api/indexer.oas2.json index 09895a510..08061df94 100644 --- a/api/indexer.oas2.json +++ b/api/indexer.oas2.json @@ -886,7 +886,7 @@ "$ref": "#/parameters/after-time" }, { - "$ref": "#/parameters/proposer" + "$ref": "#/parameters/proposers" }, { "$ref": "#/parameters/expired" @@ -2732,14 +2732,14 @@ } }, "parameters": { - "proposer": { + "proposers": { "type": "array", "items": { "type": "string", "x-algorand-format": "Address" }, "description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", - "name": "proposer", + "name": "proposers", "in": "query", "required": false }, diff --git a/api/indexer.oas3.yml b/api/indexer.oas3.yml index 761643bc3..0e2c96185 100644 --- a/api/indexer.oas3.yml +++ b/api/indexer.oas3.yml @@ -221,11 +221,11 @@ }, "x-algorand-format": "base64" }, - "proposer": { + "proposers": { "description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", - "name": "proposer", + "name": "proposers", "schema": { "items": { "type": "string", @@ -4898,7 +4898,7 @@ "description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", "explode": false, "in": "query", - "name": "proposer", + "name": "proposers", "schema": { "items": { "type": "string",