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
a1371125
Unverified
Commit
a1371125
authored
Jun 30, 2023
by
mergify[bot]
Committed by
GitHub
Jun 30, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into aj/report-hive-tests
parents
6f51ab6d
c264ed2f
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
207 additions
and
112 deletions
+207
-112
config.yml
.circleci/config.yml
+4
-0
canonicalize.go
op-bindings/ast/canonicalize.go
+6
-2
faultdisputegame.go
op-bindings/bindings/faultdisputegame.go
+2
-2
faultdisputegame_more.go
op-bindings/bindings/faultdisputegame_more.go
+2
-2
l2outputoracle_more.go
op-bindings/bindings/l2outputoracle_more.go
+1
-1
optimismportal_more.go
op-bindings/bindings/optimismportal_more.go
+1
-1
systemconfig_more.go
op-bindings/bindings/systemconfig_more.go
+1
-1
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
.gas-snapshot
packages/contracts-bedrock/.gas-snapshot
+17
-15
FaultDisputeGame.sol
.../contracts-bedrock/contracts/dispute/FaultDisputeGame.sol
+21
-8
DisputeErrors.sol
...s/contracts-bedrock/contracts/libraries/DisputeErrors.sol
+3
-0
FaultDisputeGame.t.sol
...s/contracts-bedrock/contracts/test/FaultDisputeGame.t.sol
+77
-2
No files found.
.circleci/config.yml
View file @
a1371125
...
...
@@ -685,6 +685,10 @@ jobs:
image
:
ubuntu-2204:2022.07.1
steps
:
-
checkout
-
run
:
name
:
Install pnpm package manager
command
:
|
npm i pnpm --global
-
run
:
name
:
Lint check
command
:
|
...
...
op-bindings/ast/canonicalize.go
View file @
a1371125
...
...
@@ -10,6 +10,7 @@ import (
)
var
remapTypeRe
=
regexp
.
MustCompile
(
`^(t_[\w_]+\([\w]+\))([\d]+)(_[\w]+)?$`
)
var
remapAstIdStorage
=
regexp
.
MustCompile
(
`(t_(struct|userDefinedValueType))\(([\w]+)\)([\d]+)_storage`
)
// typeRemapping represents a mapping between an a type generated by solc
// and a canonicalized type. This is because solc inserts the ast id into
...
...
@@ -63,8 +64,11 @@ func CanonicalizeASTIDs(in *solc.StorageLayout) *solc.StorageLayout {
// The storage types include the size when its a fixed size.
// This is subject to breaking in the future if a type with
// an ast id is added in a fixed storage type
if
strings
.
Contains
(
oldType
,
"storage"
)
{
// an ast id is added in a fixed storage type. We don't want
// to skip a type with `_storage` in it if it has a subtype
// with an ast id or it has an astid itself.
skip
:=
len
(
remapAstIdStorage
.
FindAllStringSubmatch
(
oldType
,
-
1
))
==
0
if
strings
.
Contains
(
oldType
,
"storage"
)
&&
skip
{
continue
}
...
...
op-bindings/bindings/faultdisputegame.go
View file @
a1371125
This diff is collapsed.
Click to expand it.
op-bindings/bindings/faultdisputegame_more.go
View file @
a1371125
This diff is collapsed.
Click to expand it.
op-bindings/bindings/l2outputoracle_more.go
View file @
a1371125
...
...
@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const
L2OutputOracleStorageLayoutJSON
=
"{
\"
storage
\"
:[{
\"
astId
\"
:1000,
\"
contract
\"
:
\"
contracts/L1/L2OutputOracle.sol:L2OutputOracle
\"
,
\"
label
\"
:
\"
_initialized
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_uint8
\"
},{
\"
astId
\"
:1001,
\"
contract
\"
:
\"
contracts/L1/L2OutputOracle.sol:L2OutputOracle
\"
,
\"
label
\"
:
\"
_initializing
\"
,
\"
offset
\"
:1,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_bool
\"
},{
\"
astId
\"
:1002,
\"
contract
\"
:
\"
contracts/L1/L2OutputOracle.sol:L2OutputOracle
\"
,
\"
label
\"
:
\"
startingBlockNumber
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
1
\"
,
\"
type
\"
:
\"
t_uint256
\"
},{
\"
astId
\"
:1003,
\"
contract
\"
:
\"
contracts/L1/L2OutputOracle.sol:L2OutputOracle
\"
,
\"
label
\"
:
\"
startingTimestamp
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
2
\"
,
\"
type
\"
:
\"
t_uint256
\"
},{
\"
astId
\"
:1004,
\"
contract
\"
:
\"
contracts/L1/L2OutputOracle.sol:L2OutputOracle
\"
,
\"
label
\"
:
\"
l2Outputs
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
3
\"
,
\"
type
\"
:
\"
t_array(t_struct(OutputProposal)
42701_storage)dyn_storage
\"
}],
\"
types
\"
:{
\"
t_array(t_struct(OutputProposal)42701_storage)dyn_storage
\"
:{
\"
encoding
\"
:
\"
dynamic_array
\"
,
\"
label
\"
:
\"
struct Types.OutputProposal[]
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
base
\"
:
\"
t_struct(OutputProposal)42701_storage
\"
},
\"
t_bool
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bool
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
},
\"
t_bytes32
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bytes32
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_struct(OutputProposal)42701
_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct Types.OutputProposal
\"
,
\"
numberOfBytes
\"
:
\"
64
\"
},
\"
t_uint128
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint128
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_uint256
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint8
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint8
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
}}}"
const
L2OutputOracleStorageLayoutJSON
=
"{
\"
storage
\"
:[{
\"
astId
\"
:1000,
\"
contract
\"
:
\"
contracts/L1/L2OutputOracle.sol:L2OutputOracle
\"
,
\"
label
\"
:
\"
_initialized
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_uint8
\"
},{
\"
astId
\"
:1001,
\"
contract
\"
:
\"
contracts/L1/L2OutputOracle.sol:L2OutputOracle
\"
,
\"
label
\"
:
\"
_initializing
\"
,
\"
offset
\"
:1,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_bool
\"
},{
\"
astId
\"
:1002,
\"
contract
\"
:
\"
contracts/L1/L2OutputOracle.sol:L2OutputOracle
\"
,
\"
label
\"
:
\"
startingBlockNumber
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
1
\"
,
\"
type
\"
:
\"
t_uint256
\"
},{
\"
astId
\"
:1003,
\"
contract
\"
:
\"
contracts/L1/L2OutputOracle.sol:L2OutputOracle
\"
,
\"
label
\"
:
\"
startingTimestamp
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
2
\"
,
\"
type
\"
:
\"
t_uint256
\"
},{
\"
astId
\"
:1004,
\"
contract
\"
:
\"
contracts/L1/L2OutputOracle.sol:L2OutputOracle
\"
,
\"
label
\"
:
\"
l2Outputs
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
3
\"
,
\"
type
\"
:
\"
t_array(t_struct(OutputProposal)
1005_storage)dyn_storage
\"
}],
\"
types
\"
:{
\"
t_array(t_struct(OutputProposal)1005_storage)dyn_storage
\"
:{
\"
encoding
\"
:
\"
dynamic_array
\"
,
\"
label
\"
:
\"
struct Types.OutputProposal[]
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
base
\"
:
\"
t_struct(OutputProposal)1005_storage
\"
},
\"
t_bool
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bool
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
},
\"
t_bytes32
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bytes32
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_struct(OutputProposal)1005
_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct Types.OutputProposal
\"
,
\"
numberOfBytes
\"
:
\"
64
\"
},
\"
t_uint128
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint128
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_uint256
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint8
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint8
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
}}}"
var
L2OutputOracleStorageLayout
=
new
(
solc
.
StorageLayout
)
...
...
op-bindings/bindings/optimismportal_more.go
View file @
a1371125
...
...
@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const
OptimismPortalStorageLayoutJSON
=
"{
\"
storage
\"
:[{
\"
astId
\"
:1000,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
_initialized
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_uint8
\"
},{
\"
astId
\"
:1001,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
_initializing
\"
,
\"
offset
\"
:1,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_bool
\"
},{
\"
astId
\"
:1002,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
params
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
1
\"
,
\"
type
\"
:
\"
t_struct(ResourceParams)
34941_storage
\"
},{
\"
astId
\"
:1003,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
__gap
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
2
\"
,
\"
type
\"
:
\"
t_array(t_uint256)48_storage
\"
},{
\"
astId
\"
:1004,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
l2Sender
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
50
\"
,
\"
type
\"
:
\"
t_address
\"
},{
\"
astId
\"
:1005,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
finalizedWithdrawals
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
51
\"
,
\"
type
\"
:
\"
t_mapping(t_bytes32,t_bool)
\"
},{
\"
astId
\"
:1006,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
provenWithdrawals
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
52
\"
,
\"
type
\"
:
\"
t_mapping(t_bytes32,t_struct(ProvenWithdrawal)34280_storage)
\"
},{
\"
astId
\"
:1007,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
paused
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
53
\"
,
\"
type
\"
:
\"
t_bool
\"
}],
\"
types
\"
:{
\"
t_address
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
address
\"
,
\"
numberOfBytes
\"
:
\"
20
\"
},
\"
t_array(t_uint256)48_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256[48]
\"
,
\"
numberOfBytes
\"
:
\"
1536
\"
,
\"
base
\"
:
\"
t_uint256
\"
},
\"
t_bool
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bool
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
},
\"
t_bytes32
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bytes32
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_mapping(t_bytes32,t_bool)
\"
:{
\"
encoding
\"
:
\"
mapping
\"
,
\"
label
\"
:
\"
mapping(bytes32 =
\u003e
bool)
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
key
\"
:
\"
t_bytes32
\"
,
\"
value
\"
:
\"
t_bool
\"
},
\"
t_mapping(t_bytes32,t_struct(ProvenWithdrawal)34280_storage)
\"
:{
\"
encoding
\"
:
\"
mapping
\"
,
\"
label
\"
:
\"
mapping(bytes32 =
\u003e
struct OptimismPortal.ProvenWithdrawal)
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
key
\"
:
\"
t_bytes32
\"
,
\"
value
\"
:
\"
t_struct(ProvenWithdrawal)34280_storage
\"
},
\"
t_struct(ProvenWithdrawal)34280_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct OptimismPortal.ProvenWithdrawal
\"
,
\"
numberOfBytes
\"
:
\"
64
\"
},
\"
t_struct(ResourceParams)34941
_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct ResourceMetering.ResourceParams
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint128
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint128
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_uint256
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint64
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint64
\"
,
\"
numberOfBytes
\"
:
\"
8
\"
},
\"
t_uint8
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint8
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
}}}"
const
OptimismPortalStorageLayoutJSON
=
"{
\"
storage
\"
:[{
\"
astId
\"
:1000,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
_initialized
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_uint8
\"
},{
\"
astId
\"
:1001,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
_initializing
\"
,
\"
offset
\"
:1,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_bool
\"
},{
\"
astId
\"
:1002,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
params
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
1
\"
,
\"
type
\"
:
\"
t_struct(ResourceParams)
1009_storage
\"
},{
\"
astId
\"
:1003,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
__gap
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
2
\"
,
\"
type
\"
:
\"
t_array(t_uint256)48_storage
\"
},{
\"
astId
\"
:1004,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
l2Sender
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
50
\"
,
\"
type
\"
:
\"
t_address
\"
},{
\"
astId
\"
:1005,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
finalizedWithdrawals
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
51
\"
,
\"
type
\"
:
\"
t_mapping(t_bytes32,t_bool)
\"
},{
\"
astId
\"
:1006,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
provenWithdrawals
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
52
\"
,
\"
type
\"
:
\"
t_mapping(t_bytes32,t_struct(ProvenWithdrawal)1008_storage)
\"
},{
\"
astId
\"
:1007,
\"
contract
\"
:
\"
contracts/L1/OptimismPortal.sol:OptimismPortal
\"
,
\"
label
\"
:
\"
paused
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
53
\"
,
\"
type
\"
:
\"
t_bool
\"
}],
\"
types
\"
:{
\"
t_address
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
address
\"
,
\"
numberOfBytes
\"
:
\"
20
\"
},
\"
t_array(t_uint256)48_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256[48]
\"
,
\"
numberOfBytes
\"
:
\"
1536
\"
,
\"
base
\"
:
\"
t_uint256
\"
},
\"
t_bool
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bool
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
},
\"
t_bytes32
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bytes32
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_mapping(t_bytes32,t_bool)
\"
:{
\"
encoding
\"
:
\"
mapping
\"
,
\"
label
\"
:
\"
mapping(bytes32 =
\u003e
bool)
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
key
\"
:
\"
t_bytes32
\"
,
\"
value
\"
:
\"
t_bool
\"
},
\"
t_mapping(t_bytes32,t_struct(ProvenWithdrawal)1008_storage)
\"
:{
\"
encoding
\"
:
\"
mapping
\"
,
\"
label
\"
:
\"
mapping(bytes32 =
\u003e
struct OptimismPortal.ProvenWithdrawal)
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
key
\"
:
\"
t_bytes32
\"
,
\"
value
\"
:
\"
t_struct(ProvenWithdrawal)1008_storage
\"
},
\"
t_struct(ProvenWithdrawal)1008_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct OptimismPortal.ProvenWithdrawal
\"
,
\"
numberOfBytes
\"
:
\"
64
\"
},
\"
t_struct(ResourceParams)1009
_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct ResourceMetering.ResourceParams
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint128
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint128
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_uint256
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint64
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint64
\"
,
\"
numberOfBytes
\"
:
\"
8
\"
},
\"
t_uint8
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint8
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
}}}"
var
OptimismPortalStorageLayout
=
new
(
solc
.
StorageLayout
)
...
...
op-bindings/bindings/systemconfig_more.go
View file @
a1371125
...
...
@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const
SystemConfigStorageLayoutJSON
=
"{
\"
storage
\"
:[{
\"
astId
\"
:1000,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
_initialized
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_uint8
\"
},{
\"
astId
\"
:1001,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
_initializing
\"
,
\"
offset
\"
:1,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_bool
\"
},{
\"
astId
\"
:1002,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
__gap
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
1
\"
,
\"
type
\"
:
\"
t_array(t_uint256)50_storage
\"
},{
\"
astId
\"
:1003,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
_owner
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
51
\"
,
\"
type
\"
:
\"
t_address
\"
},{
\"
astId
\"
:1004,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
__gap
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
52
\"
,
\"
type
\"
:
\"
t_array(t_uint256)49_storage
\"
},{
\"
astId
\"
:1005,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
overhead
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
101
\"
,
\"
type
\"
:
\"
t_uint256
\"
},{
\"
astId
\"
:1006,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
scalar
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
102
\"
,
\"
type
\"
:
\"
t_uint256
\"
},{
\"
astId
\"
:1007,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
batcherHash
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
103
\"
,
\"
type
\"
:
\"
t_bytes32
\"
},{
\"
astId
\"
:1008,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
gasLimit
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
104
\"
,
\"
type
\"
:
\"
t_uint64
\"
},{
\"
astId
\"
:1009,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
_resourceConfig
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
105
\"
,
\"
type
\"
:
\"
t_struct(ResourceConfig)
34954_storage
\"
}],
\"
types
\"
:{
\"
t_address
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
address
\"
,
\"
numberOfBytes
\"
:
\"
20
\"
},
\"
t_array(t_uint256)49_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256[49]
\"
,
\"
numberOfBytes
\"
:
\"
1568
\"
,
\"
base
\"
:
\"
t_uint256
\"
},
\"
t_array(t_uint256)50_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256[50]
\"
,
\"
numberOfBytes
\"
:
\"
1600
\"
,
\"
base
\"
:
\"
t_uint256
\"
},
\"
t_bool
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bool
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
},
\"
t_bytes32
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bytes32
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_struct(ResourceConfig)34954
_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct ResourceMetering.ResourceConfig
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint128
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint128
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_uint256
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint32
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint32
\"
,
\"
numberOfBytes
\"
:
\"
4
\"
},
\"
t_uint64
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint64
\"
,
\"
numberOfBytes
\"
:
\"
8
\"
},
\"
t_uint8
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint8
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
}}}"
const
SystemConfigStorageLayoutJSON
=
"{
\"
storage
\"
:[{
\"
astId
\"
:1000,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
_initialized
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_uint8
\"
},{
\"
astId
\"
:1001,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
_initializing
\"
,
\"
offset
\"
:1,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_bool
\"
},{
\"
astId
\"
:1002,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
__gap
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
1
\"
,
\"
type
\"
:
\"
t_array(t_uint256)50_storage
\"
},{
\"
astId
\"
:1003,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
_owner
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
51
\"
,
\"
type
\"
:
\"
t_address
\"
},{
\"
astId
\"
:1004,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
__gap
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
52
\"
,
\"
type
\"
:
\"
t_array(t_uint256)49_storage
\"
},{
\"
astId
\"
:1005,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
overhead
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
101
\"
,
\"
type
\"
:
\"
t_uint256
\"
},{
\"
astId
\"
:1006,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
scalar
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
102
\"
,
\"
type
\"
:
\"
t_uint256
\"
},{
\"
astId
\"
:1007,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
batcherHash
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
103
\"
,
\"
type
\"
:
\"
t_bytes32
\"
},{
\"
astId
\"
:1008,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
gasLimit
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
104
\"
,
\"
type
\"
:
\"
t_uint64
\"
},{
\"
astId
\"
:1009,
\"
contract
\"
:
\"
contracts/L1/SystemConfig.sol:SystemConfig
\"
,
\"
label
\"
:
\"
_resourceConfig
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
105
\"
,
\"
type
\"
:
\"
t_struct(ResourceConfig)
1010_storage
\"
}],
\"
types
\"
:{
\"
t_address
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
address
\"
,
\"
numberOfBytes
\"
:
\"
20
\"
},
\"
t_array(t_uint256)49_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256[49]
\"
,
\"
numberOfBytes
\"
:
\"
1568
\"
,
\"
base
\"
:
\"
t_uint256
\"
},
\"
t_array(t_uint256)50_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256[50]
\"
,
\"
numberOfBytes
\"
:
\"
1600
\"
,
\"
base
\"
:
\"
t_uint256
\"
},
\"
t_bool
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bool
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
},
\"
t_bytes32
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bytes32
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_struct(ResourceConfig)1010
_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct ResourceMetering.ResourceConfig
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint128
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint128
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_uint256
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint32
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint32
\"
,
\"
numberOfBytes
\"
:
\"
4
\"
},
\"
t_uint64
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint64
\"
,
\"
numberOfBytes
\"
:
\"
8
\"
},
\"
t_uint8
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint8
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
}}}"
var
SystemConfigStorageLayout
=
new
(
solc
.
StorageLayout
)
...
...
op-e2e/e2eutils/waits.go
View file @
a1371125
...
...
@@ -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 @
a1371125
...
...
@@ -511,7 +511,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
// 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
)
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
()
require
.
Nil
(
t
,
err
)
...
...
@@ -642,7 +642,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
// Wait for finalization and then create the Finalized Withdrawal Transaction
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
45
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
defer
cancel
()
_
,
err
=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
header
.
Number
)
err
=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
header
.
Number
)
require
.
Nil
(
t
,
err
)
// Finalize withdrawal
...
...
op-e2e/withdrawal_helper.go
View file @
a1371125
...
...
@@ -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
)
{
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
}
...
...
@@ -87,7 +87,8 @@ func ProveWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client,
// Get l2BlockNumber for proof generation
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
40
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
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
)
rpcClient
,
err
:=
rpc
.
Dial
(
l2Node
.
WSEndpoint
())
...
...
@@ -142,7 +143,7 @@ func FinalizeWithdrawal(t *testing.T, cfg SystemConfig, l1Client *ethclient.Clie
// Wait for finalization and then create the Finalized Withdrawal Transaction
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
30
*
time
.
Duration
(
cfg
.
DeployConfig
.
L1BlockTime
)
*
time
.
Second
)
defer
cancel
()
_
,
err
:=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
withdrawalReceipt
.
BlockNumber
)
err
:=
withdrawals
.
WaitForFinalizationPeriod
(
ctx
,
l1Client
,
predeploys
.
DevOptimismPortalAddr
,
withdrawalReceipt
.
BlockNumber
)
require
.
Nil
(
t
,
err
)
opts
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
privKey
,
cfg
.
L1ChainIDBig
())
...
...
op-node/withdrawals/utils.go
View file @
a1371125
...
...
@@ -8,6 +8,7 @@ import (
"math/big"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
...
...
@@ -22,103 +23,74 @@ import (
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
// and that the output is finalized.
// This functions polls and can block for a very long time if used on mainnet.
// This returns the block number to use for the proof generation.
func
WaitForFinalizationPeriod
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
portalAddr
common
.
Address
,
l2BlockNumber
*
big
.
Int
)
(
uint64
,
error
)
{
// WaitForOutputRootPublished waits until there is an output published for an L2 block number larger than the supplied l2BlockNumber
// This function polls and can block for a very long time if used on mainnet.
// This returns the block number to use for proof generation.
func
WaitForOutputRootPublished
(
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
opts
:=
&
bind
.
CallOpts
{
Context
:
ctx
}
portal
,
err
:=
bindings
.
NewOptimismPortalCaller
(
portalAddr
,
client
)
if
err
!=
nil
{
return
0
,
err
}
l2OOAddress
,
err
:=
portal
.
L2ORACLE
(
opts
)
l2OO
,
err
:=
createL2OOCaller
(
ctx
,
client
,
portalAddr
)
if
err
!=
nil
{
return
0
,
err
}
l2OO
,
err
:=
bindings
.
NewL2OutputOracleCaller
(
l2OOAddress
,
client
)
getL2BlockFromLatestOutput
:=
func
()
(
*
big
.
Int
,
error
)
{
return
l2OO
.
LatestBlockNumber
(
opts
)
}
outputBlockNum
,
err
:=
e2eutils
.
WaitAndGet
[
*
big
.
Int
](
ctx
,
time
.
Second
,
getL2BlockFromLatestOutput
,
func
(
latest
*
big
.
Int
)
bool
{
return
latest
.
Cmp
(
l2BlockNumber
)
>=
0
})
if
err
!=
nil
{
return
0
,
err
}
submissionInterval
,
err
:=
l2OO
.
SUBMISSIONINTERVAL
(
opts
)
return
outputBlockNum
.
Uint64
(),
nil
}
// WaitForFinalizationPeriod waits until the L1 chain has progressed far enough that l1ProvingBlockNum has completed
// the finalization period.
// This functions polls and can block for a very long time if used on mainnet.
func
WaitForFinalizationPeriod
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
portalAddr
common
.
Address
,
l1ProvingBlockNum
*
big
.
Int
)
error
{
l1ProvingBlockNum
=
new
(
big
.
Int
)
.
Set
(
l1ProvingBlockNum
)
// Don't clobber caller owned l1ProvingBlockNum
opts
:=
&
bind
.
CallOpts
{
Context
:
ctx
}
// Load finalization period
l2OO
,
err
:=
createL2OOCaller
(
ctx
,
client
,
portalAddr
)
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
)
return
fmt
.
Errorf
(
"create L2OOCaller: %w"
,
err
)
}
l2BlockNumber
=
l2BlockNumber
.
Mul
(
l2BlockNumber
,
submissionInterval
)
finalizationPeriod
,
err
:=
l2OO
.
FINALIZATIONPERIODSECONDS
(
opts
)
if
err
!=
nil
{
return
0
,
err
return
fmt
.
Errorf
(
"get finalization period: %w"
,
err
)
}
latest
,
err
:=
l2OO
.
LatestBlockNumber
(
opts
)
provingHeader
,
err
:=
client
.
HeaderByNumber
(
ctx
,
l1ProvingBlockNum
)
if
err
!=
nil
{
return
0
,
err
return
fmt
.
Errorf
(
"retrieve proving header: %w"
,
err
)
}
// Now poll for the output to be submitted on chain
var
ticker
*
time
.
Ticker
diff
:=
new
(
big
.
Int
)
.
Sub
(
l2BlockNumber
,
latest
)
if
diff
.
Cmp
(
big
.
NewInt
(
10
))
>
0
{
ticker
=
time
.
NewTicker
(
time
.
Minute
)
}
else
{
ticker
=
time
.
NewTicker
(
time
.
Second
)
}
loop
:
for
{
select
{
case
<-
ticker
.
C
:
latest
,
err
=
l2OO
.
LatestBlockNumber
(
opts
)
if
err
!=
nil
{
return
0
,
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
()
}
}
// Now wait for it to be finalized
output
,
err
:=
l2OO
.
GetL2OutputAfter
(
opts
,
l2BlockNumber
)
if
err
!=
nil
{
return
0
,
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
)
// Assume clock is relatively correct
time
.
Sleep
(
time
.
Until
(
targetTime
))
// Poll for L1 Block to have a time greater than the target time
ticker
=
time
.
NewTicker
(
time
.
Second
)
for
{
select
{
case
<-
ticker
.
C
:
header
,
err
:=
client
.
HeaderByNumber
(
ctx
,
nil
)
if
err
!=
nil
{
return
0
,
err
}
if
header
.
Time
>
targetTimestamp
.
Uint64
()
{
return
l2BlockNumber
.
Uint64
(),
nil
}
case
<-
ctx
.
Done
()
:
return
0
,
ctx
.
Err
()
return
e2eutils
.
WaitFor
(
ctx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
header
,
err
:=
client
.
HeaderByNumber
(
ctx
,
nil
)
if
err
!=
nil
{
return
false
,
fmt
.
Errorf
(
"retrieve latest header: %w"
,
err
)
}
}
return
header
.
Time
>
targetTimestamp
.
Uint64
(),
nil
})
}
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
{
...
...
packages/contracts-bedrock/.gas-snapshot
View file @
a1371125
...
...
@@ -32,30 +32,32 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44243)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 498826)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 500705)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 488169)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 497701)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 499580)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 487044)
FaultDisputeGame_Test:test_defendRoot_invalidMove_reverts() (gas: 13294)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 502174)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 504053)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 491517)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 500937)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 502816)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 490280)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17426)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17917)
FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10315)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8282)
FaultDisputeGame_Test:test_initialRootClaimData_succeeds() (gas: 17691)
FaultDisputeGame_Test:test_initialRootClaimData_succeeds() (gas: 17669)
FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 415981)
FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 26387)
FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13360)
FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 103230)
FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 408100)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 109
23
)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 109
68
)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24655)
FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 221201)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9679)
FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 106068)
FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 23692)
FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 391875)
FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 107344)
FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 224789)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9657)
FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 109754)
FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 21422)
FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 27256)
FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 395447)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8181)
FaultDisputeGame_Test:test_simpleAttack_succeeds() (gas: 107388)
FeeVault_Test:test_constructor_succeeds() (gas: 18185)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352113)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950320)
...
...
packages/contracts-bedrock/contracts/dispute/FaultDisputeGame.sol
View file @
a1371125
...
...
@@ -34,7 +34,6 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
IBigStepper public immutable VM;
/// @notice The duration of the game.
/// @dev TODO: Account for resolution buffer. (?)
Duration internal constant GAME_DURATION = Duration.wrap(7 days);
/// @notice The root claim's position is always at gindex 1.
...
...
@@ -275,10 +274,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @inheritdoc IDisputeGame
function resolve() external returns (GameStatus status_) {
// TODO: Do not allow resolution before clocks run out.
// If the game is not in progress, it cannot be resolved.
if (status != GameStatus.IN_PROGRESS) {
// If the game is not in progress, it cannot be resolved.
revert GameNotInProgress();
}
...
...
@@ -298,7 +295,6 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// If the claim is not a dangling node above the bottom of the tree,
// we can skip over it. These nodes are not relevant to the game resolution.
Position claimPos = claim.position;
if (claim.countered) {
continue;
}
...
...
@@ -306,7 +302,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// If the claim is a dangling node, we can check if it is the left-most
// dangling node we've come across so far. If it is, we can update the
// left-most trace index.
uint256 traceIndex = claim
Pos
.traceIndex(MAX_GAME_DEPTH);
uint256 traceIndex = claim
.position
.traceIndex(MAX_GAME_DEPTH);
if (traceIndex < leftMostTraceIndex) {
leftMostTraceIndex = traceIndex;
unchecked {
...
...
@@ -315,12 +311,29 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
}
}
// Create a reference to the left most uncontested claim and its parent.
ClaimData storage leftMostUncontested = claimData[leftMostIndex];
// If the left most uncontested claim's parent has not expired their clock, the game
// cannot be resolved. If the left most uncontested claim is the root, no nodes qualified,
// and we check if 3.5 days has passed since the root claim's creation.
uint256 parentIndex = leftMostUncontested.parentIndex;
Clock opposingClock = parentIndex == type(uint32).max
? leftMostUncontested.clock
: claimData[parentIndex].clock;
if (
Duration.unwrap(opposingClock.duration()) +
(block.timestamp - Timestamp.unwrap(opposingClock.timestamp())) <=
Duration.unwrap(GAME_DURATION) >> 1
) {
revert ClockNotExpired();
}
// If the left-most dangling node is at an even depth, the defender wins.
// Otherwise, the challenger wins and the root claim is deemed invalid.
if (
// slither-disable-next-line weak-prng
claimData[leftMostIndex].position.depth() % 2 == 0 &&
leftMostTraceIndex != type(uint128).max
leftMostUncontested.position.depth() % 2 == 0 && leftMostTraceIndex != type(uint128).max
) {
status_ = GameStatus.DEFENDER_WINS;
} else {
...
...
packages/contracts-bedrock/contracts/libraries/DisputeErrors.sol
View file @
a1371125
...
...
@@ -39,6 +39,9 @@ error GameNotInProgress();
/// @notice Thrown when a move is attempted to be made after the clock has timed out.
error ClockTimeExceeded();
/// @notice Thrown when the game is attempted to be resolved too early.
error ClockNotExpired();
/// @notice Thrown when a move is attempted to be made at or greater than the max depth of the game.
error GameDepthExceeded();
...
...
packages/contracts-bedrock/contracts/test/FaultDisputeGame.t.sol
View file @
a1371125
...
...
@@ -130,7 +130,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
}
/// @dev Tests that an attempt to defend the root claim reverts with the `CannotDefendRootClaim` error.
function test_
defendRoot_invalidMove
_reverts() public {
function test_
move_defendRoot
_reverts() public {
vm.expectRevert(CannotDefendRootClaim.selector);
gameProxy.defend(0, Claim.wrap(bytes32(uint256(5))));
}
...
...
@@ -175,6 +175,49 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
}
/// @notice Static unit test for the correctness of the chess clock incrementation.
function test_move_clockCorrectness_succeeds() public {
(, , , , Clock clock) = gameProxy.claimData(0);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(0), Timestamp.wrap(uint64(block.timestamp))))
);
Claim claim = Claim.wrap(bytes32(uint256(5)));
vm.warp(block.timestamp + 15);
gameProxy.attack(0, claim);
(, , , , clock) = gameProxy.claimData(1);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(15), Timestamp.wrap(uint64(block.timestamp))))
);
vm.warp(block.timestamp + 10);
gameProxy.attack(1, claim);
(, , , , clock) = gameProxy.claimData(2);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(10), Timestamp.wrap(uint64(block.timestamp))))
);
vm.warp(block.timestamp + 10);
gameProxy.attack(2, claim);
(, , , , clock) = gameProxy.claimData(3);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(25), Timestamp.wrap(uint64(block.timestamp))))
);
vm.warp(block.timestamp + 10);
gameProxy.attack(3, claim);
(, , , , clock) = gameProxy.claimData(4);
assertEq(
Clock.unwrap(clock),
Clock.unwrap(LibClock.wrap(Duration.wrap(20), Timestamp.wrap(uint64(block.timestamp))))
);
}
/// @dev Tests that an identical claim cannot be made twice. The duplicate claim attempt should
/// revert with the `ClaimAlreadyExists` error.
function test_move_duplicateClaim_reverts() public {
...
...
@@ -189,7 +232,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
}
/// @dev Static unit test for the correctness of an opening attack.
function test_simpleAttack_succeeds() public {
function test_
move_
simpleAttack_succeeds() public {
// Warp ahead 5 seconds.
vm.warp(block.timestamp + 5);
...
...
@@ -237,11 +280,19 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Static unit test for the correctness an uncontested root resolution.
function test_resolve_rootUncontested_succeeds() public {
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
GameStatus status = gameProxy.resolve();
assertEq(uint8(status), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS));
}
/// @dev Static unit test for the correctness an uncontested root resolution.
function test_resolve_rootUncontestedClockNotExpired_succeeds() public {
vm.warp(block.timestamp + 3 days + 12 hours);
vm.expectRevert(ClockNotExpired.selector);
gameProxy.resolve();
}
/// @dev Static unit test asserting that resolve reverts when the game state is
/// not in progress.
function test_resolve_notInProgress_reverts() public {
...
...
@@ -263,6 +314,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
function test_resolve_rootContested_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
GameStatus status = gameProxy.resolve();
assertEq(uint8(status), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.CHALLENGER_WINS));
...
...
@@ -273,6 +326,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6))));
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
GameStatus status = gameProxy.resolve();
assertEq(uint8(status), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS));
...
...
@@ -285,6 +340,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6))));
gameProxy.defend(1, Claim.wrap(bytes32(uint256(7))));
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
GameStatus status = gameProxy.resolve();
assertEq(uint8(status), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.CHALLENGER_WINS));
...
...
@@ -499,6 +556,9 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot is OneVsOne_Arena {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
...
...
@@ -517,6 +577,9 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot is OneVsOne_Arena {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
...
...
@@ -535,6 +598,9 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2 is OneVsOne_Arena {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
...
...
@@ -553,6 +619,9 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
...
...
@@ -571,6 +640,9 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3 is OneVsOne_Arena {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
...
...
@@ -589,6 +661,9 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot3 is OneVsOne_Arena {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
...
...
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