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

tools: block-generator applications. Part 1: create #5450

Merged
merged 97 commits into from Jun 15, 2023

Conversation

tzaffi
Copy link
Contributor

@tzaffi tzaffi commented Jun 5, 2023

Summary

Handle application creation in the block generator including local storage.

TODO in a follow up PR

  • create boxes and populate app_boxes
  • handle additional app calls, most pressingly simple app calls show the results of typical app usage on DB ingestion

Blocked by:

Test Plan

Some unit tests are added. However, most of the testing is done locally. You can try at home as follows:

NOTE: I mixed/matched some outputs from various runs so the numbers below are inconsistent

cd tools/block-generator
❯ go build
❯ ln -s ~/github/algorand/conduit/cmd/conduit/conduit conduit
❯ make debug-blockgen
... this brings up the postgres docker and prints out some info in case you want to run directly or through vs-code

❯ docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS                     NAMES
652e8cc02075   postgres   "docker-entrypoint.s…"   8 seconds ago   Up 7 seconds   0.0.0.0:15432->5432/tcp   generator-test-container

❯ make run-runner
./block-generator runner --conduit-binary ./conduit \
        --log-level trace \
        --keep-data-dir \
        --report-directory RUN_RUNNER_OUTPUTS \
        --test-duration 30s --log-level trace \
        --postgres-connection-string "host=localhost user=algorand password=algorand dbname=generator_db port=15432 sslmode=disable" \
        --scenario scenarios/config.app.create.yml  \

Running test for configuration 'scenarios/config.app.create.yml'
generator serving on localhost:11112
Received round request 0 == g.roundOffset but already advanced g.round=1. Not finishing round.
exiting block generator runner: signal: interrupt
Done running tests!

❯ cat RUN_RUNNER_OUTPUTS/config.app.create.report
scenario:config.app.create.yml
test_duration_seconds:30
test_duration_actual_seconds:30.022316
transaction_asset_create_total:14192
transaction_app_boxes_create_total:7171
transaction_app_swap_create_total:7083
early_average_import_time_sec:0.07
early_cumulative_import_time_sec:6.23
early_average_imported_tx_per_block:100.00
early_cumulative_imported_tx_per_block:9500
early_imported_round:95
early_overall_transactions_per_second:1524.83
early_uptime_seconds:30.03
final_average_import_time_sec:0.07
final_cumulative_import_time_sec:20.48
final_average_imported_tx_per_block:100.00
final_cumulative_imported_tx_per_block:28400
final_imported_round:284
final_overall_transactions_per_second:1386.54
final_uptime_seconds:30.03

❯ make enter-pg
docker exec -it generator-test-container psql -U algorand -d generator_db
psql (14.5 (Debian 14.5-1.pgdg110+1))
Type "help" for help.

generator_db=# \dt
               List of relations
 Schema |       Name        | Type  |  Owner   
--------+-------------------+-------+----------
 public | account           | table | algorand
 public | account_app       | table | algorand
 public | account_asset     | table | algorand
 public | app               | table | algorand
 public | app_box           | table | algorand
 public | asset             | table | algorand
 public | block_header      | table | algorand
 public | metastate         | table | algorand
 public | txn               | table | algorand
 public | txn_participation | table | algorand
(10 rows)

generator_db=# select count(*) from account;
 count 
-------
  1002
(1 row)

generator_db=# select count(*) from account_app;
 14899
generator_db=# select count(*) from account_asset;
 16382
generator_db=# select count(*) from app;
 16318
generator_db=# select count(*) from app_box;
     0
generator_db=# select count(*) from asset;
 16382
generator_db=# select count(*) from block_header;
   632
generator_db=# select count(*) from txn;
 62600
generator_db=# select count(*) from txn_participation;
 62600

generator_db=# exit
❯ make cleanup
rm -rf reports 

@tzaffi tzaffi requested review from shiqizng and a team June 9, 2023 14:34
@tzaffi tzaffi changed the title DRAFT tools: block-generator applications. Part 1. tools: block-generator applications. Part 1. Jun 9, 2023
@tzaffi tzaffi changed the title tools: block-generator applications. Part 1. tools: block-generator applications. Part 1: create Jun 9, 2023
"github.com/algorand/go-algorand/protocol"
)

func (g *generator) makeTxnHeader(sender basics.Address, round, intra uint64) transactions.Header {
// ---- header / boilerplate ----

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this diff is confusing. I didn't actually modify makeTxnHeader except for renaming the transactions import (→ txn). But I did introduce makeTestTxn which is very similar to makeTxnHeader and confused the differ.

@@ -20,15 +20,34 @@ import (
"encoding/binary"

"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/transactions"
txn "github.com/algorand/go-algorand/data/transactions"
"github.com/algorand/go-algorand/data/txntest"
Copy link
Contributor Author

@tzaffi tzaffi Jun 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

txntest.Txn is the modern convenience struct for testing transactions

return signTxn(txn), transactions.ApplyData{}, nil
}

func (g *generator) generateAppCallInternal(txType TxTypeID, round, intra, hintIndex uint64, hintApp *appData) (TxTypeID, transactions.Transaction, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hintIndex not used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep this param until my follow up PR is ready for review, at which point I commit to removing if still unused.

Let's not resolve this discussion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's removed in #5478

tools/block-generator/generator/generate.go Outdated Show resolved Hide resolved
numApps := uint64(len(g.apps[kind]))
if numApps == 0 {
actualAppTx = appTxTypeCreate
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this block necessary? you've assert at line 799 that appTx must be appTxTypeCreate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another one I'd like to keep till the next PR is ready, and so let's not resolve this discussion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic has been fixed in #5478

note := make([]byte, 8)
binary.LittleEndian.PutUint64(note, uint64(g.txnCounter+intra))

return transactions.Header{
return txntest.Txn{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

}

// makeTestTxn creates and populates the flat txntest.Txn structure with the given values.
func (g *generator) makeTestTxn(sender basics.Address, round, intra uint64) txntest.Txn {
note := make([]byte, 8)
binary.LittleEndian.PutUint64(note, uint64(g.txnCounter+intra))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: uint64 casting is not needed; same for makeTxnHeader

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ad = *g.pendingApps[appKindSwap][0]
holding = *ad.holdings[0]
require.Equal(t, holding, *ad.holders[0])
require.Equal(t, uint64(1001), holding.appIndex)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised the appID is still 1001. I expected to have incremented to 1002.

Copy link
Contributor Author

@tzaffi tzaffi Jun 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because I'm not passing the new intra into generateAppCallInternal(). I'm much more explicit about this in the next PR. I propose keeping this thread open and adding it as a TODO to the follow up.

winder
winder previously approved these changes Jun 12, 2023
Copy link
Contributor

@winder winder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a nit. LGTM

tools/block-generator/generator/generate.go Outdated Show resolved Hide resolved
Co-authored-by: Will Winder <wwinder.unh@gmail.com>
@winder winder merged commit 4d6e50d into algorand:master Jun 15, 2023
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants