From b8d3c799b361c84f1b39832566d3965e07b6f83a Mon Sep 17 00:00:00 2001 From: Scott Fairclough <70711990+hexoscott@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:34:54 +0000 Subject: [PATCH] preload sender and check for errors (#1480) --- zk/stages/stage_sequence_execute.go | 2 +- zk/stages/stage_sequence_execute_blocks.go | 8 ++++++ .../stage_sequence_execute_transactions.go | 28 ++++++++++++++----- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/zk/stages/stage_sequence_execute.go b/zk/stages/stage_sequence_execute.go index 43883d8f82a..9c82e0f4b9d 100644 --- a/zk/stages/stage_sequence_execute.go +++ b/zk/stages/stage_sequence_execute.go @@ -336,7 +336,7 @@ func sequencingBatchStep( log.Info(fmt.Sprintf("[%s] Info tree updates", logPrefix), "count", len(newLogs), "latestIndex", latestIndex) default: if batchState.isLimboRecovery() { - batchState.blockState.transactionsForInclusion, err = getLimboTransaction(ctx, cfg, batchState.limboRecoveryData.limboTxHash) + batchState.blockState.transactionsForInclusion, err = getLimboTransaction(ctx, cfg, batchState.limboRecoveryData.limboTxHash, executionAt) if err != nil { return err } diff --git a/zk/stages/stage_sequence_execute_blocks.go b/zk/stages/stage_sequence_execute_blocks.go index 282adc7c41b..d801fecf7fe 100644 --- a/zk/stages/stage_sequence_execute_blocks.go +++ b/zk/stages/stage_sequence_execute_blocks.go @@ -300,6 +300,14 @@ func addSenders( cryptoContext := secp256k1.ContextForThread(1) senders := make([]common.Address, 0, len(finalTransactions)) for _, transaction := range finalTransactions { + from, ok := transaction.GetSender() + if ok { + senders = append(senders, from) + continue + } + + // shouldn't be hit as we preload this value before processing the transaction + // to look for errors in handling it. from, err := signer.SenderWithContext(cryptoContext, transaction) if err != nil { return err diff --git a/zk/stages/stage_sequence_execute_transactions.go b/zk/stages/stage_sequence_execute_transactions.go index 713dc462d39..97f395be3e1 100644 --- a/zk/stages/stage_sequence_execute_transactions.go +++ b/zk/stages/stage_sequence_execute_transactions.go @@ -17,6 +17,7 @@ import ( "github.com/ledgerwatch/erigon/core/vm/evmtypes" "github.com/ledgerwatch/erigon/zk/utils" "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/secp256k1" ) func getNextPoolTransactions(ctx context.Context, cfg SequenceBlockCfg, executionAt, forkId uint64, alreadyYielded mapset.Set[[32]byte]) ([]types.Transaction, []common.Hash, bool, error) { @@ -38,7 +39,7 @@ func getNextPoolTransactions(ctx context.Context, cfg SequenceBlockCfg, executio if allConditionsOk, _, err = cfg.txPool.YieldBest(cfg.yieldSize, &slots, poolTx, executionAt, gasLimit, 0, alreadyYielded); err != nil { return err } - yieldedTxs, yieldedIds, toRemove, err := extractTransactionsFromSlot(&slots) + yieldedTxs, yieldedIds, toRemove, err := extractTransactionsFromSlot(&slots, executionAt, cfg) if err != nil { return err } @@ -55,7 +56,7 @@ func getNextPoolTransactions(ctx context.Context, cfg SequenceBlockCfg, executio return transactions, ids, allConditionsOk, err } -func getLimboTransaction(ctx context.Context, cfg SequenceBlockCfg, txHash *common.Hash) ([]types.Transaction, error) { +func getLimboTransaction(ctx context.Context, cfg SequenceBlockCfg, txHash *common.Hash, executionAt uint64) ([]types.Transaction, error) { cfg.txPool.LockFlusher() defer cfg.txPool.UnlockFlusher() @@ -70,7 +71,7 @@ func getLimboTransaction(ctx context.Context, cfg SequenceBlockCfg, txHash *comm if slots != nil { // ignore the toRemove value here, we know the RLP will be sound as we had to read it from the pool // in the first place to get it into limbo - transactions, _, _, err = extractTransactionsFromSlot(slots) + transactions, _, _, err = extractTransactionsFromSlot(slots, executionAt, cfg) if err != nil { return err } @@ -84,10 +85,12 @@ func getLimboTransaction(ctx context.Context, cfg SequenceBlockCfg, txHash *comm return transactions, nil } -func extractTransactionsFromSlot(slot *types2.TxsRlp) ([]types.Transaction, []common.Hash, []common.Hash, error) { +func extractTransactionsFromSlot(slot *types2.TxsRlp, currentHeight uint64, cfg SequenceBlockCfg) ([]types.Transaction, []common.Hash, []common.Hash, error) { ids := make([]common.Hash, 0, len(slot.TxIds)) transactions := make([]types.Transaction, 0, len(slot.Txs)) toRemove := make([]common.Hash, 0) + signer := types.MakeSigner(cfg.chainConfig, currentHeight, 0) + cryptoContext := secp256k1.ContextForThread(1) for idx, txBytes := range slot.Txs { transaction, err := types.DecodeTransaction(txBytes) if err == io.EOF { @@ -96,12 +99,23 @@ func extractTransactionsFromSlot(slot *types2.TxsRlp) ([]types.Transaction, []co if err != nil { // we have a transaction that cannot be decoded or a similar issue. We don't want to handle // this tx so just WARN about it and remove it from the pool and continue - log.Warn("Failed to decode transaction from pool, skipping and removing from pool", "error", err) + log.Warn("[extractTransaction] Failed to decode transaction from pool, skipping and removing from pool", + "error", err, + "id", slot.TxIds[idx]) toRemove = append(toRemove, slot.TxIds[idx]) continue } - var sender common.Address - copy(sender[:], slot.Senders.At(idx)) + + // now attempt to recover the sender + sender, err := signer.SenderWithContext(cryptoContext, transaction) + if err != nil { + log.Warn("[extractTransaction] Failed to recover sender from transaction, skipping and removing from pool", + "error", err, + "hash", transaction.Hash()) + toRemove = append(toRemove, slot.TxIds[idx]) + continue + } + transaction.SetSender(sender) transactions = append(transactions, transaction) ids = append(ids, slot.TxIds[idx])