Skip to content
Closed
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
2 changes: 1 addition & 1 deletion op-e2e/actions/altda/altda_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func (a *L2AltDA) NewVerifier(t helpers.Testing) *helpers.L2Verifier {

daMgr := altda.NewAltDAWithStorage(a.log, a.altDACfg, a.storage, &altda.NoopMetrics{})

verifier := helpers.NewL2Verifier(t, a.log, l1F, a.miner.BlobStore(), daMgr, engCl, a.sd.RollupCfg, &sync.Config{}, safedb.Disabled)
verifier := helpers.NewL2Verifier(t, a.log, l1F, a.miner.BlobStore(), daMgr, engCl, a.sd.RollupCfg, &sync.Config{}, safedb.Disabled, nil)

return verifier
}
Expand Down
2 changes: 1 addition & 1 deletion op-e2e/actions/derivation/batch_queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func TestDeriveChainFromNearL1Genesis(gt *testing.T) {
l2Cl, err := sources.NewEngineClient(seqEngine.RPCClient(), logger, nil, sources.EngineClientDefaultConfig(sd.RollupCfg))
require.NoError(gt, err)
verifier := helpers.NewL2Verifier(t, logger, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled,
l2Cl, sequencer.RollupCfg, &sync.Config{}, safedb.Disabled)
l2Cl, sequencer.RollupCfg, &sync.Config{}, safedb.Disabled, nil)
verifier.ActL2PipelineFull(t) // Should not get stuck in a reset loop forever
require.EqualValues(gt, l2BlockNum, seqEngine.L2Chain().CurrentSafeBlock().Number.Uint64())
require.EqualValues(gt, l2BlockNum, seqEngine.L2Chain().CurrentFinalBlock().Number.Uint64())
Expand Down
2 changes: 1 addition & 1 deletion op-e2e/actions/helpers/l2_sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type L2Sequencer struct {
func NewL2Sequencer(t Testing, log log.Logger, l1 derive.L1Fetcher, blobSrc derive.L1BlobsFetcher,
altDASrc driver.AltDAIface, eng L2API, cfg *rollup.Config, seqConfDepth uint64,
) *L2Sequencer {
ver := NewL2Verifier(t, log, l1, blobSrc, altDASrc, eng, cfg, &sync.Config{}, safedb.Disabled)
ver := NewL2Verifier(t, log, l1, blobSrc, altDASrc, eng, cfg, &sync.Config{}, safedb.Disabled, nil)
attrBuilder := derive.NewFetchingAttributesBuilder(cfg, l1, eng)
seqConfDepthL1 := confdepth.NewConfDepth(seqConfDepth, ver.syncStatus.L1Head, l1)
originSelector := sequencing.NewL1OriginSelector(t.Ctx(), log, cfg, seqConfDepthL1)
Expand Down
8 changes: 7 additions & 1 deletion op-e2e/actions/helpers/l2_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ type safeDB interface {
func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher,
blobsSrc derive.L1BlobsFetcher, altDASrc driver.AltDAIface,
eng L2API, cfg *rollup.Config, syncCfg *sync.Config, safeHeadListener safeDB,
derivationPipelineCfg *rollup.Config,
) *L2Verifier {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
Expand Down Expand Up @@ -160,7 +161,12 @@ func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher,
attributes.NewAttributesHandler(log, cfg, ctx, eng), opts)

managedMode := interopSys != nil
pipeline := derive.NewDerivationPipeline(log, cfg, l1, blobsSrc, altDASrc, eng, metrics, managedMode)

// set derivation pipeline cfg separately if needed
if derivationPipelineCfg == nil {
derivationPipelineCfg = cfg
}
pipeline := derive.NewDerivationPipeline(log, derivationPipelineCfg, l1, blobsSrc, altDASrc, eng, metrics, managedMode)
sys.Register("pipeline", derive.NewPipelineDeriver(ctx, pipeline), opts)

testActionEmitter := sys.Register("test-action", nil, opts)
Expand Down
2 changes: 1 addition & 1 deletion op-e2e/actions/helpers/setups.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func SetupVerifier(t Testing, sd *e2eutils.SetupData, log log.Logger,
jwtPath := e2eutils.WriteDefaultJWT(t)
engine := NewL2Engine(t, log.New("role", "verifier-engine"), sd.L2Cfg, jwtPath, EngineWithP2P())
engCl := engine.EngineClient(t, sd.RollupCfg)
verifier := NewL2Verifier(t, log.New("role", "verifier"), l1F, blobSrc, altda.Disabled, engCl, sd.RollupCfg, syncCfg, cfg.SafeHeadListener)
verifier := NewL2Verifier(t, log.New("role", "verifier"), l1F, blobSrc, altda.Disabled, engCl, sd.RollupCfg, syncCfg, cfg.SafeHeadListener, nil)
return engine, verifier
}

Expand Down
1 change: 1 addition & 0 deletions op-e2e/actions/proofs/block_data_hint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,6 @@ func createVerifier(t actionsHelpers.Testing, env *helpers.L2FaultProofEnv) (*ac
env.Sd.RollupCfg,
&sync.Config{},
safedb.Disabled,
nil,
), engine
}
142 changes: 58 additions & 84 deletions op-e2e/actions/proofs/isthmus_setcode_tx_test.go
Original file line number Diff line number Diff line change
@@ -1,121 +1,63 @@
package proofs_test

import (
"bytes"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm/program"
"github.com/holiman/uint256"
"github.com/stretchr/testify/require"

actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers"
"github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers"
)

var (
aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
"github.com/ethereum-optimism/optimism/op-program/client/claim"
)

func runSetCodeTxTypeTest(gt *testing.T, testCfg *helpers.TestCfg[any]) {
t := actionsHelpers.NewDefaultTesting(gt)
env := helpers.NewL2FaultProofEnv(t, testCfg, helpers.NewTestParams(), helpers.NewBatcherCfg())

// hardcoded because it's not available until after we need it
bobAddr := common.HexToAddress("0x14dC79964da2C08b23698B3D3cc7Ca32193d9955")

// Create 2 contracts, (1) writes 42 to slot 42, (2) calls (1)
store42Program := program.New().Sstore(0x42, 0x42)
callBobProgram := program.New().Call(nil, bobAddr, 1, 0, 0, 0, 0)

alloc := *actionsHelpers.DefaultAlloc
alloc.L2Alloc = make(map[common.Address]types.Account)
alloc.L2Alloc[aa] = types.Account{
Code: store42Program.Bytes(),
}
alloc.L2Alloc[bb] = types.Account{
Code: callBobProgram.Bytes(),
}

testCfg.Allocs = &alloc
cl := env.Engine.EthClient()
sequencer := env.Sequencer
miner := env.Miner

tp := helpers.NewTestParams()
env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg())
miner.ActEmptyBlock(t)
sequencer.ActL1HeadSignal(t)

cl := env.Engine.EthClient()
sequencer.ActL2EmptyBlock(t)

env.Sequencer.ActL2PipelineFull(t)
env.Miner.ActEmptyBlock(t)
env.Sequencer.ActL2StartBlock(t)
batcher := env.Batcher

aliceSecret := env.Alice.L2.Secret()
bobSecret := env.Bob.L2.Secret()

chainID := env.Sequencer.RollupCfg.L2ChainID

// Sign authorization tuples.
// The way the auths are combined, it becomes
// 1. tx -> addr1 which is delegated to 0xaaaa
// 2. addr1:0xaaaa calls into addr2:0xbbbb
// 3. addr2:0xbbbb writes to storage
auth1, err := types.SignSetCode(aliceSecret, types.SetCodeAuthorization{
ChainID: *uint256.MustFromBig(chainID),
Address: bb,
Nonce: 1,
})
require.NoError(gt, err, "failed to sign auth1")
auth2, err := types.SignSetCode(bobSecret, types.SetCodeAuthorization{
Address: aa,
Nonce: 0,
})
require.NoError(gt, err, "failed to sign auth2")

txdata := &types.SetCodeTx{
ChainID: uint256.MustFromBig(chainID),
Nonce: 0,
To: env.Alice.Address(),
Gas: 500000,
GasFeeCap: uint256.NewInt(5000000000),
GasTipCap: uint256.NewInt(2),
AuthList: []types.SetCodeAuthorization{auth1, auth2},
AuthList: []types.SetCodeAuthorization{},
}
signer := types.NewIsthmusSigner(chainID)
tx := types.MustSignNewTx(aliceSecret, signer, txdata)

err = cl.SendTransaction(t.Ctx(), tx)
require.NoError(gt, err, "failed to send set code tx")

_, err = env.Engine.EngineApi.IncludeTx(tx, env.Alice.Address())
require.NoError(t, err, "failed to include set code tx")

env.Sequencer.ActL2EndBlock(t)

// Verify delegation designations were deployed.
bobCode, err := cl.PendingCodeAt(t.Ctx(), env.Bob.Address())
require.NoError(gt, err, "failed to get bob code")
want := types.AddressToDelegation(auth2.Address)
if !bytes.Equal(bobCode, want) {
t.Fatalf("addr1 code incorrect: got %s, want %s", common.Bytes2Hex(bobCode), common.Bytes2Hex(want))
}
aliceCode, err := cl.PendingCodeAt(t.Ctx(), env.Alice.Address())
require.NoError(gt, err, "failed to get alice code")
want = types.AddressToDelegation(auth1.Address)
if !bytes.Equal(aliceCode, want) {
t.Fatalf("addr2 code incorrect: got %s, want %s", common.Bytes2Hex(aliceCode), common.Bytes2Hex(want))
}
batcher.ActL2BatchBuffer(t, func(block *types.Block) *types.Block {
// inject user tx into upgrade batch
return block.WithBody(types.Body{Transactions: append(block.Transactions(), tx)})
})

// Verify delegation executed the correct code.
fortyTwo := common.BytesToHash([]byte{0x42})
actual, err := cl.PendingStorageAt(t.Ctx(), env.Bob.Address(), fortyTwo)
require.NoError(gt, err, "failed to get addr1 storage")
batcher.ActL2ChannelClose(t)
batcher.ActL2BatchSubmit(t)

if !bytes.Equal(actual, fortyTwo[:]) {
t.Fatalf("addr2 storage wrong: expected %d, got %d", fortyTwo, actual)
}
env.Miner.ActL1StartBlock(12)(t)
env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t)
env.Miner.ActL1EndBlock(t)

// batch submit to L1. batcher should submit span batches.
env.BatchAndMine(t)
env.Sequencer.ActL1HeadSignal(t)
env.Sequencer.ActL2PipelineFull(t)

env.Sequencer.ActL1HeadSignal(t)
env.Sequencer.ActL2PipelineFull(t)
Expand All @@ -130,9 +72,41 @@ func TestSetCodeTx(gt *testing.T) {
matrix := helpers.NewMatrix[any]()
defer matrix.Run(gt)

matrix.AddDefaultTestCases(
nil,
helpers.LatestForkOnly,
runSetCodeTxTypeTest,
)
cases := []struct {
name string
expectSuccess bool
hardfork helpers.Hardfork
}{
{
name: "PreIsthmus",
expectSuccess: false,
hardfork: *helpers.Holocene,
},
{
name: "Isthmus",
expectSuccess: true,
hardfork: *helpers.Isthmus,
},
}

for _, c := range cases {
matrix.AddTestCase(
"HonestClaim-"+c.name+"-Failure",
nil,
helpers.NewForkMatrix(&c.hardfork),
runSetCodeTxTypeTest,
helpers.ExpectError(claim.ErrClaimNotValid),
)

if c.expectSuccess {
matrix.AddTestCase(
"JunkClaim-"+c.name,
nil,
helpers.NewForkMatrix(&c.hardfork),
runSetCodeTxTypeTest,
helpers.ExpectError(claim.ErrClaimNotValid),
helpers.WithL2Claim(common.HexToHash("0xdeadbeef")),
)
}
}
}
4 changes: 2 additions & 2 deletions op-e2e/actions/sync/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ func TestELSyncTransitionsToCLSyncAfterNodeRestart(gt *testing.T) {
PrepareELSyncedNode(t, miner, sequencer, seqEng, verifier, verEng, seqEngCl, batcher, dp)

// Create a new verifier which is essentially a new op-node with the sync mode of ELSync and default geth engine kind.
verifier = actionsHelpers.NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.Eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync}, actionsHelpers.DefaultVerifierCfg().SafeHeadListener)
verifier = actionsHelpers.NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.Eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync}, actionsHelpers.DefaultVerifierCfg().SafeHeadListener, nil)

// Build another 10 L1 blocks on the sequencer
for i := 0; i < 10; i++ {
Expand Down Expand Up @@ -863,7 +863,7 @@ func TestForcedELSyncCLAfterNodeRestart(gt *testing.T) {
PrepareELSyncedNode(t, miner, sequencer, seqEng, verifier, verEng, seqEngCl, batcher, dp)

// Create a new verifier which is essentially a new op-node with the sync mode of ELSync and erigon engine kind.
verifier2 := actionsHelpers.NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.Eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync, SupportsPostFinalizationELSync: true}, actionsHelpers.DefaultVerifierCfg().SafeHeadListener)
verifier2 := actionsHelpers.NewL2Verifier(t, captureLog, miner.L1Client(t, sd.RollupCfg), miner.BlobStore(), altda.Disabled, verifier.Eng, sd.RollupCfg, &sync.Config{SyncMode: sync.ELSync, SupportsPostFinalizationELSync: true}, actionsHelpers.DefaultVerifierCfg().SafeHeadListener, nil)

// Build another 10 L1 blocks on the sequencer
for i := 0; i < 10; i++ {
Expand Down
6 changes: 6 additions & 0 deletions op-node/rollup/derive/batches.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ func checkSingularBatch(cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1Blo
}
}

isIsthmus := cfg.IsIsthmus(batch.Timestamp)

// We can do this check earlier, but it's a more intensive one, so we do this last.
for i, txBytes := range batch.Transactions {
if len(txBytes) == 0 {
Expand All @@ -171,6 +173,10 @@ func checkSingularBatch(cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1Blo
log.Warn("sequencers may not embed any deposits into batch data, but found tx that has one", "tx_index", i)
return BatchDrop
}
if !isIsthmus && txBytes[0] == types.SetCodeTxType {
log.Warn("sequencers may not embed any SetCode transactions before Isthmus", "tx_index", i)
return BatchDrop
}
}

return BatchAccept
Expand Down