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

API: Experimental full assets for account endpoint. #5948

Merged
merged 18 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
6993d7f
Initial cut of support for a full assets for account endpoint. Suppor…
gmalouf Apr 30, 2024
e846d55
Patches for cleanly returning no results when next token is set above…
gmalouf Mar 6, 2024
d2d1b8e
Unit test of the AccountAssets endpoint. Updated pagination logic to …
gmalouf Apr 1, 2024
f6de85c
Update lookup limited resources sql query to conditionally/left join …
gmalouf Apr 4, 2024
55667f3
Set asset max on account assets pagination query to 1000.
gmalouf Apr 4, 2024
7bc9aa1
Add support for invoking the account assets information endpoint from…
gmalouf Apr 6, 2024
f694aba
Introduce new database target version, adding a ctype column to the r…
gmalouf Apr 9, 2024
6726399
Remove join from resources table ctype migration and add a check if d…
gmalouf Apr 10, 2024
6c3d282
OAS cleanup.
gmalouf Apr 10, 2024
7722f80
Update AccountsInitTest for latest migration.
gmalouf Apr 10, 2024
a810c49
Decrease migration runtime of ctype resources migration by 2.5x lever…
gmalouf Apr 22, 2024
5d87b80
Address test failures (k-v store version has to match sqlite, even wi…
gmalouf Apr 23, 2024
5ab49fd
Refactor resources ctype migration to use a default value, avoiding h…
gmalouf Apr 25, 2024
6bb6442
Test adjustments to properly simulate initializing a ledger from a ca…
gmalouf Apr 30, 2024
963027d
Code review tweaks.
gmalouf Apr 30, 2024
2db2669
Changes based on additional CR feedback.
gmalouf May 2, 2024
778cadf
Basic exercise of goal account assetdetails in goal-account-asset.sh
gmalouf May 2, 2024
737c178
Update test/scripts/e2e_subs/goal-account-asset.sh
gmalouf May 3, 2024
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
6 changes: 5 additions & 1 deletion ledger/catchpointfilewriter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,9 @@ func testNewLedgerFromCatchpoint(t *testing.T, catchpointWriterReadAccess tracke
var initState ledgercore.InitState
initState.Block.CurrentProtocol = protocol.ConsensusCurrentVersion
conf := config.GetDefaultLocal()
l, err := OpenLedger(logging.TestingLog(t), t.Name()+"FromCatchpoint", true, initState, conf)
dbName := fmt.Sprintf("%s.%d", t.Name()+"FromCatchpoint", crypto.RandUint64())
dbName = strings.Replace(dbName, "/", "_", -1)
l, err := OpenLedger(logging.TestingLog(t), dbName, true, initState, conf)
require.NoError(t, err)
accessor := MakeCatchpointCatchupAccessor(l, l.log)

Expand All @@ -702,6 +704,8 @@ func testNewLedgerFromCatchpoint(t *testing.T, catchpointWriterReadAccess tracke
err = accessor.BuildMerkleTrie(context.Background(), nil)
require.NoError(t, err)

resetAccountDBToV6(t, l)
gmalouf marked this conversation as resolved.
Show resolved Hide resolved

err = l.trackerDBs.Transaction(func(ctx context.Context, tx trackerdb.TransactionScope) error {
cw, err := tx.MakeCatchpointWriter()
if err != nil {
Expand Down
40 changes: 38 additions & 2 deletions ledger/ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ import (
"github.com/algorand/go-deadlock"
)

const preReleaseDBVersion = 6

func sign(secrets map[basics.Address]*crypto.SignatureSecrets, t transactions.Transaction) transactions.SignedTxn {
var sig crypto.Signature
_, ok := secrets[t.Sender]
Expand Down Expand Up @@ -2178,6 +2180,42 @@ func TestLedgerReloadShrinkDeltas(t *testing.T) {
}
}

func resetAccountDBToV6(t *testing.T, l *Ledger) {
// reset tables and re-init again, similary to the catchpount apply code
// since the ledger has only genesis accounts, this recreates them
err := l.trackerDBs.Transaction(func(ctx context.Context, tx trackerdb.TransactionScope) error {
arw, err := tx.MakeAccountsWriter()
if err != nil {
return err
}

err0 := arw.AccountsReset(ctx)
if err0 != nil {
return err0
}
tp := trackerdb.Params{
InitAccounts: l.GenesisAccounts(),
InitProto: l.GenesisProtoVersion(),
GenesisHash: l.GenesisHash(),
FromCatchpoint: true,
CatchpointEnabled: l.catchpoint.catchpointEnabled(),
DbPathPrefix: l.catchpoint.dbDirectory,
BlockDb: l.blockDBs,
}
_, err0 = tx.RunMigrations(ctx, tp, l.log, preReleaseDBVersion /*target database version*/)
if err0 != nil {
return err0
}

if err0 := tx.Testing().AccountsUpdateSchemaTest(ctx); err != nil {
return err0
}

return nil
})
require.NoError(t, err)
}

// TestLedgerReloadTxTailHistoryAccess checks txtail has MaxTxnLife + DeeperBlockHeaderHistory block headers
// for TEAL after applying catchpoint.
// Simulate catchpoints by the following:
Expand All @@ -2189,8 +2227,6 @@ func TestLedgerReloadShrinkDeltas(t *testing.T) {
func TestLedgerReloadTxTailHistoryAccess(t *testing.T) {
partitiontest.PartitionTest(t)

const preReleaseDBVersion = 6

dbName := fmt.Sprintf("%s.%d", t.Name(), crypto.RandUint64())
genesisInitState, initKeys := ledgertesting.GenerateInitState(t, protocol.ConsensusCurrentVersion, 10_000_000_000)
proto := config.Consensus[protocol.ConsensusCurrentVersion]
Expand Down
103 changes: 54 additions & 49 deletions ledger/store/trackerdb/sqlitedriver/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -943,78 +943,83 @@
return err
}

func accountsAddCreatableTypeColumn(ctx context.Context, e db.Executable) error {
func accountsAddCreatableTypeColumn(ctx context.Context, e db.Executable, populateColumn bool) error {
// Run ctype resources migration if it hasn't run yet
var creatableTypeOnResourcesRun bool
err := e.QueryRow("SELECT 1 FROM pragma_table_info('resources') WHERE name='ctype'").Scan(&creatableTypeOnResourcesRun)
if !errors.Is(err, sql.ErrNoRows) {
if err == nil {
// Already exists.
gmalouf marked this conversation as resolved.
Show resolved Hide resolved
return nil

Check warning on line 952 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L952

Added line #L952 was not covered by tests
}
} else if !errors.Is(err, sql.ErrNoRows) {
return err

Check warning on line 954 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L954

Added line #L954 was not covered by tests
} // A sql.ErrNoRows error means the column does not exist, so we need to create it

// Add ctype column
createStmt := `ALTER TABLE resources ADD COLUMN ctype INTEGER NOT NULL DEFAULT -1`
gmalouf marked this conversation as resolved.
Show resolved Hide resolved

_, err = e.ExecContext(ctx, createStmt)
if err != nil {
return err

Check warning on line 962 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L962

Added line #L962 was not covered by tests
}

// Populate the new ctype column with the corresponding creatable type from assetcreators where available
updateStmt := `UPDATE resources SET ctype = (
if populateColumn {
// Populate the new ctype column with the corresponding creatable type from assetcreators where available
updateStmt := `UPDATE resources SET ctype = (
SELECT COALESCE((SELECT ac.ctype FROM assetcreators ac WHERE ac.asset = resources.aidx),-1)
) WHERE ctype = -1`

Check warning on line 969 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L967-L969

Added lines #L967 - L969 were not covered by tests

_, err = e.ExecContext(ctx, updateStmt)
if err != nil {
return err
}

updatePrepStmt, err := e.PrepareContext(ctx, "UPDATE resources SET ctype = ? WHERE addrid = ? AND aidx = ?")
if err != nil {
return err
}
defer updatePrepStmt.Close()

// Pull resource entries into memory where ctype is not set
rows, err := e.QueryContext(ctx, "SELECT addrid, aidx, data FROM resources r WHERE ctype = -1")
if err != nil {
return err
}
defer rows.Close()

// Update the ctype column for subset of resources where ctype was not resolved from assetcreators
for rows.Next() {
var addrid int64
var aidx int64
var encodedData []byte
err = rows.Scan(&addrid, &aidx, &encodedData)
if err != nil {
return err
_, err0 := e.ExecContext(ctx, updateStmt)
if err0 != nil {
return err0

Check warning on line 973 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L971-L973

Added lines #L971 - L973 were not covered by tests
}

var rd trackerdb.ResourcesData
err = protocol.Decode(encodedData, &rd)
if err != nil {
return err
updatePrepStmt, err0 := e.PrepareContext(ctx, "UPDATE resources SET ctype = ? WHERE addrid = ? AND aidx = ?")
if err0 != nil {
return err0

Check warning on line 978 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L976-L978

Added lines #L976 - L978 were not covered by tests
}
defer updatePrepStmt.Close()

Check warning on line 980 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L980

Added line #L980 was not covered by tests

var ct basics.CreatableType
if rd.IsAsset() && rd.IsApp() {
// This should never happen!
return fmt.Errorf("unable to discern creatable type for addrid %d, resource %d", addrid, aidx)
} else if rd.IsAsset() {
ct = basics.AssetCreatable
} else if rd.IsApp() {
ct = basics.AppCreatable
} else { // This should never happen!
return fmt.Errorf("unable to discern creatable type for addrid %d, resource %d", addrid, aidx)
// Pull resource entries into memory where ctype is not set
rows, err0 := e.QueryContext(ctx, "SELECT addrid, aidx, data FROM resources r WHERE ctype = -1")
if err0 != nil {
return err0

Check warning on line 985 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L983-L985

Added lines #L983 - L985 were not covered by tests
}
defer rows.Close()

Check warning on line 987 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L987

Added line #L987 was not covered by tests

_, err = updatePrepStmt.ExecContext(ctx, ct, addrid, aidx)
if err != nil {
return err
// Update the ctype column for subset of resources where ctype was not resolved from assetcreators
for rows.Next() {
var addrid int64
var aidx int64
var encodedData []byte
err0 = rows.Scan(&addrid, &aidx, &encodedData)
if err0 != nil {
return err0

Check warning on line 996 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L990-L996

Added lines #L990 - L996 were not covered by tests
}

var rd trackerdb.ResourcesData
err0 = protocol.Decode(encodedData, &rd)
if err0 != nil {
return err0

Check warning on line 1002 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L999-L1002

Added lines #L999 - L1002 were not covered by tests
}

var ct basics.CreatableType
if rd.IsAsset() && rd.IsApp() {

Check warning on line 1006 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L1005-L1006

Added lines #L1005 - L1006 were not covered by tests
// This should never happen!
return fmt.Errorf("unable to discern creatable type for addrid %d, resource %d", addrid, aidx)
} else if rd.IsAsset() {
ct = basics.AssetCreatable
} else if rd.IsApp() {
ct = basics.AppCreatable
} else { // This should never happen!
return fmt.Errorf("unable to discern creatable type for addrid %d, resource %d", addrid, aidx)

Check warning on line 1014 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L1008-L1014

Added lines #L1008 - L1014 were not covered by tests
}

_, err0 = updatePrepStmt.ExecContext(ctx, ct, addrid, aidx)
if err0 != nil {
return err0

Check warning on line 1019 in ledger/store/trackerdb/sqlitedriver/schema.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/schema.go#L1017-L1019

Added lines #L1017 - L1019 were not covered by tests
}
}
}

return rows.Err()
return nil
jasonpaulos marked this conversation as resolved.
Show resolved Hide resolved
}
20 changes: 14 additions & 6 deletions ledger/store/trackerdb/sqlitedriver/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,29 +101,37 @@
err = performKVStoreNullBlobConversion(context.Background(), e)
require.NoError(tb, err)

err = accountsAddCreatableTypeColumn(context.Background(), e)
err = accountsAddCreatableTypeColumn(context.Background(), e, false)
require.NoError(tb, err)

return newDB
}

// AccountsUpdateSchemaTest adds some empty tables for tests to work with a "v6" store.
func AccountsUpdateSchemaTest(ctx context.Context, e db.Executable) (err error) {
if err := accountsCreateOnlineAccountsTable(ctx, e); err != nil {
if err = accountsCreateOnlineAccountsTable(ctx, e); err != nil {

Check warning on line 112 in ledger/store/trackerdb/sqlitedriver/testing.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/testing.go#L112

Added line #L112 was not covered by tests
return err
}
if err := accountsCreateTxTailTable(ctx, e); err != nil {
if err = accountsCreateTxTailTable(ctx, e); err != nil {

Check warning on line 115 in ledger/store/trackerdb/sqlitedriver/testing.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/testing.go#L115

Added line #L115 was not covered by tests
return err
}
if err := accountsCreateOnlineRoundParamsTable(ctx, e); err != nil {
if err = accountsCreateOnlineRoundParamsTable(ctx, e); err != nil {

Check warning on line 118 in ledger/store/trackerdb/sqlitedriver/testing.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/testing.go#L118

Added line #L118 was not covered by tests
return err
}
if err := accountsCreateCatchpointFirstStageInfoTable(ctx, e); err != nil {
if err = accountsCreateCatchpointFirstStageInfoTable(ctx, e); err != nil {

Check warning on line 121 in ledger/store/trackerdb/sqlitedriver/testing.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/testing.go#L121

Added line #L121 was not covered by tests
return err
}
// this line creates kvstore table, even if it is not required in accountDBVersion 6 -> 7
// or in later version where we need kvstore table, some tests will fail
if err := accountsCreateBoxTable(ctx, e); err != nil {
if err = accountsCreateBoxTable(ctx, e); err != nil {
return err

Check warning on line 127 in ledger/store/trackerdb/sqlitedriver/testing.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/testing.go#L126-L127

Added lines #L126 - L127 were not covered by tests
}
// this adds the resources table and ctype column, even if it is not required in accountDBVersion 6 -> 7
// this prevents some tests from failing.
if err = accountsCreateResourceTable(ctx, e); err != nil {
return err

Check warning on line 132 in ledger/store/trackerdb/sqlitedriver/testing.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/testing.go#L131-L132

Added lines #L131 - L132 were not covered by tests
}
if err = accountsAddCreatableTypeColumn(ctx, e, false); err != nil {

Check warning on line 134 in ledger/store/trackerdb/sqlitedriver/testing.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/testing.go#L134

Added line #L134 was not covered by tests
return err
}
return createStateProofVerificationTable(ctx, e)
Expand Down
2 changes: 1 addition & 1 deletion ledger/store/trackerdb/sqlitedriver/trackerdbV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@
tu.log.Warnf("trackerDBInitialize failed to upgrade accounts database (ledger.tracker.sqlite) from schema 9 : %v", err)
return
}
case 10:
err = tu.upgradeDatabaseSchema10(ctx, e)
if err != nil {
tu.log.Warnf("trackerDBInitialize failed to upgrade accounts database (ledger.tracker.sqlite) from schema 10 : %v", err)
return

Check warning on line 143 in ledger/store/trackerdb/sqlitedriver/trackerdbV2.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/trackerdbV2.go#L139-L143

Added lines #L139 - L143 were not covered by tests
}
default:
return trackerdb.InitParams{}, fmt.Errorf("trackerDBInitialize unable to upgrade database from schema version %d", tu.schemaVersion)
Expand Down Expand Up @@ -515,13 +515,13 @@

// upgradeDatabaseSchema10 upgrades the database schema from version 10 to version 11,
// altering the resources table to add a new column, resources.ctype.
func (tu *trackerDBSchemaInitializer) upgradeDatabaseSchema10(ctx context.Context, e db.Executable) (err error) {
err = accountsAddCreatableTypeColumn(ctx, e)
err = accountsAddCreatableTypeColumn(ctx, e, true)
if err != nil {
return err

Check warning on line 521 in ledger/store/trackerdb/sqlitedriver/trackerdbV2.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/trackerdbV2.go#L518-L521

Added lines #L518 - L521 were not covered by tests
}
// update version
return tu.setVersion(ctx, e, 11)

Check warning on line 524 in ledger/store/trackerdb/sqlitedriver/trackerdbV2.go

View check run for this annotation

Codecov / codecov/patch

ledger/store/trackerdb/sqlitedriver/trackerdbV2.go#L524

Added line #L524 was not covered by tests
}

func removeEmptyDirsOnSchemaUpgrade(dbDirectory string) (err error) {
Expand Down
8 changes: 6 additions & 2 deletions ledger/store/trackerdb/testsuite/accounts_kv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,9 @@ func CustomTestResourcesQueryAllLimited(t *customT) {
resDataA1AcctA := trackerdb.ResourcesData{}
appParams := ledgertesting.RandomAppParams()
resDataA1AcctA.SetAppParams(appParams, true)
resDataA1AcctA.SetAppLocalState(basics.AppLocalState{})
resDataA1AcctB := trackerdb.ResourcesData{}
appParamsB := ledgertesting.RandomAppParams()
resDataA1AcctB.SetAppParams(appParamsB, true)
resDataA1AcctB.SetAppLocalState(basics.AppLocalState{})
aidxResA1 := basics.CreatableIndex(2)
_, err = aow.InsertResource(refAccA, aidxResA1, resDataA1AcctA)
require.NoError(t, err)
Expand Down Expand Up @@ -383,6 +383,10 @@ func CustomTestResourcesQueryAllLimited(t *customT) {
require.Equal(t, resDataWithParamsA0AcctB, prs[0].Data)
require.Equal(t, expectedRound, rnd) // db round (from the return)

// Delete app owner for A-1
_, err = aow.DeleteCreatable(aidxResA1, basics.AppCreatable)
require.NoError(t, err)

// Set min to 1, should return only 1 resource (index 1)
prs, rnd, err = aor.LookupLimitedResources(addrB, 1, 1, basics.AssetCreatable)
require.NoError(t, err)
Expand Down
Loading