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

fix tx index provided in the tx log responses #3303

Merged
merged 1 commit into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
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
6 changes: 4 additions & 2 deletions state/pgstatestorage/pgstatestorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,11 @@ func (p *PostgresStorage) GetStateRootByBatchNumber(ctx context.Context, batchNu
// GetLogsByBlockNumber get all the logs from a specific block ordered by log index
func (p *PostgresStorage) GetLogsByBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) ([]*types.Log, error) {
const query = `
SELECT t.l2_block_num, b.block_hash, l.tx_hash, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3
SELECT t.l2_block_num, b.block_hash, l.tx_hash, r.tx_index, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3
FROM state.log l
INNER JOIN state.transaction t ON t.hash = l.tx_hash
INNER JOIN state.l2block b ON b.block_num = t.l2_block_num
INNER JOIN state.receipt r ON r.tx_hash = t.hash
WHERE b.block_num = $1
ORDER BY l.log_index ASC`

Expand All @@ -142,11 +143,12 @@ func (p *PostgresStorage) GetLogsByBlockNumber(ctx context.Context, blockNumber
func (p *PostgresStorage) GetLogs(ctx context.Context, fromBlock uint64, toBlock uint64, addresses []common.Address, topics [][]common.Hash, blockHash *common.Hash, since *time.Time, dbTx pgx.Tx) ([]*types.Log, error) {
// query parts
const queryCount = `SELECT count(*) `
const querySelect = `SELECT t.l2_block_num, b.block_hash, l.tx_hash, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3 `
const querySelect = `SELECT t.l2_block_num, b.block_hash, l.tx_hash, r.tx_index, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3 `

const queryBody = `FROM state.log l
INNER JOIN state.transaction t ON t.hash = l.tx_hash
INNER JOIN state.l2block b ON b.block_num = t.l2_block_num
INNER JOIN state.receipt r ON r.tx_hash = t.hash
WHERE (l.address = any($1) OR $1 IS NULL)
AND (l.topic0 = any($2) OR $2 IS NULL)
AND (l.topic1 = any($3) OR $3 IS NULL)
Expand Down
8 changes: 5 additions & 3 deletions state/pgstatestorage/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,11 @@ func (p *PostgresStorage) getTransactionLogs(ctx context.Context, transactionHas
q := p.getExecQuerier(dbTx)

const getTransactionLogsSQL = `
SELECT t.l2_block_num, b.block_hash, l.tx_hash, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3
SELECT t.l2_block_num, b.block_hash, l.tx_hash, r.tx_index, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3
FROM state.log l
INNER JOIN state.transaction t ON t.hash = l.tx_hash
INNER JOIN state.l2block b ON b.block_num = t.l2_block_num
INNER JOIN state.receipt r ON r.tx_hash = t.hash
WHERE t.hash = $1
ORDER BY l.log_index ASC`
rows, err := q.Query(ctx, getTransactionLogsSQL, transactionHash.String())
Expand All @@ -391,10 +392,11 @@ func scanLogs(rows pgx.Rows) ([]*types.Log, error) {
}

var log types.Log
var txIndex uint
var blockHash, txHash, logAddress, logData string
var topic0, topic1, topic2, topic3 *string

err := rows.Scan(&log.BlockNumber, &blockHash, &txHash, &log.Index,
err := rows.Scan(&log.BlockNumber, &blockHash, &txHash, &txIndex, &log.Index,
&logAddress, &logData, &topic0, &topic1, &topic2, &topic3)
if err != nil {
return nil, err
Expand All @@ -403,7 +405,7 @@ func scanLogs(rows pgx.Rows) ([]*types.Log, error) {
log.BlockHash = common.HexToHash(blockHash)
log.TxHash = common.HexToHash(txHash)
log.Address = common.HexToAddress(logAddress)
log.TxIndex = uint(0)
log.TxIndex = txIndex
log.Data, err = hex.DecodeHex(logData)
if err != nil {
return nil, err
Expand Down
147 changes: 146 additions & 1 deletion test/e2e/sc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"context"
"math/big"
"testing"
"time"

"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/0xPolygonHermez/zkevm-node/state"
"github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Counter"
"github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/EmitLog2"
"github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/FailureTest"
Expand Down Expand Up @@ -265,8 +267,9 @@ func TestEmitLog2(t *testing.T) {
log0 := getLogByIndex(0, logs)
assert.Equal(t, 0, len(log0.Topics))

_, err = sc.ParseLog(getLogByIndex(1, logs))
logWithoutParameters, err := sc.ParseLog(getLogByIndex(1, logs))
require.NoError(t, err)
assert.Equal(t, 1, len(logWithoutParameters.Raw.Topics))

logA, err := sc.ParseLogA(getLogByIndex(2, logs))
require.NoError(t, err)
Expand Down Expand Up @@ -329,6 +332,148 @@ func TestEmitLog2(t *testing.T) {
}
}

func TestLogTxIndex(t *testing.T) {
if testing.Short() {
t.Skip()
}

var err error
err = operations.Teardown()
require.NoError(t, err)

defer func() { require.NoError(t, operations.Teardown()) }()

ctx := context.Background()
opsCfg := operations.GetDefaultOperationsConfig()
opsMan, err := operations.NewManager(ctx, opsCfg)
require.NoError(t, err)
err = opsMan.Setup()
require.NoError(t, err)

assertTxHashAndIndex := func(t *testing.T, log types.Log, tx *types.Transaction, receipt *types.Receipt) {
assert.Equal(t, tx.Hash().String(), log.TxHash.String())
assert.Equal(t, receipt.TxHash.String(), log.TxHash.String())
assert.Equal(t, receipt.TransactionIndex, log.TxIndex)
}

for _, network := range networks {
log.Debugf(network.Name)
client := operations.MustGetClient(network.URL)
wsClient := operations.MustGetClient(network.WebSocketURL)
auth := operations.MustGetAuth(network.PrivateKey, network.ChainID)

// deploy sc
scAddr, scTx, sc, err := EmitLog2.DeployEmitLog2(auth, client)
require.NoError(t, err)

logTx(scTx)
err = operations.WaitTxToBeMined(ctx, client, scTx, operations.DefaultTimeoutTxToBeMined)
require.NoError(t, err)

if network.Name == "Local L2" {
// stops sequencer
err = operations.StopComponent("seq")
require.NoError(t, err)
}

logsFromSubscription := make(chan types.Log)
query := ethereum.FilterQuery{Addresses: []common.Address{scAddr}}
sub, err := wsClient.SubscribeFilterLogs(context.Background(), query, logsFromSubscription)
require.NoError(t, err)

// send transfer
gasPrice, err := client.SuggestGasPrice(ctx)
require.NoError(t, err)
nonce, err := client.PendingNonceAt(ctx, auth.From)
require.NoError(t, err)
tx := types.NewTx(&types.LegacyTx{
To: state.Ptr(common.HexToAddress("0x1")),
Gas: 30000,
GasPrice: gasPrice,
Value: big.NewInt(1000),
Nonce: nonce,
})
signedTx, err := auth.Signer(auth.From, tx)
require.NoError(t, err)
err = client.SendTransaction(ctx, signedTx)
require.NoError(t, err)

// send log tx
auth.Nonce = big.NewInt(0).SetUint64(nonce + 1)
scCallTx, err := sc.EmitLogs(auth)
require.NoError(t, err)
logTx(scCallTx)

time.Sleep(time.Second)

if network.Name == "Local L2" {
// starts sequencer and wait log tx to get mined
err = operations.StartComponent("seq", func() (done bool, err error) {
err = operations.WaitTxToBeMined(ctx, client, scCallTx, operations.DefaultTimeoutTxToBeMined)
return true, err
})
require.NoError(t, err)
} else {
err = operations.WaitTxToBeMined(ctx, client, scCallTx, operations.DefaultTimeoutTxToBeMined)
require.NoError(t, err)
}

scCallTxReceipt, err := client.TransactionReceipt(ctx, scCallTx.Hash())
require.NoError(t, err)

if network.Name == "Local L2" {
assert.Equal(t, uint(1), scCallTxReceipt.TransactionIndex)
}

// validate logs from filterLogs
filterBlock := scCallTxReceipt.BlockNumber
logs, err := client.FilterLogs(ctx, ethereum.FilterQuery{
FromBlock: filterBlock, ToBlock: filterBlock,
Addresses: []common.Address{scAddr},
})
require.NoError(t, err)

assert.Equal(t, 4, len(logs))
for i := range logs {
l := getLogByIndex(i, logs)
assertTxHashAndIndex(t, l, scCallTx, scCallTxReceipt)
}

// validate logs from receipt
logs = make([]types.Log, len(scCallTxReceipt.Logs))
for i, log := range scCallTxReceipt.Logs {
logs[i] = *log
}

assert.Equal(t, 4, len(logs))
for i := range logs {
l := getLogByIndex(i, logs)
assertTxHashAndIndex(t, l, scCallTx, scCallTxReceipt)
}

// validate logs by subscription
logs = []types.Log{}
out:
for {
select {
case err := <-sub.Err():
require.NoError(t, err)
case vLog, closed := <-logsFromSubscription:
logs = append(logs, vLog)
if len(logs) == 4 && closed {
break out
}
}
}

assert.Equal(t, 4, len(logs))
for i := range logs {
l := getLogByIndex(i, logs)
assertTxHashAndIndex(t, l, scCallTx, scCallTxReceipt)
}
}
}

func getLogByIndex(index int, logs []types.Log) types.Log {
for _, log := range logs {
if int(log.Index) == index {
Expand Down
Loading