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

Add ledger.GetBlockAddresses() #2872

Merged
merged 5 commits into from
Sep 13, 2021
Merged
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
37 changes: 35 additions & 2 deletions ledger/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,21 @@ type loadedTransactionGroup struct {
err error
}

// Return the maximum number of addresses referenced in any given transaction.
func maxAddressesInTxn(proto *config.ConsensusParams) int {
return 7 + proto.MaxAppTxnAccounts
}

// Write the list of addresses referenced in `txn` to `out`. Addresses might repeat.
func getTxnAddresses(txn *transactions.Transaction, out *[]basics.Address) {
*out = (*out)[:0]

*out = append(
*out, txn.Sender, txn.Receiver, txn.CloseRemainderTo, txn.AssetSender,
txn.AssetReceiver, txn.AssetCloseTo, txn.FreezeAccount)
*out = append(*out, txn.ApplicationCallTxnFields.Accounts...)
}

// loadAccounts loads the account data for the provided transaction group list. It also loads the feeSink account and add it to the first returned transaction group.
// The order of the transaction groups returned by the channel is identical to the one in the input array.
func loadAccounts(ctx context.Context, l ledgerForEvaluator, rnd basics.Round, groups [][]transactions.SignedTxnWithAD, feeSinkAddr basics.Address, consensusParams config.ConsensusParams) chan loadedTransactionGroup {
Expand All @@ -1320,8 +1335,7 @@ func loadAccounts(ctx context.Context, l ledgerForEvaluator, rnd basics.Round, g
defer close(outChan)

accountTasks := make(map[basics.Address]*addrTask)
maxAddressesPerTransaction := 7 + consensusParams.MaxAppTxnAccounts
addressesCh := make(chan *addrTask, len(groups)*consensusParams.MaxTxGroupSize*maxAddressesPerTransaction)
addressesCh := make(chan *addrTask, len(groups)*consensusParams.MaxTxGroupSize*maxAddressesInTxn(&consensusParams))
// totalBalances counts the total number of balances over all the transaction groups
totalBalances := 0

Expand Down Expand Up @@ -1362,6 +1376,7 @@ func loadAccounts(ctx context.Context, l ledgerForEvaluator, rnd basics.Round, g
task := &groupTask{}
groupsReady[i] = task
for _, stxn := range group {
// If you add new addresses here, also add them in getTxnAddresses().
initAccount(stxn.Txn.Sender, task)
initAccount(stxn.Txn.Receiver, task)
initAccount(stxn.Txn.CloseRemainderTo, task)
Expand Down Expand Up @@ -1503,6 +1518,24 @@ func (vb ValidatedBlock) WithSeed(s committee.Seed) ValidatedBlock {
}
}

// GetBlockAddresses returns all addresses referenced in `block`.
func GetBlockAddresses(block *bookkeeping.Block) map[basics.Address]struct{} {
// Reserve a reasonable memory size for the map.
res := make(map[basics.Address]struct{}, len(block.Payset)+2)
res[block.FeeSink] = struct{}{}
res[block.RewardsPool] = struct{}{}

var refAddresses []basics.Address
for _, stib := range block.Payset {
getTxnAddresses(&stib.Txn, &refAddresses)
for _, address := range refAddresses {
res[address] = struct{}{}
}
}

return res
}

// Eval evaluates a block without validation using the given `proto`. Return the state
// delta and transactions with modified apply data according to `proto`.
// This function is used by Indexer which modifies `proto` to retrieve the asset
Expand Down