Skip to content

Commit

Permalink
Write app call addresses in txn_participation table.
Browse files Browse the repository at this point in the history
  • Loading branch information
tolikzinovyev committed Nov 3, 2021
1 parent 9833f05 commit eda1a3a
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 35 deletions.
30 changes: 30 additions & 0 deletions accounting/accounting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package accounting

import (
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/transactions"
)

// GetTransactionParticipants calls function `add` for every address referenced in the
// given transaction, possibly with repetition.
func GetTransactionParticipants(stxnad *transactions.SignedTxnWithAD, includeInner bool, add func(address basics.Address)) {
txn := &stxnad.Txn

add(txn.Sender)
add(txn.Receiver)
add(txn.CloseRemainderTo)
add(txn.AssetSender)
add(txn.AssetReceiver)
add(txn.AssetCloseTo)
add(txn.FreezeAccount)

for _, address := range txn.ApplicationCallTxnFields.Accounts {
add(address)
}

if includeInner {
for _, inner := range stxnad.ApplyData.EvalDelta.InnerTxns {
GetTransactionParticipants(&inner, includeInner, add)
}
}
}
23 changes: 3 additions & 20 deletions idb/postgres/internal/writer/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/algorand/go-algorand/protocol"
"github.com/jackc/pgx/v4"

"github.com/algorand/indexer/accounting"
"github.com/algorand/indexer/idb"
"github.com/algorand/indexer/idb/postgres/internal/encoding"
"github.com/algorand/indexer/idb/postgres/internal/schema"
Expand Down Expand Up @@ -265,24 +266,6 @@ func (w *Writer) addTransactions(block *bookkeeping.Block, modifiedTxns []transa
return nil
}

func getTransactionParticipantsImpl(stxnad *transactions.SignedTxnWithAD, includeInner bool, add func(address basics.Address)) {
txn := stxnad.Txn

add(txn.Sender)
add(txn.Receiver)
add(txn.CloseRemainderTo)
add(txn.AssetSender)
add(txn.AssetReceiver)
add(txn.AssetCloseTo)
add(txn.FreezeAccount)

if includeInner {
for _, inner := range stxnad.ApplyData.EvalDelta.InnerTxns {
getTransactionParticipantsImpl(&inner, includeInner, add)
}
}
}

// getTransactionParticipants returns referenced addresses from the txn and all inner txns
func getTransactionParticipants(stxnad *transactions.SignedTxnWithAD, includeInner bool) []basics.Address {
const acctsPerTxn = 7
Expand All @@ -302,7 +285,7 @@ func getTransactionParticipants(stxnad *transactions.SignedTxnWithAD, includeInn
res = append(res, address)
}

getTransactionParticipantsImpl(stxnad, includeInner, add)
accounting.GetTransactionParticipants(stxnad, includeInner, add)
return res
}

Expand All @@ -318,7 +301,7 @@ func getTransactionParticipants(stxnad *transactions.SignedTxnWithAD, includeInn
participants[address] = struct{}{}
}

getTransactionParticipantsImpl(stxnad, includeInner, add)
accounting.GetTransactionParticipants(stxnad, includeInner, add)

res := make([]basics.Address, 0, len(participants))
for addr := range participants {
Expand Down
64 changes: 64 additions & 0 deletions idb/postgres/internal/writer/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,70 @@ func TestWriterTxnParticipationTableBasic(t *testing.T) {
}
}

func TestWriterTxnParticipationTableAppCallAddresses(t *testing.T) {
db, shutdownFunc := setupPostgres(t)
defer shutdownFunc()

block := bookkeeping.Block{
BlockHeader: bookkeeping.BlockHeader{
Round: basics.Round(2),
GenesisID: test.MakeGenesis().ID(),
GenesisHash: test.GenesisHash,
UpgradeState: bookkeeping.UpgradeState{
CurrentProtocol: test.Proto,
},
},
Payset: make(transactions.Payset, 1),
}

stxnad := test.MakeCreateAppTxn(test.AccountA)
stxnad.Txn.ApplicationCallTxnFields.Accounts =
[]basics.Address{test.AccountB, test.AccountC}
var err error
block.Payset[0], err = block.EncodeSignedTxn(stxnad.SignedTxn, stxnad.ApplyData)
require.NoError(t, err)

f := func(tx pgx.Tx) error {
w, err := writer.MakeWriter(tx)
require.NoError(t, err)

err = w.AddBlock(&block, block.Payset, ledgercore.StateDelta{})
require.NoError(t, err)

w.Close()
return nil
}
err = pgutil.TxWithRetry(db, serializable, f, nil)
require.NoError(t, err)

results, err := txnParticipationQuery(db, `SELECT * FROM txn_participation ORDER BY round, intra, addr`)
assert.NoError(t, err)

expected := []txnParticipationRow{
{
addr: test.AccountA,
round: 2,
intra: 0,
},
{
addr: test.AccountB,
round: 2,
intra: 0,
},
{
addr: test.AccountC,
round: 2,
intra: 0,
},
}

// Verify expected participation
assert.Len(t, results, len(expected))
for i := range results {
assert.Equal(t, expected[i], results[i])
}
}

// Create a new account and then delete it.
func TestWriterAccountTableBasic(t *testing.T) {
db, shutdownFunc := setupPostgres(t)
Expand Down
20 changes: 5 additions & 15 deletions idb/postgres/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/jackc/pgx/v4/pgxpool"
log "github.com/sirupsen/logrus"

"github.com/algorand/indexer/accounting"
models "github.com/algorand/indexer/api/generated/v2"
"github.com/algorand/indexer/idb"
"github.com/algorand/indexer/idb/migration"
Expand Down Expand Up @@ -158,20 +159,6 @@ func (db *IndexerDb) init(opts idb.IndexerDbOptions) (chan struct{}, error) {
return db.runAvailableMigrations()
}

// Add addresses referenced in `txn` to `out`.
func getTxnAddresses(txn *transactions.Transaction, out map[basics.Address]struct{}) {
out[txn.Sender] = struct{}{}
out[txn.Receiver] = struct{}{}
out[txn.CloseRemainderTo] = struct{}{}
out[txn.AssetSender] = struct{}{}
out[txn.AssetReceiver] = struct{}{}
out[txn.AssetCloseTo] = struct{}{}
out[txn.FreezeAccount] = struct{}{}
for _, address := range txn.ApplicationCallTxnFields.Accounts {
out[address] = struct{}{}
}
}

// Returns all addresses referenced in `block`.
func getBlockAddresses(block *bookkeeping.Block) map[basics.Address]struct{} {
// Reserve a reasonable memory size for the map.
Expand All @@ -180,7 +167,10 @@ func getBlockAddresses(block *bookkeeping.Block) map[basics.Address]struct{} {
res[block.FeeSink] = struct{}{}
res[block.RewardsPool] = struct{}{}
for _, stib := range block.Payset {
getTxnAddresses(&stib.Txn, res)
addFunc := func(address basics.Address) {
res[address] = struct{}{}
}
accounting.GetTransactionParticipants(&stib.SignedTxnWithAD, true, addFunc)
}

return res
Expand Down

0 comments on commit eda1a3a

Please sign in to comment.