Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
55667361
Unverified
Commit
55667361
authored
Dec 01, 2023
by
protolambda
Committed by
GitHub
Dec 01, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8358 from testinprod-io/tip/spanbatch-hardfork-e2e
op-e2e: Improve e2e test for span batches
parents
918459c4
d1d67e80
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
382 additions
and
27 deletions
+382
-27
l2_batcher.go
op-e2e/actions/l2_batcher.go
+10
-1
span_batch_test.go
op-e2e/actions/span_batch_test.go
+372
-26
No files found.
op-e2e/actions/l2_batcher.go
View file @
55667361
...
@@ -44,6 +44,9 @@ type BatcherCfg struct {
...
@@ -44,6 +44,9 @@ type BatcherCfg struct {
BatcherKey
*
ecdsa
.
PrivateKey
BatcherKey
*
ecdsa
.
PrivateKey
GarbageCfg
*
GarbageChannelCfg
GarbageCfg
*
GarbageChannelCfg
ForceSubmitSingularBatch
bool
ForceSubmitSpanBatch
bool
}
}
type
L2BlockRefs
interface
{
type
L2BlockRefs
interface
{
...
@@ -157,7 +160,13 @@ func (s *L2Batcher) Buffer(t Testing) error {
...
@@ -157,7 +160,13 @@ func (s *L2Batcher) Buffer(t Testing) error {
var
batchType
uint
=
derive
.
SingularBatchType
var
batchType
uint
=
derive
.
SingularBatchType
var
spanBatchBuilder
*
derive
.
SpanBatchBuilder
=
nil
var
spanBatchBuilder
*
derive
.
SpanBatchBuilder
=
nil
if
s
.
rollupCfg
.
IsDelta
(
block
.
Time
())
{
if
s
.
l2BatcherCfg
.
ForceSubmitSingularBatch
&&
s
.
l2BatcherCfg
.
ForceSubmitSpanBatch
{
t
.
Fatalf
(
"ForceSubmitSingularBatch and ForceSubmitSpanBatch cannot be set to true at the same time"
)
}
else
if
s
.
l2BatcherCfg
.
ForceSubmitSingularBatch
{
// use SingularBatchType
}
else
if
s
.
l2BatcherCfg
.
ForceSubmitSpanBatch
||
s
.
rollupCfg
.
IsDelta
(
block
.
Time
())
{
// If both ForceSubmitSingularBatch and ForceSubmitSpanbatch are false, use SpanBatch automatically if Delta HF is activated.
batchType
=
derive
.
SpanBatchType
batchType
=
derive
.
SpanBatchType
spanBatchBuilder
=
derive
.
NewSpanBatchBuilder
(
s
.
rollupCfg
.
Genesis
.
L2Time
,
s
.
rollupCfg
.
L2ChainID
)
spanBatchBuilder
=
derive
.
NewSpanBatchBuilder
(
s
.
rollupCfg
.
Genesis
.
L2Time
,
s
.
rollupCfg
.
L2ChainID
)
}
}
...
...
op-e2e/actions/span_batch_test.go
View file @
55667361
...
@@ -40,17 +40,14 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) {
...
@@ -40,17 +40,14 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) {
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
miner
,
seqEngine
,
sequencer
:=
setupSequencerTest
(
t
,
sd
,
log
)
miner
,
seqEngine
,
sequencer
:=
setupSequencerTest
(
t
,
sd
,
log
)
verifEngine
,
verifier
:=
setupVerifier
(
t
,
sd
,
log
,
miner
.
L1Client
(
t
,
sd
.
RollupCfg
),
&
sync
.
Config
{})
verifEngine
,
verifier
:=
setupVerifier
(
t
,
sd
,
log
,
miner
.
L1Client
(
t
,
sd
.
RollupCfg
),
&
sync
.
Config
{})
rollupSeqCl
:=
sequencer
.
RollupClient
()
rollupSeqCl
:=
sequencer
.
RollupClient
()
dp2
:=
e2eutils
.
MakeDeployParams
(
t
,
p
)
minTs
:=
hexutil
.
Uint64
(
0
)
// Force batcher to submit SpanBatches to L1.
// activate Delta hardfork for batcher. so batcher will submit SpanBatches to L1.
batcher
:=
NewL2Batcher
(
log
,
sd
.
RollupCfg
,
&
BatcherCfg
{
dp2
.
DeployConfig
.
L2GenesisDeltaTimeOffset
=
&
minTs
sd2
:=
e2eutils
.
Setup
(
t
,
dp2
,
defaultAlloc
)
batcher
:=
NewL2Batcher
(
log
,
sd2
.
RollupCfg
,
&
BatcherCfg
{
MinL1TxSize
:
0
,
MinL1TxSize
:
0
,
MaxL1TxSize
:
128
_000
,
MaxL1TxSize
:
128
_000
,
BatcherKey
:
dp
.
Secrets
.
Batcher
,
BatcherKey
:
dp
.
Secrets
.
Batcher
,
ForceSubmitSpanBatch
:
true
,
},
rollupSeqCl
,
miner
.
EthClient
(),
seqEngine
.
EthClient
(),
seqEngine
.
EngineClient
(
t
,
sd
.
RollupCfg
))
},
rollupSeqCl
,
miner
.
EthClient
(),
seqEngine
.
EthClient
(),
seqEngine
.
EngineClient
(
t
,
sd
.
RollupCfg
))
// Alice makes a L2 tx
// Alice makes a L2 tx
...
@@ -114,6 +111,113 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) {
...
@@ -114,6 +111,113 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) {
require
.
ErrorIs
(
t
,
err
,
ethereum
.
NotFound
)
require
.
ErrorIs
(
t
,
err
,
ethereum
.
NotFound
)
}
}
// TestHardforkMiddleOfSpanBatch tests behavior of op-node Delta hardfork.
// If Delta activation time is in the middle of time range of a SpanBatch, op-node must drop the batch.
func
TestHardforkMiddleOfSpanBatch
(
gt
*
testing
.
T
)
{
t
:=
NewDefaultTesting
(
gt
)
p
:=
&
e2eutils
.
TestParams
{
MaxSequencerDrift
:
20
,
// larger than L1 block time we simulate in this test (12)
SequencerWindowSize
:
24
,
ChannelTimeout
:
20
,
L1BlockTime
:
12
,
}
dp
:=
e2eutils
.
MakeDeployParams
(
t
,
p
)
// Activate HF in the middle of the first epoch
deltaOffset
:=
hexutil
.
Uint64
(
6
)
dp
.
DeployConfig
.
L2GenesisDeltaTimeOffset
=
&
deltaOffset
sd
:=
e2eutils
.
Setup
(
t
,
dp
,
defaultAlloc
)
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
miner
,
seqEngine
,
sequencer
:=
setupSequencerTest
(
t
,
sd
,
log
)
verifEngine
,
verifier
:=
setupVerifier
(
t
,
sd
,
log
,
miner
.
L1Client
(
t
,
sd
.
RollupCfg
),
&
sync
.
Config
{})
minerCl
:=
miner
.
EthClient
()
rollupSeqCl
:=
sequencer
.
RollupClient
()
// Force batcher to submit SpanBatches to L1.
batcher
:=
NewL2Batcher
(
log
,
sd
.
RollupCfg
,
&
BatcherCfg
{
MinL1TxSize
:
0
,
MaxL1TxSize
:
128
_000
,
BatcherKey
:
dp
.
Secrets
.
Batcher
,
ForceSubmitSpanBatch
:
true
,
},
rollupSeqCl
,
miner
.
EthClient
(),
seqEngine
.
EthClient
(),
seqEngine
.
EngineClient
(
t
,
sd
.
RollupCfg
))
// Alice makes a L2 tx
cl
:=
seqEngine
.
EthClient
()
n
,
err
:=
cl
.
PendingNonceAt
(
t
.
Ctx
(),
dp
.
Addresses
.
Alice
)
require
.
NoError
(
t
,
err
)
signer
:=
types
.
LatestSigner
(
sd
.
L2Cfg
.
Config
)
tx
:=
types
.
MustSignNewTx
(
dp
.
Secrets
.
Alice
,
signer
,
&
types
.
DynamicFeeTx
{
ChainID
:
sd
.
L2Cfg
.
Config
.
ChainID
,
Nonce
:
n
,
GasTipCap
:
big
.
NewInt
(
2
*
params
.
GWei
),
GasFeeCap
:
new
(
big
.
Int
)
.
Add
(
miner
.
l1Chain
.
CurrentBlock
()
.
BaseFee
,
big
.
NewInt
(
2
*
params
.
GWei
)),
Gas
:
params
.
TxGas
,
To
:
&
dp
.
Addresses
.
Bob
,
Value
:
e2eutils
.
Ether
(
2
),
})
require
.
NoError
(
gt
,
cl
.
SendTransaction
(
t
.
Ctx
(),
tx
))
sequencer
.
ActL2PipelineFull
(
t
)
verifier
.
ActL2PipelineFull
(
t
)
miner
.
ActEmptyBlock
(
t
)
sequencer
.
ActL1HeadSignal
(
t
)
// Make a L2 block with the TX
sequencer
.
ActL2StartBlock
(
t
)
seqEngine
.
ActL2IncludeTx
(
dp
.
Addresses
.
Alice
)(
t
)
sequencer
.
ActL2EndBlock
(
t
)
// HF is not activated yet
unsafeOriginNum
:=
new
(
big
.
Int
)
.
SetUint64
(
sequencer
.
L2Unsafe
()
.
L1Origin
.
Number
)
unsafeHeader
,
err
:=
minerCl
.
HeaderByNumber
(
t
.
Ctx
(),
unsafeOriginNum
)
require
.
NoError
(
t
,
err
)
require
.
False
(
t
,
sd
.
RollupCfg
.
IsDelta
(
unsafeHeader
.
Time
))
// Make L2 blocks until the next epoch
sequencer
.
ActBuildToL1Head
(
t
)
// HF is activated for the last unsafe block
unsafeOriginNum
=
new
(
big
.
Int
)
.
SetUint64
(
sequencer
.
L2Unsafe
()
.
L1Origin
.
Number
)
unsafeHeader
,
err
=
minerCl
.
HeaderByNumber
(
t
.
Ctx
(),
unsafeOriginNum
)
require
.
NoError
(
t
,
err
)
require
.
True
(
t
,
sd
.
RollupCfg
.
IsDelta
(
unsafeHeader
.
Time
))
// Batch submit to L1. batcher should submit span batches.
batcher
.
ActSubmitAll
(
t
)
// Confirm batch on L1
miner
.
ActL1StartBlock
(
12
)(
t
)
miner
.
ActL1IncludeTx
(
dp
.
Addresses
.
Batcher
)(
t
)
miner
.
ActL1EndBlock
(
t
)
bl
:=
miner
.
l1Chain
.
CurrentBlock
()
log
.
Info
(
"bl"
,
"txs"
,
len
(
miner
.
l1Chain
.
GetBlockByHash
(
bl
.
Hash
())
.
Transactions
()))
// Now make enough L1 blocks that the verifier will have to derive a L2 block
// It will also eagerly derive the block from the batcher
for
i
:=
uint64
(
0
);
i
<
sd
.
RollupCfg
.
SeqWindowSize
;
i
++
{
miner
.
ActL1StartBlock
(
12
)(
t
)
miner
.
ActL1EndBlock
(
t
)
}
// Try to sync verifier from L1 batch. but verifier should drop every span batch.
verifier
.
ActL1HeadSignal
(
t
)
verifier
.
ActL2PipelineFull
(
t
)
require
.
Equal
(
t
,
uint64
(
2
),
verifier
.
SyncStatus
()
.
SafeL2
.
L1Origin
.
Number
)
verifCl
:=
verifEngine
.
EthClient
()
for
i
:=
int64
(
1
);
i
<
int64
(
verifier
.
L2Safe
()
.
Number
);
i
++
{
block
,
_
:=
verifCl
.
BlockByNumber
(
t
.
Ctx
(),
big
.
NewInt
(
i
))
require
.
NoError
(
t
,
err
)
// Because verifier drops every span batch, it should generate empty blocks.
// So every block has only L1 attribute deposit transaction.
require
.
Equal
(
t
,
block
.
Transactions
()
.
Len
(),
1
)
}
// Check that the tx from alice is not included in verifier's chain
_
,
_
,
err
=
verifCl
.
TransactionByHash
(
t
.
Ctx
(),
tx
.
Hash
())
require
.
ErrorIs
(
t
,
err
,
ethereum
.
NotFound
)
}
// TestAcceptSingularBatchAfterHardfork tests behavior of op-node after Delta hardfork.
// TestAcceptSingularBatchAfterHardfork tests behavior of op-node after Delta hardfork.
// op-node must accept SingularBatch after Delta hardfork.
// op-node must accept SingularBatch after Delta hardfork.
func
TestAcceptSingularBatchAfterHardfork
(
gt
*
testing
.
T
)
{
func
TestAcceptSingularBatchAfterHardfork
(
gt
*
testing
.
T
)
{
...
@@ -133,17 +237,14 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) {
...
@@ -133,17 +237,14 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) {
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
miner
,
seqEngine
,
sequencer
:=
setupSequencerTest
(
t
,
sd
,
log
)
miner
,
seqEngine
,
sequencer
:=
setupSequencerTest
(
t
,
sd
,
log
)
verifEngine
,
verifier
:=
setupVerifier
(
t
,
sd
,
log
,
miner
.
L1Client
(
t
,
sd
.
RollupCfg
),
&
sync
.
Config
{})
verifEngine
,
verifier
:=
setupVerifier
(
t
,
sd
,
log
,
miner
.
L1Client
(
t
,
sd
.
RollupCfg
),
&
sync
.
Config
{})
rollupSeqCl
:=
sequencer
.
RollupClient
()
rollupSeqCl
:=
sequencer
.
RollupClient
()
dp2
:=
e2eutils
.
MakeDeployParams
(
t
,
p
)
// not activate Delta hardfork for batcher
// Force batcher to submit SingularBatches to L1.
dp2
.
DeployConfig
.
L2GenesisDeltaTimeOffset
=
nil
batcher
:=
NewL2Batcher
(
log
,
sd
.
RollupCfg
,
&
BatcherCfg
{
sd2
:=
e2eutils
.
Setup
(
t
,
dp2
,
defaultAlloc
)
batcher
:=
NewL2Batcher
(
log
,
sd2
.
RollupCfg
,
&
BatcherCfg
{
MinL1TxSize
:
0
,
MinL1TxSize
:
0
,
MaxL1TxSize
:
128
_000
,
MaxL1TxSize
:
128
_000
,
BatcherKey
:
dp
.
Secrets
.
Batcher
,
BatcherKey
:
dp
.
Secrets
.
Batcher
,
ForceSubmitSingularBatch
:
true
,
},
rollupSeqCl
,
miner
.
EthClient
(),
seqEngine
.
EthClient
(),
seqEngine
.
EngineClient
(
t
,
sd
.
RollupCfg
))
},
rollupSeqCl
,
miner
.
EthClient
(),
seqEngine
.
EthClient
(),
seqEngine
.
EngineClient
(
t
,
sd
.
RollupCfg
))
// Alice makes a L2 tx
// Alice makes a L2 tx
...
@@ -202,6 +303,97 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) {
...
@@ -202,6 +303,97 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) {
require
.
NotNil
(
t
,
vTx
)
require
.
NotNil
(
t
,
vTx
)
}
}
// TestMixOfBatchesAfterHardfork tests behavior of op-node after Delta hardfork.
// op-node must accept SingularBatch and SpanBatch in sequence.
func
TestMixOfBatchesAfterHardfork
(
gt
*
testing
.
T
)
{
t
:=
NewDefaultTesting
(
gt
)
p
:=
&
e2eutils
.
TestParams
{
MaxSequencerDrift
:
20
,
// larger than L1 block time we simulate in this test (12)
SequencerWindowSize
:
24
,
ChannelTimeout
:
20
,
L1BlockTime
:
12
,
}
minTs
:=
hexutil
.
Uint64
(
0
)
dp
:=
e2eutils
.
MakeDeployParams
(
t
,
p
)
// Activate Delta hardfork for verifier.
dp
.
DeployConfig
.
L2GenesisDeltaTimeOffset
=
&
minTs
sd
:=
e2eutils
.
Setup
(
t
,
dp
,
defaultAlloc
)
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
miner
,
seqEngine
,
sequencer
:=
setupSequencerTest
(
t
,
sd
,
log
)
verifEngine
,
verifier
:=
setupVerifier
(
t
,
sd
,
log
,
miner
.
L1Client
(
t
,
sd
.
RollupCfg
),
&
sync
.
Config
{})
rollupSeqCl
:=
sequencer
.
RollupClient
()
seqEngCl
:=
seqEngine
.
EthClient
()
sequencer
.
ActL2PipelineFull
(
t
)
verifier
.
ActL2PipelineFull
(
t
)
miner
.
ActEmptyBlock
(
t
)
var
txHashes
[
4
]
common
.
Hash
for
i
:=
0
;
i
<
4
;
i
++
{
// Alice makes a L2 tx
n
,
err
:=
seqEngCl
.
PendingNonceAt
(
t
.
Ctx
(),
dp
.
Addresses
.
Alice
)
require
.
NoError
(
t
,
err
)
signer
:=
types
.
LatestSigner
(
sd
.
L2Cfg
.
Config
)
tx
:=
types
.
MustSignNewTx
(
dp
.
Secrets
.
Alice
,
signer
,
&
types
.
DynamicFeeTx
{
ChainID
:
sd
.
L2Cfg
.
Config
.
ChainID
,
Nonce
:
n
,
GasTipCap
:
big
.
NewInt
(
2
*
params
.
GWei
),
GasFeeCap
:
new
(
big
.
Int
)
.
Add
(
miner
.
l1Chain
.
CurrentBlock
()
.
BaseFee
,
big
.
NewInt
(
2
*
params
.
GWei
)),
Gas
:
params
.
TxGas
,
To
:
&
dp
.
Addresses
.
Bob
,
Value
:
e2eutils
.
Ether
(
2
),
})
require
.
NoError
(
gt
,
seqEngCl
.
SendTransaction
(
t
.
Ctx
(),
tx
))
txHashes
[
i
]
=
tx
.
Hash
()
// Make L2 block
sequencer
.
ActL1HeadSignal
(
t
)
sequencer
.
ActL2StartBlock
(
t
)
seqEngine
.
ActL2IncludeTx
(
dp
.
Addresses
.
Alice
)(
t
)
sequencer
.
ActL2EndBlock
(
t
)
sequencer
.
ActBuildToL1Head
(
t
)
// Select batcher mode
batcherCfg
:=
BatcherCfg
{
MinL1TxSize
:
0
,
MaxL1TxSize
:
128
_000
,
BatcherKey
:
dp
.
Secrets
.
Batcher
,
ForceSubmitSpanBatch
:
i
%
2
==
0
,
// Submit SpanBatch for odd numbered batches
ForceSubmitSingularBatch
:
i
%
2
==
1
,
// Submit SingularBatch for even numbered batches
}
batcher
:=
NewL2Batcher
(
log
,
sd
.
RollupCfg
,
&
batcherCfg
,
rollupSeqCl
,
miner
.
EthClient
(),
seqEngine
.
EthClient
(),
seqEngine
.
EngineClient
(
t
,
sd
.
RollupCfg
))
// Submit all new blocks
batcher
.
ActSubmitAll
(
t
)
// Confirm batch on L1
miner
.
ActL1StartBlock
(
12
)(
t
)
miner
.
ActL1IncludeTx
(
dp
.
Addresses
.
Batcher
)(
t
)
miner
.
ActL1EndBlock
(
t
)
}
// Now make enough L1 blocks that the verifier will have to derive a L2 block
// It will also eagerly derive the block from the batcher
for
i
:=
uint64
(
0
);
i
<
sd
.
RollupCfg
.
SeqWindowSize
;
i
++
{
miner
.
ActL1StartBlock
(
12
)(
t
)
miner
.
ActL1EndBlock
(
t
)
}
// Sync verifier from L1 batch in otherwise empty sequence window
verifier
.
ActL1HeadSignal
(
t
)
verifier
.
ActL2PipelineFull
(
t
)
require
.
Equal
(
t
,
uint64
(
5
),
verifier
.
SyncStatus
()
.
SafeL2
.
L1Origin
.
Number
)
// Check that the tx from alice made it into the L2 chain
verifCl
:=
verifEngine
.
EthClient
()
for
_
,
txHash
:=
range
txHashes
{
vTx
,
isPending
,
err
:=
verifCl
.
TransactionByHash
(
t
.
Ctx
(),
txHash
)
require
.
NoError
(
t
,
err
)
require
.
False
(
t
,
isPending
)
require
.
NotNil
(
t
,
vTx
)
}
}
// TestSpanBatchEmptyChain tests derivation of empty chain using SpanBatch.
// TestSpanBatchEmptyChain tests derivation of empty chain using SpanBatch.
func
TestSpanBatchEmptyChain
(
gt
*
testing
.
T
)
{
func
TestSpanBatchEmptyChain
(
gt
*
testing
.
T
)
{
t
:=
NewDefaultTesting
(
gt
)
t
:=
NewDefaultTesting
(
gt
)
...
@@ -231,25 +423,34 @@ func TestSpanBatchEmptyChain(gt *testing.T) {
...
@@ -231,25 +423,34 @@ func TestSpanBatchEmptyChain(gt *testing.T) {
verifier
.
ActL2PipelineFull
(
t
)
verifier
.
ActL2PipelineFull
(
t
)
miner
.
ActEmptyBlock
(
t
)
miner
.
ActEmptyBlock
(
t
)
sequencer
.
ActL1HeadSignal
(
t
)
// Make 1200 empty L2 blocks (L1BlockTime / L2BlockTime * 100)
// Make 1200 empty L2 blocks (L1BlockTime / L2BlockTime * 100)
for
i
:=
0
;
i
<
100
;
i
++
{
for
i
:=
0
;
i
<
100
;
i
++
{
sequencer
.
ActL1HeadSignal
(
t
)
sequencer
.
ActBuildToL1Head
(
t
)
sequencer
.
ActBuildToL1Head
(
t
)
if
i
%
10
==
9
{
if
i
%
10
==
9
{
// batch submit to L1
// batch submit to L1
batcher
.
ActSubmitAll
(
t
)
batcher
.
ActSubmitAll
(
t
)
// Since the unsafe head could be changed due to the reorg during derivation, save the current unsafe head.
unsafeHead
:=
sequencer
.
L2Unsafe
()
.
ID
()
// confirm batch on L1
// confirm batch on L1
miner
.
ActL1StartBlock
(
12
)(
t
)
miner
.
ActL1StartBlock
(
12
)(
t
)
miner
.
ActL1IncludeTx
(
dp
.
Addresses
.
Batcher
)(
t
)
miner
.
ActL1IncludeTx
(
dp
.
Addresses
.
Batcher
)(
t
)
miner
.
ActL1EndBlock
(
t
)
miner
.
ActL1EndBlock
(
t
)
sequencer
.
ActL1HeadSignal
(
t
)
sequencer
.
ActL2PipelineFull
(
t
)
// After derivation pipeline, the safe head must be same as latest unsafe head
// i.e. There must be no reorg during derivation pipeline.
require
.
Equal
(
t
,
sequencer
.
L2Safe
()
.
ID
(),
unsafeHead
)
}
else
{
}
else
{
miner
.
ActEmptyBlock
(
t
)
miner
.
ActEmptyBlock
(
t
)
sequencer
.
ActL1HeadSignal
(
t
)
}
}
}
}
sequencer
.
ActL1HeadSignal
(
t
)
sequencer
.
ActL2PipelineFull
(
t
)
verifier
.
ActL1HeadSignal
(
t
)
verifier
.
ActL1HeadSignal
(
t
)
verifier
.
ActL2PipelineFull
(
t
)
verifier
.
ActL2PipelineFull
(
t
)
...
@@ -308,9 +509,7 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) {
...
@@ -308,9 +509,7 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) {
totalTxCount
:=
0
totalTxCount
:=
0
// Make 600 L2 blocks (L1BlockTime / L2BlockTime * 50) including 1~3 txs
// Make 600 L2 blocks (L1BlockTime / L2BlockTime * 50) including 1~3 txs
for
i
:=
0
;
i
<
50
;
i
++
{
for
i
:=
0
;
i
<
50
;
i
++
{
sequencer
.
ActL1HeadSignal
(
t
)
for
sequencer
.
derivation
.
UnsafeL2Head
()
.
L1Origin
.
Number
<
sequencer
.
l1State
.
L1Head
()
.
Number
{
for
sequencer
.
derivation
.
UnsafeL2Head
()
.
L1Origin
.
Number
<
sequencer
.
l1State
.
L1Head
()
.
Number
{
sequencer
.
ActL2PipelineFull
(
t
)
sequencer
.
ActL2StartBlock
(
t
)
sequencer
.
ActL2StartBlock
(
t
)
// fill the block with random number of L2 txs
// fill the block with random number of L2 txs
for
j
:=
0
;
j
<
rand
.
Intn
(
3
);
j
++
{
for
j
:=
0
;
j
<
rand
.
Intn
(
3
);
j
++
{
...
@@ -345,16 +544,25 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) {
...
@@ -345,16 +544,25 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) {
// batch submit to L1
// batch submit to L1
batcher
.
ActSubmitAll
(
t
)
batcher
.
ActSubmitAll
(
t
)
// Since the unsafe head could be changed due to the reorg during derivation, save the current unsafe head.
unsafeHead
:=
sequencer
.
L2Unsafe
()
.
ID
()
// confirm batch on L1
// confirm batch on L1
miner
.
ActL1StartBlock
(
12
)(
t
)
miner
.
ActL1StartBlock
(
12
)(
t
)
miner
.
ActL1IncludeTx
(
dp
.
Addresses
.
Batcher
)(
t
)
miner
.
ActL1IncludeTx
(
dp
.
Addresses
.
Batcher
)(
t
)
miner
.
ActL1EndBlock
(
t
)
miner
.
ActL1EndBlock
(
t
)
sequencer
.
ActL1HeadSignal
(
t
)
sequencer
.
ActL2PipelineFull
(
t
)
// After derivation pipeline, the safe head must be same as latest unsafe head
// i.e. There must be no reorg during derivation pipeline.
require
.
Equal
(
t
,
sequencer
.
L2Safe
()
.
ID
(),
unsafeHead
)
}
else
{
}
else
{
miner
.
ActEmptyBlock
(
t
)
miner
.
ActEmptyBlock
(
t
)
sequencer
.
ActL1HeadSignal
(
t
)
}
}
}
}
sequencer
.
ActL1HeadSignal
(
t
)
sequencer
.
ActL2PipelineFull
(
t
)
verifier
.
ActL1HeadSignal
(
t
)
verifier
.
ActL1HeadSignal
(
t
)
verifier
.
ActL2PipelineFull
(
t
)
verifier
.
ActL2PipelineFull
(
t
)
...
@@ -363,3 +571,141 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) {
...
@@ -363,3 +571,141 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) {
require
.
Equal
(
t
,
verifier
.
L2Unsafe
(),
verifier
.
L2Safe
())
require
.
Equal
(
t
,
verifier
.
L2Unsafe
(),
verifier
.
L2Safe
())
require
.
Equal
(
t
,
sequencer
.
L2Safe
(),
verifier
.
L2Safe
())
require
.
Equal
(
t
,
sequencer
.
L2Safe
(),
verifier
.
L2Safe
())
}
}
func
TestBatchEquivalence
(
gt
*
testing
.
T
)
{
t
:=
NewDefaultTesting
(
gt
)
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
p
:=
&
e2eutils
.
TestParams
{
MaxSequencerDrift
:
20
,
// larger than L1 block time we simulate in this test (12)
SequencerWindowSize
:
24
,
ChannelTimeout
:
20
,
L1BlockTime
:
12
,
}
// Delta activated deploy config
dp
:=
e2eutils
.
MakeDeployParams
(
t
,
p
)
minTs
:=
hexutil
.
Uint64
(
0
)
dp
.
DeployConfig
.
L2GenesisDeltaTimeOffset
=
&
minTs
sdDeltaActivated
:=
e2eutils
.
Setup
(
t
,
dp
,
defaultAlloc
)
// Delta deactivated deploy config
rcfg
:=
*
sdDeltaActivated
.
RollupCfg
rcfg
.
DeltaTime
=
nil
sdDeltaDeactivated
:=
&
e2eutils
.
SetupData
{
L1Cfg
:
sdDeltaActivated
.
L1Cfg
,
L2Cfg
:
sdDeltaActivated
.
L2Cfg
,
RollupCfg
:
&
rcfg
,
DeploymentsL1
:
sdDeltaActivated
.
DeploymentsL1
,
}
// Setup sequencer
miner
,
seqEngine
,
sequencer
:=
setupSequencerTest
(
t
,
sdDeltaActivated
,
log
)
rollupSeqCl
:=
sequencer
.
RollupClient
()
seqEngCl
:=
seqEngine
.
EthClient
()
// Setup Delta activated spanVerifier
_
,
spanVerifier
:=
setupVerifier
(
t
,
sdDeltaActivated
,
log
,
miner
.
L1Client
(
t
,
sdDeltaActivated
.
RollupCfg
),
&
sync
.
Config
{})
// Setup Delta deactivated spanVerifier
_
,
singularVerifier
:=
setupVerifier
(
t
,
sdDeltaDeactivated
,
log
,
miner
.
L1Client
(
t
,
sdDeltaDeactivated
.
RollupCfg
),
&
sync
.
Config
{})
// Setup SpanBatcher
spanBatcher
:=
NewL2Batcher
(
log
,
sdDeltaActivated
.
RollupCfg
,
&
BatcherCfg
{
MinL1TxSize
:
0
,
MaxL1TxSize
:
128
_000
,
BatcherKey
:
dp
.
Secrets
.
Batcher
,
ForceSubmitSpanBatch
:
true
,
},
rollupSeqCl
,
miner
.
EthClient
(),
seqEngine
.
EthClient
(),
seqEngine
.
EngineClient
(
t
,
sdDeltaActivated
.
RollupCfg
))
// Setup SingularBatcher
singularBatcher
:=
NewL2Batcher
(
log
,
sdDeltaDeactivated
.
RollupCfg
,
&
BatcherCfg
{
MinL1TxSize
:
0
,
MaxL1TxSize
:
128
_000
,
BatcherKey
:
dp
.
Secrets
.
Batcher
,
ForceSubmitSingularBatch
:
true
,
},
rollupSeqCl
,
miner
.
EthClient
(),
seqEngine
.
EthClient
(),
seqEngine
.
EngineClient
(
t
,
sdDeltaDeactivated
.
RollupCfg
))
const
numTestUsers
=
5
var
privKeys
[
numTestUsers
]
*
ecdsa
.
PrivateKey
var
addrs
[
numTestUsers
]
common
.
Address
for
i
:=
0
;
i
<
numTestUsers
;
i
++
{
// Create a new test account
privateKey
,
err
:=
dp
.
Secrets
.
Wallet
.
PrivateKey
(
accounts
.
Account
{
URL
:
accounts
.
URL
{
Path
:
fmt
.
Sprintf
(
"m/44'/60'/0'/0/%d"
,
10
+
i
),
},
})
privKeys
[
i
]
=
privateKey
addr
:=
crypto
.
PubkeyToAddress
(
privateKey
.
PublicKey
)
require
.
NoError
(
t
,
err
)
addrs
[
i
]
=
addr
}
miner
.
ActEmptyBlock
(
t
)
sequencer
.
ActL1HeadSignal
(
t
)
sequencer
.
ActL2PipelineFull
(
t
)
totalTxCount
:=
0
// Build random blocks
for
sequencer
.
derivation
.
UnsafeL2Head
()
.
L1Origin
.
Number
<
sequencer
.
l1State
.
L1Head
()
.
Number
{
sequencer
.
ActL2StartBlock
(
t
)
// fill the block with random number of L2 txs
for
j
:=
0
;
j
<
rand
.
Intn
(
3
);
j
++
{
userIdx
:=
totalTxCount
%
numTestUsers
signer
:=
types
.
LatestSigner
(
sdDeltaActivated
.
L2Cfg
.
Config
)
data
:=
make
([]
byte
,
rand
.
Intn
(
100
))
_
,
err
:=
crand
.
Read
(
data
[
:
])
// fill with random bytes
require
.
NoError
(
t
,
err
)
gas
,
err
:=
core
.
IntrinsicGas
(
data
,
nil
,
false
,
true
,
true
,
false
)
require
.
NoError
(
t
,
err
)
baseFee
:=
seqEngine
.
l2Chain
.
CurrentBlock
()
.
BaseFee
nonce
,
err
:=
seqEngCl
.
PendingNonceAt
(
t
.
Ctx
(),
addrs
[
userIdx
])
require
.
NoError
(
t
,
err
)
tx
:=
types
.
MustSignNewTx
(
privKeys
[
userIdx
],
signer
,
&
types
.
DynamicFeeTx
{
ChainID
:
sdDeltaActivated
.
L2Cfg
.
Config
.
ChainID
,
Nonce
:
nonce
,
GasTipCap
:
big
.
NewInt
(
2
*
params
.
GWei
),
GasFeeCap
:
new
(
big
.
Int
)
.
Add
(
new
(
big
.
Int
)
.
Mul
(
baseFee
,
big
.
NewInt
(
2
)),
big
.
NewInt
(
2
*
params
.
GWei
)),
Gas
:
gas
,
To
:
&
dp
.
Addresses
.
Bob
,
Value
:
big
.
NewInt
(
0
),
Data
:
data
,
})
require
.
NoError
(
gt
,
seqEngCl
.
SendTransaction
(
t
.
Ctx
(),
tx
))
seqEngine
.
ActL2IncludeTx
(
addrs
[
userIdx
])(
t
)
totalTxCount
+=
1
}
sequencer
.
ActL2EndBlock
(
t
)
}
// Submit SpanBatch
spanBatcher
.
ActSubmitAll
(
t
)
miner
.
ActL1StartBlock
(
12
)(
t
)
miner
.
ActL1IncludeTx
(
dp
.
Addresses
.
Batcher
)(
t
)
miner
.
ActL1EndBlock
(
t
)
// Run derivation pipeline for verifiers
spanVerifier
.
ActL1HeadSignal
(
t
)
spanVerifier
.
ActL2PipelineFull
(
t
)
singularVerifier
.
ActL1HeadSignal
(
t
)
singularVerifier
.
ActL2PipelineFull
(
t
)
// Delta activated spanVerifier must be synced
require
.
Equal
(
t
,
spanVerifier
.
L2Safe
(),
sequencer
.
L2Unsafe
())
// Delta deactivated spanVerifier could not derive SpanBatch
require
.
Equal
(
t
,
singularVerifier
.
L2Safe
()
.
Number
,
uint64
(
0
))
// Submit SingularBatches
singularBatcher
.
ActSubmitAll
(
t
)
miner
.
ActL1StartBlock
(
12
)(
t
)
miner
.
ActL1IncludeTx
(
dp
.
Addresses
.
Batcher
)(
t
)
miner
.
ActL1EndBlock
(
t
)
// Run derivation pipeline for verifiers
spanVerifier
.
ActL1HeadSignal
(
t
)
spanVerifier
.
ActL2PipelineFull
(
t
)
singularVerifier
.
ActL1HeadSignal
(
t
)
singularVerifier
.
ActL2PipelineFull
(
t
)
// Delta deactivated spanVerifier must be synced
require
.
Equal
(
t
,
spanVerifier
.
L2Safe
(),
singularVerifier
.
L2Safe
())
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment