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
bf9146b2
Unverified
Commit
bf9146b2
authored
Mar 16, 2023
by
mergify[bot]
Committed by
GitHub
Mar 16, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5146 from ethereum-optimism/refcell/batcher/manager/tests
feat(op-batcher): Channel Manager Tests
parents
26bf70ca
f460748c
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
265 additions
and
7 deletions
+265
-7
channel_manager_test.go
op-batcher/batcher/channel_manager_test.go
+265
-7
No files found.
op-batcher/batcher/channel_manager_test.go
View file @
bf9146b2
package
batcher
_test
package
batcher
import
(
import
(
"io"
"io"
...
@@ -7,7 +7,6 @@ import (
...
@@ -7,7 +7,6 @@ import (
"testing"
"testing"
"time"
"time"
"github.com/ethereum-optimism/optimism/op-batcher/batcher"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
derivetest
"github.com/ethereum-optimism/optimism/op-node/rollup/derive/test"
derivetest
"github.com/ethereum-optimism/optimism/op-node/rollup/derive/test"
...
@@ -19,11 +18,56 @@ import (
...
@@ -19,11 +18,56 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
// TestPendingChannelTimeout tests that the channel manager
// correctly identifies when a pending channel is timed out.
func
TestPendingChannelTimeout
(
t
*
testing
.
T
)
{
// Create a new channel manager with a ChannelTimeout
log
:=
testlog
.
Logger
(
t
,
log
.
LvlCrit
)
m
:=
NewChannelManager
(
log
,
ChannelConfig
{
ChannelTimeout
:
100
,
})
// Pending channel is nil so is cannot be timed out
timeout
:=
m
.
pendingChannelIsTimedOut
()
require
.
False
(
t
,
timeout
)
// Set the pending channel
err
:=
m
.
ensurePendingChannel
(
eth
.
BlockID
{})
require
.
NoError
(
t
,
err
)
// There are no confirmed transactions so
// the pending channel cannot be timed out
timeout
=
m
.
pendingChannelIsTimedOut
()
require
.
False
(
t
,
timeout
)
// Manually set a confirmed transactions
// To avoid other methods clearing state
m
.
confirmedTransactions
[
frameID
{
frameNumber
:
0
}]
=
eth
.
BlockID
{
Number
:
0
}
m
.
confirmedTransactions
[
frameID
{
frameNumber
:
1
}]
=
eth
.
BlockID
{
Number
:
99
}
// Since the ChannelTimeout is 100, the
// pending channel should not be timed out
timeout
=
m
.
pendingChannelIsTimedOut
()
require
.
False
(
t
,
timeout
)
// Add a confirmed transaction with a higher number
// than the ChannelTimeout
m
.
confirmedTransactions
[
frameID
{
frameNumber
:
2
,
}]
=
eth
.
BlockID
{
Number
:
101
,
}
// Now the pending channel should be timed out
timeout
=
m
.
pendingChannelIsTimedOut
()
require
.
True
(
t
,
timeout
)
}
// TestChannelManagerReturnsErrReorg ensures that the channel manager
// TestChannelManagerReturnsErrReorg ensures that the channel manager
// detects a reorg when it has cached L1 blocks.
// detects a reorg when it has cached L1 blocks.
func
TestChannelManagerReturnsErrReorg
(
t
*
testing
.
T
)
{
func
TestChannelManagerReturnsErrReorg
(
t
*
testing
.
T
)
{
log
:=
testlog
.
Logger
(
t
,
log
.
LvlCrit
)
log
:=
testlog
.
Logger
(
t
,
log
.
LvlCrit
)
m
:=
batcher
.
NewChannelManager
(
log
,
batcher
.
ChannelConfig
{})
m
:=
NewChannelManager
(
log
,
ChannelConfig
{})
a
:=
types
.
NewBlock
(
&
types
.
Header
{
a
:=
types
.
NewBlock
(
&
types
.
Header
{
Number
:
big
.
NewInt
(
0
),
Number
:
big
.
NewInt
(
0
),
...
@@ -48,14 +92,16 @@ func TestChannelManagerReturnsErrReorg(t *testing.T) {
...
@@ -48,14 +92,16 @@ func TestChannelManagerReturnsErrReorg(t *testing.T) {
err
=
m
.
AddL2Block
(
c
)
err
=
m
.
AddL2Block
(
c
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
err
=
m
.
AddL2Block
(
x
)
err
=
m
.
AddL2Block
(
x
)
require
.
ErrorIs
(
t
,
err
,
batcher
.
ErrReorg
)
require
.
ErrorIs
(
t
,
err
,
ErrReorg
)
require
.
Equal
(
t
,
[]
*
types
.
Block
{
a
,
b
,
c
},
m
.
blocks
)
}
}
// TestChannelManagerReturnsErrReorgWhenDrained ensures that the channel manager
// TestChannelManagerReturnsErrReorgWhenDrained ensures that the channel manager
// detects a reorg even if it does not have any blocks inside it.
// detects a reorg even if it does not have any blocks inside it.
func
TestChannelManagerReturnsErrReorgWhenDrained
(
t
*
testing
.
T
)
{
func
TestChannelManagerReturnsErrReorgWhenDrained
(
t
*
testing
.
T
)
{
log
:=
testlog
.
Logger
(
t
,
log
.
LvlCrit
)
log
:=
testlog
.
Logger
(
t
,
log
.
LvlCrit
)
m
:=
batcher
.
NewChannelManager
(
log
,
batcher
.
ChannelConfig
{
m
:=
NewChannelManager
(
log
,
ChannelConfig
{
TargetFrameSize
:
0
,
TargetFrameSize
:
0
,
MaxFrameSize
:
120
_000
,
MaxFrameSize
:
120
_000
,
ApproxComprRatio
:
1.0
,
ApproxComprRatio
:
1.0
,
...
@@ -86,14 +132,226 @@ func TestChannelManagerReturnsErrReorgWhenDrained(t *testing.T) {
...
@@ -86,14 +132,226 @@ func TestChannelManagerReturnsErrReorgWhenDrained(t *testing.T) {
require
.
ErrorIs
(
t
,
err
,
io
.
EOF
)
require
.
ErrorIs
(
t
,
err
,
io
.
EOF
)
err
=
m
.
AddL2Block
(
x
)
err
=
m
.
AddL2Block
(
x
)
require
.
ErrorIs
(
t
,
err
,
batcher
.
ErrReorg
)
require
.
ErrorIs
(
t
,
err
,
ErrReorg
)
}
// TestChannelManagerNextTxData checks the nextTxData function.
func
TestChannelManagerNextTxData
(
t
*
testing
.
T
)
{
log
:=
testlog
.
Logger
(
t
,
log
.
LvlCrit
)
m
:=
NewChannelManager
(
log
,
ChannelConfig
{})
// Nil pending channel should return EOF
returnedTxData
,
err
:=
m
.
nextTxData
()
require
.
ErrorIs
(
t
,
err
,
io
.
EOF
)
require
.
Equal
(
t
,
txData
{},
returnedTxData
)
// Set the pending channel
// The nextTxData function should still return EOF
// since the pending channel has no frames
err
=
m
.
ensurePendingChannel
(
eth
.
BlockID
{})
require
.
NoError
(
t
,
err
)
returnedTxData
,
err
=
m
.
nextTxData
()
require
.
ErrorIs
(
t
,
err
,
io
.
EOF
)
require
.
Equal
(
t
,
txData
{},
returnedTxData
)
// Manually push a frame into the pending channel
channelID
:=
m
.
pendingChannel
.
ID
()
frame
:=
frameData
{
data
:
[]
byte
{},
id
:
frameID
{
chID
:
channelID
,
frameNumber
:
uint16
(
0
),
},
}
m
.
pendingChannel
.
PushFrame
(
frame
)
require
.
Equal
(
t
,
1
,
m
.
pendingChannel
.
NumFrames
())
// Now the nextTxData function should return the frame
returnedTxData
,
err
=
m
.
nextTxData
()
expectedTxData
:=
txData
{
frame
}
expectedChannelID
:=
expectedTxData
.
ID
()
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expectedTxData
,
returnedTxData
)
require
.
Equal
(
t
,
0
,
m
.
pendingChannel
.
NumFrames
())
require
.
Equal
(
t
,
expectedTxData
,
m
.
pendingTransactions
[
expectedChannelID
])
}
// TestClearChannelManager tests clearing the channel manager.
func
TestClearChannelManager
(
t
*
testing
.
T
)
{
// Create a channel manager
log
:=
testlog
.
Logger
(
t
,
log
.
LvlCrit
)
rng
:=
rand
.
New
(
rand
.
NewSource
(
time
.
Now
()
.
UnixNano
()))
m
:=
NewChannelManager
(
log
,
ChannelConfig
{
// Need to set the channel timeout here so we don't clear pending
// channels on confirmation. This would result in [TxConfirmed]
// clearing confirmed transactions, and reseting the pendingChannels map
ChannelTimeout
:
10
,
// Have to set the max frame size here otherwise the channel builder would not
// be able to output any frames
MaxFrameSize
:
1
,
})
// Channel Manager state should be empty by default
require
.
Empty
(
t
,
m
.
blocks
)
require
.
Equal
(
t
,
common
.
Hash
{},
m
.
tip
)
require
.
Nil
(
t
,
m
.
pendingChannel
)
require
.
Empty
(
t
,
m
.
pendingTransactions
)
require
.
Empty
(
t
,
m
.
confirmedTransactions
)
// Add a block to the channel manager
a
,
_
:=
derivetest
.
RandomL2Block
(
rng
,
4
)
newL1Tip
:=
a
.
Hash
()
l1BlockID
:=
eth
.
BlockID
{
Hash
:
a
.
Hash
(),
Number
:
a
.
NumberU64
(),
}
err
:=
m
.
AddL2Block
(
a
)
require
.
NoError
(
t
,
err
)
// Make sure there is a channel builder
err
=
m
.
ensurePendingChannel
(
l1BlockID
)
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
m
.
pendingChannel
)
require
.
Equal
(
t
,
0
,
len
(
m
.
confirmedTransactions
))
// Process the blocks
// We should have a pending channel with 1 frame
// and no more blocks since processBlocks consumes
// the list
err
=
m
.
processBlocks
()
require
.
NoError
(
t
,
err
)
err
=
m
.
pendingChannel
.
OutputFrames
()
require
.
NoError
(
t
,
err
)
_
,
err
=
m
.
nextTxData
()
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
0
,
len
(
m
.
blocks
))
require
.
Equal
(
t
,
newL1Tip
,
m
.
tip
)
require
.
Equal
(
t
,
1
,
len
(
m
.
pendingTransactions
))
// Add a new block so we can test clearing
// the channel manager with a full state
b
:=
types
.
NewBlock
(
&
types
.
Header
{
Number
:
big
.
NewInt
(
1
),
ParentHash
:
a
.
Hash
(),
},
nil
,
nil
,
nil
,
nil
)
err
=
m
.
AddL2Block
(
b
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
1
,
len
(
m
.
blocks
))
require
.
Equal
(
t
,
b
.
Hash
(),
m
.
tip
)
// Clear the channel manager
m
.
Clear
()
// Check that the entire channel manager state cleared
require
.
Empty
(
t
,
m
.
blocks
)
require
.
Equal
(
t
,
common
.
Hash
{},
m
.
tip
)
require
.
Nil
(
t
,
m
.
pendingChannel
)
require
.
Empty
(
t
,
m
.
pendingTransactions
)
require
.
Empty
(
t
,
m
.
confirmedTransactions
)
}
// TestChannelManagerTxConfirmed checks the [ChannelManager.TxConfirmed] function.
func
TestChannelManagerTxConfirmed
(
t
*
testing
.
T
)
{
// Create a channel manager
log
:=
testlog
.
Logger
(
t
,
log
.
LvlCrit
)
m
:=
NewChannelManager
(
log
,
ChannelConfig
{
// Need to set the channel timeout here so we don't clear pending
// channels on confirmation. This would result in [TxConfirmed]
// clearing confirmed transactions, and reseting the pendingChannels map
ChannelTimeout
:
10
,
})
// Let's add a valid pending transaction to the channel manager
// So we can demonstrate that TxConfirmed's correctness
err
:=
m
.
ensurePendingChannel
(
eth
.
BlockID
{})
require
.
NoError
(
t
,
err
)
channelID
:=
m
.
pendingChannel
.
ID
()
frame
:=
frameData
{
data
:
[]
byte
{},
id
:
frameID
{
chID
:
channelID
,
frameNumber
:
uint16
(
0
),
},
}
m
.
pendingChannel
.
PushFrame
(
frame
)
require
.
Equal
(
t
,
1
,
m
.
pendingChannel
.
NumFrames
())
returnedTxData
,
err
:=
m
.
nextTxData
()
expectedTxData
:=
txData
{
frame
}
expectedChannelID
:=
expectedTxData
.
ID
()
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expectedTxData
,
returnedTxData
)
require
.
Equal
(
t
,
0
,
m
.
pendingChannel
.
NumFrames
())
require
.
Equal
(
t
,
expectedTxData
,
m
.
pendingTransactions
[
expectedChannelID
])
require
.
Equal
(
t
,
1
,
len
(
m
.
pendingTransactions
))
// An unknown pending transaction should not be marked as confirmed
// and should not be removed from the pending transactions map
actualChannelID
:=
m
.
pendingChannel
.
ID
()
unknownChannelID
:=
derive
.
ChannelID
([
derive
.
ChannelIDLength
]
byte
{
0x69
})
require
.
NotEqual
(
t
,
actualChannelID
,
unknownChannelID
)
unknownTxID
:=
frameID
{
chID
:
unknownChannelID
,
frameNumber
:
0
}
blockID
:=
eth
.
BlockID
{
Number
:
0
,
Hash
:
common
.
Hash
{
0x69
}}
m
.
TxConfirmed
(
unknownTxID
,
blockID
)
require
.
Empty
(
t
,
m
.
confirmedTransactions
)
require
.
Equal
(
t
,
1
,
len
(
m
.
pendingTransactions
))
// Now let's mark the pending transaction as confirmed
// and check that it is removed from the pending transactions map
// and added to the confirmed transactions map
m
.
TxConfirmed
(
expectedChannelID
,
blockID
)
require
.
Empty
(
t
,
m
.
pendingTransactions
)
require
.
Equal
(
t
,
1
,
len
(
m
.
confirmedTransactions
))
require
.
Equal
(
t
,
blockID
,
m
.
confirmedTransactions
[
expectedChannelID
])
}
// TestChannelManagerTxFailed checks the [ChannelManager.TxFailed] function.
func
TestChannelManagerTxFailed
(
t
*
testing
.
T
)
{
// Create a channel manager
log
:=
testlog
.
Logger
(
t
,
log
.
LvlCrit
)
m
:=
NewChannelManager
(
log
,
ChannelConfig
{})
// Let's add a valid pending transaction to the channel
// manager so we can demonstrate correctness
err
:=
m
.
ensurePendingChannel
(
eth
.
BlockID
{})
require
.
NoError
(
t
,
err
)
channelID
:=
m
.
pendingChannel
.
ID
()
frame
:=
frameData
{
data
:
[]
byte
{},
id
:
frameID
{
chID
:
channelID
,
frameNumber
:
uint16
(
0
),
},
}
m
.
pendingChannel
.
PushFrame
(
frame
)
require
.
Equal
(
t
,
1
,
m
.
pendingChannel
.
NumFrames
())
returnedTxData
,
err
:=
m
.
nextTxData
()
expectedTxData
:=
txData
{
frame
}
expectedChannelID
:=
expectedTxData
.
ID
()
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expectedTxData
,
returnedTxData
)
require
.
Equal
(
t
,
0
,
m
.
pendingChannel
.
NumFrames
())
require
.
Equal
(
t
,
expectedTxData
,
m
.
pendingTransactions
[
expectedChannelID
])
require
.
Equal
(
t
,
1
,
len
(
m
.
pendingTransactions
))
// Trying to mark an unknown pending transaction as failed
// shouldn't modify state
m
.
TxFailed
(
frameID
{})
require
.
Equal
(
t
,
0
,
m
.
pendingChannel
.
NumFrames
())
require
.
Equal
(
t
,
expectedTxData
,
m
.
pendingTransactions
[
expectedChannelID
])
// Now we still have a pending transaction
// Let's mark it as failed
m
.
TxFailed
(
expectedChannelID
)
require
.
Empty
(
t
,
m
.
pendingTransactions
)
// There should be a frame in the pending channel now
require
.
Equal
(
t
,
1
,
m
.
pendingChannel
.
NumFrames
())
}
}
func
TestChannelManager_TxResend
(
t
*
testing
.
T
)
{
func
TestChannelManager_TxResend
(
t
*
testing
.
T
)
{
require
:=
require
.
New
(
t
)
require
:=
require
.
New
(
t
)
rng
:=
rand
.
New
(
rand
.
NewSource
(
time
.
Now
()
.
UnixNano
()))
rng
:=
rand
.
New
(
rand
.
NewSource
(
time
.
Now
()
.
UnixNano
()))
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
m
:=
batcher
.
NewChannelManager
(
log
,
batcher
.
ChannelConfig
{
m
:=
NewChannelManager
(
log
,
ChannelConfig
{
TargetFrameSize
:
0
,
TargetFrameSize
:
0
,
MaxFrameSize
:
120
_000
,
MaxFrameSize
:
120
_000
,
ApproxComprRatio
:
1.0
,
ApproxComprRatio
:
1.0
,
...
...
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