Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync with upstream #6

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ Below is a snippet of the output from `algorand-indexer api-config`:
optional:
- currency-greater-than: disabled
- currency-less-than: disabled
- online-only: disabled
/v2/assets/{asset-id}/transactions:
optional:
- note-prefix: disabled
Expand Down
5 changes: 3 additions & 2 deletions accounting/rewind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import (
"errors"
"testing"

sdk "github.com/algorand/go-algorand-sdk/v2/types"
"github.com/algorand/indexer/v3/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"

models "github.com/algorand/indexer/v3/api/generated/v2"
"github.com/algorand/indexer/v3/idb"
"github.com/algorand/indexer/v3/idb/mocks"
"github.com/algorand/indexer/v3/types"

sdk "github.com/algorand/go-algorand-sdk/v2/types"
)

func TestBasic(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion api/disabled_parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ func GetDefaultDisabledMapConfigForPostgres() *DisabledMapConfig {
rval.addEntry(restPath, http.MethodGet, parameterNames)
}

get("/v2/accounts", []string{"currency-greater-than", "currency-less-than"})
get("/v2/accounts", []string{"currency-greater-than", "currency-less-than", "online-only"})
get("/v2/accounts/{account-id}/transactions", []string{"note-prefix", "tx-type", "sig-type", "asset-id", "before-time", "after-time", "rekey-to"})
get("/v2/assets", []string{"name", "unit"})
get("/v2/assets/{asset-id}/balances", []string{"currency-greater-than", "currency-less-than"})
Expand Down
2 changes: 2 additions & 0 deletions api/error_messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const (
ErrMultipleBoxes = "multiple application boxes found for this app id and box name, please contact us, this shouldn't happen"
ErrFailedLookingUpBoxes = "failed while looking up application boxes"
errMultiAcctRewind = "multiple accounts rewind is not supported by this server"
errOnlineOnlyRewind = "simultaneously rewinding and searching for online accounts is not supported"
errOnlineOnlyDeleted = "simultaneously searching for online and deleted accounts is not supported"
errRewindingAccount = "error while rewinding account"
errLookingUpBlockForRound = "error while looking up block for round"
errBlockHeaderSearch = "error while searching for block headers"
Expand Down
339 changes: 170 additions & 169 deletions api/generated/common/routes.go

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions api/generated/common/types.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

480 changes: 244 additions & 236 deletions api/generated/v2/routes.go

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions api/generated/v2/types.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions api/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,14 @@ func (si *ServerImplementation) SearchForAccounts(ctx echo.Context, params gener
return badRequest(ctx, errMultiAcctRewind)
}

// Input validations related to the "online-only" parameter
if params.Round != nil && boolOrDefault(params.OnlineOnly) {
return badRequest(ctx, errOnlineOnlyRewind)
}
if boolOrDefault(params.OnlineOnly) && boolOrDefault(params.IncludeAll) {
return badRequest(ctx, errOnlineOnlyDeleted)
}

var spendingAddrBytes []byte
if params.AuthAddr != nil {
spendingAddr, err := sdk.DecodeAddress(*params.AuthAddr)
Expand All @@ -435,6 +443,7 @@ func (si *ServerImplementation) SearchForAccounts(ctx echo.Context, params gener
EqualToAuthAddr: spendingAddrBytes,
IncludeDeleted: boolOrDefault(params.IncludeAll),
MaxResources: si.opts.MaxAPIResourcesPerAccount,
OnlineOnly: boolOrDefault(params.OnlineOnly),
}

if params.Exclude != nil {
Expand Down
74 changes: 74 additions & 0 deletions api/handlers_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,80 @@ func TestVersion(t *testing.T) {
require.Equal(t, response.Version, "(unknown version)")
}

// TestAccountsOnlineOnlyParam exercises the `online-only` parameter in `GET /v2/accounts`.
func TestAccountsOnlineOnlyParam(t *testing.T) {

// Spin a fresh database
db, shutdownFunc := setupIdb(t, test.MakeGenesis())
defer shutdownFunc()

// Load a block (with a keyreg txn) into the database
vb, err := test.ReadValidatedBlockFromFile("test_resources/validated_blocks/KeyregTransactionWithStateProofKeys.vb")
require.NoError(t, err)
err = db.AddBlock(&vb)
require.NoError(t, err)
api := &ServerImplementation{db: db}

e := echo.New()
{
//////////
// When // We query for only online accounts
//////////
req := httptest.NewRequest(http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
c.SetPath("/v2/accounts")
err = api.SearchForAccounts(c, generated.SearchForAccountsParams{OnlineOnly: boolPtr(true)})
//////////
// Then // Only AccountA should be returned
//////////
require.NoError(t, err)
require.Equal(t, http.StatusOK, rec.Code)
var response generated.AccountsResponse
data := rec.Body.Bytes()
err = json.Decode(data, &response)
require.NoError(t, err)
require.Equal(t, 1, len(response.Accounts))
require.Equal(t, test.AccountA.String(), response.Accounts[0].Address)
}
{
//////////
// When // We query for accounts using online-only=false
//////////
req := httptest.NewRequest(http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
c.SetPath("/v2/accounts")
err = api.SearchForAccounts(c, generated.SearchForAccountsParams{OnlineOnly: boolPtr(false)})
//////////
// Then // All accounts should be returned, regardless of whether their status is online or not
//////////
require.NoError(t, err)
require.Equal(t, http.StatusOK, rec.Code)
var response generated.AccountsResponse
data := rec.Body.Bytes()
err = json.Decode(data, &response)
require.NoError(t, err)
require.Equal(t, len(test.MakeGenesis().Allocation), len(response.Accounts))
}
{
//////////
// When // We query for accounts using both `online-only=true` and `include-all=true` parameters
//////////
req := httptest.NewRequest(http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
c.SetPath("/v2/accounts")
err = api.SearchForAccounts(c, generated.SearchForAccountsParams{OnlineOnly: boolPtr(true), IncludeAll: boolPtr(true)})
//////////
// Then // The response should be a 404 "bad request"
//////////
require.NoError(t, err)
require.Equal(t, http.StatusBadRequest, rec.Code)
require.Contains(t, rec.Body.String(), errOnlineOnlyDeleted)
}
}

func TestAccountClearsNonUTF8(t *testing.T) {
db, shutdownFunc := setupIdb(t, test.MakeGenesis())
defer shutdownFunc()
Expand Down
10 changes: 9 additions & 1 deletion api/indexer.oas2.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,14 @@
{
"type": "integer",
"description": "Include results for the specified round. For performance reasons, this parameter may be disabled on some configurations. Using application-id or asset-id filters will return both creator and opt-in accounts. Filtering by include-all will return creator and opt-in accounts for deleted assets and accounts. Non-opt-in managers are not included in the results when asset-id is used.",

"name": "round",
"in": "query"
},
{
"$ref": "#/parameters/application-id"
},
{
"$ref": "#/parameters/online-only"
}
],
"responses": {
Expand Down Expand Up @@ -2972,6 +2974,12 @@
"in": "query",
"x-algorand-format": "base64"
},
"online-only": {
"type": "boolean",
"description": "When this is set to true, return only accounts whose participation status is currently online.",
"name": "online-only",
"in": "query"
},
"rekey-to": {
"type": "boolean",
"description": "Include results which include the rekey-to field.",
Expand Down
16 changes: 16 additions & 0 deletions api/indexer.oas3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,14 @@
},
"x-algorand-format": "base64"
},
"online-only": {
"description": "When this is set to true, return only accounts whose participation status is currently online.",
"in": "query",
"name": "online-only",
"schema": {
"type": "boolean"
}
},
"proposers": {
"description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.",
"explode": false,
Expand Down Expand Up @@ -2644,6 +2652,14 @@
"schema": {
"type": "integer"
}
},
{
"description": "When this is set to true, return only accounts whose participation status is currently online.",
"in": "query",
"name": "online-only",
"schema": {
"type": "boolean"
}
}
],
"responses": {
Expand Down
5 changes: 3 additions & 2 deletions api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ type ExtraOptions struct {
// Tokens are the access tokens which can access the API.
Tokens []string

// Respond to Private Network Access preflight requests sent to the indexer.
EnablePrivateNetworkAccessHeader bool
// DeveloperMode turns on features like AddressSearchRoundRewind
DeveloperMode bool

// Respond to Private Network Access preflight requests sent to the indexer.
EnablePrivateNetworkAccessHeader bool

// MetricsEndpoint turns on the /metrics endpoint for prometheus metrics.
MetricsEndpoint bool

Expand Down
2 changes: 2 additions & 0 deletions cmd/algorand-indexer/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,9 @@ func runDaemon(daemonConfig *daemonConfig) error {
// makeOptions converts CLI options to server options
func makeOptions(daemonConfig *daemonConfig) (options api.ExtraOptions) {
options.EnablePrivateNetworkAccessHeader = daemonConfig.enablePrivateNetworkAccessHeader

options.DeveloperMode = daemonConfig.developerMode

if daemonConfig.tokenString != "" {
options.Tokens = append(options.Tokens, daemonConfig.tokenString)
}
Expand Down
1 change: 1 addition & 0 deletions docs/DisablingParametersGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ The configuration file that is used to enable/disable parameters is a YAML file
optional:
- currency-greater-than: disabled
- currency-less-than: disabled
- online-only: disabled
/v2/assets/{asset-id}/transactions:
optional:
- note-prefix: disabled
Expand Down
7 changes: 6 additions & 1 deletion idb/idb.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ type AccountQueryOptions struct {
// return any accounts with this auth addr
EqualToAuthAddr []byte

// OnlineOnly, when set to true, indicates that only accounts that are online should be returned.
//
// When set to false, this parameter is ignored (i.e. it becomes a no-op).
OnlineOnly bool

// Filter on accounts with current balance greater than x
AlgosGreaterThan *uint64
// Filter on accounts with current balance less than x.
Expand All @@ -326,7 +331,7 @@ type AccountQueryOptions struct {
// MaxResources is the maximum combined number of AppParam, AppLocalState, AssetParam, and AssetHolding objects allowed.
MaxResources uint64

// IncludeDeleted indicated whether to include deleted Assets, Applications, etc within the account.
// IncludeDeleted indicates whether to include deleted Assets, Applications, etc within the account.
IncludeDeleted bool

Limit uint64
Expand Down
3 changes: 3 additions & 0 deletions idb/postgres/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -2031,6 +2031,9 @@ func (db *IndexerDb) buildAccountQuery(opts idb.AccountQueryOptions, countOnly b
whereArgs = append(whereArgs, encoding.Base64(opts.EqualToAuthAddr))
partNumber++
}
if opts.OnlineOnly {
whereParts = append(whereParts, "((a.account_data->>'onl' IS NOT NULL) AND (a.account_data->>'voteLst' IS NOT NULL) AND ((a.account_data->>'onl') = '1'))")
}
query = `SELECT a.addr, a.microalgos, a.rewards_total, a.created_at, a.closed_at, a.deleted, a.rewardsbase, a.keytype, a.account_data FROM account a`
if opts.HasAssetID != 0 {
// inner join requires match, filtering on presence of asset
Expand Down