Skip to content

Commit

Permalink
fix trace for tx index greater than 0 (0xPolygonHermez#3153)
Browse files Browse the repository at this point in the history
  • Loading branch information
tclemos authored Jan 26, 2024
1 parent f69f0f9 commit 65a507e
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 27 deletions.
9 changes: 6 additions & 3 deletions state/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has
// since the executor only stores the state roots by block, we need to
// execute all the txs in the block until the tx we want to trace
var txsToEncode []types.Transaction
var effectivePercentage []uint8
for i := 0; i <= int(receipt.TransactionIndex); i++ {
txsToEncode = append(txsToEncode, *l2Block.Transactions()[i])
effectivePercentage = append(effectivePercentage, MaxEffectivePercentage)
log.Debugf("trace will reprocess tx: %v", l2Block.Transactions()[i].Hash().String())
}

// gets batch that including the l2 block
Expand Down Expand Up @@ -106,7 +109,7 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has
}
}
// generate batch l2 data for the transaction
batchL2Data, err := EncodeTransactions(txsToEncode, []uint8{MaxEffectivePercentage}, forkId)
batchL2Data, err := EncodeTransactions(txsToEncode, effectivePercentage, forkId)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -187,7 +190,7 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has
deltaTimestamp := uint32(uint64(time.Now().Unix()) - l2Block.Time())
transactions := s.BuildChangeL2Block(deltaTimestamp, uint32(0))

batchL2Data, err := EncodeTransactions(txsToEncode, []uint8{MaxEffectivePercentage}, forkId)
batchL2Data, err := EncodeTransactions(txsToEncode, effectivePercentage, forkId)
if err != nil {
log.Errorf("error encoding transaction ", err)
return nil, err
Expand Down Expand Up @@ -243,7 +246,7 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has
if err != nil {
return nil, err
}
response = convertedResponse.BlockResponses[0].TransactionResponses[0]
response = convertedResponse.BlockResponses[0].TransactionResponses[len(convertedResponse.BlockResponses[0].TransactionResponses)-1]
}

// Sanity check
Expand Down
46 changes: 35 additions & 11 deletions test/e2e/debug_calltracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/0xPolygonHermez/zkevm-node/test/operations"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
Expand Down Expand Up @@ -179,19 +180,42 @@ func TestDebugTraceTransactionCallTracer(t *testing.T) {
require.NoError(t, err)
}

signedTx, err := tc.createSignedTx(t, ctx, auth, ethereumClient, customData)
require.NoError(t, err)

err = ethereumClient.SendTransaction(ctx, signedTx)
require.NoError(t, err)

log.Debugf("tx sent: %v", signedTx.Hash().String())
var receipt *ethTypes.Receipt
var signedTx *ethTypes.Transaction
forceTxIndexDifferentFromZero := tcIdx%2 == 0
for {
log.Debugf("forceTxIndexDifferentFromZero: %v", forceTxIndexDifferentFromZero)
var err error
if forceTxIndexDifferentFromZero {
// send eth transfers txs to make the trace tx to not be the index 0 in the block
sendEthTransfersWithoutWaiting(t, ctx, ethereumClient, auth, common.HexToAddress(operations.DefaultSequencerAddress), big.NewInt(1), 3)
}
signedTx, err = tc.createSignedTx(t, ctx, auth, ethereumClient, customData)
require.NoError(t, err)

err = operations.WaitTxToBeMined(ctx, ethereumClient, signedTx, operations.DefaultTimeoutTxToBeMined)
if err != nil && !strings.HasPrefix(err.Error(), "transaction has failed, reason:") {
err = ethereumClient.SendTransaction(ctx, signedTx)
require.NoError(t, err)
}

log.Debugf("tx sent: %v", signedTx.Hash().String())

err = operations.WaitTxToBeMined(ctx, ethereumClient, signedTx, operations.DefaultTimeoutTxToBeMined)
if err != nil && !strings.HasPrefix(err.Error(), "transaction has failed, reason:") {
require.NoError(t, err)
}

if forceTxIndexDifferentFromZero {
receipt, err = ethereumClient.TransactionReceipt(ctx, signedTx.Hash())
require.NoError(t, err)
if receipt.TransactionIndex != 0 {
log.Debugf("tx receipt has tx index %v, accepted", receipt.TransactionIndex)
break
} else {
log.Debugf("tx receipt has tx index 0, retrying")
}
} else {
break
}
}
debugOptions := map[string]interface{}{
"tracer": "callTracer",
"tracerConfig": map[string]interface{}{
Expand Down Expand Up @@ -415,7 +439,7 @@ func TestDebugTraceBlockCallTracer(t *testing.T) {
require.NoError(t, err)
require.Nil(t, response.Error)
require.NotNil(t, response.Result)
log.Debugf("%s response:%s", debugID, string(response.Result))
// log.Debugf("%s response:%s", debugID, string(response.Result))

txHash := signedTx.Hash().String()
resultForTx := findTxInResponse(t, response.Result, txHash, debugID)
Expand Down
34 changes: 34 additions & 0 deletions test/e2e/debug_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Revert2"
"github.com/0xPolygonHermez/zkevm-node/test/operations"
"github.com/0xPolygonHermez/zkevm-node/test/testutils"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
ethTypes "github.com/ethereum/go-ethereum/core/types"
Expand Down Expand Up @@ -849,3 +850,36 @@ func createDeployCreate0SignedTx(t *testing.T, ctx context.Context, auth *bind.T

return auth.Signer(auth.From, tx)
}

func sendEthTransfersWithoutWaiting(t *testing.T, ctx context.Context, client *ethclient.Client, auth *bind.TransactOpts, to common.Address, value *big.Int, howMany int) {
nonce, err := client.PendingNonceAt(ctx, auth.From)
require.NoError(t, err)

gasPrice, err := client.SuggestGasPrice(ctx)
require.NoError(t, err)

gas, err := client.EstimateGas(ctx, ethereum.CallMsg{
From: auth.From,
To: &auth.From,
GasPrice: gasPrice,
Value: value,
})
require.NoError(t, err)

for i := 0; i < howMany; i++ {
tx := ethTypes.NewTx(&ethTypes.LegacyTx{
To: &to,
Nonce: nonce + uint64(i),
GasPrice: gasPrice,
Value: value,
Gas: gas,
})

signedTx, err := auth.Signer(auth.From, tx)
require.NoError(t, err)

err = client.SendTransaction(ctx, signedTx)
require.NoError(t, err)
log.Debugf("sending eth transfer: %v", signedTx.Hash().String())
}
}
50 changes: 37 additions & 13 deletions test/e2e/debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,24 +396,48 @@ func TestDebugTraceTransaction(t *testing.T) {
require.NoError(t, err)
}

signedTx, err := tc.createSignedTx(t, ctx, auth, ethereumClient, customData)
require.NoError(t, err)

balance, err := ethereumClient.BalanceAt(ctx, auth.From, nil)
require.NoError(t, err)
var receipt *ethTypes.Receipt
var signedTx *ethTypes.Transaction
forceTxIndexDifferentFromZero := tcIdx%2 == 0
for {
log.Debugf("forceTxIndexDifferentFromZero: %v", forceTxIndexDifferentFromZero)
var err error
if forceTxIndexDifferentFromZero {
// send eth transfers txs to make the trace tx to not be the index 0 in the block
sendEthTransfersWithoutWaiting(t, ctx, ethereumClient, auth, common.HexToAddress(operations.DefaultSequencerAddress), big.NewInt(1), 3)
}

log.Debugf("%s balance of %v: %v", debugID, auth.From, balance.String())
signedTx, err = tc.createSignedTx(t, ctx, auth, ethereumClient, customData)
require.NoError(t, err)

err = ethereumClient.SendTransaction(ctx, signedTx)
require.NoError(t, err)
balance, err := ethereumClient.BalanceAt(ctx, auth.From, nil)
require.NoError(t, err)

log.Debugf("%s tx sent: %v", debugID, signedTx.Hash().String())
log.Debugf("%s balance of %v: %v", debugID, auth.From, balance.String())

err = operations.WaitTxToBeMined(ctx, ethereumClient, signedTx, operations.DefaultTimeoutTxToBeMined)
if err != nil && !strings.HasPrefix(err.Error(), "transaction has failed, reason:") {
err = ethereumClient.SendTransaction(ctx, signedTx)
require.NoError(t, err)
}

log.Debugf("%s tx sent: %v", debugID, signedTx.Hash().String())

err = operations.WaitTxToBeMined(ctx, ethereumClient, signedTx, operations.DefaultTimeoutTxToBeMined)
if err != nil && !strings.HasPrefix(err.Error(), "transaction has failed, reason:") {
require.NoError(t, err)
}

if forceTxIndexDifferentFromZero {
receipt, err = ethereumClient.TransactionReceipt(ctx, signedTx.Hash())
require.NoError(t, err)
if receipt.TransactionIndex != 0 {
log.Debugf("tx receipt has tx index %v, accepted", receipt.TransactionIndex)
break
} else {
log.Debugf("tx receipt has tx index 0, retrying")
}
} else {
break
}
}
debugOptions := map[string]interface{}{
"disableStorage": false,
"disableStack": false,
Expand All @@ -425,7 +449,7 @@ func TestDebugTraceTransaction(t *testing.T) {
require.NoError(t, err)
require.Nil(t, response.Error)
require.NotNil(t, response.Result)
log.Debugf("%s response:%s", debugID, string(response.Result))
// log.Debugf("%s response:%s", debugID, string(response.Result))

resultForTx := convertJson(t, response.Result, debugID)
results[network.Name] = resultForTx
Expand Down

0 comments on commit 65a507e

Please sign in to comment.