Skip to content
51 changes: 51 additions & 0 deletions op-node/rollup/derive/attributes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,57 @@ func TestPreparePayloadAttributes(t *testing.T) {
require.Equal(t, l1InfoTx, []byte(attrs.Transactions[0]))
require.True(t, attrs.NoTxPool)
})
t.Run("same origin with deposits on post-Isthmus", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
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

receipts, depositTxs, err := makeReceipts(rng, l1Info.InfoHash, cfg.DepositContractAddress, []receiptData{
{goodReceipt: true, DepositLogs: []bool{true, false}},
{goodReceipt: true, DepositLogs: []bool{true}},
{goodReceipt: false, DepositLogs: []bool{true}},
{goodReceipt: false, DepositLogs: []bool{false}},
})
require.NoError(t, err)
usedDepositTxs, err := encodeDeposits(depositTxs)
require.NoError(t, err)

// sets config to post-interop
cfg.RegolithTime = &zero64
cfg.EcotoneTime = &zero64
cfg.InteropTime = &zero64
cfg.BlockTime = 2
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bedrock, Canyon, Fjord, Granite are missing


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

l2Txs := append(append(make([]eth.Data, 0), l1InfoTx), usedDepositTxs...)

l1Fetcher.ExpectFetchReceipts(epoch.Hash, l1Info, receipts, nil)
attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, l1CfgFetcher)
attrs, err := attrBuilder.PreparePayloadAttributes(context.Background(), l2Parent, epoch)
require.NoError(t, err)
require.NotNil(t, attrs)
require.Equal(t, l2Parent.Time+cfg.BlockTime, uint64(attrs.Timestamp))
require.Equal(t, eth.Bytes32(l1Info.InfoMixDigest), attrs.PrevRandao)
require.Equal(t, predeploys.SequencerFeeVaultAddr, attrs.SuggestedFeeRecipient)
require.Equal(t, len(l2Txs), len(attrs.Transactions), "Expected txs to equal l1 info tx + user deposit txs + DepositsComplete")
require.Equal(t, l2Txs, attrs.Transactions)
require.Equal(t, DepositsCompleteBytes4, attrs.Transactions[1+len(depositTxs)][:4])
require.True(t, attrs.NoTxPool)
depositsCompleteTx, err := DepositsCompleteBytes(l2Parent.SequenceNumber, l1Info)
require.NoError(t, err)
require.Equal(t, l2Txs, append(attrs.Transactions, depositsCompleteTx))
})

// 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 {
Expand Down
15 changes: 15 additions & 0 deletions op-node/rollup/derive/deposit_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package derive
import (
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -34,3 +35,17 @@ func TestEcotone4788ContractSourceHash(t *testing.T) {

assert.Equal(t, expected, actual.Hex())
}

// TestAfterForceIncludeSourceHash
// cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000003 $(cast keccak 0x01))
// # 0x8afb1c4a581d0e71ab65334e3365ba5511fb15c13fa212776f9d4dafc6287845
func TestAfterForceIncludeSource(t *testing.T) {
source := AfterForceIncludeSource{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this name is not consistent, its after force include, which iirc we moved away from

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we agreed to go with AfterForceInclude, but I'm happy to re-name it to a better name :)

L1BlockHash: common.Hash{0x01},
}

actual := source.SourceHash()
expected := "0x8afb1c4a581d0e71ab65334e3365ba5511fb15c13fa212776f9d4dafc6287845"

assert.Equal(t, expected, actual.Hex())
}
17 changes: 14 additions & 3 deletions op-node/rollup/derive/fuzz_parsers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,26 @@ func FuzzL1InfoEcotoneRoundTrip(f *testing.F) {
}
enc, err := in.marshalBinaryEcotone()
if err != nil {
t.Fatalf("Failed to marshal binary: %v", err)
t.Fatalf("Failed to marshal Ecotone binary: %v", err)
}
var out L1BlockInfo
err = out.unmarshalBinaryEcotone(enc)
if err != nil {
t.Fatalf("Failed to unmarshal binary: %v", err)
t.Fatalf("Failed to unmarshal Ecotone binary: %v", err)
}
if !cmp.Equal(in, out, cmp.Comparer(testutils.BigEqual)) {
t.Fatalf("The data did not round trip correctly. in: %v. out: %v", in, out)
t.Fatalf("The Ecotone data did not round trip correctly. in: %v. out: %v", in, out)
}
enc, err = in.marshalBinaryIsthmus()
if err != nil {
t.Fatalf("Failed to marshal Isthmus binary: %v", err)
}
err = out.unmarshalBinaryIsthmus(enc)
if err != nil {
t.Fatalf("Failed to unmarshal Isthmus binary: %v", err)
}
if !cmp.Equal(in, out, cmp.Comparer(testutils.BigEqual)) {
t.Fatalf("The Isthmus data did not round trip correctly. in: %v. out: %v", in, out)
}

})
Expand Down
7 changes: 4 additions & 3 deletions op-node/rollup/derive/l1_block_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ const (
DepositsCompleteSignature = "depositsComplete()"
L1InfoArguments = 8
L1InfoBedrockLen = 4 + 32*L1InfoArguments
L1InfoEcotoneLen = 4 + 32*5 // after Ecotone upgrade, args are packed into 5 32-byte slots
DepositsCompleteLen = 4 // only the selector
L1InfoEcotoneLen = 4 + 32*5 // after Ecotone upgrade, args are packed into 5 32-byte slots
DepositsCompleteLen = 4 // only the selector
DepositsCompleteGas = uint64(15_000) // over estimated gas limit for DepositsComplete transaction
)

var (
Expand Down Expand Up @@ -400,7 +401,7 @@ func DepositsCompleteDeposit(seqNumber uint64, block eth.BlockInfo) (*types.Depo
// GasBenchMark_L1BlockIsthmus_DepositsComplete:test_depositsComplete_benchmark() (gas: 7768)
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
// GasBenchMark_L1BlockIsthmus_DepositsComplete_Warm:test_depositsComplete_benchmark() (gas: 5768)
// see `test_depositsComplete_benchmark` at: `/packages/contracts-bedrock/test/BenchmarkTest.t.sol`
Gas: 15_000,
Gas: DepositsCompleteGas,
IsSystemTransaction: false,
Data: DepositsCompleteBytes4,
}
Expand Down
77 changes: 77 additions & 0 deletions op-node/rollup/derive/l1_block_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,81 @@ func TestParseL1InfoDepositTxData(t *testing.T) {
require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas))
require.Equal(t, L1InfoEcotoneLen, len(depTx.Data))
})
t.Run("Isthmus", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
info := testutils.MakeBlockInfo(nil)(rng)
zero := uint64(0)
rollupCfg := rollup.Config{
RegolithTime: &zero,
EcotoneTime: &zero,
InteropTime: &zero,
}
depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 1)
require.NoError(t, err)
require.False(t, depTx.IsSystemTransaction)
require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas))
require.Equal(t, L1InfoEcotoneLen, len(depTx.Data))
require.Equal(t, L1InfoFuncEcotoneBytes4, depTx.Data[:4])
// should still send Ecotone signature since upgrade happens after deposits
})
t.Run("first-block isthmus", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
info := testutils.MakeBlockInfo(nil)(rng)
zero := uint64(2)
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
rollupCfg := rollup.Config{
RegolithTime: &zero,
EcotoneTime: &zero,
InteropTime: &zero,
BlockTime: 2,
}
depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 2)
require.NoError(t, err)
require.False(t, depTx.IsSystemTransaction)
require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas))
require.Equal(t, L1InfoBedrockLen, len(depTx.Data))
require.Equal(t, L1InfoFuncIsthmusBytes4, depTx.Data[:4])
})
t.Run("genesis-block isthmus", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
info := testutils.MakeBlockInfo(nil)(rng)
zero := uint64(0)
rollupCfg := rollup.Config{
RegolithTime: &zero,
EcotoneTime: &zero,
InteropTime: &zero,
BlockTime: 2,
}
depTx, err := L1InfoDeposit(&rollupCfg, randomL1Cfg(rng, info), randomSeqNr(rng), info, 0)
require.NoError(t, err)
require.False(t, depTx.IsSystemTransaction)
require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas))
require.Equal(t, L1InfoEcotoneLen, len(depTx.Data))
require.Equal(t, L1InfoBedrockLen, len(depTx.Data))
})
}

func TestDepositsCompleteBytes(t *testing.T) {
randomSeqNr := func(rng *rand.Rand) uint64 {
return rng.Uint64()
}
t.Run("valid return bytes", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
info := testutils.MakeBlockInfo(nil)(rng)
depTxByes, err := DepositsCompleteBytes(randomSeqNr(rng), info)
require.NoError(t, err)
require.Equal(t, depTxByes, DepositsCompleteBytes4)
require.Equal(t, DepositsCompleteLen, len(depTxByes))
Comment thread
skeletor-spaceman marked this conversation as resolved.
})
t.Run("valid return Transaction", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
info := testutils.MakeBlockInfo(nil)(rng)
depTx, err := DepositsCompleteDeposit(randomSeqNr(rng), info)
require.NoError(t, err)
require.Equal(t, depTx.Data, DepositsCompleteBytes4)
require.Equal(t, DepositsCompleteLen, len(depTx.Data))
require.Equal(t, DepositsCompleteGas, depTx.Gas)
require.False(t, depTx.IsSystemTransaction)
require.Equal(t, depTx.Value, big.NewInt(0))
require.Equal(t, depTx.From, L1InfoDepositerAddress)
})
}