Skip to content

Commit

Permalink
tracer: Default to ledger tracer when starting new evaluator (#5521)
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric-Warehime committed Jul 5, 2023
1 parent 55bfa51 commit ec9e662
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 2 deletions.
12 changes: 12 additions & 0 deletions daemon/algod/api/client/restClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,18 @@ func (client RestClient) GetLedgerStateDelta(round uint64) (response model.Ledge
return
}

// GetLedgerStateDeltaForTransactionGroup retrieves the ledger state delta for the txn group specified by the id
func (client RestClient) GetLedgerStateDeltaForTransactionGroup(id string) (response model.LedgerStateDeltaForTransactionGroupResponse, err error) {
err = client.get(&response, fmt.Sprintf("/v2/deltas/txn/group/%s", id), nil)
return
}

// GetTransactionGroupLedgerStateDeltasForRound retrieves the ledger state deltas for the txn groups in the specified round
func (client RestClient) GetTransactionGroupLedgerStateDeltasForRound(round uint64) (response model.TransactionGroupLedgerStateDeltasForRoundResponse, err error) {
err = client.get(&response, fmt.Sprintf("/v2/deltas/%d/txn/group", round), nil)
return
}

// SetBlockTimestampOffset sets the offset in seconds to add to the block timestamp when in devmode
func (client RestClient) SetBlockTimestampOffset(offset uint64) (err error) {
err = client.post(nil, fmt.Sprintf("/v2/devmode/blocks/offset/%d", offset), nil, nil, true)
Expand Down
8 changes: 6 additions & 2 deletions ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -836,15 +836,19 @@ func (l *Ledger) VerifiedTransactionCache() verify.VerifiedTransactionCache {
// If a value of zero or less is passed to maxTxnBytesPerBlock, the consensus MaxTxnBytesPerBlock would
// be used instead.
// The tracer argument is a logic.EvalTracer which will be attached to the evaluator and have its hooked invoked during
// the eval process for each block. A nil tracer will skip tracer invocation entirely.
// the eval process for each block. A nil tracer will default to the tracer attached to the ledger.
func (l *Ledger) StartEvaluator(hdr bookkeeping.BlockHeader, paysetHint, maxTxnBytesPerBlock int, tracer logic.EvalTracer) (*eval.BlockEvaluator, error) {
tracerForEval := tracer
if tracerForEval == nil {
tracerForEval = l.tracer
}
return eval.StartEvaluator(l, hdr,
eval.EvaluatorOptions{
PaysetHint: paysetHint,
Generate: true,
Validate: true,
MaxTxnBytesPerBlock: maxTxnBytesPerBlock,
Tracer: tracer,
Tracer: tracerForEval,
})
}

Expand Down
39 changes: 39 additions & 0 deletions test/e2e-go/features/devmode/devmode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,42 @@ func TestDevMode(t *testing.T) {
prevTime = currTime
}
}

// Starts up a devmode network, sends a txn, and fetches the txn group delta for that txn
func TestTxnGroupDeltasDevMode(t *testing.T) {
partitiontest.PartitionTest(t)

if testing.Short() {
t.Skip()
}

// Start devmode network, and send a transaction.
var fixture fixtures.RestClientFixture
fixture.SetupNoStart(t, filepath.Join("nettemplates", "DevModeTxnTracerNetwork.json"))
fixture.Start()
defer fixture.Shutdown()
sender, err := fixture.GetRichestAccount()
require.NoError(t, err)
key := crypto.GenerateSignatureSecrets(crypto.Seed{})
receiver := basics.Address(key.SignatureVerifier)
txn := fixture.SendMoneyAndWait(0, 100000, 1000, sender.Address, receiver.String(), "")
require.NotNil(t, txn.ConfirmedRound)
_, err = fixture.AlgodClient.Block(*txn.ConfirmedRound)
require.NoError(t, err)

// Test GetLedgerStateDeltaForTransactionGroup and verify the response contains a delta
txngroupResponse, err := fixture.AlgodClient.GetLedgerStateDeltaForTransactionGroup(txn.Txn.ID().String())
require.NoError(t, err)
require.True(t, len(txngroupResponse) > 0)

// Test GetTransactionGroupLedgerStateDeltasForRound and verify the response contains the delta for our txn
roundResponse, err := fixture.AlgodClient.GetTransactionGroupLedgerStateDeltasForRound(1)
require.NoError(t, err)
require.Equal(t, len(roundResponse.Deltas), 1)
groupDelta := roundResponse.Deltas[0]
require.Equal(t, 1, len(groupDelta.Ids))
require.Equal(t, groupDelta.Ids[0], txn.Txn.ID().String())

// Assert that the TxIDs field across both endpoint responses is the same
require.Equal(t, txngroupResponse["Txids"], groupDelta.Delta["Txids"])
}
88 changes: 88 additions & 0 deletions test/e2e-go/restAPI/restClient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,94 @@ end:
assertBoxCount(numberOfBoxesRemaining)
}

func TestSimulateTxnTracerDevMode(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

a := require.New(fixtures.SynchronizedTest(t))
var localFixture fixtures.RestClientFixture
localFixture.Setup(t, filepath.Join("nettemplates", "DevModeTxnTracerNetwork.json"))
defer localFixture.Shutdown()

testClient := localFixture.LibGoalClient

_, err := testClient.WaitForRound(1)
a.NoError(err)

wh, err := testClient.GetUnencryptedWalletHandle()
a.NoError(err)
addresses, err := testClient.ListAddresses(wh)
a.NoError(err)
senderBalance, senderAddress := getMaxBalAddr(t, testClient, addresses)
if senderAddress == "" {
t.Error("no addr with funds")
}
a.NoError(err)

toAddress := getDestAddr(t, testClient, nil, senderAddress, wh)
closeToAddress := getDestAddr(t, testClient, nil, senderAddress, wh)

// Ensure these accounts don't exist
receiverBalance, err := testClient.GetBalance(toAddress)
a.NoError(err)
a.Zero(receiverBalance)
closeToBalance, err := testClient.GetBalance(closeToAddress)
a.NoError(err)
a.Zero(closeToBalance)

txn, err := testClient.ConstructPayment(senderAddress, toAddress, 0, senderBalance/2, nil, closeToAddress, [32]byte{}, 0, 0)
a.NoError(err)
stxn, err := testClient.SignTransactionWithWallet(wh, nil, txn)
a.NoError(err)

currentRoundBeforeSimulate, err := testClient.CurrentRound()
a.NoError(err)

simulateRequest := v2.PreEncodedSimulateRequest{
TxnGroups: []v2.PreEncodedSimulateRequestTransactionGroup{
{
Txns: []transactions.SignedTxn{stxn},
},
},
}
result, err := testClient.SimulateTransactions(simulateRequest)
a.NoError(err)

currentAfterAfterSimulate, err := testClient.CurrentRound()
a.NoError(err)

// We can assert equality here since DevMode rounds are controlled by txn sends.
a.Equal(result.LastRound, currentRoundBeforeSimulate)
a.Equal(result.LastRound, currentAfterAfterSimulate)

closingAmount := senderBalance - txn.Fee.Raw - txn.Amount.Raw
expectedResult := v2.PreEncodedSimulateResponse{
Version: 2,
LastRound: result.LastRound, // checked above
TxnGroups: []v2.PreEncodedSimulateTxnGroupResult{
{
Txns: []v2.PreEncodedSimulateTxnResult{
{
Txn: v2.PreEncodedTxInfo{
Txn: stxn,
ClosingAmount: &closingAmount,
},
},
},
},
},
}
a.Equal(expectedResult, result)

// Ensure the transaction did not actually get applied to the ledger
receiverBalance, err = testClient.GetBalance(toAddress)
a.NoError(err)
a.Zero(receiverBalance)
closeToBalance, err = testClient.GetBalance(closeToAddress)
a.NoError(err)
a.Zero(closeToBalance)
}

func TestSimulateTransaction(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()
Expand Down
36 changes: 36 additions & 0 deletions test/testdata/nettemplates/DevModeTxnTracerNetwork.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"Genesis": {
"NetworkName": "devmodefollowernet",
"LastPartKeyRound": 3000,
"Wallets": [
{
"Name": "Wallet1",
"Stake": 40,
"Online": true
},
{
"Name": "Wallet2",
"Stake": 40,
"Online": true
},
{
"Name": "Wallet3",
"Stake": 20,
"Online": true
}
],
"DevMode": true
},
"Nodes": [
{
"Name": "Node",
"IsRelay": false,
"ConfigJSONOverride": "{\"EnableTxnEvalTracer\":true}",
"Wallets": [
{ "Name": "Wallet1", "ParticipationOnly": false },
{ "Name": "Wallet2", "ParticipationOnly": false },
{ "Name": "Wallet3", "ParticipationOnly": false }
]
}
]
}

0 comments on commit ec9e662

Please sign in to comment.