-
Notifications
You must be signed in to change notification settings - Fork 197
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
Implement queries for historical balances (state) #4371
Conversation
Codecov Report
@@ Coverage Diff @@
## rc/2022-july #4371 +/- ##
================================================
+ Coverage 73.75% 73.80% +0.04%
================================================
Files 671 675 +4
Lines 86488 86769 +281
================================================
+ Hits 63793 64039 +246
- Misses 17919 17938 +19
- Partials 4776 4792 +16
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
…elrond-go into historical-balances-08-12
…elrond-go into historical-balances-08-12
@@ -9,7 +9,7 @@ require ( | |||
github.com/ElrondNetwork/concurrent-map v0.1.3 | |||
github.com/ElrondNetwork/covalent-indexer-go v1.0.6 | |||
github.com/ElrondNetwork/elastic-indexer-go v1.2.38 | |||
github.com/ElrondNetwork/elrond-go-core v1.1.18 | |||
github.com/ElrondNetwork/elrond-go-core v1.1.19-0.20220813193723-a7d8c4aeaa87 |
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.
|
||
func (n *Node) getBlockRootHash(headerHash []byte, header data.HeaderHandler) []byte { | ||
blockRootHash, err := n.processComponents.ScheduledTxsExecutionHandler().GetScheduledRootHashForHeader(headerHash) | ||
if err != nil { |
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.
Unfortunately, we have to swallow this error.
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.
Perhaps compare it with some well-known errors, then log.Warn
if necessary?
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.
it is ok like this. We either return the roothash (that we can find on disk) as the function states.
I think we have a similar approach in the block processors process/block/shardblock.go L1208 + L1250-L1253
numSpecifiedBlockCoordinates++ | ||
} | ||
|
||
if numSpecifiedBlockCoordinates > 1 { |
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.
elegant implementation 👍
@@ -15,11 +17,44 @@ func parseBoolUrlParam(c *gin.Context, name string) (bool, error) { | |||
return strconv.ParseBool(param) | |||
} | |||
|
|||
func parseUintUrlParam(c *gin.Context, name string) (uint64, error) { | |||
func parseUint32UrlParam(c *gin.Context, name string) (core.OptionalUint32, error) { |
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.
👍
return core.OptionalUint32{Value: uint32(value), HasValue: true}, nil | ||
} | ||
|
||
func parseUint64UrlParam(c *gin.Context, name string) (core.OptionalUint64, error) { |
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.
👍
…elrond-go into historical-balances-08-12
@@ -30,6 +31,13 @@ func (n *Node) loadUserAccountHandlerByPubKey(pubKey []byte, options api.Account | |||
|
|||
account, blockInfo, err := repository.GetAccountWithBlockInfo(pubKey, options) | |||
if err != nil { | |||
blockInfo, ok := extractBlockInfoIfErrAccountNotFoundAtBlock(err) |
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.
interesting approach for error handling/passing/extracting data out of it
accountsDB.mutRecreateAndGet.RLock() | ||
if !accountsDB.shouldRecreateTrieUnprotected(rootHash) { | ||
// Re-creation is not necessary, but make sure no other routine re-creates it. | ||
defer accountsDB.mutRecreateAndGet.RUnlock() |
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.
👍 yup, this should stay on defer
for j := 0; j < numCallsPerRootHash; j++ { | ||
wg.Add(1) | ||
|
||
go func(rootHashAsInt int) { |
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.
wondering how these numbers numRootHashes = 128 and numCallsPerRootHash = 128 do not crash the race detector since it can handle a maximum 8192 go routines
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.
System test passed.
Description of the reasoning behind the pull request (what feature was missing / how the problem was manifesting itself / what was the motive behind the refactoring)
address/erd1alice?blockNonce=12345
.Proposed Changes
addressGroup
), allow one to provide extra URL parameters (query parameters) for account-related endpoints. These parameters are:blockNonce
,blockHash
,blockRootHash
. They are mutually exclusive.node
object, handle the new query options and appropriately delegate the queries to theaccountsRepository
. TheaccountsRepository
relies on a new component (see below) to resolve historical queries.accountsDBApi
, add a new implementation ofAccountsAdapterAPI
:accountsDBApiWithHistory
. This implementation is able to provide historical state (balance etc.) for the queried account, by recreating the trie at a specifiedrootHash
.rootHash
is possible thanks to: Enable snapshot even if pruning is disabled #4365.AccountsStatePruningEnabled = false
. The implementation is also subject to (affected by):NumActivePersisters = K
.Testing procedure
check:data
validation flow, withhistorical balances
enabled, on local testnet, then on devnet./address/erd1alice?blockNonce=...
,/address/erd1alice?blockHash=...
,/address/erd1alice?blockRootHash=...
. On the response, also check theblockInfo
field. It should match the provided coordinates.sender = Alice
, broadcast a transaction that transfers some value. Say this transaction is added in block N. Then, queryaddress/erd1alice?blockNonce=(N-1)
,address/erd1alice?blockNonce=(N)
andaddress/erd1alice?blockNonce=(N+1)
. Check output.AccountsStatePruningEnabled = false
andNumActivePersisters = K
, where K should be at least 3 (3 is fine).