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

prefetcher test #4250

Closed
Closed
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
315 changes: 315 additions & 0 deletions test/e2e-go/features/transactions/accountv2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/transactions"
"github.com/algorand/go-algorand/data/transactions/logic"
Expand Down Expand Up @@ -335,3 +336,317 @@ int 1
// 3 global state update in total, 2 local state updates
checkEvalDelta(t, &client, txnRound, txnRound+1, 3, 2)
}

// Add offending asset index greater than uint64
func TestAccountInformationWithBadAssetIdx(t *testing.T) {
partitiontest.PartitionTest(t)
defer fixtures.ShutdownSynchronizedTest(t)

t.Parallel()
AccountInformationCheckWithOffendingFields(t, []basics.AssetIndex{12181853637140359511}, nil, nil)
}

// Add missing asset index
func TestAccountInformationWithMissingAssetIdx(t *testing.T) {
partitiontest.PartitionTest(t)
defer fixtures.ShutdownSynchronizedTest(t)

AccountInformationCheckWithOffendingFields(t, []basics.AssetIndex{121818}, nil, nil)
}

// Add offending app index greater than uint64
func TestAccountInformationWithBadAppIdx(t *testing.T) {
partitiontest.PartitionTest(t)
defer fixtures.ShutdownSynchronizedTest(t)

AccountInformationCheckWithOffendingFields(t, nil, []basics.AppIndex{12181853637140359511}, nil)
}

// Add missing app index
func TestAccountInformationWithMissingApp(t *testing.T) {
partitiontest.PartitionTest(t)
defer fixtures.ShutdownSynchronizedTest(t)

AccountInformationCheckWithOffendingFields(t, nil, []basics.AppIndex{121818}, nil)
}

// Add missing account address
func TestAccountInformationWithMissingAddress(t *testing.T) {
partitiontest.PartitionTest(t)
defer fixtures.ShutdownSynchronizedTest(t)

randAddr := basics.Address{}
crypto.RandBytes(randAddr[:])
AccountInformationCheckWithOffendingFields(t, nil, nil, []basics.Address{randAddr})
}

func AccountInformationCheckWithOffendingFields(t *testing.T,
foreignAssets []basics.AssetIndex,
foreignApps []basics.AppIndex,
accounts []basics.Address) {

a := require.New(fixtures.SynchronizedTest(t))

var fixture fixtures.RestClientFixture
proto, ok := config.Consensus[protocol.ConsensusFuture]
a.True(ok)
proto.AgreementFilterTimeoutPeriod0 = 400 * time.Millisecond
proto.AgreementFilterTimeout = 400 * time.Millisecond
fixture.SetConsensus(config.ConsensusProtocols{protocol.ConsensusFuture: proto})

fixture.Setup(t, filepath.Join("nettemplates", "TwoNodes50EachV26.json"))
defer fixture.Shutdown()

client := fixture.LibGoalClient
accountList, err := fixture.GetWalletsSortedByBalance()
a.NoError(err)

creator := accountList[0].Address
wh, err := client.GetUnencryptedWalletHandle()
a.NoError(err)

user, err := client.GenerateAddress(wh)
a.NoError(err)

fee := uint64(1000)

var txn transactions.Transaction

// Fund the manager, so it can issue transactions later on
txn, err = client.SendPaymentFromUnencryptedWallet(creator, user, fee, 10000000000, nil)
a.NoError(err)

round, err := client.CurrentRound()
a.NoError(err)
fixture.WaitForConfirmedTxn(round+4, creator, txn.ID().String())

// There should be no apps to start with
ad, err := client.AccountData(creator)
a.NoError(err)
a.Zero(len(ad.AppParams))

ad, err = client.AccountData(user)
a.NoError(err)
a.Zero(len(ad.AppParams))
a.Equal(basics.MicroAlgos{Raw: 10000000000}, ad.MicroAlgos)

counter := `#pragma version 2
// a simple global and local calls counter app
byte b64 Y291bnRlcg== // counter
dup
app_global_get
int 1
+
app_global_put // update the counter
int 0
int 0
app_opted_in
bnz opted_in
err
opted_in:
int 0 // account idx for app_local_put
byte b64 Y291bnRlcg== // counter
int 0
byte b64 Y291bnRlcg==
app_local_get
int 1 // increment
+
app_local_put
int 1
`
approvalOps, err := logic.AssembleString(counter)
a.NoError(err)
clearstateOps, err := logic.AssembleString("#pragma version 2\nint 1")
a.NoError(err)
schema := basics.StateSchema{
NumUint: 1,
}

// create the app
tx, err := client.MakeUnsignedAppCreateTx(
transactions.OptInOC, approvalOps.Program, clearstateOps.Program, schema, schema, nil, nil, nil, nil, 0)
a.NoError(err)
tx, err = client.FillUnsignedTxTemplate(creator, 0, 0, fee, tx)
a.NoError(err)
wh, err = client.GetUnencryptedWalletHandle()
a.NoError(err)
signedTxn, err := client.SignTransactionWithWallet(wh, nil, tx)
a.NoError(err)
txid, err := client.BroadcastTransaction(signedTxn)
a.NoError(err)
round, err = client.CurrentRound()
a.NoError(err)
// ensure transaction is accepted into a block within 5 rounds.
confirmed := fixture.WaitForAllTxnsToConfirm(round+5, map[string]string{txid: signedTxn.Txn.Sender.String()})
a.True(confirmed)

// check creator's balance record for the app entry and the state changes
ad, err = client.AccountData(creator)
a.NoError(err)
a.Equal(1, len(ad.AppParams))
var appIdx basics.AppIndex
var params basics.AppParams
for i, p := range ad.AppParams {
appIdx = i
params = p
break
}
a.Equal(approvalOps.Program, params.ApprovalProgram)
a.Equal(clearstateOps.Program, params.ClearStateProgram)
a.Equal(schema, params.LocalStateSchema)
a.Equal(schema, params.GlobalStateSchema)
a.Equal(1, len(params.GlobalState))
value, ok := params.GlobalState["counter"]
a.True(ok)
a.Equal(uint64(1), value.Uint)

a.Equal(1, len(ad.AppLocalStates))
state, ok := ad.AppLocalStates[appIdx]
a.True(ok)
a.Equal(schema, state.Schema)
a.Equal(1, len(state.KeyValue))
value, ok = state.KeyValue["counter"]
a.True(ok)
a.Equal(uint64(1), value.Uint)

txInfo, err := fixture.LibGoalClient.PendingTransactionInformationV2(txid)
a.NoError(err)
a.NotNil(txInfo.ConfirmedRound)
a.NotZero(*txInfo.ConfirmedRound)
txnRound := *txInfo.ConfirmedRound

// 1 global state update in total, 1 local state updates
checkEvalDelta(t, &client, txnRound, txnRound+1, 1, 1)

// call the app
tx, err = client.MakeUnsignedAppOptInTx(uint64(appIdx), nil, nil, nil, nil)
a.NoError(err)
if foreignAssets != nil {
tx.ForeignAssets = foreignAssets
}
if foreignApps != nil {
tx.ForeignApps = foreignApps
}
if accounts != nil {
tx.Accounts = accounts
}
tx, err = client.FillUnsignedTxTemplate(user, 0, 0, fee, tx)
a.NoError(err)
wh, err = client.GetUnencryptedWalletHandle()
a.NoError(err)
signedTxn, err = client.SignTransactionWithWallet(wh, nil, tx)
a.NoError(err)
txid, err = client.BroadcastTransaction(signedTxn)
a.NoError(err)
round, err = client.CurrentRound()
a.NoError(err)
_, err = client.WaitForRound(round + 3)
a.NoError(err)

// Ensure the txn committed
resp, err := client.GetPendingTransactions(2)
a.NoError(err)
a.Equal(uint64(0), resp.TotalTxns)
txinfo, err := client.TransactionInformation(signedTxn.Txn.Sender.String(), txid)
a.NoError(err)
a.True(txinfo.ConfirmedRound != 0)

// check creator's balance record for the app entry and the state changes
ad, err = client.AccountData(creator)
a.NoError(err)
a.Equal(1, len(ad.AppParams))
params, ok = ad.AppParams[appIdx]
a.True(ok)
a.Equal(approvalOps.Program, params.ApprovalProgram)
a.Equal(clearstateOps.Program, params.ClearStateProgram)
a.Equal(schema, params.LocalStateSchema)
a.Equal(schema, params.GlobalStateSchema)
a.Equal(1, len(params.GlobalState))
value, ok = params.GlobalState["counter"]
a.True(ok)
a.Equal(uint64(2), value.Uint)

a.Equal(1, len(ad.AppLocalStates))
state, ok = ad.AppLocalStates[appIdx]
a.True(ok)
a.Equal(schema, state.Schema)
a.Equal(1, len(state.KeyValue))
value, ok = state.KeyValue["counter"]
a.True(ok)
a.Equal(uint64(1), value.Uint)

a.Equal(uint64(2), ad.TotalAppSchema.NumUint)

// check user's balance record for the app entry and the state changes
ad, err = client.AccountData(user)
a.NoError(err)
a.Equal(0, len(ad.AppParams))

a.Equal(1, len(ad.AppLocalStates))
state, ok = ad.AppLocalStates[appIdx]
a.True(ok)
a.Equal(schema, state.Schema)
a.Equal(1, len(state.KeyValue))
value, ok = state.KeyValue["counter"]
a.True(ok)
a.Equal(uint64(1), value.Uint)

txInfo, err = fixture.LibGoalClient.PendingTransactionInformationV2(txid)
a.NoError(err)
a.NotNil(txInfo.ConfirmedRound)
a.NotZero(*txInfo.ConfirmedRound)
txnRound = *txInfo.ConfirmedRound

// 2 global state update in total, 1 local state updates
checkEvalDelta(t, &client, txnRound, txnRound+1, 2, 1)

a.Equal(basics.MicroAlgos{Raw: 10000000000 - fee}, ad.MicroAlgos)

app, err := client.ApplicationInformation(uint64(appIdx))
a.NoError(err)
a.Equal(uint64(appIdx), app.Id)
a.Equal(creator, app.Params.Creator)

// call the app
tx, err = client.MakeUnsignedAppNoOpTx(uint64(appIdx), nil, nil, nil, nil)
a.NoError(err)
tx, err = client.FillUnsignedTxTemplate(user, 0, 0, fee, tx)
a.NoError(err)
signedTxn, err = client.SignTransactionWithWallet(wh, nil, tx)
a.NoError(err)
txid, err = client.BroadcastTransaction(signedTxn)
a.NoError(err)
for {
round, err = client.CurrentRound()
a.NoError(err)
_, err = client.WaitForRound(round + 1)
a.NoError(err)
// Ensure the txn committed
resp, err = client.GetPendingTransactions(2)
a.NoError(err)
if resp.TotalTxns == 1 {
a.Equal(resp.TruncatedTxns.Transactions[0].TxID, txid)
continue
}
a.Equal(uint64(0), resp.TotalTxns)
break
}

ad, err = client.AccountData(creator)
a.NoError(err)
a.Equal(1, len(ad.AppParams))
params, ok = ad.AppParams[appIdx]
a.True(ok)
value, ok = params.GlobalState["counter"]
a.True(ok)
a.Equal(uint64(3), value.Uint)

txInfo, err = fixture.LibGoalClient.PendingTransactionInformationV2(txid)
a.NoError(err)
a.NotNil(txInfo.ConfirmedRound)
a.NotZero(*txInfo.ConfirmedRound)
txnRound = *txInfo.ConfirmedRound

// 3 global state update in total, 2 local state updates
checkEvalDelta(t, &client, txnRound, txnRound+1, 3, 2)
}