diff --git a/README.md b/README.md index dd3181cdf..e785e26d2 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/accounting/rewind.go b/accounting/rewind.go index 992d47f83..46b6736d9 100644 --- a/accounting/rewind.go +++ b/accounting/rewind.go @@ -165,15 +165,21 @@ func AccountAtRound(ctx context.Context, account models.Account, round uint64, d return } } + acct.Round = round + // Due to accounts being closed and re-opened, we cannot always rewind Rewards. So clear it out. acct.Rewards = 0 + // Computing pending rewards is not supported. acct.PendingRewards = 0 acct.Amount = acct.AmountWithoutPendingRewards + // MinBalance is not supported. acct.MinBalance = 0 + // TODO: Clear out the closed-at field as well. Like Rewards we cannot know this value for all accounts. //acct.ClosedAt = 0 + return } diff --git a/accounting/rewind_test.go b/accounting/rewind_test.go new file mode 100644 index 000000000..457197396 --- /dev/null +++ b/accounting/rewind_test.go @@ -0,0 +1,80 @@ +package accounting + +import ( + "context" + "errors" + "testing" + + "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) { + var a sdk.Address + a[0] = 'a' + + account := models.Account{ + Address: a.String(), + Amount: 100, + AmountWithoutPendingRewards: 100, + Round: 8, + } + + txnRow := idb.TxnRow{ + Round: 7, + Txn: &sdk.SignedTxnWithAD{ + SignedTxn: sdk.SignedTxn{ + Txn: sdk.Transaction{ + Type: sdk.PaymentTx, + PaymentTxnFields: sdk.PaymentTxnFields{ + Receiver: a, + Amount: sdk.MicroAlgos(2), + }, + }, + }, + }, + } + + ch := make(chan idb.TxnRow, 1) + ch <- txnRow + close(ch) + var outCh <-chan idb.TxnRow = ch + + db := &mocks.IndexerDb{} + db.On("GetSpecialAccounts", mock.Anything).Return(types.SpecialAddresses{}, nil) + db.On("Transactions", mock.Anything, mock.Anything).Return(outCh, uint64(8)) + + account, err := AccountAtRound(context.Background(), account, 6, db) + assert.NoError(t, err) + + assert.Equal(t, uint64(98), account.Amount) +} + +// Test that when idb.Transactions() returns stale data the first time, we return an error. +func TestStaleTransactions1(t *testing.T) { + var a sdk.Address + a[0] = 'a' + + account := models.Account{ + Address: a.String(), + Round: 8, + } + + ch := make(chan idb.TxnRow) + var outCh <-chan idb.TxnRow = ch + close(ch) + + db := &mocks.IndexerDb{} + db.On("GetSpecialAccounts", mock.Anything).Return(types.SpecialAddresses{}, nil) + db.On("Transactions", mock.Anything, mock.Anything).Return(outCh, uint64(7)).Once() + + account, err := AccountAtRound(context.Background(), account, 6, db) + assert.True(t, errors.As(err, &ConsistencyError{}), "err: %v", err) +} diff --git a/api/disabled_parameters.go b/api/disabled_parameters.go index 67c8cb0ad..4eecfad7a 100644 --- a/api/disabled_parameters.go +++ b/api/disabled_parameters.go @@ -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"}) diff --git a/api/error_messages.go b/api/error_messages.go index 0060e5214..131ce3f43 100644 --- a/api/error_messages.go +++ b/api/error_messages.go @@ -39,6 +39,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" diff --git a/api/generated/common/routes.go b/api/generated/common/routes.go index 96cc47fff..6f0a0b933 100644 --- a/api/generated/common/routes.go +++ b/api/generated/common/routes.go @@ -97,177 +97,178 @@ var swaggerSpec = []string{ "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", - "y5QWKyEdlW/5agU66/Gh/xcAAP//SKFC4MsCAQA=", + "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", + "AQA=", } // 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 cc5008f60..582b049ca 100644 --- a/api/generated/common/types.go +++ b/api/generated/common/types.go @@ -1324,6 +1324,9 @@ type Next = string // NotePrefix defines model for note-prefix. type NotePrefix = string +// OnlineOnly defines model for online-only. +type OnlineOnly = bool + // Participation defines model for participation. type Participation = []string diff --git a/api/generated/v2/routes.go b/api/generated/v2/routes.go index 4d3984127..b59e75e0b 100644 --- a/api/generated/v2/routes.go +++ b/api/generated/v2/routes.go @@ -166,6 +166,13 @@ func (w *ServerInterfaceWrapper) SearchForAccounts(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter application-id: %s", err)) } + // ------------- Optional query parameter "online-only" ------------- + + err = runtime.BindQueryParameter("form", true, false, "online-only", ctx.QueryParams(), ¶ms.OnlineOnly) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter online-only: %s", err)) + } + // Invoke the callback with all the unmarshalled arguments err = w.Handler.SearchForAccounts(ctx, params) return err @@ -1442,225 +1449,226 @@ var swaggerSpec = []string{ "r3jEbPKGbviqXBFRrmb2xOaV1GykOxqgeIqRFAjXrMH+CrpgmjArVHPU02Eee8j2DBWj6bKfNSNMe7jx", "im4SJUuRDVBHDZEqFPd1wVI+5ywj1Sh9sNTT7IOHi8PgqZXkABw/SC841Sx7wBFsEzlWy6PsFzig4FRP", "yM9OgIKvRl4wUclZKDEwUih2yWWpq059crederecLaRhSaHYnG+6QL5322HZA7ZxUp4nc44E1DzIDodE", - "tRemYMKbIn0N1ncIK516k6TFCpBvC6mZum8ctrm+2+CzfidiiNxYLUclIecUCJTdtd98Z/1b3XBKuLG7", - "LjXT0IptaGqIttrwvBQpki9utoP3xEN4m9uhByHXvUWjahW3sWeKXbBtVB1oU2WkMZURemm/YN/dpKWa", - "YQ+nHcgcUPsLmcJOhjCIGUCjBHl5RHu3Xx2njxv8G/0HWFTCudHcnFzL9I9jeFTr24rWTDdnZdR8keCI", - "HdbFFx+sljjnOQjq/7Qcy59sqa2w2Dxbr1NqvhDUlIqdnYsv7F8kIe8NFRlVmf1lhT+9KXPD3/OF/SnH", - "n17LBU/f80XfpnhYo08B0G2F/9jx4qZ/s6mWG5vCf47NUFDb8IJtFbNz0HQO/2zmgEh0rv5AqwDIqaaY", - "T6aT5awPil0KV72raeNNaLa1alfP5sCQuyUVRxgP0owtG7+Xb4x+MTdPeIHy6kIKjXvnduud+83+ZKU4", - "92QbqDen/9QoPNUQWobBlOE4ktOy7H//TbH55Gzy/53WD8On2E2fugknlQXT9EnnSP6ocQwACb9jCajf", - "rIrSoLYSo60VMfxYwdaes8ZnOfsnS83kk+3ZBOMhWxVm+8gC7FHreLulGyc9cN/aJ3yD+4j6SgJ6R3fk", - "n7WzihZ0wQUsfErWSybIil5YmkqFNEumiD0Lpo3XXJB5oDJTvbo69cfdspNJjNREzlRf+1DrU3ttNfj3", - "oMEf44hbNtUDzjoG0njy1cl3NvaYKLA40tnvfI4+P/9Ii4Jnm/PzXxtGJC4ytomfx40edi4XSUYNvRqO", - "Ll7YrhEEvc841HzqPxYCHRd5DjiF2+Wox9quI1+2K9HYkbJGbsX1iarWzDyjORXpUdjpzA01+ITfcMEB", - "iB/Qej8esz/maiuPccRud49ykfE5evAVHg83doerR/5rH+2xjnTQQd6yRghTHmOT7grxR4w/LsY/y2V6", - "gQ/hR2FXdrjhRxrMPh5sxadwD49xsFc60b0HNmTmu0KmEY2OjEZyc3wkkpvYrM/khnCBxl2nnzyTG3Zf", - "DRMzC9tw5JSbF25KqT5vmwEufAgePXOu3RqeB0S4s3bJ3ysl1RFO11twWvBMJyumNV2w+FNKuEbfcMii", - "PMBwIMwuAR4gfmA0N8vnS3YDVDcYe891/VC/NR1hY2+UcAbPYvvWH6xqj0mmOeyBtC6YRt/33bs/5KKx", - "5cMJYuNM2+Rw+Bnrww75k39rDJ8Be19TQ3ZkT4q6yBx0gTgX5+IFm3MBboZn58LSodMZ1TzVp6VmypmB", - "ThaSnBE35Atq6LmYTNsMqs8fAaIIHDRFOct5Si7YNnYKGN4QGUEamgeek0Gkg3sPrt8Ju3iGoyYWHWRp", - "EhdYlSgG3sDd2XTlLQcjY8jFrlmnxI2NTn0ucMuNH8f9jtt+N2x0Z0QDF82QA3uQP0njvGzomiAikVIz", - "TX5b0eIjF+ZXkpyXjx9/xcjToqjfp36r4yMsoPC0f9THLlgsnGHCNkbRBJxZ44iiyxVw2jwn0LYZe6Hk", - "QtGVc4ZtR3Xs2GmcfBinCpYFK3qPvT5NA2W/dVTwO1myvBsLcujBBJaxK5/LHuvajujED0EQLV1QLrSn", - "7ZovhMVqF5A0YyS1vJxlJ+TVnABtmjZicF00saN7FQHgGmOIQrf9lAqILQJfCsBtKrZtnxPNjPHePu/Y", - "Bdt+CLzIDvS0cH7gdA9jy0o7XMXc6lMla6rJSoInUsqEybfOtTyCgnFgSi4M+rg2onU6gASxM/ZWBFb+", - "vuijwIueFgVZ5HLmaEeFi2cVMvo+/WTirQVAH4FERLXaZjTTvtXjNeuLujp8dXa8a12ynWu6MnLNudIQ", - "oMCoI/U0vAxXwDEXPdEF5R9LBlKUVBBF0MQj7S9vDL0rP0yI8mDC8EuWsJwv+CwWqp/SBsf0wVrOj6sa", - "QRM+J9xo4h46LBBcEEXFglnpBT1daY6BxVFocqpNsmRUmRmjPQ77cDB1rGNj2bY/WYPvuMi5YFO7OWxj", - "8ZjbnVBMsDXL7Gq4cm2I5eFlD6sHgJyLbnZFeHz32vctPteKi8RtXSQCxcsv1e56AdXHI4RXCeDC7ysG", - "MbhyrSFyKiPShY92giNLq4LGQev48g/wmXrb6GMH2Se7RaU1OW8LZR35KQoyNk7smrszldo5hVNlPLPz", - "o6PeA1CfEHDHdZs0yyEWsQr+x/OmioUejBgM3weO7hOP/eTNtYeXbkm1v3gQ6uv5xCCJtYeY1ehr6WiA", - "v6Hewe28ObukfTvd7/8LQWltl14QIbqhuj6aBZOZeL9f7+zrPXztv5belXluqU0pLoRcW3XmEB/e6QSv", - "fBfgSwliCn72iOFAfKCDo7Fw/H0+B/qREC4ye4lA6aDGR17LlGOAa02TLS1f2B9P7AAWu+wAg0eIoa0b", - "EiRsKXMcmPwkw/snFocAKRgHvkL92MBggr9ZXAsHMR0kdgzk4yKOcam/5VZPaEhFABiEy88YExgPSLiY", - "EkvKLmluSZmLZ6kHiataDxtakhPc9aM+FSxuIcIVgeRy0JpQ1rnKakLx3wMd1012QDyTmwTST3RhhSwS", - "RZFUREyKfIvB2m09HUaw65EpYIiPxLhgW4wTh8wFcEvAIuvox4zl0kr6soNh9UHtAf66gB8Rmt0Cfgyb", - "NaAeSt412u3INrB36h75ug/tHgIOXQOAtv29CiBxFp69RpmmKNNl/DU3nNYBO0iR42Sk7yp2Eb6JRdFT", - "7Nnfrhmv8jx/OyiSsdGKYJOZs0MFulCM+1lylEqhmdAlRKoZmcr8pGOl0yxnoEYkDYEsuWCR6PL3vnFg", - "tyMP+dzq548C7UCxBdeGNVJtVDFWdVznFtJTFNQYpuzw///D/zz7+DT5X5r88Tj527+f/vrn158efdH5", - "8cmn7777v82fvvr03aP//LdJD1tmVtyW8/ia3klZMT5oTKBxY2m3DvWlNCwBvS+5pHnsee8lKIVRSasZ", - "/IL5YHiPzR0mumDbJON5GcfFnyoqqMsZUGouCKOWElKTLkGabsxo2+yYDfSfnlW9pkdb1AB0VvbomwN/", - "Jnjdoqe7LnEEmWLH3j2c3n3cQdZAMnrBcny87E/chhctsw1Pdj0cdC5G5sfepS0GUPRzHhwpupam13b/", - "KuAlHeQWboK4Mt1Z0VAb0LrK1RGKoGtaGblu3NYTri6097hR4iYW9/Eay+sOP3R50Qybw7wd4MAOMVmi", - "ANTBKbgrbrA9+BS8i3SZq1UjtFM48IIEwiWmVBJtIbOFZ1U+k2Fn4WUFl15FlhUn3C3LHg/nWETZwrXH", - "0I/MlVzBZevKmqEBsscu0cC6mrW0ZnWZP7v4YuklKCh734EZzX9k219sWzhV29tLmENvSW2m8Vqe1ziu", - "dTTXe/OKYb4bcS/mY2hRH9pDjkh8m2i8UB94A3K50LEQ5kUd9h9iwYxZpZhtWFqa2uzZMq5X9v/blQHb", - "Dwnx6OzA5wDzlO6WFGB/3Fh7TuxtRR5v8sBoUSh5SfPEveVGqTm08K+9tyxrxS/Uh++fvn7rIIYHREZV", - "Uuka8YVAo1rHuLdrsaKG3PMYDIYobwBos3T3mMt14wF4DbmsWqqrFZ4cFuHG1I/4wTV1D8JzL2of+Lzr", - "nAxwibucDWqDD/oaNP0L6CXluTfZexjjrAKXVLtyHMwtwgGu7acQ+JUkR6X/ncsbvwl7CE04w45UVStM", - "mKaJdCmp6sOyyig8CgBarujWYguaZbsUR5QrsOwkOuexZ7GmuZJAqx591g5lWeuuQex3PcAm1gIrGDy6", - "fT4ap2+3ZtI5u5WC/14ywjMmjP2k4M61rqG9dT4H7JW1l8gLNuaKvUX9BSY8RHNxCQOvtbhqlKvoL1Y/", - "ibwm4qm59VRndx09pjbhduU4AGK3EhM6EXXAfVGZJj0WVS8MVDSekQ/wLgxn7IgNPZ6Bwb0T3L1zXOFU", - "9meE94qSSygZpw8H6UFhfspraT86mSv5R8yLdt2dNpgQe8UHHay9tO5JjxbDWxmbr3BEVWbP64JUab3X", - "BqrNHau3jbpMQH04vZesT+4O32CaLqk9hBzuG4SBUHV+/isqlv6dlwq8YM+h3EBD5Ylf09BB+RTHr6+p", - "g7lrj6DrGU0vIoupvQIbL9FGEt+pytXaPJ0TEjgYVm1d2tOCqRU3TXJfa1RXlWxx2sEybS3CAjaFwqtL", - "PZxrGRmmFGsqjE9e6wiY6x3mulpLpQ0kZI+uMmMpX9G853mvJpAZX3DMNltqFuRKdf1JIbkwiDQZ10VO", - "t+huWe/Iqzl5PA2IlzuEjF9yzWc5gxZfYosZ1SCL1BYm38Wuigmz1ND8yYDmy1JkimVm6dL4akkqpQMM", - "NHXiZ2bWjAnyGNp9+TfyELxcNL9kj+zmOZlycvbl3+CFEf94HKflkDq/l7Z6kh7HWvDpwa6WKbrB4rQW", - "S8UcdGewy5AbAy0dwd9/Y1ZU0EUso+EOWLBP/a7f2geRYdZ3EJkIN/F5maGW6iRLqpexChupXK24WTl/", - "By1XFlvqpH84lx8F3/SRXFfg+I/ggVyQuHHtdi0+8XIiP9EVa27ilFBNdGlBrY1WjridEJfuMsMk4LU1", - "EbYEq5KgRxrafOdBzZDSzJP/CNKgn/RBmcy+/boL6TNMo+7yo+NcwwG/9e1WTDN1OeyieTHJ9SEPhRTJ", - "ypKH7JGj1M071+vOFCfLbYeT3UMOlZHsKMlurKIBlb0WfokdA14T46plHIR2B6/s1hGwVBFs+PndaycP", - "rKRiTdvqzMcUNSQLxYzi7BJCL+JnY8e85hGofNDmXwf6u31D98JhIED5GxsT1TEyv7sdzn+9Wnaf0ivl", - "xQVjBReLU/TfBmEaR22L0TMpyh6LZSGt7MRpTqARKejW7nIlgu7wDZ8zppNU5jlLozpqK/rKNicF5Xht", - "wizC3vFxx1wLJpjmuoedn59/XCythmI/W04cWFkwIAB97vTtX1EPeE+E/YIJC/erF/ug7gzcdKsIcuDu", - "suE0/MF+dn0gbTnWDUhg3v5dtu0svG99nQGXNpfq5e1vbX/qeSyF4HKre/rdxq6hxn8/UIJXoy8c1ZQ0", - "97GdgN1zplwNvgY4YIOBKmmMEc3FxV7f/L35Pd65tv1O9efnH5XI7Mk9d+Fz6CPVfMfGw1xTeJdgIquh", - "T5eU9/ikasbiE9oPdsb3UhmOTjuM3bEDn1E0vYgaID/YL7py4kNP+8CdTw8O5ILXiLe2zwc/W+wxlq+Y", - "NnRVRPfOaLtzyAuAr9jtq7pYgqlZKkWmLQaljLBC6uW+jAI6PtVGwGQ+Y3WDMqdSYY5okF2NbEV7D92S", - "nXHtTRgTJaXpA9TC2UhIIKUhtDRLy8J8HAGDIkXtlWD0G+itQcLvE/LGShk+LTnN8+2UcPMAx1HOs5OS", - "FVMXOSNGMUbWS6kZyRm9ZHVdPBjtgSYfNjzTUPUuZxueyoWixZKnRKqMKSyYCDUtrC6Nndx8j0+Ii+p1", - "cRAfNgKWV1VVCteJy/TRK9WLVrjiKYpw7Z+hXJlm+SWkM19LBELXuQ2g0EazOFZpMGYw4/M5U1gFJXPv", - "QNCv/hDABBX+INSgGtat6fZpQAfDEr2kT775tg/RnnzzbQzX3v/w9Mk33/pSJuWG55yqbdjMtpqSWclz", - "44oJUHLJUiNVaHHgQhtGsw5uoTXKzQKyjK94EnYJ6zC+/+HpN18++T9PvvnWma+CWXwUtAuwY+KSKyns", - "J28wrDDETVnNxjZcmzuQlsxGJKAvx7i6PZoUjmUjnmMj4gIvms+5LRK2QvuUv/g5yxZMTWtGbOlqnXPE", - "KndSBRLwnGGImOWLXBglszJlmOnifYNuBGDxDkhV3abA3Qbuui+EWcPpLamVzELIK9CAH6NCJmRzhXDH", - "2CVTGNNTD/QQmUMAlzZUgZ8SuC25pbLsUZy1l8VC0YwN80IAZvUz9qgSN/gRLuVhA/xi27cVrIYO0JCs", - "4wJsEMjBoNpezXNjPGcHlejV31yavgFaHHnh6XiskMqo5I1K3qjkjUreqOSNSt41lbxRgRoVqFGBGhWo", - "UYEaFaj7r0C960tB8xKr8yuWY64QqGmN1dY7ms+cscQKWVGMtxoJZDB2tfpC/LHfoN6svelwl7UVibxA", - "VGWRwiwmcRcAgClJaZ6WOYrpO8SzdUpzcKWrETtncyMt7gU5dgJfKm7nmkGILRaDxvmU5WFBD8i7e8nU", - "1rXAp2tfe9neG9WKfeiKoUnOLlkeBZxRBbLDD3JNVlRsq7OwU9RgTIPUIhXkKGCCiz2e9s/uVT0AH++Z", - "Q8jdQNqj6NncLDzngikuM54SLv7J3EUPxXLAGCziLoXhorQ0iChWw42snkCOo3Yeoy4GqGhMpoWLGmYB", - "q8PgBVs3TjsLhPBmNLk29IIh2D4bk5Nuhp6pYppnZRyyuaJpE7LDkNFd3nfUsFNVHa0+El62iFd1yXdd", - "ujYut9CmdVrdXeqlUw26PIRY0SplBnE0PBJt61L4+pY92rg0Eph2kPyyGvuSKd2M4wz8rNhmz9i2RWN8", - "TGzsc8MdPkviA3p073xbJMc1znn5GTOXQX+Xly62gz1ZnysA9JqbdJnEIu8dANjCwvCurR53p0TpAm4h", - "m89ZaobAAGkPZmwuFeuFAj9bKF4wmkHKrTptBSasaIPy8CdJ7NA6EHmE5qBI1BIPjPLogLptFYbsQ/5f", - "5EDcdxnLwJV8wDXwMo47++iWuTYOeV5VacMo2TINu1KF5wZ3BFI7xn1k/aQZy+l215TQoDlpJfN672Dk", - "OZAB0TIUDAfuzeLkp3b3bNfktkl7wdX17N6KsBRz5yRlJErIFyOoclC4tO6RoLeoE6BFZroCNJ65oabg", - "el17dN2+V+Zx8grGE8P46P3ONsAXvw/wR3sj7tg9DQ6wluhxJb/GESWoyhFFmaz6HuSUwkBtWL/PXk5x", - "J4ZiU8sV0GPUPdi32D59f0nznkw171ihmAY7ASUfvn/62kUV9OWrSeOpYs7PP1JjcQr6kd5svZ+mk57U", - "eufnH2dAMTFxXnUaXffMaBCqJUTcdrefO72vFtPUV4Ui2FAfzNwF6EefQYMUlLtImTpZT3dnXdambnqs", - "IVk46gNuL8KlReq9Qj9QvXxJUyPVtlsCw6rWPblJz88/2vM+ZIu//DZO7i0I8Uk+BAlQmyayKoAKgpe8", - "PCTnnUSoBDKhLqmznPk/raYfZD2tvk+mk44doD6LH2ZgR0c5Irony1mh5qB+YlOwHzaSt1px4wefotk9", - "67gq/hcM88grNtsSvZRrMGGDOQhzLXexZjlLirgxAZjx2zrFl4/h9FMTVzTn9g1/APOXmi/icH8JVOB9", - "tWVyTv4u2Ae+YtVv7yE529/nc83MqxcP3/44Jc+oSZdTgr89IqXIWJVvk7z98ckdLfNJfI1P7BJ/ZFug", - "CoKtE222OSNmLVEbJKxYshVTNK9x565W0HtQT4YeFJwNnNMTd1DhAa2othoBpKFr9/+FKYgFf3Qni+9b", - "eXfd9+JmRWlrUHoqElq2hM9YzoIoVzOpS2V6K3Rls6TKFBI0CJQXV2ErLCu0N/sP18mKLxQoafFR+yuD", - "BUJ1RCZG40B3J/wrdL/1oMVWGwtvQVyDF8iwbuYYC34lMrZhqn6nfVOvLlJRMVliuc+kfv6JS1PInm/3", - "1mDqRTuFNizbYV+eHyg8YJBXbhXLQePnVxtfJKDYi2TN+GIZ39i3VxraKv77D+3y9g8tRjbewDvlU3sh", - "ASN7RMN5LTjurH8XyJjgKWR6vHnMEpd/X7KQKcaSjBU94JrsQET4j57Nbpd8jxBqzVdFjvG+jpR00p0f", - "lFu0zily8ylqjp3n48YzdrArB6EeP1HHVWHZn4V8d3qOv4vnclXkrF/dL6hAhX/OhbM0rpfUEJpl4F5F", - "c+JfrWWalqp2O2kn4PiF5jwDRU9D4QohZQGVKgrDhf0P5OyUpcH/M6rsf9DFsPk/xKpAs7NDTeBcIN+5", - "H8gn75pMJ9h54jE7qvdF3RQ7m9LMYO7PE+Lu4fVfMJZBDoq6gNgpTQ16bLj4XMHMWqqLiOFlpsEC3vCy", - "9Nn849SUKlMWFI0qtAqacVV7qkIAFWgOMl1q9LVrOJjtpZVsU1hcOxzATK0uB0JYbZ4Ul0y511rpyojg", - "uyxWJurk6CYOvEPWFCPVV8z5PMhPr2tTimxzLSTuMEJo0P1VaNkLPAe7Dtyp2hZGnkIbaHKqjSpTo9GH", - "u56zg5V2o9GVce/yOiKFlQSk5uiBYWSi2CWjfQ+LoHGx30tmDxmcC2xjUg0QO9ihRLu9xzh2fGsBkNB5", - "D/PkoLttvvX1Uajd8xUtPuIsv5KEvEOIq+qZ4J+70ovicD9OHCoGuqa5SXq1HCdfkvc0N6EYAVo4eqY1", - "rA3xWkUowUZHT+9C5bAwXR0F7YJZtkvcX19B3O+lHTBvxShQAmteqUtn8hiODt5IYie51XW8q25slyoE", - "6xu2inBTAtIQNwr7r/461QZWKjISzK8J3I1IeChcXSaM2l4lszRfJDqXByzvPV+8tx32bKlv1tnTXK6Z", - "Suy8O444984RmGIFWzaqh1Xle3E89O1iGbGL0VfbCBz4oJ1wXfbvRT12y42O5qkUSWP226U6SC8TwK6k", - "Smy5Z/foqrl7hdetD6VaQCS2XCzixT4sob9g2/thS4jEH3TOE5xS+o05oGj8VLlgBc/ia+f2gm4NTUFn", - "T+FQq66BpOkqJO+4V6Z5r2qPyBVPlaTgPlZXGWMdCdYpe+B9Xe3GLpe4+HMY1mLDzh+2BavCCLrVlVe0", - "8PoW6OFWCD65SaMVeVcFUHR94FMpDOVQQzkq3GP4AMsLIFT1a97JvULfXwLO3PKO270/6QoQKHhqDyNO", - "7P+7W2YUu4MXnwu2TXI+Z4b3uNDkc/9y5ZudHE2m6EuL3XBRAMtDjmkg6lTfRCr8soAvYUZxgnQU8uJp", - "/5cmGTNMrSwqLuWarMp0CbI7XTCfUxuemCEWpjVRY3SfhLSZEd6lhNIFTXEgzPSYU7Vgirjki1UpWv9k", - "vaIc7kkdv9BOyQaurTTmPrAv0/cbzP4Y0C5w9gjSfkcSinswLtj2FH0Z4PcrEJL+7OE9gEEq8RsE6VoZ", - "ycM09nvw9aLhBoL13Rv5/ivwj+gOYuFzJoQD3UG6CfqHLg/WAdeh1Ky7zuEJWMK9jai49dqG+jJ1N7fH", - "BWmf51FPlV7noAJ0HPoSgI/89uVvRLE5U2C3+uILGP6LL6bOw+q3J83PFtu++CLuhhm9OcfzdKqKP9ox", - "3HRR7AiS43TfUJHJawyuR1dby9CkACfzPG8FaYqMQH5JEE8oxKyxXBYs2hrq04ccFHL+K7Yoc4rBiVwI", - "poZkKmgkd0b132yEM3XBnx82ItY2FCehdbAd5yJW7cUjf2KaGzcwAVFYnK1K1J5CEuurjlinwa5HxIS6", - "1xnxJWbxrUb08ebXGfODGwNGLc0yoVkWDxTUCwFmOW+M4z4xJAjAeMJNbKqSRdqPELjpsqBWAbjs95Lm", - "LsBYQDjvB8jUnF4wkUEMlqVyMKORhAldKmcStLDCeBYUN4wMmbmum1wh+h9eMPprwJ+ff1QpWn9dDI7L", - "/wnJxrGrFTMyezhydx1d296qmH31B6xkS+1crqHPNgDe7ftUL0Bjtep/w28VCAtj4aDIhu/fM3xdsra6", - "hD3lJ+o6Ii3OjCUPH7568YhAecy+QoWBorV/2WHV3GEQYVLZDiztciOHQDFnrC8AsRUKTeasxxS8s2Kr", - "HQu0QizdCq3aQSN7oRyYY+UHqqEwq2te59W4j4lVGkCSVy+ickajINLBVUCnk4WSZTyPw0LB01Dbe90q", - "ASBgoQKP7rCnT775lmR8wbQ5If+AegrIfLul8JunSXhdYp82PgBgVU0eFINc+HQw59IdaCedAXdh1DDM", - "HXgEege/K7K1yuu3t27jnvp20wkIOYnZxBIkvuoIQKRwAexQmyYgXo2on2OkReTCKIqUPJHggtuFD11z", - "ax8L5Qm8Yl0UGkDiL9hWsasKQj9CZ3Qp20nGciBjUKv5alQsZ7QncCrfRO7iV0+S+jqekNe2N2FiLpVV", - "0VclPBuyDRR2cK93ocgL5Q8wlYGVwLHygfiDKQkWCEGkeyVvX9hqsyHInKagHGiXRMHCUBVmqqycD9+D", - "aDRFIB+hgtu9t6QUhqMsZbfxl2AXC8vFLND/WPI8ggWFtN91CMeUCEkkeBqFLTGrS121A2F2WTEaiHS7", - "NCMsR5fF/QYsJkA4+OugNmtt3kiXVCzY8JKeXZwcdMG7Ra0j1zxecdQuYIELWBwFzrv1+hOyJzrefgCZ", - "RjGssFGZ4m45zxjdrpi4Khd6i73R0SFl/JKp3eqE6lEnfO/dSoRiF2ybGBkfm+ErFYr5ld4GRlektsEa", - "pz1KVBVijJ5coSCMN8jKG/MSXoeDd1BvdHX6YeWcdsG2tetMgKxORbyCyoZsMW5S/8BXrFZyUCqMyVN8", - "EEtEXTWuJGO6NSTZD3YspxpmN1boHqzAvrtxYvCjcYC2watxJ4XaFW5B4NMEqYh2RLltC9aMawYvx8rq", - "18jxAwaIE/KiypEFTo2YaqROnIXGsbbrIyaEqqpsceWNaFR54zd4R4LnHNyaCCFwDVA2sm26UpJrQtM5", - "NOizKvlmmzlTdbuYZce3nKs/6oZdo5JvVhTgptBjHnOttCngpannpF2r5QySbEbl8toHtKDbiRcXJ9OJ", - "Xbj9xy7M/jtXf9h/iiKfWMwq5pPpZDnr+oHG77lDnQQmiyQCmTQ15Ya8WV3YGgP3WF1Di2BfegN4kQqY", - "76Em0dBoj1Xv6h+e0zz/sBHO97AbHLzD25MWGCD82nl5VoTcUnvnMuwtZY6IhK8/NE2tJJjViXECOB9o", - "0i7Pi+lyugV6d3iA7iXkbUkhRGGqFr3rBiNZV1rlKaFqUWKStltY354V9ChAtOCZSwnrHdI7kh1Sj1Kx", - "jEjlEh7yucsU2VcwdH81dNy9womWPK0lyDpXTw+mT62OxApX00+KJK282S07tYqokeQcvcDPJyfkFWbW", - "UoxmSIcVNyxWrruxfqixtGZ5Dm8YiNFJdbp5LdCf2FvUKO2uAbMVA5+NSCX+z7LsO5yYLntOrI8qofDV", - "PKQ7OKHn3Zr1UJNSSPMZndOgAvDn5x9ZARerWV01jN0oiqomfM7svv9eQtCdJdgwbI9dWCrGFyKhRdFH", - "EOfUMwLdPq4oO2hSKZeUNTx43eESldR+NSIKrz04GCZaoVkiRb7d5WYeIa/VXliRqJc9VDVNdB3vo90q", - "g1Krw5boyczbYIWA2F7iPeb6rlC5/9rl+lsDNKjGvr6NoKZIgf+QF7aH3ieZBS+rOyUzrAya24UjfVIs", - "8fzTUyyRYdHQso6ROhdPyR9MSafTVkPZC1Hb4121OZeh+STSqarfqzvd2lMeWBcZF79DOuytM35+/nFD", - "O1IGwHQN+eJqpeL3nvHLnoq14Rn75zlXqvaaBadxxh0bW8d5dl/haAb7GpT5DP3KkMhUdStxt13pXkAW", - "uu6plrvzNOc7T3PH+I08dWuvRGIC9Dj5dEonZgRc+x3HHrFY0v64yLpweXfqIZe/clgYhBpekb4ucvhZ", - "d6BH//M9peiZ+hQf7q1Wpp3g5eE7IY6ExEsJaJbPPTXz74H+xTrENMuZkK+taHEF/8FrEI8A4n4/B9br", - "5VBnf3SMOVJMAUeo/SmsrOlfQCMi44Fr96PHjxC+tpP+0bD4qF7KMs+w/ugKMlbWOmbkdFyd8UourOu+", - "o+sIeHqEgd06mCHcbEJe2ZFpvqZb7e25NWb1D+d3FauURmyJYUpbNELH90al6JrOUl5wJkzl5xOei0Xy", - "fitofGBnTbVUB3Nt8svKauGc/WldsL/5Qucf6FxRchpw6KnbZpo3zQU4sLdY2zbP/dh+RdWRBgxtfxqT", - "Khg8oH7Vlu4hevVz9k6CF+TFOZDUVR2R3FXz9ZO65SzZxQyXM5phbi7PDp3zgb+2aHnfoAeDkpd1wIKA", - "PZZxTFnOkgu2TTKel73h8svZhZv7R7Z94Vrika6oSZcBUPWl9PlBgy5XoB/LWTIo0KiZ3cylQOqrprKc", - "abee94xlDdzEVwzbs5I4208aDzQBqyiav+/IY2c5w/S3vG+Fl9wt8Rdp2KsX4WnZRe06Mexxx3k0g+vQ", - "RdIAL+qTbmzKnvvvXCh2X360uh9687EXXnucpv/OCymaSQd63m6FbWSP8w1VF41b75i1G8BeeUVaozZ0", - "jCDxiGY5Jmxv5T3oi8rTLHcvnkFmPgg0qd4fXZRRRt5RkckVeelTHj785d3LR0QxXebGMxlf/8EyHwfJ", - "3RY06l14oeZu5e+DCL1q+Vy4h9cF10ZFHi5ufVVwC/Y5OdpGc21qT0f0a8Gk2J0kFNxJQXExFCbcy0ds", - "K+QktWCqIcsemM6gdsEMSJScd0HQO6be4whl2+S4VPCGuu5Kh10YWK67MY1Zitb9uW8ItMeU4L0wdlNP", - "98B7KPl03ZB+upmuph+ieliHZgXlEux5+pJsLcH/WlpWMAXGhlrtA9xOG8pW043d8WF47PHe6MFD4l43", - "9+Z4cVd3r2fBJJqZadcPFicE6d/xllozgv74ckHzPFB+5qXIdGsLqwQFu9w0duo+TvXxbXZ6fPQpBUM1", - "gUagfhMSEPBcoFudo0FrmfLaV0fLlQtrJH8X+dal7m3XPau3EkRzl6GonSVhwVOXtvNQx5LXvu+n6WRV", - "5oZfcZw3vi96usTZIV84VigyqjLCsifffPPl3+4u2eungSf8OtjgrhegW5Z7ZaCGp009tlrdACLmj/Jk", - "Ibskq/exXS3qt8fqcT2W3n74GzkA0p9uwz+0OD+y2baR71latT03vP5pan9bUr2sSSc+vHnDBBWUOHrV", - "dg6GmMbgof+WU144xE6u5b/Vuh59hKO+JPfhboTkEfFhKEl8E1CSzgpXbon47mLxxQd6w14XObOyXU0D", - "e1N3+aNBlu/nfM8XnasTjhffdWgAflXSSiKYvd4Kk7XEBQbCGqorBBF09ud9CFcsF+dSMW0hijvpLVU0", - "u9GunL91ttVI9ZmDzvZ9a09b2ZBg33ol3OLijpJm7cKB+5E5Ju6vuVtk7sv/QoYEA1cJ8NqJ7/ql5yAT", - "9S7U783x3NSfh2dRqq10DRfJPi9WXXg/1g9BuHqYFZC8QvSvnZ9BjhWYI8ul+UTnD1cmqblf108D8gkC", - "ieYSM6oIQ1NTF2CZPHUjTaaTUuWTs8nSmEKfnZ6u1+sTP81JKlenC4isTIws0+WpHwhS1zbSNbourkao", - "Zbv51vBUk6dvX4GQzE3OIK4Kji5I4n02eXLyGNO9MkELPjmbfHXy+ORLvCJLwItTTK0+Ofvz03Ryevnk", - "NHSOXMTio94zqtIlorFrewKpSxmqs6+yqtFLqZ764dxDN/iITM4+drJSwtMKRJNx+/fvJVPbydTvamD3", - "r90vuvRwf9IOtEtpDAwwpcI0KIqR1EvtgW8RuA8RdskE4YiJOV9hoQt0tqLp0olpEZih7YEA1xXj6IIF", - "8J6QnzULKrbKC4hzRP3CBzr5gqNVpx7A7BAxuGoa181YgbvmdBvwE6fCv7UuILIXnslFENBw0ih56N7m", - "fJFgNECnW1KKHEzTIvAT0dXSoBomptBKqdsBF1Lsoyl0/wn4SRIHYWIhPPBEXmG0ByjDID24+A8wazpd", - "2eH4tMoWHXqKTdFhRW4h36Zmtl2Vf7n1pDh1nl52WPwcuCKCDxL6kfUt2IWmJDTPY8sMvAvay/x+45ZZ", - "Yz+uVpfpEnwS24C2IcMMwi77TRV36PZm6voHfmI+HrzyD6taisYGDuhjt4NtilxmbHI2p7lm8e1huMjG", - "1lQSoXfDx71zrnCtSHiNHvg6CfzBJo0ofttCSBHPz9xJg2q2QLot05kceuvg2tzfK2enuNZ98373gVOV", - "kXU6C8j+bC+hyxgX5RpVPo5+arfXm3735z7wPZ/xL4veT8GFlGLZ/YIpGFKk8JqugVp4UzXivHenzLim", - "sxxzcIMdquGLB/wB5KCmC2rofTfnOdwhOEXkfZidpvJfEJklTAkXNWMnL6GXHXq2JQF5aQyzYwTYgIos", - "ovMGXPBqhp+kSFynFRV0YWG0qGs5bBhqhy4HuKtg2wyRdxdKVhW3D8DCMEl2v1DS9sTcMcOvVjnHujVA", - "bZ48fuzlR2dfD0Y7/adGTbAesD+C5ZCw2RgR8kVLd+Y3qUrRN04B5aZVUZp+77iNSUBa6Y78s3aMoqAL", - "LpxPKZzsil6gUI8B1M6l21Mon87GikDVc6QTmtytGWA8ruXS5gb8GpX3m5A/BNfOR3aBX1/rHHsLFvUX", - "DmqtwzccAvY7h4AYloIFjz5NJ9987kuwSE0XGirkgd4x+fVTS5s5/dPHVPDsU69q81rKi7KoHkWCMqZd", - "DQfbunv1bAtEYqeGUz21eL4DJAWKzNQUpQJyEu6RUSU7SF4fyoWOSDFHOXmUk29HTr4RVnoAA71Bhhln", - "UiOPmnz9+OuRzd4fNpsD89vDZk87FGAf3xWBh2KbjsoCyW2+9RZ0HxyJ/os7uPPTooCcNWCV1veJTx9d", - "zfirsuXR0HslQ++RWWnrvh+gntaz1Dd1VFaDkM/Wxo4SwSgRfI4SQRVgfidygFdN7g//v5FXz5Hnjzz/", - "1nh+daOHMfqwfvDI3z1/r4woI1MfmfrnxtQjOewPY/HeWhk3Zl6L5T/HoZ+GoI36/ygLjLLAzej/DQJw", - "qOo/CgSRHE+jWDCKBZ+3WHC4zl8JBK230KOIAqMRYGT8I+O/cyPAyOxH7X9k858/mw8j04Y61jUTjX1o", - "lNtUzJFtlhHB1vayGUlkbpnRHg4fDrSPwY984ziRQUENQDvLnG8cdfaZtlxN9dqHW0jDsGRELxSQdwUG", - "O9hxHyPo+/z2q69/Rif21Q3CSY9cnSG2hXwBwY7eQf+fduc8NpZ1jpDKd9PX9KiCY6HehuYLklSpGuwv", - "K/wJwn/f84X9KcefIPEAhl3H9kHzRf9GaOi2wn/seIMW6ShAsJBmzoXZ1knw8XOJi7/30gHWT0kNhF/M", - "MTIunHrFRbJz+qrBUUCYsbl0oUABDHSzBwbf4NDIiRvVZvzKgjUtuKXCUOKfvHFEhwry7uVz8tVXX/2N", - "4OW32g2iS9+CcUisfxQCVxGPjJrq8xBS9O7lcwDgfeXXOqjV3kOtMOpYK4cR79/C/8JBp3/JyL+7DJDA", - "VTszhNMssSDcblGlKhu302pxXG37L6IlTydt1eL6FWBb2lJzJ1sTjoFg/1LK65DH6TC1RfMFpi+7xQHv", - "yjf/1ouxuqg/NGrVVJcOJYYqXLfOtBcl6NjsaoL3aHYezQfje/Nf8b35XzqcONin0z+bxHp/WHFQsLLP", - "kFk3iYcUx0TiNsvYKxb/5V4Nb4zsHEhsbi9y9JpPSeM7zGciynaI0OlMbnoJ0X+B+Ge1/4YsCtdwJjfE", - "3qupE190Kxlt1QBaO5vDM/dbXabcGfkX0pVmTC0loWqBhegfwGBcLM5ggAeYBocDNSmdHIINuTBnXz75", - "6mvXRNE1mW0N01MHD0BHvv0aoLFdH8y+/fqBf4KgkGTe/nT29Lvv3BiF4sLQWc6chaEzpzbqbMnyXLoO", - "Tj5mnYb2w9l//8//npycPBhCyuXGUvOnIvuJrtjtE/Wn9dlxAUeTHPVEmu1ua9OjAiju73DD0HU5wy7i", - "/0xuYtfd3pkgs8j4dj/yjOPxDF2uVlRtLa1nBq59gGrOZQ6NAC1p9MrMhulD2U3NYaAKU8VCINkrbUqB", - "WiorYeZsw1O5ULRYcstRtieDbDLPALxbp7ejceB+GQf6S8YXPNucn//aQDkuMraJ6+8Vug+yNDyTmxdu", - "ShktS/w5mAPwNuDChxCmZ+F1bl79kdONnO4mOR2i3QAed5BV5zSXC32AaYfY9gOUgtdyoe/GxjOyp+O4", - "vt2xS9Nf1L8IKi9VD/Wh66hjd1xX5bR2v29hq6D05M2kCL7/Ys2NvnnkcpF4jnF4LqDFC9v1s5adrmGK", - "3WUE3B1VFb5kQ8tdCtOgiKjxYXdkjgdwq4YvAqb9vkUvhP2z29H3WBGPOl8puOmbz36b3H7I4BgDNsaA", - "jarpbXoPwCGf/umv536PAbjmQ9KQ24bDtcmaPIy+AjfsKwBkbigtvMXM0jDlSG5GY979dnVoU8zTGc2p", - "SNleixyK3tqAGdrXolkvJRAUlxQfCMxOiuonG3WjUTcaq+mNgU1DA5uOJnQdVxoJiecgLe0NF3xM2Rnj", - "erOaNYwq219JADkk30XjeQJssY4+7Up6gakuLEvF9Bc7db4x5cWY8mJMeTGmvBhTXtzhk/SYnGJMTjHq", - "cP/aySmGuJ24l0wLqBQM/ZkbjVEG6BVFbtoTpbOo53I144LVWpBfQV1+2kh7UNBoSU3Fh31DI4muXA32", - "rCtRMu/hr+CJA5pxyvgl/HeuGPuDJYYqK2EP4beN1XgAoUhmMH9YJfOgtVnJGK1uxCcF8XWq1QoS0poq", - "ay2hxK9kaoXlrSzJGi5Lzi+gv6uwaTd9RSwSt6p+G0mMKntfqF33BODZm35kehuvQGMmlTGTyphJ5S9g", - "EpnlMr1IloxmYGbY74AGHYjrcEKehX82TR/csv6UCXg4AVQiUmVMRcwlQhpPZCo1W5amKM0OTzeY+gcH", - "+WgtuRVryagjjjriX1RH/NCU6TjqNjmnQEPsBvxmCb/UTOnf6oZTwg1hG/s7hkiyDU0N0XTFyLwUKVIY", - "brZDy7n7SeL13A/UMHbXZu96Kvq39xVVFygce3A82Q75wwPYMMNTXuCDdllk8JhNWptJ05QVFpmsFLai", - "RDP7DWJF/au/DyQ/dJv0PdkntiksP79v2+TAuiebRGeaCXPf9gihumd4ZNnuvdwtN9X92q6p3ywIobi/", - "RCuc+BZ28MgOCXYXD4ioruX30ROh8kTAPZyOOZ/+hV3H64sS1baBzjCRFZIL0xA07fj/9f0HUg+ClswZ", - "W9JLLkEq5RkThqc036c6j0rzqDSPSvOoNI9K86g0j0rzqDSPSvOoNI9K86g0j0rzqDTfW6X59E842wR1", - "0r0x19Cpz+ce7tI+JRivDE4Xr2IUAnRN9xu82ESKfEvmOV2ckH/YKwR3BDIhGe9LNK3f2ZEOZ5KhXu38", - "1dvearpHcUD6ndgpb9ZZZy9VG6/n5+xIMiiSJvAjGVo1th1A4x1L4w6OXIPjaNu9tNK7D6tHW9nLxsCc", - "MTBnDMy534E5IQWZbclCybIgr144DQTQokIdPK3EFUPAGHywoK2pyvTUF0tIl1TRFLYOXH3/fUpOoe13", - "1Ug/v3vth+lZMgCS7Iz/uSbCjYFKY23esTbvaKUfw5/G8Kcx/GkMf/pXD3+6y5Cl6Y0Xgh2DosagqNGW", - "daem5vBoT/+0OtH+5J7EqtN5g0P22Z1DrBuS4dMpZbdXB+0WSUiwXQdd1uGXc8yDOZKX+2Iq/zSdaKYu", - "/V0vVT45myyNKfTZ6Snb0FWRs5NUrk7hldn1/7OS++VqBYyq+sWNHPziSJntvkmk4pb35ole08WCqcTO", - "jDA/OXk8+fT/AgAA//+iEaM6j8ABAA==", + "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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 2b373c4c7..b41a55eef 100644 --- a/api/generated/v2/types.go +++ b/api/generated/v2/types.go @@ -1415,6 +1415,9 @@ type Next = string // NotePrefix defines model for note-prefix. type NotePrefix = string +// OnlineOnly defines model for online-only. +type OnlineOnly = bool + // Participation defines model for participation. type Participation = []string @@ -1661,6 +1664,9 @@ type SearchForAccountsParams struct { // ApplicationId Application ID ApplicationId *uint64 `form:"application-id,omitempty" json:"application-id,omitempty"` + + // OnlineOnly When this is set to true, return only accounts whose participation status is currently online. + OnlineOnly *bool `form:"online-only,omitempty" json:"online-only,omitempty"` } // SearchForAccountsParamsExclude defines parameters for SearchForAccounts. diff --git a/api/handlers.go b/api/handlers.go index f18399121..b915e4cac 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -29,7 +29,6 @@ import ( // ServerImplementation implements the handler interface used by the generated route definitions. type ServerImplementation struct { - // EnableAddressSearchRoundRewind is allows configuring whether or not the // 'accounts' endpoint allows specifying a round number. This is done for // performance reasons, because requesting many accounts at a particular @@ -416,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) @@ -436,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 { diff --git a/api/handlers_e2e_test.go b/api/handlers_e2e_test.go index 95a09ee58..c4c9e29b8 100644 --- a/api/handlers_e2e_test.go +++ b/api/handlers_e2e_test.go @@ -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() diff --git a/api/handlers_test.go b/api/handlers_test.go index 6f4134608..111dc8a39 100644 --- a/api/handlers_test.go +++ b/api/handlers_test.go @@ -9,6 +9,7 @@ import ( "math" "net/http" "net/http/httptest" + "strings" "testing" "time" @@ -673,6 +674,7 @@ func TestFetchTransactions(t *testing.T) { // Setup the mocked responses mockIndexer := &mocks.IndexerDb{} si := testServerImplementation(mockIndexer) + si.EnableAddressSearchRoundRewind = true si.timeout = 1 * time.Second roundTime := time.Now() @@ -748,9 +750,26 @@ func TestFetchTransactions(t *testing.T) { } } +func TestFetchAccountsRewindRoundTooLarge(t *testing.T) { + ch := make(chan idb.AccountRow) + close(ch) + var outCh <-chan idb.AccountRow = ch + + db := &mocks.IndexerDb{} + db.On("GetAccounts", mock.Anything, mock.Anything).Return(outCh, uint64(7)).Once() + + si := testServerImplementation(db) + si.EnableAddressSearchRoundRewind = true + atRound := uint64(8) + _, _, err := si.fetchAccounts(context.Background(), idb.AccountQueryOptions{}, &atRound) + assert.Error(t, err) + assert.True(t, strings.HasPrefix(err.Error(), errRewindingAccount), err.Error()) +} + func TestLookupApplicationLogsByID(t *testing.T) { mockIndexer := &mocks.IndexerDb{} si := testServerImplementation(mockIndexer) + si.EnableAddressSearchRoundRewind = true txnBytes := loadResourceFileOrPanic("test_resources/app_call_logs.txn") var stxn sdk.SignedTxnWithAD @@ -1111,6 +1130,13 @@ func TestBigNumbers(t *testing.T) { return si.SearchForApplications(ctx, generated.SearchForApplicationsParams{ApplicationId: uint64Ptr(uint64(math.MaxInt64 + 1))}) }, }, + { + name: "SearchForAccountInvalidRound", + errString: errValueExceedingInt64, + callHandler: func(ctx echo.Context, si ServerImplementation) error { + return si.SearchForAccounts(ctx, generated.SearchForAccountsParams{Round: uint64Ptr(uint64(math.MaxInt64 + 1))}) + }, + }, { name: "SearchForAccountInvalidAppID", errString: errValueExceedingInt64, @@ -1125,6 +1151,15 @@ func TestBigNumbers(t *testing.T) { return si.SearchForAccounts(ctx, generated.SearchForAccountsParams{AssetId: uint64Ptr(uint64(math.MaxInt64 + 1))}) }, }, + { + name: "LookupAccountByID", + errString: errValueExceedingInt64, + callHandler: func(ctx echo.Context, si ServerImplementation) error { + return si.LookupAccountByID(ctx, + "PBH2JQNVP5SBXLTOWNHHPGU6FUMBVS4ZDITPK5RA5FG2YIIFS6UYEMFM2Y", + generated.LookupAccountByIDParams{Round: uint64Ptr(uint64(math.MaxInt64 + 1))}) + }, + }, { name: "SearchForAssets", errString: errValueExceedingInt64, diff --git a/api/indexer.oas2.json b/api/indexer.oas2.json index fa84254fd..97d658ed2 100644 --- a/api/indexer.oas2.json +++ b/api/indexer.oas2.json @@ -86,6 +86,9 @@ }, { "$ref": "#/parameters/application-id" + }, + { + "$ref": "#/parameters/online-only" } ], "responses": { @@ -3173,6 +3176,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.", diff --git a/api/indexer.oas3.yml b/api/indexer.oas3.yml index aec70e739..88cc66039 100644 --- a/api/indexer.oas3.yml +++ b/api/indexer.oas3.yml @@ -231,6 +231,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" + } + }, "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, @@ -2824,6 +2832,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": { diff --git a/cmd/algorand-indexer/daemon.go b/cmd/algorand-indexer/daemon.go index faf36608b..d88233299 100644 --- a/cmd/algorand-indexer/daemon.go +++ b/cmd/algorand-indexer/daemon.go @@ -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) } diff --git a/cmd/idbtest/idbtest.go b/cmd/idbtest/idbtest.go index b2f6c3df1..e6a62554e 100644 --- a/cmd/idbtest/idbtest.go +++ b/cmd/idbtest/idbtest.go @@ -9,6 +9,7 @@ import ( "os" "time" + "github.com/algorand/indexer/v3/accounting" models "github.com/algorand/indexer/v3/api/generated/v2" "github.com/algorand/indexer/v3/idb" _ "github.com/algorand/indexer/v3/idb/postgres" @@ -159,6 +160,9 @@ func main() { MaxRound: account.Round, } printTxnQuery(db, tf) + raccount, err := accounting.AccountAtRound(context.Background(), account, round, db) + maybeFail(err, "AccountAtRound, %v", err) + fmt.Printf("raccount %s\n", string(ajson.Encode(raccount))) } if txntest { diff --git a/docs/DisablingParametersGuide.md b/docs/DisablingParametersGuide.md index f088f2b72..901577903 100644 --- a/docs/DisablingParametersGuide.md +++ b/docs/DisablingParametersGuide.md @@ -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 diff --git a/idb/idb.go b/idb/idb.go index e4462743c..c98fd3d78 100644 --- a/idb/idb.go +++ b/idb/idb.go @@ -305,6 +305,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. @@ -327,7 +332,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 diff --git a/idb/postgres/internal/writer/test_resources/heartbeat.txn b/idb/postgres/internal/writer/test_resources/heartbeat.txn new file mode 100644 index 000000000..c20700037 Binary files /dev/null and b/idb/postgres/internal/writer/test_resources/heartbeat.txn differ diff --git a/idb/postgres/internal/writer/write_txn_participation.go b/idb/postgres/internal/writer/write_txn_participation.go index d458d8548..e1066cd75 100644 --- a/idb/postgres/internal/writer/write_txn_participation.go +++ b/idb/postgres/internal/writer/write_txn_participation.go @@ -40,6 +40,8 @@ func addTransactionParticipants(stxnad *types.SignedTxnWithAD, includeInner bool for _, address := range txn.ApplicationCallTxnFields.Accounts { add(address) } + case types.HeartbeatTx: + add(txn.HbAddress) } if includeInner { diff --git a/idb/postgres/internal/writer/writer_test.go b/idb/postgres/internal/writer/writer_test.go index e0edcbfb8..61a20667a 100644 --- a/idb/postgres/internal/writer/writer_test.go +++ b/idb/postgres/internal/writer/writer_test.go @@ -481,9 +481,9 @@ func TestWriterTxnParticipationTableNoPayout(t *testing.T) { tests = append(tests, testcase) } { - stxnad := test.MakeCreateAppTxn(sdk.Address(test.AccountA)) + stxnad := test.MakeCreateAppTxn(test.AccountA) stxnad.Txn.ApplicationCallTxnFields.Accounts = - []sdk.Address{sdk.Address(test.AccountB), sdk.Address(test.AccountC)} + []sdk.Address{test.AccountB, test.AccountC} stib, err := util.EncodeSignedTxn(makeBlockFunc().BlockHeader, stxnad.SignedTxn, stxnad.ApplyData) require.NoError(t, err) @@ -492,17 +492,40 @@ func TestWriterTxnParticipationTableNoPayout(t *testing.T) { payset: []sdk.SignedTxnInBlock{stib}, expected: []txnParticipationRow{ { - addr: sdk.Address(test.AccountA), + addr: test.AccountA, round: 2, intra: 0, }, { - addr: sdk.Address(test.AccountB), + addr: test.AccountB, round: 2, intra: 0, }, { - addr: sdk.Address(test.AccountC), + addr: test.AccountC, + round: 2, + intra: 0, + }, + }, + } + tests = append(tests, testcase) + } + { + stxnad0 := test.MakeHeartbeatTxn(test.AccountA, test.AccountD) + stib0, err := util.EncodeSignedTxn(makeBlockFunc().BlockHeader, stxnad0.SignedTxn, stxnad0.ApplyData) + require.NoError(t, err) + + testcase := testtype{ + name: "heartbeat", + payset: []sdk.SignedTxnInBlock{stib0}, + expected: []txnParticipationRow{ + { + addr: test.AccountA, + round: 2, + intra: 0, + }, + { + addr: test.AccountD, round: 2, intra: 0, }, @@ -648,6 +671,40 @@ func TestWriterTxnParticipationTableWithPayout(t *testing.T) { } tests = append(tests, testcase) } + { + stxnad0 := test.MakeHeartbeatTxn(test.AccountA, test.AccountD) + stib0, err := util.EncodeSignedTxn(makeBlockFunc().BlockHeader, stxnad0.SignedTxn, stxnad0.ApplyData) + require.NoError(t, err) + + testcase := testtype{ + name: "heartbeat", + payset: []sdk.SignedTxnInBlock{stib0}, + expected: []txnParticipationRow{ + { + addr: test.AccountA, + round: 2, + intra: 0, + }, + { + addr: test.AccountD, + round: 2, + intra: 0, + }, + // Payout involved accounts + { + addr: test.AccountE, + round: 2, + intra: 1, + }, + { + addr: test.FeeAddr, + round: 2, + intra: 1, + }, + }, + } + tests = append(tests, testcase) + } for _, testcase := range tests { t.Run(testcase.name, func(t *testing.T) { diff --git a/idb/postgres/postgres.go b/idb/postgres/postgres.go index 7e8b96e88..be136f1f8 100644 --- a/idb/postgres/postgres.go +++ b/idb/postgres/postgres.go @@ -2130,6 +2130,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 diff --git a/util/test/account_testutil.go b/util/test/account_testutil.go index a5e475e69..566599c4d 100644 --- a/util/test/account_testutil.go +++ b/util/test/account_testutil.go @@ -4,7 +4,9 @@ import ( "crypto/rand" "crypto/sha512" "fmt" + "os" + "github.com/algorand/indexer/v3/idb" "github.com/algorand/indexer/v3/util" "github.com/algorand/go-algorand-sdk/v2/encoding/msgpack" @@ -352,6 +354,31 @@ func MakeAppCallWithInnerTxn(appSender, paymentSender, paymentReceiver, assetSen return createApp } +// MakeHeartbeatTxn creates a heartbeat transaction, overriding fields with the provided values. +func MakeHeartbeatTxn(sender, hbAddress sdk.Address) sdk.SignedTxnWithAD { + var hbTxn sdk.SignedTxn + _ = msgpack.Decode(loadResourceFileOrPanic("test_resources/heartbeat.txn"), &hbTxn) + + hbTxn.Txn.Sender = sender + hbTxn.Txn.GenesisHash = GenesisHash + var fields = hbTxn.Txn.HeartbeatTxnFields + fields.HbAddress = hbAddress + return sdk.SignedTxnWithAD{ + SignedTxn: hbTxn, + } +} + +func loadResourceFileOrPanic(path string) []byte { + data, err := os.ReadFile(path) + + if err != nil { + panic(fmt.Sprintf("Failed to load resource file: '%s'", path)) + } + var ret idb.TxnRow + _ = msgpack.Decode(data, &ret) + return data +} + // MakeBlockForTxns takes some transactions and constructs a block compatible with the indexer import function. func MakeBlockForTxns(prevHeader sdk.BlockHeader, inputs ...*sdk.SignedTxnWithAD) (sdk.Block, error) { res := sdk.Block{BlockHeader: prevHeader}