Commit 096d9c2b authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

Merge pull request #4961 from ethereum-optimism/regolith-sys-deposits

op-node: regolith fork systemtx change
parents 0c1f45e1 68e2b490
...@@ -147,7 +147,7 @@ func TestInvalidDepositInFCU(t *testing.T) { ...@@ -147,7 +147,7 @@ func TestInvalidDepositInFCU(t *testing.T) {
require.Nil(t, err) require.Nil(t, err)
// Create the test data (L1 Info Tx and then always failing deposit) // 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) require.Nil(t, err)
// Create a deposit from alice that will always fail (not enough funds) // Create a deposit from alice that will always fail (not enough funds)
......
...@@ -100,7 +100,7 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex ...@@ -100,7 +100,7 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
l2Parent, nextL2Time, eth.ToBlockID(l1Info), l1Info.Time())) 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 { if err != nil {
return nil, NewCriticalError(fmt.Errorf("failed to create l1InfoTx: %w", err)) return nil, NewCriticalError(fmt.Errorf("failed to create l1InfoTx: %w", err))
} }
......
...@@ -66,7 +66,7 @@ func TestAttributesQueue(t *testing.T) { ...@@ -66,7 +66,7 @@ func TestAttributesQueue(t *testing.T) {
l2Fetcher := &testutils.MockL2Client{} l2Fetcher := &testutils.MockL2Client{}
l2Fetcher.ExpectSystemConfigByL2Hash(safeHead.Hash, parentL1Cfg, nil) 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) require.NoError(t, err)
attrs := eth.PayloadAttributes{ attrs := eth.PayloadAttributes{
Timestamp: eth.Uint64Quantity(safeHead.Time + cfg.BlockTime), Timestamp: eth.Uint64Quantity(safeHead.Time + cfg.BlockTime),
......
...@@ -113,7 +113,7 @@ func TestPreparePayloadAttributes(t *testing.T) { ...@@ -113,7 +113,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Info.InfoParentHash = l2Parent.L1Origin.Hash l1Info.InfoParentHash = l2Parent.L1Origin.Hash
l1Info.InfoNum = l2Parent.L1Origin.Number + 1 l1Info.InfoNum = l2Parent.L1Origin.Number + 1
epoch := l1Info.ID() epoch := l1Info.ID()
l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg) l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg, false)
require.NoError(t, err) require.NoError(t, err)
l1Fetcher.ExpectFetchReceipts(epoch.Hash, l1Info, nil, nil) l1Fetcher.ExpectFetchReceipts(epoch.Hash, l1Info, nil, nil)
attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, l1CfgFetcher) attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, l1CfgFetcher)
...@@ -150,7 +150,7 @@ func TestPreparePayloadAttributes(t *testing.T) { ...@@ -150,7 +150,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
epoch := l1Info.ID() epoch := l1Info.ID()
l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg) l1InfoTx, err := L1InfoDepositBytes(0, l1Info, testSysCfg, false)
require.NoError(t, err) require.NoError(t, err)
l2Txs := append(append(make([]eth.Data, 0), l1InfoTx), usedDepositTxs...) l2Txs := append(append(make([]eth.Data, 0), l1InfoTx), usedDepositTxs...)
...@@ -180,7 +180,7 @@ func TestPreparePayloadAttributes(t *testing.T) { ...@@ -180,7 +180,7 @@ func TestPreparePayloadAttributes(t *testing.T) {
l1Info.InfoNum = l2Parent.L1Origin.Number l1Info.InfoNum = l2Parent.L1Origin.Number
epoch := l1Info.ID() epoch := l1Info.ID()
l1InfoTx, err := L1InfoDepositBytes(l2Parent.SequenceNumber+1, l1Info, testSysCfg) l1InfoTx, err := L1InfoDepositBytes(l2Parent.SequenceNumber+1, l1Info, testSysCfg, false)
require.NoError(t, err) require.NoError(t, err)
l1Fetcher.ExpectInfoByHash(epoch.Hash, l1Info, nil) l1Fetcher.ExpectInfoByHash(epoch.Hash, l1Info, nil)
...@@ -195,6 +195,53 @@ func TestPreparePayloadAttributes(t *testing.T) { ...@@ -195,6 +195,53 @@ func TestPreparePayloadAttributes(t *testing.T) {
require.Equal(t, l1InfoTx, []byte(attrs.Transactions[0])) require.Equal(t, l1InfoTx, []byte(attrs.Transactions[0]))
require.True(t, attrs.NoTxPool) 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) { func encodeDeposits(deposits []*types.DepositTx) (out []eth.Data, err error) {
......
...@@ -26,6 +26,10 @@ var ( ...@@ -26,6 +26,10 @@ var (
L1BlockAddress = predeploys.L1BlockAddr L1BlockAddress = predeploys.L1BlockAddr
) )
const (
RegolithSystemTxGas = 1_000_000
)
// L1BlockInfo presents the information stored in a L1Block.setL1BlockValues call // L1BlockInfo presents the information stored in a L1Block.setL1BlockValues call
type L1BlockInfo struct { type L1BlockInfo struct {
Number uint64 Number uint64
...@@ -115,7 +119,7 @@ func L1InfoDepositTxData(data []byte) (L1BlockInfo, error) { ...@@ -115,7 +119,7 @@ func L1InfoDepositTxData(data []byte) (L1BlockInfo, error) {
// L1InfoDeposit creates a L1 Info deposit transaction based on the L1 block, // L1InfoDeposit creates a L1 Info deposit transaction based on the L1 block,
// and the L2 block-height difference with the start of the epoch. // 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{ infoDat := L1BlockInfo{
Number: block.NumberU64(), Number: block.NumberU64(),
Time: block.Time(), Time: block.Time(),
...@@ -137,7 +141,7 @@ func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfi ...@@ -137,7 +141,7 @@ func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfi
} }
// Set a very large gas limit with `IsSystemTransaction` to ensure // Set a very large gas limit with `IsSystemTransaction` to ensure
// that the L1 Attributes Transaction does not run out of gas. // that the L1 Attributes Transaction does not run out of gas.
return &types.DepositTx{ out := &types.DepositTx{
SourceHash: source.SourceHash(), SourceHash: source.SourceHash(),
From: L1InfoDepositerAddress, From: L1InfoDepositerAddress,
To: &L1BlockAddress, To: &L1BlockAddress,
...@@ -146,12 +150,18 @@ func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfi ...@@ -146,12 +150,18 @@ func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfi
Gas: 150_000_000, Gas: 150_000_000,
IsSystemTransaction: true, IsSystemTransaction: true,
Data: data, 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. // L1InfoDepositBytes returns a serialized L1-info attributes transaction.
func L1InfoDepositBytes(seqNumber uint64, l1Info eth.BlockInfo, sysCfg eth.SystemConfig) ([]byte, error) { func L1InfoDepositBytes(seqNumber uint64, l1Info eth.BlockInfo, sysCfg eth.SystemConfig, regolith bool) ([]byte, error) {
dep, err := L1InfoDeposit(seqNumber, l1Info, sysCfg) dep, err := L1InfoDeposit(seqNumber, l1Info, sysCfg, regolith)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create L1 info tx: %w", err) return nil, fmt.Errorf("failed to create L1 info tx: %w", err)
} }
......
...@@ -65,7 +65,7 @@ func TestParseL1InfoDepositTxData(t *testing.T) { ...@@ -65,7 +65,7 @@ func TestParseL1InfoDepositTxData(t *testing.T) {
info := testCase.mkInfo(rng) info := testCase.mkInfo(rng)
l1Cfg := testCase.mkL1Cfg(rng, info) l1Cfg := testCase.mkL1Cfg(rng, info)
seqNr := testCase.seqNr(rng) seqNr := testCase.seqNr(rng)
depTx, err := L1InfoDeposit(seqNr, info, l1Cfg) depTx, err := L1InfoDeposit(seqNr, info, l1Cfg, false)
require.NoError(t, err) require.NoError(t, err)
res, err := L1InfoDepositTxData(depTx.Data) res, err := L1InfoDepositTxData(depTx.Data)
require.NoError(t, err, "expected valid deposit info") require.NoError(t, err, "expected valid deposit info")
...@@ -95,11 +95,19 @@ func TestParseL1InfoDepositTxData(t *testing.T) { ...@@ -95,11 +95,19 @@ func TestParseL1InfoDepositTxData(t *testing.T) {
t.Run("invalid selector", func(t *testing.T) { t.Run("invalid selector", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234)) rng := rand.New(rand.NewSource(1234))
info := testutils.MakeBlockInfo(nil)(rng) 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) require.NoError(t, err)
_, err = rand.Read(depTx.Data[0:4]) _, err = rand.Read(depTx.Data[0:4])
require.NoError(t, err) require.NoError(t, err)
_, err = L1InfoDepositTxData(depTx.Data) _, err = L1InfoDepositTxData(depTx.Data)
require.ErrorContains(t, err, "function signature") 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))
})
} }
...@@ -27,7 +27,7 @@ func FuzzParseL1InfoDepositTxDataValid(f *testing.F) { ...@@ -27,7 +27,7 @@ func FuzzParseL1InfoDepositTxDataValid(f *testing.F) {
typeProvider.Fuzz(&sysCfg) typeProvider.Fuzz(&sysCfg)
// Create our deposit tx from our info // 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") require.NoError(t, err, "error creating deposit tx from L1 info")
// Get our info from out deposit tx // Get our info from out deposit tx
...@@ -71,7 +71,7 @@ func FuzzDecodeDepositTxDataToL1Info(f *testing.F) { ...@@ -71,7 +71,7 @@ func FuzzDecodeDepositTxDataToL1Info(f *testing.F) {
GasLimit: uint64(0), 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.NoError(t, err, "error creating deposit tx from L1 info")
require.Equal(t, depTx.Data, fuzzedData) require.Equal(t, depTx.Data, fuzzedData)
}) })
......
...@@ -245,7 +245,7 @@ func TestSequencerChaosMonkey(t *testing.T) { ...@@ -245,7 +245,7 @@ func TestSequencerChaosMonkey(t *testing.T) {
InfoBaseFee: big.NewInt(1234), InfoBaseFee: big.NewInt(1234),
InfoReceiptRoot: common.Hash{}, 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) require.NoError(t, err)
testGasLimit := eth.Uint64Quantity(10_000_000) testGasLimit := eth.Uint64Quantity(10_000_000)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment