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

Filter transaction #2807

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
6 changes: 3 additions & 3 deletions arbos/block_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ type SequencingHooks struct {
TxErrors []error
DiscardInvalidTxsEarly bool
PreTxFilter func(*params.ChainConfig, *types.Header, *state.StateDB, *arbosState.ArbosState, *types.Transaction, *arbitrum_types.ConditionalOptions, common.Address, *L1Info) error
PostTxFilter func(*types.Header, *arbosState.ArbosState, *types.Transaction, common.Address, uint64, *core.ExecutionResult) error
PostTxFilter func(*types.Header, *state.StateDB, *arbosState.ArbosState, *types.Transaction, common.Address, uint64, *core.ExecutionResult) error
ConditionalOptionsForTx []*arbitrum_types.ConditionalOptions
}

Expand All @@ -129,7 +129,7 @@ func NoopSequencingHooks() *SequencingHooks {
func(*params.ChainConfig, *types.Header, *state.StateDB, *arbosState.ArbosState, *types.Transaction, *arbitrum_types.ConditionalOptions, common.Address, *L1Info) error {
return nil
},
func(*types.Header, *arbosState.ArbosState, *types.Transaction, common.Address, uint64, *core.ExecutionResult) error {
func(*types.Header, *state.StateDB, *arbosState.ArbosState, *types.Transaction, common.Address, uint64, *core.ExecutionResult) error {
return nil
},
nil,
Expand Down Expand Up @@ -322,7 +322,7 @@ func ProduceBlockAdvanced(
vm.Config{},
runMode,
func(result *core.ExecutionResult) error {
return hooks.PostTxFilter(header, state, tx, sender, dataGas, result)
return hooks.PostTxFilter(header, statedb, state, tx, sender, dataGas, result)
},
)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion execution/gethexec/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ func (s *Sequencer) preTxFilter(_ *params.ChainConfig, header *types.Header, sta
return nil
}

func (s *Sequencer) postTxFilter(header *types.Header, _ *arbosState.ArbosState, tx *types.Transaction, sender common.Address, dataGas uint64, result *core.ExecutionResult) error {
func (s *Sequencer) postTxFilter(header *types.Header, _ *state.StateDB, _ *arbosState.ArbosState, tx *types.Transaction, sender common.Address, dataGas uint64, result *core.ExecutionResult) error {
ganeshvanahalli marked this conversation as resolved.
Show resolved Hide resolved
if result.Err != nil && result.UsedGas > dataGas && result.UsedGas-dataGas <= s.config().MaxRevertGasReject {
return arbitrum.NewRevertReason(result)
}
Expand Down
2 changes: 1 addition & 1 deletion go-ethereum
112 changes: 112 additions & 0 deletions system_tests/seq_filter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package arbtest

import (
"context"
"errors"
"math/big"
"testing"
"time"

"github.com/ethereum/go-ethereum/arbitrum_types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"

"github.com/offchainlabs/nitro/arbos"
"github.com/offchainlabs/nitro/arbos/arbosState"
"github.com/offchainlabs/nitro/arbos/arbostypes"
"github.com/offchainlabs/nitro/arbos/l1pricing"
"github.com/offchainlabs/nitro/util/arbmath"
)

func TestSequencerTxFilter(t *testing.T) {
t.Parallel()

builder, header, txes, hooks, cleanup := setupSequencerFilterTest(t, false)
defer cleanup()

block, err := builder.L2.ExecNode.ExecEngine.SequenceTransactions(header, txes, hooks)
ganeshvanahalli marked this conversation as resolved.
Show resolved Hide resolved
if block != nil {
t.Fatal("block shouldn't be generated when all txes have failed")
}
Require(t, err) // There shouldn't be any error in block generation
if len(hooks.TxErrors) != 2 {
t.Fatalf("expected 2 tx errors, found: %d", len(hooks.TxErrors))
}
for _, err := range hooks.TxErrors {
if err.Error() != state.ErrArbTxFilter.Error() {
t.Fatalf("expected ErrArbTxFilter, found: %s", err.Error())
}
}
}

func TestSequencerBlockFilter(t *testing.T) {
t.Parallel()

builder, header, txes, hooks, cleanup := setupSequencerFilterTest(t, true)
defer cleanup()

block, err := builder.L2.ExecNode.ExecEngine.SequenceTransactions(header, txes, hooks)
ganeshvanahalli marked this conversation as resolved.
Show resolved Hide resolved
if block != nil {
t.Fatal("block shouldn't be generated when all txes have failed")
}
if err == nil {
t.Fatal("expected ErrArbTxFilter but found nil")
}
if err.Error() != state.ErrArbTxFilter.Error() {
t.Fatalf("expected ErrArbTxFilter, found: %s", err.Error())
}
}

func setupSequencerFilterTest(t *testing.T, withBlock bool) (*NodeBuilder, *arbostypes.L1IncomingMessageHeader, types.Transactions, *arbos.SequencingHooks, func()) {
ctx, cancel := context.WithCancel(context.Background())

builder := NewNodeBuilder(ctx).DefaultConfig(t, false)
builder.isSequencer = true
builderCleanup := builder.Build(t)

builder.L2Info.GenerateAccount("User")
var latestL2 uint64
var err error
for i := 0; latestL2 < 3; i++ {
_, _ = builder.L2.TransferBalance(t, "Owner", "User", big.NewInt(1e18), builder.L2Info)
latestL2, err = builder.L2.Client.BlockNumber(ctx)
Require(t, err)
}

header := &arbostypes.L1IncomingMessageHeader{
Kind: arbostypes.L1MessageType_L2Message,
Poster: l1pricing.BatchPosterAddress,
BlockNumber: 1,
Timestamp: arbmath.SaturatingUCast[uint64](time.Now().Unix()),
RequestId: nil,
L1BaseFee: nil,
}

var txes types.Transactions
txes = append(txes, builder.L2Info.PrepareTx("Owner", "User", builder.L2Info.TransferGas, big.NewInt(1e12), nil))
txes = append(txes, builder.L2Info.PrepareTx("User", "Owner", builder.L2Info.TransferGas, big.NewInt(1e12), nil))

preTxFilter := func(_ *params.ChainConfig, _ *types.Header, statedb *state.StateDB, _ *arbosState.ArbosState, tx *types.Transaction, _ *arbitrum_types.ConditionalOptions, _ common.Address, _ *arbos.L1Info) error {
if _, ok := tx.GetInner().(*types.DynamicFeeTx); ok {
statedb.FilterTx(withBlock)
}
return nil
}
postTxFilter := func(_ *types.Header, statedb *state.StateDB, _ *arbosState.ArbosState, _ *types.Transaction, _ common.Address, _ uint64, _ *core.ExecutionResult) error {
if statedb.IsTxInvalid() {
return errors.New("internal error")
}
return nil
}
hooks := &arbos.SequencingHooks{TxErrors: []error{}, DiscardInvalidTxsEarly: false, PreTxFilter: preTxFilter, PostTxFilter: postTxFilter, ConditionalOptionsForTx: nil}

cleanup := func() {
builderCleanup()
cancel()
}

return builder, header, txes, hooks, cleanup
}
Loading