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
e85c4837
Unverified
Commit
e85c4837
authored
Jun 29, 2023
by
Adrian Sutton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
op-e2e: Simplify and correct wait period when finalizing withdrawals.
parent
69ba4ea1
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
72 additions
and
78 deletions
+72
-78
waits.go
op-e2e/e2eutils/waits.go
+21
-0
system_tob_test.go
op-e2e/system_tob_test.go
+2
-2
withdrawal_helper.go
op-e2e/withdrawal_helper.go
+4
-3
utils.go
op-node/withdrawals/utils.go
+45
-73
No files found.
op-e2e/e2eutils/waits.go
View file @
e85c4837
...
@@ -78,3 +78,24 @@ func WaitFor(ctx context.Context, rate time.Duration, cb func() (bool, error)) e
...
@@ -78,3 +78,24 @@ func WaitFor(ctx context.Context, rate time.Duration, cb func() (bool, error)) e
}
}
}
}
}
}
func
WaitAndGet
[
T
interface
{}](
ctx
context
.
Context
,
pollRate
time
.
Duration
,
get
func
()
(
T
,
error
),
predicate
func
(
T
)
bool
)
(
T
,
error
)
{
tick
:=
time
.
NewTicker
(
pollRate
)
defer
tick
.
Stop
()
var
nilT
T
for
{
select
{
case
<-
ctx
.
Done
()
:
return
nilT
,
ctx
.
Err
()
case
<-
tick
.
C
:
val
,
err
:=
get
()
if
err
!=
nil
{
return
nilT
,
err
}
if
predicate
(
val
)
{
return
val
,
nil
}
}
}
}
op-e2e/system_tob_test.go
View file @
e85c4837
...
@@ -511,7 +511,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
...
@@ -511,7 +511,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
// Wait for the finalization period, then we can finalize this withdrawal.
// Wait for the finalization period, then we can finalize this withdrawal.
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
40
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
40
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
blockNumber
,
err
:=
withdrawals
.
WaitFor
FinalizationPerio
d
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
receipt
.
BlockNumber
)
blockNumber
,
err
:=
withdrawals
.
WaitFor
OutputRootPublishe
d
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
receipt
.
BlockNumber
)
cancel
()
cancel
()
require
.
Nil
(
t
,
err
)
require
.
Nil
(
t
,
err
)
...
@@ -642,7 +642,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
...
@@ -642,7 +642,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
// Wait for finalization and then create the Finalized Withdrawal Transaction
// Wait for finalization and then create the Finalized Withdrawal Transaction
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
45
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
45
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
defer
cancel
()
defer
cancel
()
_
,
err
=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
header
.
Number
)
err
=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
header
.
Number
)
require
.
Nil
(
t
,
err
)
require
.
Nil
(
t
,
err
)
// Finalize withdrawal
// Finalize withdrawal
...
...
op-e2e/withdrawal_helper.go
View file @
e85c4837
...
@@ -79,7 +79,7 @@ func defaultWithdrawalTxOpts() *WithdrawalTxOpts {
...
@@ -79,7 +79,7 @@ func defaultWithdrawalTxOpts() *WithdrawalTxOpts {
func
ProveAndFinalizeWithdrawal
(
t
*
testing
.
T
,
cfg
SystemConfig
,
l1Client
*
ethclient
.
Client
,
l2Node
*
node
.
Node
,
ethPrivKey
*
ecdsa
.
PrivateKey
,
l2WithdrawalReceipt
*
types
.
Receipt
)
(
*
types
.
Receipt
,
*
types
.
Receipt
)
{
func
ProveAndFinalizeWithdrawal
(
t
*
testing
.
T
,
cfg
SystemConfig
,
l1Client
*
ethclient
.
Client
,
l2Node
*
node
.
Node
,
ethPrivKey
*
ecdsa
.
PrivateKey
,
l2WithdrawalReceipt
*
types
.
Receipt
)
(
*
types
.
Receipt
,
*
types
.
Receipt
)
{
params
,
proveReceipt
:=
ProveWithdrawal
(
t
,
cfg
,
l1Client
,
l2Node
,
ethPrivKey
,
l2WithdrawalReceipt
)
params
,
proveReceipt
:=
ProveWithdrawal
(
t
,
cfg
,
l1Client
,
l2Node
,
ethPrivKey
,
l2WithdrawalReceipt
)
finalizeReceipt
:=
FinalizeWithdrawal
(
t
,
cfg
,
l1Client
,
ethPrivKey
,
l2Withdrawal
Receipt
,
params
)
finalizeReceipt
:=
FinalizeWithdrawal
(
t
,
cfg
,
l1Client
,
ethPrivKey
,
prove
Receipt
,
params
)
return
proveReceipt
,
finalizeReceipt
return
proveReceipt
,
finalizeReceipt
}
}
...
@@ -87,7 +87,8 @@ func ProveWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client,
...
@@ -87,7 +87,8 @@ func ProveWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client,
// Get l2BlockNumber for proof generation
// Get l2BlockNumber for proof generation
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
40
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
40
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
defer
cancel
()
defer
cancel
()
blockNumber
,
err
:=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
l2WithdrawalReceipt
.
BlockNumber
)
blockNumber
,
err
:=
withdrawals
.
WaitForOutputRootPublished
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
l2WithdrawalReceipt
.
BlockNumber
)
require
.
Nil
(
t
,
err
)
require
.
Nil
(
t
,
err
)
rpcClient
,
err
:=
rpc
.
Dial
(
l2Node
.
WSEndpoint
())
rpcClient
,
err
:=
rpc
.
Dial
(
l2Node
.
WSEndpoint
())
...
@@ -142,7 +143,7 @@ func FinalizeWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Clie
...
@@ -142,7 +143,7 @@ func FinalizeWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Clie
// Wait for finalization and then create the Finalized Withdrawal Transaction
// Wait for finalization and then create the Finalized Withdrawal Transaction
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
30
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
30
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
defer
cancel
()
defer
cancel
()
_
,
err
:=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
withdrawalReceipt
.
BlockNumber
)
err
:=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
withdrawalReceipt
.
BlockNumber
)
require
.
Nil
(
t
,
err
)
require
.
Nil
(
t
,
err
)
opts
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
privKey
,
cfg
.
L1ChainIDBig
())
opts
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
privKey
,
cfg
.
L1ChainIDBig
())
...
...
op-node/withdrawals/utils.go
View file @
e85c4837
...
@@ -8,6 +8,7 @@ import (
...
@@ -8,6 +8,7 @@ import (
"math/big"
"math/big"
"time"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
...
@@ -22,103 +23,74 @@ import (
...
@@ -22,103 +23,74 @@ import (
var
MessagePassedTopic
=
crypto
.
Keccak256Hash
([]
byte
(
"MessagePassed(uint256,address,address,uint256,uint256,bytes,bytes32)"
))
var
MessagePassedTopic
=
crypto
.
Keccak256Hash
([]
byte
(
"MessagePassed(uint256,address,address,uint256,uint256,bytes,bytes32)"
))
// WaitForFinalizationPeriod waits until there is OutputProof for an L2 block number larger than the supplied l2BlockNumber
// WaitForOutputRootPublished waits until there is an output published for an L2 block number larger than the supplied l2BlockNumber
// and that the output is finalized.
// This function polls and can block for a very long time if used on mainnet.
// This functions polls and can block for a very long time if used on mainnet.
// This returns the block number to use for proof generation.
// This returns the block number to use for the proof generation.
func
WaitForOutputRootPublished
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
portalAddr
common
.
Address
,
l2BlockNumber
*
big
.
Int
)
(
uint64
,
error
)
{
func
WaitForFinalizationPeriod
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
portalAddr
common
.
Address
,
l2BlockNumber
*
big
.
Int
)
(
uint64
,
error
)
{
l2BlockNumber
=
new
(
big
.
Int
)
.
Set
(
l2BlockNumber
)
// Don't clobber caller owned l2BlockNumber
l2BlockNumber
=
new
(
big
.
Int
)
.
Set
(
l2BlockNumber
)
// Don't clobber caller owned l2BlockNumber
opts
:=
&
bind
.
CallOpts
{
Context
:
ctx
}
opts
:=
&
bind
.
CallOpts
{
Context
:
ctx
}
portal
,
err
:=
bindings
.
NewOptimismPortalCaller
(
portalAddr
,
client
)
l2OO
,
err
:=
createL2OOCaller
(
ctx
,
client
,
portalAddr
)
if
err
!=
nil
{
return
0
,
err
}
l2OOAddress
,
err
:=
portal
.
L2ORACLE
(
opts
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
0
,
err
}
}
l2OO
,
err
:=
bindings
.
NewL2OutputOracleCaller
(
l2OOAddress
,
client
)
if
err
!=
nil
{
return
0
,
err
}
submissionInterval
,
err
:=
l2OO
.
SUBMISSIONINTERVAL
(
opts
)
if
err
!=
nil
{
return
0
,
err
}
// Convert blockNumber to submission interval boundary
rem
:=
new
(
big
.
Int
)
l2BlockNumber
,
rem
=
l2BlockNumber
.
DivMod
(
l2BlockNumber
,
submissionInterval
,
rem
)
if
rem
.
Cmp
(
common
.
Big0
)
!=
0
{
l2BlockNumber
=
l2BlockNumber
.
Add
(
l2BlockNumber
,
common
.
Big1
)
}
l2BlockNumber
=
l2BlockNumber
.
Mul
(
l2BlockNumber
,
submissionInterval
)
finalizationPeriod
,
err
:=
l2OO
.
FINALIZATIONPERIODSECONDS
(
opts
)
getL2BlockFromLatestOutput
:=
func
()
(
*
big
.
Int
,
error
)
{
return
l2OO
.
LatestBlockNumber
(
opts
)
}
if
err
!=
nil
{
outputBlockNum
,
err
:=
e2eutils
.
WaitAndGet
[
*
big
.
Int
](
ctx
,
time
.
Second
,
getL2BlockFromLatestOutput
,
func
(
latest
*
big
.
Int
)
bool
{
return
0
,
err
return
latest
.
Cmp
(
l2BlockNumber
)
>=
0
}
})
latest
,
err
:=
l2OO
.
LatestBlockNumber
(
opts
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
0
,
err
}
}
return
outputBlockNum
.
Uint64
(),
nil
}
// Now poll for the output to be submitted on chain
// WaitForFinalizationPeriod waits until the L1 chain has progressed far enough that l1ProvingBlockNum has completed
var
ticker
*
time
.
Ticker
// the finalization period.
diff
:=
new
(
big
.
Int
)
.
Sub
(
l2BlockNumber
,
latest
)
// This functions polls and can block for a very long time if used on mainnet.
if
diff
.
Cmp
(
big
.
NewInt
(
10
))
>
0
{
func
WaitForFinalizationPeriod
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
portalAddr
common
.
Address
,
l1ProvingBlockNum
*
big
.
Int
)
error
{
ticker
=
time
.
NewTicker
(
time
.
Minute
)
l1ProvingBlockNum
=
new
(
big
.
Int
)
.
Set
(
l1ProvingBlockNum
)
// Don't clobber caller owned l1ProvingBlockNum
}
else
{
opts
:=
&
bind
.
CallOpts
{
Context
:
ctx
}
ticker
=
time
.
NewTicker
(
time
.
Second
)
}
loop
:
// Load finalization period
for
{
l2OO
,
err
:=
createL2OOCaller
(
ctx
,
client
,
portalAddr
)
select
{
case
<-
ticker
.
C
:
latest
,
err
=
l2OO
.
LatestBlockNumber
(
opts
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
fmt
.
Errorf
(
"create L2OOCaller: %w"
,
err
)
}
// Already passed the submitted block (likely just equals rather than >= here).
if
latest
.
Cmp
(
l2BlockNumber
)
>=
0
{
break
loop
}
case
<-
ctx
.
Done
()
:
return
0
,
ctx
.
Err
()
}
}
finalizationPeriod
,
err
:=
l2OO
.
FINALIZATIONPERIODSECONDS
(
opts
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"get finalization period: %w"
,
err
)
}
}
// Now wait for it to be finalized
provingHeader
,
err
:=
client
.
HeaderByNumber
(
ctx
,
l1ProvingBlockNum
)
output
,
err
:=
l2OO
.
GetL2OutputAfter
(
opts
,
l2BlockNumber
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
fmt
.
Errorf
(
"retrieve proving header: %w"
,
err
)
}
if
output
.
OutputRoot
==
[
32
]
byte
{}
{
return
0
,
errors
.
New
(
"empty output root. likely no proposal at timestamp"
)
}
}
targetTimestamp
:=
new
(
big
.
Int
)
.
Add
(
output
.
Timestamp
,
finalizationPeriod
)
targetTimestamp
:=
new
(
big
.
Int
)
.
Add
(
new
(
big
.
Int
)
.
SetUint64
(
provingHeader
.
Time
),
finalizationPeriod
)
targetTime
:=
time
.
Unix
(
targetTimestamp
.
Int64
(),
0
)
targetTime
:=
time
.
Unix
(
targetTimestamp
.
Int64
(),
0
)
// Assume clock is relatively correct
// Assume clock is relatively correct
time
.
Sleep
(
time
.
Until
(
targetTime
))
time
.
Sleep
(
time
.
Until
(
targetTime
))
// Poll for L1 Block to have a time greater than the target time
// Poll for L1 Block to have a time greater than the target time
ticker
=
time
.
NewTicker
(
time
.
Second
)
return
e2eutils
.
WaitFor
(
ctx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
for
{
select
{
case
<-
ticker
.
C
:
header
,
err
:=
client
.
HeaderByNumber
(
ctx
,
nil
)
header
,
err
:=
client
.
HeaderByNumber
(
ctx
,
nil
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
false
,
fmt
.
Errorf
(
"retrieve latest header: %w"
,
err
)
}
if
header
.
Time
>
targetTimestamp
.
Uint64
()
{
return
l2BlockNumber
.
Uint64
(),
nil
}
}
case
<-
ctx
.
Done
()
:
return
header
.
Time
>
targetTimestamp
.
Uint64
(),
nil
return
0
,
ctx
.
Err
()
})
}
func
createL2OOCaller
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
portalAddr
common
.
Address
)
(
*
bindings
.
L2OutputOracleCaller
,
error
)
{
portal
,
err
:=
bindings
.
NewOptimismPortalCaller
(
portalAddr
,
client
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"create OptimismPortalCaller: %w"
,
err
)
}
}
l2OOAddress
,
err
:=
portal
.
L2ORACLE
(
&
bind
.
CallOpts
{
Context
:
ctx
})
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"create L2ORACLE: %w"
,
err
)
}
}
return
bindings
.
NewL2OutputOracleCaller
(
l2OOAddress
,
client
)
}
}
type
ProofClient
interface
{
type
ProofClient
interface
{
...
...
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