-
Notifications
You must be signed in to change notification settings - Fork 89
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
account min-balance #825
account min-balance #825
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #825 +/- ##
===========================================
+ Coverage 57.67% 58.19% +0.51%
===========================================
Files 35 36 +1
Lines 4362 4432 +70
===========================================
+ Hits 2516 2579 +63
- Misses 1539 1545 +6
- Partials 307 308 +1
Continue to review full report at Codecov.
|
README.md
Outdated
@@ -1,23 +1,28 @@ | |||
<!-- markdownlint-disable MD041 --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
linting with vscode's markdownlint
extension
api/README.md
Outdated
The Makefile will install our fork of **oapi-codegen**, use `make oapi-codegen` to install it directly. | ||
|
||
1. Document your changes by editing **indexer.oas2.yml** | ||
1. Document your changes by editing **indexer.oas2.json** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo
parity/json_diff.py
Outdated
@@ -0,0 +1,197 @@ | |||
from copy import deepcopy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code to generate algod v. indexer parity reports. I include a circle test that:
- pulls latest
go-algorand
submodule - uses this library to generate yaml reports
- asserts that the results are as expected. In particular:
- all essential features of algod have their counterparts in indexer (think of
min-balance
) - terminology remain consistent
- etc.
@@ -0,0 +1,115 @@ | |||
____________________ 61 New Attributes ____________________ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This report shows all the "essential" differences between algod and indexer in a relatively human-friendly format. There are variants of this report that limit the scope to:
- changes of common attributes
- attributes which are not present in algod but exist in indexer
- attributes which are present in algod but missing from indexer
However, this report shos ALL the differences (the union of the above)
- INDEXER: '"[\\lsch\\] global schema"' | ||
- ALGOD: '"[\\gsch\\] global schema"' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo?
- INDEXER: '"\\[tt\\] value type."' | ||
- ALGOD: '"\\[tt\\] value type. Value `1` refers to **bytes**, value `2` refers to **uint**"' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks outdated on indexer
// Some data which is relevant for MinBalance but duplicated is ignored. In particular: | ||
// * TotalAppSchema - gotten from account.AppsTotalSchema and not re-calc'ed from CreatedApps | ||
// * TotalExtraPages - gotten from account.AppsTotalExtraPages and not re-calc'ed from CreatedApps | ||
func minBalanceProjection(account *generated.Account) basics.AccountData { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a similar function AccountToAccountData
in go-algorand
that fills out all of the fields (but has some minor issues when applied to Indexer's generated.Account
). It is also possible to try and unmarshall the basics.Account
directly from the database as is partially done elsewhere. After some thought, I decided that this was the simplest approach - get only the essential data into a basics.AccountData
at the most convenient location and calculate MinBalance
from it.
api/handlers.go
Outdated
@@ -13,6 +13,7 @@ import ( | |||
log "github.com/sirupsen/logrus" | |||
|
|||
"github.com/algorand/go-algorand/data/basics" | |||
"github.com/algorand/go-algorand/data/bookkeeping" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for BlockHeader
@@ -960,7 +964,7 @@ | |||
], | |||
"properties": { | |||
"type": { | |||
"description": "\\[tt\\] value type.", | |||
"description": "\\[tt\\] value type. Value `1` refers to **bytes**, value `2` refers to **uint**", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was spotted by the new python indexer vs. algod parity test.
@@ -1036,7 +1040,7 @@ | |||
"$ref": "#/definitions/ApplicationStateSchema" | |||
}, | |||
"global-state-schema": { | |||
"description": "[\\lsch\\] global schema", | |||
"description": "[\\gsch\\] global schema", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
@winder and @algorandskiy have brought to my attention some important changes that are in the works to handle unlimited assets and which affect the way min-balance is calculated (though technically, the formula remains the same). In particular, we can see that new var a basics.Account // which perhaps? has as part of it a ledger.AccountBase, or something like that
... populate a ...
minBalance := basics.MinBalance(proto, a.TotalAssets, a.TotalAppSchema, a.TotalAppParams, a.TotalAppLocalStates, a.TotalExtraAPpPages) @winder - Do you think we should wait for these changes to the ledger to get merged into |
@@ -252,6 +252,8 @@ type AccountQueryOptions struct { | |||
|
|||
IncludeAssetHoldings bool | |||
IncludeAssetParams bool | |||
// IncludeMinBalance indicates whether to calculate min-balance as well (a realatively slow operation) | |||
IncludeMinBalance bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are database layer options, so this option doesn't need to be here. I think we can get away with using the nil round check, or just skip/unset it in the rewind function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
idb/idb.go
Outdated
@@ -173,7 +173,7 @@ type IndexerDb interface { | |||
// The next multiple functions return a channel with results as well as the latest round | |||
// accounted. | |||
Transactions(ctx context.Context, tf TransactionFilter) (<-chan TxnRow, uint64) | |||
GetAccounts(ctx context.Context, opts AccountQueryOptions) (<-chan AccountRow, uint64) | |||
GetAccounts(ctx context.Context, opts AccountQueryOptions) (<-chan AccountRow, uint64, *bookkeeping.BlockHeader) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tolikzinovyev I'm curious what you think about this. The protocol is needed for the min balance calculation, but this approach puts accounting logic in the REST API. There are a few other bits of accounting logic outside of the eval function (sig type, created/deleted at, pending rewards calculations, maybe others). Is there a way to make this sort of accounting logic pluggable so that it can be encapsulated so that it doesn't need to be part of the DB/REST API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the right solution is to return basics.AccountData
s in IndexerDb.GetAccounts()
like it's done in other IndexerDb
functions, and in api
invoke basics.AccountData.MinBalance()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems reasonable, but it still has the same problem, you need ConsensusParams to pass into MinBalance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't say it's a problem. GetAccounts()
returns the current round. Similarly, it can return the current consensus version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An Even Quicker Approach
If we're aiming to get this PR out as soon as possible, an even quicker option is C which doesn't return any basics.AccountData
. I could still push the calc of MinBalance
closer to the view without a large effort. In this case, I would still create issues similar to the above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to wait for the ledger refactoring changes. Whether or not these approaches will continue working depend on changes that are yet to be made. For example, do we add the asset counts lazily or as a migration? If it's done lazily we may not always be able to compute the min balance depending on the REST API changes for the ledger refactoring (one proposal includes an option to return account data with asset/application data removed).
Regardless of that, I think we should skip the basics.AccountData
conversion. Does it really help solve our problem? We're constructing it from metadata outside of algod, so we may end up with data inconsistencies based on how we reassemble it from Postgres.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with the first part, but ideally the database layer shouldn't construct api
types imo. Constructing basics.AccountData
from data in postgres is pretty straightforward, it's already done in idb/postgres/internal/ledger_for_evaluator/
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I support Will's position that we wait for the ledger refactoring changes. We don't want to add this now, and then have updates to this work become a blocker for the ledger refactoring project (we have enough complex dependencies there already).
People can continue to work without min balance being easily available for a little bit longer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add
min-balance
information to the/v2/accounts
endpointFixes
#808 #676
Summary of changes
accounting/calculated.go
-EnrichMinBalance
: main workhorse of thie PRaccounting/calculated_test.go
- new unit testsapi/error_messages.go
- new error messageapi/handlers.go
- mostly infetchAccounts()
api/indexer.oas2.json
- addmin-balance
and fix a couple of typos (discovered by future circle test in Nightly Tests: compare2algod in addition to the regular tests #839 )idb/postgres/postgres.go
- modifyGetAccounts
adding a third output of type*bookkeeping.BlockHeader
Minor Changes in
GetAccounts()
Just for Tests to Passapi/handlers_test.go
cmd/e2equeries/main.go
cmd/idbtest/idbtest.go
idb/dummy/dummy.go
idb/idb.go
idb/mocks/IndexerDb.go
idb/postgres/postgres_integration_test.go
util/test/testutil.go
Auto Generated
api/generated/common/routes.go
api/generated/common/types.go
api/generated/v2/routes.go
api/generated/v2/types.go
api/indexer.oas3.yml
Test Plan
Unit Tests. Working on an integration tests via the sandbox.
Related Follow-up PR
#839 - Add a test that alerts automatically when a new discrepency arises between
algod
andindexer
algod
compatriatealgorand/go-algorand#3287