Skip to content

Commit

Permalink
Merge pull request ethereum-optimism#4961 from ethereum-optimism/rego…
Browse files Browse the repository at this point in the history
…lith-sys-deposits

op-node: regolith fork systemtx change
  • Loading branch information
mslipper authored Feb 23, 2023
2 parents 0c1f45e + 68e2b49 commit 096d9c2
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 16 deletions.
2 changes: 1 addition & 1 deletion op-e2e/op_geth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func TestInvalidDepositInFCU(t *testing.T) {
require.Nil(t, err)

// Create the test data (L1 Info Tx and then always failing deposit)
l1Info, err := derive.L1InfoDepositBytes(1, l1Block, rollupGenesis.SystemConfig)
l1Info, err := derive.L1InfoDepositBytes(1, l1Block, rollupGenesis.SystemConfig, false)
require.Nil(t, err)

// Create a deposit from alice that will always fail (not enough funds)
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/derive/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
l2Parent, nextL2Time, eth.ToBlockID(l1Info), l1Info.Time()))
}

l1InfoTx, err := L1InfoDepositBytes(seqNumber, l1Info, sysConfig)
l1InfoTx, err := L1InfoDepositBytes(seqNumber, l1Info, sysConfig, ba.cfg.IsRegolith(nextL2Time))
if err != nil {
return nil, NewCriticalError(fmt.Errorf("failed to create l1InfoTx: %w", err))
}
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/derive/attributes_queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestAttributesQueue(t *testing.T) {
l2Fetcher := &testutils.MockL2Client{}
l2Fetcher.ExpectSystemConfigByL2Hash(safeHead.Hash, parentL1Cfg, nil)

l1InfoTx, err := L1InfoDepositBytes(safeHead.SequenceNumber+1, l1Info, expectedL1Cfg)
l1InfoTx, err := L1InfoDepositBytes(safeHead.SequenceNumber+1, l1Info, expectedL1Cfg, false)
require.NoError(t, err)
attrs := eth.PayloadAttributes{
Timestamp: eth.Uint64Quantity(safeHead.Time + cfg.BlockTime),
Expand Down
53 changes: 50 additions & 3 deletions op-node/rollup/derive/attributes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Info.InfoParentHash = l2Parent.L1Origin.Hash
l1Info.InfoNum = l2Parent.L1Origin.Number + 1
epoch := l1Info.ID()
l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg)
l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg, false)
require.NoError(t, err)
l1Fetcher.ExpectFetchReceipts(epoch.Hash, l1Info, nil, nil)
attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, l1CfgFetcher)
Expand Down Expand Up @@ -150,7 +150,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
require.NoError(t, err)

epoch := l1Info.ID()
l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg)
l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg, false)
require.NoError(t, err)

l2Txs := append(append(make([]eth.Data, 0), l1InfoTx), usedDepositTxs...)
Expand Down Expand Up @@ -180,7 +180,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Info.InfoNum = l2Parent.L1Origin.Number

epoch := l1Info.ID()
l1InfoTx, err := L1InfoDepositBytes(l2Parent.SequenceNumber+1, l1Info, testSysCfg)
l1InfoTx, err := L1InfoDepositBytes(l2Parent.SequenceNumber+1, l1Info, testSysCfg, false)
require.NoError(t, err)

l1Fetcher.ExpectInfoByHash(epoch.Hash, l1Info, nil)
Expand All @@ -195,6 +195,53 @@ func TestPreparePayloadAttributes(t *testing.T) {
require.Equal(t, l1InfoTx, []byte(attrs.Transactions[0]))
require.True(t, attrs.NoTxPool)
})
// Test that the payload attributes builder changes the deposit format based on L2-time-based regolith activation
t.Run("regolith", func(t *testing.T) {
testCases := []struct {
name string
l1Time uint64
l2ParentTime uint64
regolithTime uint64
regolith bool
}{
{"exactly", 900, 1000 - cfg.BlockTime, 1000, true},
{"almost", 900, 1000 - cfg.BlockTime - 1, 1000, false},
{"inactive", 700, 700, 1000, false},
{"l1 time before regolith", 1000, 1001, 1001, true},
{"l1 time way before regolith", 1000, 2000, 2000, true},
{"l1 time before regoltih and l2 after", 1000, 3000, 2000, true},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
cfgCopy := *cfg // copy, we are making regolith config modifications
cfg := &cfgCopy
rng := rand.New(rand.NewSource(1234))
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
cfg.RegolithTime = &tc.regolithTime
l2Parent.Time = tc.l2ParentTime

l1CfgFetcher := &testutils.MockL2Client{}
l1CfgFetcher.ExpectSystemConfigByL2Hash(l2Parent.Hash, testSysCfg, nil)
defer l1CfgFetcher.AssertExpectations(t)

l1Info := testutils.RandomBlockInfo(rng)
l1Info.InfoParentHash = l2Parent.L1Origin.Hash
l1Info.InfoNum = l2Parent.L1Origin.Number + 1
l1Info.InfoTime = tc.l1Time

epoch := l1Info.ID()
l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg, tc.regolith)
require.NoError(t, err)
l1Fetcher.ExpectFetchReceipts(epoch.Hash, l1Info, nil, nil)
attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, l1CfgFetcher)
attrs, err := attrBuilder.PreparePayloadAttributes(context.Background(), l2Parent, epoch)
require.NoError(t, err)
require.Equal(t, l1InfoTx, []byte(attrs.Transactions[0]))
})
}
})
}

func encodeDeposits(deposits []*types.DepositTx) (out []eth.Data, err error) {
Expand Down
20 changes: 15 additions & 5 deletions op-node/rollup/derive/l1_block_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ var (
L1BlockAddress = predeploys.L1BlockAddr
)

const (
RegolithSystemTxGas = 1_000_000
)

// L1BlockInfo presents the information stored in a L1Block.setL1BlockValues call
type L1BlockInfo struct {
Number uint64
Expand Down Expand Up @@ -115,7 +119,7 @@ func L1InfoDepositTxData(data []byte) (L1BlockInfo, error) {

// L1InfoDeposit creates a L1 Info deposit transaction based on the L1 block,
// and the L2 block-height difference with the start of the epoch.
func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfig) (*types.DepositTx, error) {
func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfig, regolith bool) (*types.DepositTx, error) {
infoDat := L1BlockInfo{
Number: block.NumberU64(),
Time: block.Time(),
Expand All @@ -137,7 +141,7 @@ func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfi
}
// Set a very large gas limit with `IsSystemTransaction` to ensure
// that the L1 Attributes Transaction does not run out of gas.
return &types.DepositTx{
out := &types.DepositTx{
SourceHash: source.SourceHash(),
From: L1InfoDepositerAddress,
To: &L1BlockAddress,
Expand All @@ -146,12 +150,18 @@ func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfi
Gas: 150_000_000,
IsSystemTransaction: true,
Data: data,
}, nil
}
// With the regolith fork we disable the IsSystemTx functionality, and allocate real gas
if regolith {
out.IsSystemTransaction = false
out.Gas = RegolithSystemTxGas
}
return out, nil
}

// L1InfoDepositBytes returns a serialized L1-info attributes transaction.
func L1InfoDepositBytes(seqNumber uint64, l1Info eth.BlockInfo, sysCfg eth.SystemConfig) ([]byte, error) {
dep, err := L1InfoDeposit(seqNumber, l1Info, sysCfg)
func L1InfoDepositBytes(seqNumber uint64, l1Info eth.BlockInfo, sysCfg eth.SystemConfig, regolith bool) ([]byte, error) {
dep, err := L1InfoDeposit(seqNumber, l1Info, sysCfg, regolith)
if err != nil {
return nil, fmt.Errorf("failed to create L1 info tx: %w", err)
}
Expand Down
12 changes: 10 additions & 2 deletions op-node/rollup/derive/l1_block_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestParseL1InfoDepositTxData(t *testing.T) {
info := testCase.mkInfo(rng)
l1Cfg := testCase.mkL1Cfg(rng, info)
seqNr := testCase.seqNr(rng)
depTx, err := L1InfoDeposit(seqNr, info, l1Cfg)
depTx, err := L1InfoDeposit(seqNr, info, l1Cfg, false)
require.NoError(t, err)
res, err := L1InfoDepositTxData(depTx.Data)
require.NoError(t, err, "expected valid deposit info")
Expand Down Expand Up @@ -95,11 +95,19 @@ func TestParseL1InfoDepositTxData(t *testing.T) {
t.Run("invalid selector", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
info := testutils.MakeBlockInfo(nil)(rng)
depTx, err := L1InfoDeposit(randomSeqNr(rng), info, randomL1Cfg(rng, info))
depTx, err := L1InfoDeposit(randomSeqNr(rng), info, randomL1Cfg(rng, info), false)
require.NoError(t, err)
_, err = rand.Read(depTx.Data[0:4])
require.NoError(t, err)
_, err = L1InfoDepositTxData(depTx.Data)
require.ErrorContains(t, err, "function signature")
})
t.Run("regolith", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
info := testutils.MakeBlockInfo(nil)(rng)
depTx, err := L1InfoDeposit(randomSeqNr(rng), info, randomL1Cfg(rng, info), true)
require.NoError(t, err)
require.False(t, depTx.IsSystemTransaction)
require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas))
})
}
4 changes: 2 additions & 2 deletions op-node/rollup/derive/l1_block_info_tob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func FuzzParseL1InfoDepositTxDataValid(f *testing.F) {
typeProvider.Fuzz(&sysCfg)

// Create our deposit tx from our info
depTx, err := L1InfoDeposit(seqNr, &l1Info, sysCfg)
depTx, err := L1InfoDeposit(seqNr, &l1Info, sysCfg, false)
require.NoError(t, err, "error creating deposit tx from L1 info")

// Get our info from out deposit tx
Expand Down Expand Up @@ -71,7 +71,7 @@ func FuzzDecodeDepositTxDataToL1Info(f *testing.F) {
GasLimit: uint64(0),
}

depTx, err := L1InfoDeposit(res.SequenceNumber, &l1Info, sysCfg)
depTx, err := L1InfoDeposit(res.SequenceNumber, &l1Info, sysCfg, false)
require.NoError(t, err, "error creating deposit tx from L1 info")
require.Equal(t, depTx.Data, fuzzedData)
})
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/driver/sequencer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func TestSequencerChaosMonkey(t *testing.T) {
InfoBaseFee: big.NewInt(1234),
InfoReceiptRoot: common.Hash{},
}
infoDep, err := derive.L1InfoDepositBytes(seqNr, l1Info, cfg.Genesis.SystemConfig)
infoDep, err := derive.L1InfoDepositBytes(seqNr, l1Info, cfg.Genesis.SystemConfig, false)
require.NoError(t, err)

testGasLimit := eth.Uint64Quantity(10_000_000)
Expand Down

0 comments on commit 096d9c2

Please sign in to comment.