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
dade91a8
Unverified
Commit
dade91a8
authored
Aug 18, 2023
by
mergify[bot]
Committed by
GitHub
Aug 18, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into jg/race_cond_in_batcher
parents
d8cda3f1
edafea3e
Changes
47
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
47 changed files
with
592 additions
and
681 deletions
+592
-681
hip-olives-press.md
.changeset/hip-olives-press.md
+5
-0
config.yml
.circleci/config.yml
+2
-11
mergify.yml
.github/mergify.yml
+54
-6
Makefile
Makefile
+4
-0
__init__.py
bedrock-devnet/devnet/__init__.py
+31
-2
go.mod
go.mod
+0
-1
go.sum
go.sum
+0
-2
config.go
indexer/config/config.go
+3
-8
Makefile
op-bindings/Makefile
+1
-1
trace.sh
op-chain-ops/crossdomain/testdata/trace.sh
+1
-1
main_test.go
op-challenger/cmd/main_test.go
+23
-6
config.go
op-challenger/config/config.go
+7
-6
config_test.go
op-challenger/config/config_test.go
+10
-4
executor_test.go
op-challenger/fault/cannon/executor_test.go
+1
-1
flags.go
op-challenger/flags/flags.go
+19
-4
charlie.sh
op-challenger/scripts/alphabet/charlie.sh
+4
-1
init_game.sh
op-challenger/scripts/alphabet/init_game.sh
+1
-1
mallory.sh
op-challenger/scripts/alphabet/mallory.sh
+4
-1
parallel.sh
op-challenger/scripts/parallel.sh
+1
-1
visualize.sh
op-challenger/scripts/visualize.sh
+1
-1
alphabet_helper.go
op-e2e/e2eutils/disputegame/alphabet_helper.go
+1
-0
cannon_helper.go
op-e2e/e2eutils/disputegame/cannon_helper.go
+11
-3
game_helper.go
op-e2e/e2eutils/disputegame/game_helper.go
+7
-6
helper.go
op-e2e/e2eutils/disputegame/helper.go
+16
-15
system_test.go
op-e2e/system_test.go
+2
-2
rpc.go
op-node/client/rpc.go
+3
-3
script.sh
op-node/cmd/batch_decoder/script.sh
+3
-0
state.go
op-node/rollup/driver/state.go
+2
-2
sync_client.go
op-node/sources/sync_client.go
+6
-6
retry.go
op-program/host/prefetcher/retry.go
+12
-12
retry_test.go
op-program/host/prefetcher/retry_test.go
+5
-5
dial.go
op-service/client/dial.go
+3
-3
operation.go
op-service/retry/operation.go
+1
-1
operation_test.go
op-service/retry/operation_test.go
+1
-1
strategies.go
op-service/retry/strategies.go
+15
-16
strategies_test.go
op-service/retry/strategies_test.go
+5
-5
txmgr.go
op-service/txmgr/txmgr.go
+2
-2
package.json
packages/common-ts/package.json
+1
-1
logger.ts
packages/common-ts/src/common/logger.ts
+1
-1
slither.sh
packages/contracts-bedrock/scripts/slither.sh
+1
-1
verify-foundry-install.sh
packages/contracts-bedrock/scripts/verify-foundry-install.sh
+1
-1
.depcheckrc
packages/sdk/.depcheckrc
+1
-0
package.json
packages/sdk/package.json
+14
-13
CHANGELOG.md
packages/web3js-plugin/CHANGELOG.md
+6
-0
README.md
packages/web3js-plugin/README.md
+8
-2
package.json
packages/web3js-plugin/package.json
+1
-1
pnpm-lock.yaml
pnpm-lock.yaml
+291
-521
No files found.
.changeset/hip-olives-press.md
0 → 100644
View file @
dade91a8
---
'
@eth-optimism/sdk'
:
patch
---
Updated npm dependencies to latest
.circleci/config.yml
View file @
dade91a8
...
...
@@ -945,17 +945,8 @@ jobs:
name
:
Bring up the stack
command
:
make devnet-up
-
run
:
name
:
Check L2 config
command
:
go run cmd/check-l2/main.go --l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545
working_directory
:
op-chain-ops
-
run
:
name
:
Deposit ERC20 through the bridge
command
:
timeout 8m npx hardhat deposit-erc20 --network devnetL1 --l1-contracts-json-path ../../.devnet/addresses.json
working_directory
:
packages/sdk
-
run
:
name
:
Deposit ETH through the bridge
command
:
timeout 8m npx hardhat deposit-eth --network devnetL1 --l1-contracts-json-path ../../.devnet/addresses.json
working_directory
:
packages/sdk
name
:
Test the stack
command
:
make devnet-test
-
run
:
name
:
Dump op-node logs
command
:
|
...
...
.github/mergify.yml
View file @
dade91a8
...
...
@@ -221,17 +221,14 @@ pull_request_rules:
label
:
add
:
-
A-ops
-
name
:
Add A-pkg-
sdk label and ecopod reviewers
-
name
:
Add A-pkg-
chain-mon label
conditions
:
-
'
files~=^packages/
sdk
/'
-
'
files~=^packages/
chain-mon
/'
-
'
#label<5'
actions
:
label
:
add
:
-
A-pkg-sdk
request_reviews
:
users
:
-
roninjin10
-
A-pkg-chain-mon
-
name
:
Add A-pkg-common-ts label and ecopod reviewers
conditions
:
-
'
files~=^packages/common-ts/'
...
...
@@ -250,6 +247,57 @@ pull_request_rules:
label
:
add
:
-
A-pkg-contracts-bedrock
-
name
:
Add A-pkg-contracts-ts label
conditions
:
-
'
files~=^packages/contracts-ts/'
-
'
#label<5'
actions
:
label
:
add
:
-
A-pkg-contracts-ts
-
name
:
Add A-pkg-core-utils label
conditions
:
-
'
files~=^packages/core-utils/'
-
'
#label<5'
actions
:
label
:
add
:
-
A-pkg-core-utils
-
name
:
Add A-pkg-fee-estimation label
conditions
:
-
'
files~=^packages/fee-estimation/'
-
'
#label<5'
actions
:
label
:
add
:
-
A-pkg-fee-estimation
-
name
:
Add A-pkg-sdk label and ecopod reviewers
conditions
:
-
'
files~=^packages/sdk/'
-
'
#label<5'
actions
:
label
:
add
:
-
A-pkg-sdk
request_reviews
:
users
:
-
roninjin10
-
name
:
Add A-pkg-web3js-plugin label
conditions
:
-
'
files~=^packages/web3js-plugin/'
-
'
#label<5'
actions
:
label
:
add
:
-
A-pkg-web3js-plugin
-
name
:
Add A-proxyd label
conditions
:
-
'
files~=^proxyd/'
-
'
#label<5'
actions
:
label
:
add
:
-
A-proxyd
-
name
:
Add M-docs label
conditions
:
-
'
files~=^(technical-documents|specs)\/'
...
...
Makefile
View file @
dade91a8
...
...
@@ -96,6 +96,10 @@ devnet-up:
# alias for devnet-up
devnet-up-deploy
:
devnet-up
devnet-test
:
PYTHONPATH
=
./bedrock-devnet python3 ./bedrock-devnet/main.py
--monorepo-dir
=
.
--test
.PHONY
:
devnet-test
devnet-down
:
@
(
cd
./ops-bedrock
&&
GENESIS_TIMESTAMP
=
$(
shell
date
+%s
)
docker-compose stop
)
.PHONY
:
devnet-down
...
...
bedrock-devnet/devnet/__init__.py
View file @
dade91a8
...
...
@@ -18,6 +18,7 @@ pjoin = os.path.join
parser
=
argparse
.
ArgumentParser
(
description
=
'Bedrock devnet launcher'
)
parser
.
add_argument
(
'--monorepo-dir'
,
help
=
'Directory of the monorepo'
,
default
=
os
.
getcwd
())
parser
.
add_argument
(
'--allocs'
,
help
=
'Only create the allocs and exit'
,
type
=
bool
,
action
=
argparse
.
BooleanOptionalAction
)
parser
.
add_argument
(
'--test'
,
help
=
'Tests the deployment, must already be deployed'
,
type
=
bool
,
action
=
argparse
.
BooleanOptionalAction
)
log
=
logging
.
getLogger
()
...
...
@@ -57,6 +58,8 @@ def main():
ops_bedrock_dir
=
pjoin
(
monorepo_dir
,
'ops-bedrock'
)
deploy_config_dir
=
pjoin
(
contracts_bedrock_dir
,
'deploy-config'
),
devnet_config_path
=
pjoin
(
contracts_bedrock_dir
,
'deploy-config'
,
'devnetL1.json'
)
ops_chain_ops
=
pjoin
(
monorepo_dir
,
'op-chain-ops'
)
sdk_dir
=
pjoin
(
monorepo_dir
,
'packages'
,
'sdk'
)
paths
=
Bunch
(
mono_repo_dir
=
monorepo_dir
,
...
...
@@ -68,6 +71,8 @@ def main():
devnet_config_path
=
devnet_config_path
,
op_node_dir
=
op_node_dir
,
ops_bedrock_dir
=
ops_bedrock_dir
,
ops_chain_ops
=
ops_chain_ops
,
sdk_dir
=
sdk_dir
,
genesis_l1_path
=
pjoin
(
devnet_dir
,
'genesis-l1.json'
),
genesis_l2_path
=
pjoin
(
devnet_dir
,
'genesis-l2.json'
),
allocs_path
=
pjoin
(
devnet_dir
,
'allocs-l1.json'
),
...
...
@@ -76,6 +81,11 @@ def main():
rollup_config_path
=
pjoin
(
devnet_dir
,
'rollup.json'
)
)
if
args
.
test
:
log
.
info
(
'Testing deployed devnet'
)
devnet_test
(
paths
)
return
os
.
makedirs
(
devnet_dir
,
exist_ok
=
True
)
if
args
.
allocs
:
...
...
@@ -250,8 +260,26 @@ def wait_for_rpc_server(url):
log
.
info
(
f
'Waiting for RPC server at {url}'
)
time
.
sleep
(
1
)
def
devnet_test
(
paths
):
# Check the L2 config
run_command
(
[
'go'
,
'run'
,
'cmd/check-l2/main.go'
,
'--l2-rpc-url'
,
'http://localhost:9545'
,
'--l1-rpc-url'
,
'http://localhost:8545'
],
cwd
=
paths
.
ops_chain_ops
,
)
run_command
(
[
'npx'
,
'hardhat'
,
'deposit-erc20'
,
'--network'
,
'devnetL1'
,
'--l1-contracts-json-path'
,
paths
.
addresses_json_path
],
cwd
=
paths
.
sdk_dir
,
timeout
=
8
*
60
,
)
run_command
(
[
'npx'
,
'hardhat'
,
'deposit-eth'
,
'--network'
,
'devnetL1'
,
'--l1-contracts-json-path'
,
paths
.
addresses_json_path
],
cwd
=
paths
.
sdk_dir
,
timeout
=
8
*
60
,
)
def
run_command
(
args
,
check
=
True
,
shell
=
False
,
cwd
=
None
,
env
=
None
):
def
run_command
(
args
,
check
=
True
,
shell
=
False
,
cwd
=
None
,
env
=
None
,
timeout
=
None
):
env
=
env
if
env
else
{}
return
subprocess
.
run
(
args
,
...
...
@@ -261,7 +289,8 @@ def run_command(args, check=True, shell=False, cwd=None, env=None):
**
os
.
environ
,
**
env
},
cwd
=
cwd
cwd
=
cwd
,
timeout
=
timeout
)
...
...
go.mod
View file @
dade91a8
...
...
@@ -24,7 +24,6 @@ require (
github.com/ipfs/go-ds-leveldb v0.5.0
github.com/jackc/pgtype v1.14.0
github.com/jackc/pgx/v5 v5.4.3
github.com/joho/godotenv v1.5.1
github.com/libp2p/go-libp2p v0.27.8
github.com/libp2p/go-libp2p-pubsub v0.9.3
github.com/libp2p/go-libp2p-testing v0.12.0
...
...
go.sum
View file @
dade91a8
...
...
@@ -429,8 +429,6 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
...
...
indexer/config/config.go
View file @
dade91a8
...
...
@@ -8,7 +8,6 @@ import (
"github.com/BurntSushi/toml"
"github.com/ethereum/go-ethereum/common"
geth_log
"github.com/ethereum/go-ethereum/log"
"github.com/joho/godotenv"
)
// in future presets can just be onchain config and fetched on initialization
...
...
@@ -89,13 +88,7 @@ type MetricsConfig struct {
// LoadConfig loads the `indexer.toml` config file from a given path
func
LoadConfig
(
logger
geth_log
.
Logger
,
path
string
)
(
Config
,
error
)
{
if
err
:=
godotenv
.
Load
();
err
!=
nil
{
logger
.
Warn
(
"Unable to load .env file"
,
err
)
logger
.
Info
(
"Continuing without .env file"
)
}
else
{
logger
.
Info
(
"Loaded .env file"
)
}
logger
.
Info
(
"Loading config file"
,
"path"
,
path
)
var
conf
Config
data
,
err
:=
os
.
ReadFile
(
path
)
...
...
@@ -105,6 +98,8 @@ func LoadConfig(logger geth_log.Logger, path string) (Config, error) {
data
=
[]
byte
(
os
.
ExpandEnv
(
string
(
data
)))
logger
.
Debug
(
"Decoding config file"
,
"data"
,
string
(
data
))
if
_
,
err
:=
toml
.
Decode
(
string
(
data
),
&
conf
);
err
!=
nil
{
logger
.
Info
(
"Failed to decode config file"
,
"message"
,
err
)
return
conf
,
err
...
...
op-bindings/Makefile
View file @
dade91a8
SHELL
:=
/
bin/
bash
SHELL
:=
/
usr/bin/env
bash
pkg
:=
bindings
monorepo-base
:=
$(
shell
dirname
$
(
realpath
.
))
...
...
op-chain-ops/crossdomain/testdata/trace.sh
View file @
dade91a8
#!/
bin/
bash
#!/
usr/bin/env
bash
HASH
=
$1
...
...
op-challenger/cmd/main_test.go
View file @
dade91a8
...
...
@@ -15,7 +15,7 @@ import (
var
(
l1EthRpc
=
"http://example.com:8545"
game
AddressValue
=
"0xaa
00000000000000000000000000000000000000"
game
FactoryAddressValue
=
"0xbb
00000000000000000000000000000000000000"
cannonNetwork
=
chaincfg
.
AvailableNetworks
()[
0
]
otherCannonNetwork
=
chaincfg
.
AvailableNetworks
()[
1
]
cannonBin
=
"./bin/cannon"
...
...
@@ -44,14 +44,14 @@ func TestLogLevel(t *testing.T) {
func
TestDefaultCLIOptionsMatchDefaultConfig
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
config
.
TraceTypeAlphabet
))
defaultCfg
:=
config
.
NewConfig
(
l1EthRpc
,
common
.
HexToAddress
(
gameAddressValue
)
,
config
.
TraceTypeAlphabet
,
true
)
defaultCfg
:=
config
.
NewConfig
(
common
.
HexToAddress
(
gameFactoryAddressValue
),
l1EthRpc
,
config
.
TraceTypeAlphabet
,
true
)
// Add in the extra CLI options required when using alphabet trace type
defaultCfg
.
AlphabetTrace
=
alphabetTrace
require
.
Equal
(
t
,
defaultCfg
,
cfg
)
}
func
TestDefaultConfigIsValid
(
t
*
testing
.
T
)
{
cfg
:=
config
.
NewConfig
(
l1EthRpc
,
common
.
HexToAddress
(
gameAddressValue
)
,
config
.
TraceTypeAlphabet
,
true
)
cfg
:=
config
.
NewConfig
(
common
.
HexToAddress
(
gameFactoryAddressValue
),
l1EthRpc
,
config
.
TraceTypeAlphabet
,
true
)
// Add in options that are required based on the specific trace type
// To avoid needing to specify unused options, these aren't included in the params for NewConfig
cfg
.
AlphabetTrace
=
alphabetTrace
...
...
@@ -89,9 +89,26 @@ func TestTraceType(t *testing.T) {
})
}
func
TestGameAddress
(
t
*
testing
.
T
)
{
func
TestGame
Factory
Address
(
t
*
testing
.
T
)
{
t
.
Run
(
"Required"
,
func
(
t
*
testing
.
T
)
{
verifyArgsInvalid
(
t
,
"flag game-address is required"
,
addRequiredArgsExcept
(
config
.
TraceTypeAlphabet
,
"--game-address"
))
verifyArgsInvalid
(
t
,
"flag game-factory-address is required"
,
addRequiredArgsExcept
(
config
.
TraceTypeAlphabet
,
"--game-factory-address"
))
})
t
.
Run
(
"Valid"
,
func
(
t
*
testing
.
T
)
{
addr
:=
common
.
Address
{
0xbb
,
0xcc
,
0xdd
}
cfg
:=
configForArgs
(
t
,
addRequiredArgsExcept
(
config
.
TraceTypeAlphabet
,
"--game-factory-address"
,
"--game-factory-address="
+
addr
.
Hex
()))
require
.
Equal
(
t
,
addr
,
cfg
.
GameFactoryAddress
)
})
t
.
Run
(
"Invalid"
,
func
(
t
*
testing
.
T
)
{
verifyArgsInvalid
(
t
,
"invalid address: foo"
,
addRequiredArgsExcept
(
config
.
TraceTypeAlphabet
,
"--game-factory-address"
,
"--game-factory-address=foo"
))
})
}
func
TestGameAddress
(
t
*
testing
.
T
)
{
t
.
Run
(
"Optional"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgsExcept
(
config
.
TraceTypeAlphabet
,
"--game-address"
))
require
.
NoError
(
t
,
cfg
.
Check
())
})
t
.
Run
(
"Valid"
,
func
(
t
*
testing
.
T
)
{
...
...
@@ -316,7 +333,7 @@ func requiredArgs(traceType config.TraceType) map[string]string {
args
:=
map
[
string
]
string
{
"--agree-with-proposed-output"
:
agreeWithProposedOutput
,
"--l1-eth-rpc"
:
l1EthRpc
,
"--game-
address"
:
game
AddressValue
,
"--game-
factory-address"
:
gameFactory
AddressValue
,
"--trace-type"
:
traceType
.
String
(),
}
switch
traceType
{
...
...
op-challenger/config/config.go
View file @
dade91a8
...
...
@@ -18,7 +18,7 @@ var (
ErrMissingCannonAbsolutePreState
=
errors
.
New
(
"missing cannon absolute pre-state"
)
ErrMissingAlphabetTrace
=
errors
.
New
(
"missing alphabet trace"
)
ErrMissingL1EthRPC
=
errors
.
New
(
"missing l1 eth rpc url"
)
ErrMissingGame
Address
=
errors
.
New
(
"missing game
address"
)
ErrMissingGame
FactoryAddress
=
errors
.
New
(
"missing game factory
address"
)
ErrMissingCannonSnapshotFreq
=
errors
.
New
(
"missing cannon snapshot freq"
)
ErrMissingCannonRollupConfig
=
errors
.
New
(
"missing cannon network or rollup config path"
)
ErrMissingCannonL2Genesis
=
errors
.
New
(
"missing cannon network or l2 genesis path"
)
...
...
@@ -65,6 +65,7 @@ const DefaultCannonSnapshotFreq = uint(1_000_000_000)
// It is used to initialize the challenger.
type
Config
struct
{
L1EthRpc
string
// L1 RPC Url
GameFactoryAddress
common
.
Address
// Address of the dispute game factory
GameAddress
common
.
Address
// Address of the fault game
AgreeWithProposedOutput
bool
// Temporary config if we agree or disagree with the posted output
...
...
@@ -88,14 +89,14 @@ type Config struct {
}
func
NewConfig
(
gameFactoryAddress
common
.
Address
,
l1EthRpc
string
,
gameAddress
common
.
Address
,
traceType
TraceType
,
agreeWithProposedOutput
bool
,
)
Config
{
return
Config
{
L1EthRpc
:
l1EthRpc
,
Game
Address
:
game
Address
,
L1EthRpc
:
l1EthRpc
,
Game
FactoryAddress
:
gameFactory
Address
,
AgreeWithProposedOutput
:
agreeWithProposedOutput
,
...
...
@@ -111,8 +112,8 @@ func (c Config) Check() error {
if
c
.
L1EthRpc
==
""
{
return
ErrMissingL1EthRPC
}
if
c
.
GameAddress
==
(
common
.
Address
{})
{
return
ErrMissingGameAddress
if
c
.
Game
Factory
Address
==
(
common
.
Address
{})
{
return
ErrMissingGame
Factory
Address
}
if
c
.
TraceType
==
""
{
return
ErrMissingTraceType
...
...
op-challenger/config/config_test.go
View file @
dade91a8
...
...
@@ -10,7 +10,7 @@ import (
var
(
validL1EthRpc
=
"http://localhost:8545"
validGame
Address
=
common
.
HexToAddress
(
"0x7bdd3b028C4796eF0EAf07d11394d0d9d8c24139"
)
validGame
FactoryAddress
=
common
.
Address
{
0x23
}
validAlphabetTrace
=
"abcdefgh"
validCannonBin
=
"./bin/cannon"
validCannonOpProgramBin
=
"./bin/op-program"
...
...
@@ -22,7 +22,7 @@ var (
)
func
validConfig
(
traceType
TraceType
)
Config
{
cfg
:=
NewConfig
(
valid
L1EthRpc
,
validGameAddress
,
traceType
,
agreeWithProposedOutput
)
cfg
:=
NewConfig
(
valid
GameFactoryAddress
,
validL1EthRpc
,
traceType
,
agreeWithProposedOutput
)
switch
traceType
{
case
TraceTypeAlphabet
:
cfg
.
AlphabetTrace
=
validAlphabetTrace
...
...
@@ -62,10 +62,16 @@ func TestL1EthRpcRequired(t *testing.T) {
require
.
ErrorIs
(
t
,
config
.
Check
(),
ErrMissingL1EthRPC
)
}
func
TestGameAddressRequired
(
t
*
testing
.
T
)
{
func
TestGameFactoryAddressRequired
(
t
*
testing
.
T
)
{
config
:=
validConfig
(
TraceTypeCannon
)
config
.
GameFactoryAddress
=
common
.
Address
{}
require
.
ErrorIs
(
t
,
config
.
Check
(),
ErrMissingGameFactoryAddress
)
}
func
TestGameAddressNotRequired
(
t
*
testing
.
T
)
{
config
:=
validConfig
(
TraceTypeCannon
)
config
.
GameAddress
=
common
.
Address
{}
require
.
ErrorIs
(
t
,
config
.
Check
(),
ErrMissingGameAddress
)
require
.
NoError
(
t
,
config
.
Check
()
)
}
func
TestAlphabetTraceRequired
(
t
*
testing
.
T
)
{
...
...
op-challenger/fault/cannon/executor_test.go
View file @
dade91a8
...
...
@@ -21,7 +21,7 @@ const execTestCannonPrestate = "/foo/pre.json"
func
TestGenerateProof
(
t
*
testing
.
T
)
{
input
:=
"starting.json"
cfg
:=
config
.
NewConfig
(
"http://localhost:8888"
,
common
.
Address
{
0xaa
}
,
config
.
TraceTypeCannon
,
true
)
cfg
:=
config
.
NewConfig
(
common
.
Address
{
0xbb
},
"http://localhost:8888"
,
config
.
TraceTypeCannon
,
true
)
cfg
.
CannonDatadir
=
t
.
TempDir
()
cfg
.
CannonAbsolutePreState
=
"pre.json"
cfg
.
CannonBin
=
"./bin/cannon"
...
...
op-challenger/flags/flags.go
View file @
dade91a8
...
...
@@ -10,6 +10,7 @@ import (
openum
"github.com/ethereum-optimism/optimism/op-service/enum"
oplog
"github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
"github.com/urfave/cli/v2"
)
...
...
@@ -29,7 +30,12 @@ var (
Usage
:
"HTTP provider URL for L1."
,
EnvVars
:
prefixEnvVars
(
"L1_ETH_RPC"
),
}
DGFAddressFlag
=
&
cli
.
StringFlag
{
FactoryAddressFlag
=
&
cli
.
StringFlag
{
Name
:
"game-factory-address"
,
Usage
:
"Address of the fault game factory contract."
,
EnvVars
:
prefixEnvVars
(
"GAME_FACTORY_ADDRESS"
),
}
GameAddressFlag
=
&
cli
.
StringFlag
{
Name
:
"game-address"
,
Usage
:
"Address of the Fault Game contract."
,
EnvVars
:
prefixEnvVars
(
"GAME_ADDRESS"
),
...
...
@@ -105,7 +111,7 @@ var (
// requiredFlags are checked by [CheckRequired]
var
requiredFlags
=
[]
cli
.
Flag
{
L1EthRpcFlag
,
DGF
AddressFlag
,
Factory
AddressFlag
,
TraceTypeFlag
,
AgreeWithProposedOutputFlag
,
}
...
...
@@ -113,6 +119,7 @@ var requiredFlags = []cli.Flag{
// optionalFlags is a list of unchecked cli flags
var
optionalFlags
=
[]
cli
.
Flag
{
AlphabetFlag
,
GameAddressFlag
,
CannonNetworkFlag
,
CannonRollupConfigFlag
,
CannonL2GenesisFlag
,
...
...
@@ -181,10 +188,17 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
if
err
:=
CheckRequired
(
ctx
);
err
!=
nil
{
return
nil
,
err
}
dgfAddress
,
err
:=
opservice
.
ParseAddress
(
ctx
.
String
(
DGF
AddressFlag
.
Name
))
gameFactoryAddress
,
err
:=
opservice
.
ParseAddress
(
ctx
.
String
(
Factory
AddressFlag
.
Name
))
if
err
!=
nil
{
return
nil
,
err
}
var
gameAddress
common
.
Address
if
ctx
.
IsSet
(
GameAddressFlag
.
Name
)
{
gameAddress
,
err
=
opservice
.
ParseAddress
(
ctx
.
String
(
GameAddressFlag
.
Name
))
if
err
!=
nil
{
return
nil
,
err
}
}
txMgrConfig
:=
txmgr
.
ReadCLIConfig
(
ctx
)
...
...
@@ -194,7 +208,8 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
// Required Flags
L1EthRpc
:
ctx
.
String
(
L1EthRpcFlag
.
Name
),
TraceType
:
traceTypeFlag
,
GameAddress
:
dgfAddress
,
GameFactoryAddress
:
gameFactoryAddress
,
GameAddress
:
gameAddress
,
AlphabetTrace
:
ctx
.
String
(
AlphabetFlag
.
Name
),
CannonNetwork
:
ctx
.
String
(
CannonNetworkFlag
.
Name
),
CannonRollupConfigPath
:
ctx
.
String
(
CannonRollupConfigFlag
.
Name
),
...
...
op-challenger/scripts/alphabet/charlie.sh
View file @
dade91a8
#!/
bin/
bash
#!/
usr/bin/env
bash
set
-euo
pipefail
SOURCE_DIR
=
$(
cd
$(
dirname
"
${
BASH_SOURCE
[0]
}
"
)
&&
pwd
)
CHALLENGER_DIR
=
$(
echo
${
SOURCE_DIR
%/*/*
}
)
MONOREPO_DIR
=
$(
echo
${
SOURCE_DIR
%/*/*/*
}
)
# Check that the fault game address file exists
FAULT_GAME_ADDR_FILE
=
"
$CHALLENGER_DIR
/.fault-game-address"
...
...
@@ -14,6 +15,7 @@ fi
# Charlie's Address: 0xF45B7537828CB2fffBC69996B054c2Aaf36DC778
CHARLIE_KEY
=
"74feb147d72bfae943e6b4e483410933d9e447d5dc47d52432dcc2c1454dabb7"
DISPUTE_GAME_PROXY
=
$(
jq
-r
.DisputeGameFactoryProxy
$MONOREPO_DIR
/.devnet/addresses.json
)
FAULT_GAME_ADDRESS
=
$(
cat
$FAULT_GAME_ADDR_FILE
)
echo
"Fault dispute game address:
$FAULT_GAME_ADDRESS
"
...
...
@@ -21,6 +23,7 @@ $CHALLENGER_DIR/bin/op-challenger \
--l1-eth-rpc
http://localhost:8545
\
--trace-type
=
"alphabet"
\
--alphabet
"abcdefgh"
\
--game-factory-address
$DISPUTE_GAME_PROXY
\
--game-address
$FAULT_GAME_ADDRESS
\
--private-key
$CHARLIE_KEY
\
--num-confirmations
1
\
...
...
op-challenger/scripts/alphabet/init_game.sh
View file @
dade91a8
#!/
bin/
bash
#!/
usr/bin/env
bash
set
-euo
pipefail
...
...
op-challenger/scripts/alphabet/mallory.sh
View file @
dade91a8
#!/
bin/
bash
#!/
usr/bin/env
bash
set
-euo
pipefail
SOURCE_DIR
=
$(
cd
$(
dirname
"
${
BASH_SOURCE
[0]
}
"
)
&&
pwd
)
CHALLENGER_DIR
=
$(
echo
${
SOURCE_DIR
%/*/*
}
)
MONOREPO_DIR
=
$(
echo
${
SOURCE_DIR
%/*/*/*
}
)
# Check that the fault game address file exists
FAULT_GAME_ADDR_FILE
=
"
$CHALLENGER_DIR
/.fault-game-address"
...
...
@@ -14,6 +15,7 @@ fi
# Mallory's Address: 0x4641c704a6c743f73ee1f36C7568Fbf4b80681e4
MALLORY_KEY
=
"28d7045146193f5f4eeb151c4843544b1b0d30a7ac1680c845a416fac65a7715"
DISPUTE_GAME_PROXY
=
$(
jq
-r
.DisputeGameFactoryProxy
$MONOREPO_DIR
/.devnet/addresses.json
)
FAULT_GAME_ADDRESS
=
$(
cat
$FAULT_GAME_ADDR_FILE
)
echo
"Fault dispute game address:
$FAULT_GAME_ADDRESS
"
...
...
@@ -21,6 +23,7 @@ $CHALLENGER_DIR/bin/op-challenger \
--l1-eth-rpc
http://localhost:8545
\
--trace-type
=
"alphabet"
\
--alphabet
"abcdexyz"
\
--game-factory-address
$DISPUTE_GAME_PROXY
\
--game-address
$FAULT_GAME_ADDRESS
\
--private-key
$MALLORY_KEY
\
--num-confirmations
1
\
...
...
op-challenger/scripts/parallel.sh
View file @
dade91a8
#!/
bin/
bash
#!/
usr/bin/env
bash
# set -x
...
...
op-challenger/scripts/visualize.sh
View file @
dade91a8
#!/
bin/
bash
#!/
usr/bin/env
bash
set
-euo
pipefail
...
...
op-e2e/e2eutils/disputegame/alphabet_helper.go
View file @
dade91a8
...
...
@@ -15,6 +15,7 @@ type AlphabetGameHelper struct {
func
(
g
*
AlphabetGameHelper
)
StartChallenger
(
ctx
context
.
Context
,
l1Endpoint
string
,
name
string
,
options
...
challenger
.
Option
)
*
challenger
.
Helper
{
opts
:=
[]
challenger
.
Option
{
func
(
c
*
config
.
Config
)
{
c
.
GameFactoryAddress
=
g
.
factoryAddr
c
.
GameAddress
=
g
.
addr
c
.
TraceType
=
config
.
TraceTypeAlphabet
// By default the challenger agrees with the root claim (thus disagrees with the proposed output)
...
...
op-e2e/e2eutils/disputegame/cannon_helper.go
View file @
dade91a8
...
...
@@ -24,7 +24,7 @@ type CannonGameHelper struct {
}
func
(
g
*
CannonGameHelper
)
StartChallenger
(
ctx
context
.
Context
,
rollupCfg
*
rollup
.
Config
,
l2Genesis
*
core
.
Genesis
,
l1Endpoint
string
,
l2Endpoint
string
,
name
string
,
options
...
challenger
.
Option
)
*
challenger
.
Helper
{
opts
:=
[]
challenger
.
Option
{
createConfigOption
(
g
.
t
,
rollupCfg
,
l2Genesis
,
g
.
addr
,
l2Endpoint
)}
opts
:=
[]
challenger
.
Option
{
createConfigOption
(
g
.
t
,
rollupCfg
,
l2Genesis
,
g
.
factoryAddr
,
g
.
addr
,
l2Endpoint
)}
opts
=
append
(
opts
,
options
...
)
c
:=
challenger
.
NewChallenger
(
g
.
t
,
ctx
,
l1Endpoint
,
name
,
opts
...
)
g
.
t
.
Cleanup
(
func
()
{
...
...
@@ -34,7 +34,7 @@ func (g *CannonGameHelper) StartChallenger(ctx context.Context, rollupCfg *rollu
}
func
(
g
*
CannonGameHelper
)
CreateHonestActor
(
ctx
context
.
Context
,
rollupCfg
*
rollup
.
Config
,
l2Genesis
*
core
.
Genesis
,
l1Client
bind
.
ContractCaller
,
l1Endpoint
string
,
l2Endpoint
string
,
options
...
challenger
.
Option
)
*
HonestHelper
{
opts
:=
[]
challenger
.
Option
{
createConfigOption
(
g
.
t
,
rollupCfg
,
l2Genesis
,
g
.
addr
,
l2Endpoint
)}
opts
:=
[]
challenger
.
Option
{
createConfigOption
(
g
.
t
,
rollupCfg
,
l2Genesis
,
g
.
factoryAddr
,
g
.
addr
,
l2Endpoint
)}
opts
=
append
(
opts
,
options
...
)
cfg
:=
challenger
.
NewChallengerConfig
(
g
.
t
,
l1Endpoint
,
opts
...
)
provider
,
err
:=
cannon
.
NewTraceProvider
(
ctx
,
testlog
.
Logger
(
g
.
t
,
log
.
LvlInfo
)
.
New
(
"role"
,
"CorrectTrace"
),
cfg
,
l1Client
)
...
...
@@ -48,9 +48,17 @@ func (g *CannonGameHelper) CreateHonestActor(ctx context.Context, rollupCfg *rol
}
}
func
createConfigOption
(
t
*
testing
.
T
,
rollupCfg
*
rollup
.
Config
,
l2Genesis
*
core
.
Genesis
,
gameAddr
common
.
Address
,
l2Endpoint
string
)
challenger
.
Option
{
func
createConfigOption
(
t
*
testing
.
T
,
rollupCfg
*
rollup
.
Config
,
l2Genesis
*
core
.
Genesis
,
factoryAddr
common
.
Address
,
gameAddr
common
.
Address
,
l2Endpoint
string
,
)
challenger
.
Option
{
return
func
(
c
*
config
.
Config
)
{
require
:=
require
.
New
(
t
)
c
.
GameFactoryAddress
=
factoryAddr
c
.
GameAddress
=
gameAddr
c
.
TraceType
=
config
.
TraceTypeCannon
c
.
AgreeWithProposedOutput
=
false
...
...
op-e2e/e2eutils/disputegame/game_helper.go
View file @
dade91a8
...
...
@@ -17,12 +17,13 @@ import (
)
type
FaultGameHelper
struct
{
t
*
testing
.
T
require
*
require
.
Assertions
client
*
ethclient
.
Client
opts
*
bind
.
TransactOpts
game
*
bindings
.
FaultDisputeGame
addr
common
.
Address
t
*
testing
.
T
require
*
require
.
Assertions
client
*
ethclient
.
Client
opts
*
bind
.
TransactOpts
game
*
bindings
.
FaultDisputeGame
factoryAddr
common
.
Address
addr
common
.
Address
}
func
(
g
*
FaultGameHelper
)
GameDuration
(
ctx
context
.
Context
)
time
.
Duration
{
...
...
op-e2e/e2eutils/disputegame/helper.go
View file @
dade91a8
...
...
@@ -119,12 +119,13 @@ func (h *FactoryHelper) StartAlphabetGame(ctx context.Context, claimedAlphabet s
return
&
AlphabetGameHelper
{
FaultGameHelper
:
FaultGameHelper
{
t
:
h
.
t
,
require
:
h
.
require
,
client
:
h
.
client
,
opts
:
h
.
opts
,
game
:
game
,
addr
:
createdEvent
.
DisputeProxy
,
t
:
h
.
t
,
require
:
h
.
require
,
client
:
h
.
client
,
opts
:
h
.
opts
,
game
:
game
,
factoryAddr
:
h
.
factoryAddr
,
addr
:
createdEvent
.
DisputeProxy
,
},
claimedAlphabet
:
claimedAlphabet
,
}
...
...
@@ -137,7 +138,7 @@ func (h *FactoryHelper) StartCannonGame(ctx context.Context, rootClaim common.Ha
func
(
h
*
FactoryHelper
)
StartCannonGameWithCorrectRoot
(
ctx
context
.
Context
,
rollupCfg
*
rollup
.
Config
,
l2Genesis
*
core
.
Genesis
,
l1Endpoint
string
,
l2Endpoint
string
,
options
...
challenger
.
Option
)
(
*
CannonGameHelper
,
*
HonestHelper
)
{
l2BlockNumber
,
l1Head
:=
h
.
prepareCannonGame
(
ctx
)
challengerOpts
:=
[]
challenger
.
Option
{
createConfigOption
(
h
.
t
,
rollupCfg
,
l2Genesis
,
common
.
Address
{
0xaa
},
l2Endpoint
)}
challengerOpts
:=
[]
challenger
.
Option
{
createConfigOption
(
h
.
t
,
rollupCfg
,
l2Genesis
,
h
.
factoryAddr
,
common
.
Address
{
0xaa
},
l2Endpoint
)}
challengerOpts
=
append
(
challengerOpts
,
options
...
)
cfg
:=
challenger
.
NewChallengerConfig
(
h
.
t
,
l1Endpoint
,
challengerOpts
...
)
opts
:=
&
bind
.
CallOpts
{
Context
:
ctx
}
...
...
@@ -200,20 +201,20 @@ func (h *FactoryHelper) createCannonGame(ctx context.Context, l2BlockNumber uint
return
&
CannonGameHelper
{
FaultGameHelper
:
FaultGameHelper
{
t
:
h
.
t
,
require
:
h
.
require
,
client
:
h
.
client
,
opts
:
h
.
opts
,
game
:
game
,
addr
:
createdEvent
.
DisputeProxy
,
t
:
h
.
t
,
require
:
h
.
require
,
client
:
h
.
client
,
opts
:
h
.
opts
,
game
:
game
,
factoryAddr
:
h
.
factoryAddr
,
addr
:
createdEvent
.
DisputeProxy
,
},
}
}
func
(
h
*
FactoryHelper
)
StartChallenger
(
ctx
context
.
Context
,
l1Endpoint
string
,
name
string
,
options
...
challenger
.
Option
)
*
challenger
.
Helper
{
opts
:=
[]
challenger
.
Option
{
func
(
c
*
config
.
Config
)
{
// Uncomment when challenger actually supports setting the game factory address
//c.FactoryAddress = h.factoryAddr
c
.
GameFactoryAddress
=
h
.
factoryAddr
c
.
TraceType
=
config
.
TraceTypeAlphabet
},
}
...
...
op-e2e/system_test.go
View file @
dade91a8
...
...
@@ -34,9 +34,9 @@ import (
"github.com/ethereum-optimism/optimism/op-node/rollup/driver"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-service/backoff"
"github.com/ethereum-optimism/optimism/op-service/eth"
oppprof
"github.com/ethereum-optimism/optimism/op-service/pprof"
"github.com/ethereum-optimism/optimism/op-service/retry"
)
func
TestL2OutputSubmitter
(
t
*
testing
.
T
)
{
...
...
@@ -533,7 +533,7 @@ func TestSystemMockP2P(t *testing.T) {
// poll to see if the verifier node is connected & meshed on gossip.
// Without this verifier, we shouldn't start sending blocks around, or we'll miss them and fail the test.
backOffStrategy
:=
backoff
.
Exponential
()
backOffStrategy
:=
retry
.
Exponential
()
for
i
:=
0
;
i
<
10
;
i
++
{
if
check
()
{
break
...
...
op-node/client/rpc.go
View file @
dade91a8
...
...
@@ -8,7 +8,7 @@ import (
"regexp"
"time"
"github.com/ethereum-optimism/optimism/op-service/
backoff
"
"github.com/ethereum-optimism/optimism/op-service/
retry
"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/log"
"github.com/prometheus/client_golang/prometheus"
...
...
@@ -103,8 +103,8 @@ func NewRPC(ctx context.Context, lgr log.Logger, addr string, opts ...RPCOption)
// Dials a JSON-RPC endpoint repeatedly, with a backoff, until a client connection is established. Auth is optional.
func
dialRPCClientWithBackoff
(
ctx
context
.
Context
,
log
log
.
Logger
,
addr
string
,
attempts
int
,
opts
...
rpc
.
ClientOption
)
(
*
rpc
.
Client
,
error
)
{
bOff
:=
backoff
.
Exponential
()
return
backoff
.
Do
(
ctx
,
attempts
,
bOff
,
func
()
(
*
rpc
.
Client
,
error
)
{
bOff
:=
retry
.
Exponential
()
return
retry
.
Do
(
ctx
,
attempts
,
bOff
,
func
()
(
*
rpc
.
Client
,
error
)
{
if
!
IsURLAvailable
(
addr
)
{
log
.
Warn
(
"failed to dial address, but may connect later"
,
"addr"
,
addr
)
return
nil
,
fmt
.
Errorf
(
"address unavailable (%s)"
,
addr
)
...
...
op-node/cmd/batch_decoder/script.sh
0 → 100755
View file @
dade91a8
echo
$1
jq
'.frames[] | {timestamp, inclusion_block}'
$1
jq
'.batches[]|.Timestamp'
$1
op-node/rollup/driver/state.go
View file @
dade91a8
...
...
@@ -15,8 +15,8 @@ import (
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-service/backoff"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/retry"
)
// Deprecated: use eth.SyncStatus instead.
...
...
@@ -178,7 +178,7 @@ func (s *Driver) eventLoop() {
var
delayedStepReq
<-
chan
time
.
Time
// keep track of consecutive failed attempts, to adjust the backoff time accordingly
bOffStrategy
:=
backoff
.
Exponential
()
bOffStrategy
:=
retry
.
Exponential
()
stepAttempts
:=
0
// step requests a derivation step to be taken. Won't deadlock if the channel is full.
...
...
op-node/sources/sync_client.go
View file @
dade91a8
...
...
@@ -11,8 +11,8 @@ import (
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/sources/caching"
"github.com/ethereum-optimism/optimism/op-service/backoff"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/retry"
"github.com/ethereum/go-ethereum/log"
"github.com/libp2p/go-libp2p/core/peer"
...
...
@@ -130,10 +130,10 @@ func (s *SyncClient) eventLoop() {
defer
s
.
wg
.
Done
()
s
.
log
.
Info
(
"Starting sync client event loop"
)
backoffStrategy
:=
&
backoff
.
ExponentialStrategy
{
Min
:
1000
,
Max
:
20
_000
,
MaxJitter
:
250
,
backoffStrategy
:=
&
retry
.
ExponentialStrategy
{
Min
:
1000
*
time
.
Millisecond
,
Max
:
20
_000
*
time
.
Millisecond
,
MaxJitter
:
250
*
time
.
Millisecond
,
}
for
{
...
...
@@ -142,7 +142,7 @@ func (s *SyncClient) eventLoop() {
s
.
log
.
Debug
(
"Shutting down RPC sync worker"
)
return
case
reqNum
:=
<-
s
.
requests
:
_
,
err
:=
backoff
.
Do
(
s
.
resCtx
,
5
,
backoffStrategy
,
func
()
(
interface
{},
error
)
{
_
,
err
:=
retry
.
Do
(
s
.
resCtx
,
5
,
backoffStrategy
,
func
()
(
interface
{},
error
)
{
// Limit the maximum time for fetching payloads
ctx
,
cancel
:=
context
.
WithTimeout
(
s
.
resCtx
,
time
.
Second
*
10
)
defer
cancel
()
...
...
op-program/host/prefetcher/retry.go
View file @
dade91a8
...
...
@@ -4,8 +4,8 @@ import (
"context"
"math"
"github.com/ethereum-optimism/optimism/op-service/backoff"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/retry"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
...
...
@@ -16,19 +16,19 @@ const maxAttempts = math.MaxInt // Succeed or die trying
type
RetryingL1Source
struct
{
logger
log
.
Logger
source
L1Source
strategy
backoff
.
Strategy
strategy
retry
.
Strategy
}
func
NewRetryingL1Source
(
logger
log
.
Logger
,
source
L1Source
)
*
RetryingL1Source
{
return
&
RetryingL1Source
{
logger
:
logger
,
source
:
source
,
strategy
:
backoff
.
Exponential
(),
strategy
:
retry
.
Exponential
(),
}
}
func
(
s
*
RetryingL1Source
)
InfoByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
error
)
{
return
backoff
.
Do
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
(
eth
.
BlockInfo
,
error
)
{
return
retry
.
Do
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
(
eth
.
BlockInfo
,
error
)
{
res
,
err
:=
s
.
source
.
InfoByHash
(
ctx
,
blockHash
)
if
err
!=
nil
{
s
.
logger
.
Warn
(
"Failed to retrieve info"
,
"hash"
,
blockHash
,
"err"
,
err
)
...
...
@@ -38,7 +38,7 @@ func (s *RetryingL1Source) InfoByHash(ctx context.Context, blockHash common.Hash
}
func
(
s
*
RetryingL1Source
)
InfoAndTxsByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Transactions
,
error
)
{
return
backoff
.
Do2
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
(
eth
.
BlockInfo
,
types
.
Transactions
,
error
)
{
return
retry
.
Do2
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
(
eth
.
BlockInfo
,
types
.
Transactions
,
error
)
{
i
,
t
,
err
:=
s
.
source
.
InfoAndTxsByHash
(
ctx
,
blockHash
)
if
err
!=
nil
{
s
.
logger
.
Warn
(
"Failed to retrieve l1 info and txs"
,
"hash"
,
blockHash
,
"err"
,
err
)
...
...
@@ -48,7 +48,7 @@ func (s *RetryingL1Source) InfoAndTxsByHash(ctx context.Context, blockHash commo
}
func
(
s
*
RetryingL1Source
)
FetchReceipts
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Receipts
,
error
)
{
return
backoff
.
Do2
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
(
eth
.
BlockInfo
,
types
.
Receipts
,
error
)
{
return
retry
.
Do2
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
(
eth
.
BlockInfo
,
types
.
Receipts
,
error
)
{
i
,
r
,
err
:=
s
.
source
.
FetchReceipts
(
ctx
,
blockHash
)
if
err
!=
nil
{
s
.
logger
.
Warn
(
"Failed to fetch receipts"
,
"hash"
,
blockHash
,
"err"
,
err
)
...
...
@@ -62,11 +62,11 @@ var _ L1Source = (*RetryingL1Source)(nil)
type
RetryingL2Source
struct
{
logger
log
.
Logger
source
L2Source
strategy
backoff
.
Strategy
strategy
retry
.
Strategy
}
func
(
s
*
RetryingL2Source
)
InfoAndTxsByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Transactions
,
error
)
{
return
backoff
.
Do2
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
(
eth
.
BlockInfo
,
types
.
Transactions
,
error
)
{
return
retry
.
Do2
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
(
eth
.
BlockInfo
,
types
.
Transactions
,
error
)
{
i
,
t
,
err
:=
s
.
source
.
InfoAndTxsByHash
(
ctx
,
blockHash
)
if
err
!=
nil
{
s
.
logger
.
Warn
(
"Failed to retrieve l2 info and txs"
,
"hash"
,
blockHash
,
"err"
,
err
)
...
...
@@ -76,7 +76,7 @@ func (s *RetryingL2Source) InfoAndTxsByHash(ctx context.Context, blockHash commo
}
func
(
s
*
RetryingL2Source
)
NodeByHash
(
ctx
context
.
Context
,
hash
common
.
Hash
)
([]
byte
,
error
)
{
return
backoff
.
Do
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
([]
byte
,
error
)
{
return
retry
.
Do
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
([]
byte
,
error
)
{
n
,
err
:=
s
.
source
.
NodeByHash
(
ctx
,
hash
)
if
err
!=
nil
{
s
.
logger
.
Warn
(
"Failed to retrieve node"
,
"hash"
,
hash
,
"err"
,
err
)
...
...
@@ -86,7 +86,7 @@ func (s *RetryingL2Source) NodeByHash(ctx context.Context, hash common.Hash) ([]
}
func
(
s
*
RetryingL2Source
)
CodeByHash
(
ctx
context
.
Context
,
hash
common
.
Hash
)
([]
byte
,
error
)
{
return
backoff
.
Do
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
([]
byte
,
error
)
{
return
retry
.
Do
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
([]
byte
,
error
)
{
c
,
err
:=
s
.
source
.
CodeByHash
(
ctx
,
hash
)
if
err
!=
nil
{
s
.
logger
.
Warn
(
"Failed to retrieve code"
,
"hash"
,
hash
,
"err"
,
err
)
...
...
@@ -96,7 +96,7 @@ func (s *RetryingL2Source) CodeByHash(ctx context.Context, hash common.Hash) ([]
}
func
(
s
*
RetryingL2Source
)
OutputByRoot
(
ctx
context
.
Context
,
root
common
.
Hash
)
(
eth
.
Output
,
error
)
{
return
backoff
.
Do
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
(
eth
.
Output
,
error
)
{
return
retry
.
Do
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
(
eth
.
Output
,
error
)
{
o
,
err
:=
s
.
source
.
OutputByRoot
(
ctx
,
root
)
if
err
!=
nil
{
s
.
logger
.
Warn
(
"Failed to fetch l2 output"
,
"root"
,
root
,
"err"
,
err
)
...
...
@@ -110,7 +110,7 @@ func NewRetryingL2Source(logger log.Logger, source L2Source) *RetryingL2Source {
return
&
RetryingL2Source
{
logger
:
logger
,
source
:
source
,
strategy
:
backoff
.
Exponential
(),
strategy
:
retry
.
Exponential
(),
}
}
...
...
op-program/host/prefetcher/retry_test.go
View file @
dade91a8
...
...
@@ -7,8 +7,8 @@ import (
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-node/testutils"
"github.com/ethereum-optimism/optimism/op-service/backoff"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/retry"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
...
...
@@ -104,8 +104,8 @@ func createL1Source(t *testing.T) (*RetryingL1Source, *testutils.MockL1Source) {
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlDebug
)
mock
:=
&
testutils
.
MockL1Source
{}
source
:=
NewRetryingL1Source
(
logger
,
mock
)
// Avoid sleeping in tests by using a fixed
backoff
strategy with no delay
source
.
strategy
=
backoff
.
Fixed
(
0
)
// Avoid sleeping in tests by using a fixed
retry
strategy with no delay
source
.
strategy
=
retry
.
Fixed
(
0
)
return
source
,
mock
}
...
...
@@ -217,8 +217,8 @@ func createL2Source(t *testing.T) (*RetryingL2Source, *MockL2Source) {
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlDebug
)
mock
:=
&
MockL2Source
{}
source
:=
NewRetryingL2Source
(
logger
,
mock
)
// Avoid sleeping in tests by using a fixed
backoff
strategy with no delay
source
.
strategy
=
backoff
.
Fixed
(
0
)
// Avoid sleeping in tests by using a fixed
retry
strategy with no delay
source
.
strategy
=
retry
.
Fixed
(
0
)
return
source
,
mock
}
...
...
op-service/client/dial.go
View file @
dade91a8
...
...
@@ -7,7 +7,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-service/
backoff
"
"github.com/ethereum-optimism/optimism/op-service/
retry
"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
...
...
@@ -49,8 +49,8 @@ func DialRollupClientWithTimeout(timeout time.Duration, log log.Logger, url stri
// Dials a JSON-RPC endpoint repeatedly, with a backoff, until a client connection is established. Auth is optional.
func
dialRPCClientWithBackoff
(
ctx
context
.
Context
,
log
log
.
Logger
,
addr
string
)
(
*
rpc
.
Client
,
error
)
{
bOff
:=
backoff
.
Fixed
(
defaultRetryTime
)
return
backoff
.
Do
(
ctx
,
defaultRetryCount
,
bOff
,
func
()
(
*
rpc
.
Client
,
error
)
{
bOff
:=
retry
.
Fixed
(
defaultRetryTime
)
return
retry
.
Do
(
ctx
,
defaultRetryCount
,
bOff
,
func
()
(
*
rpc
.
Client
,
error
)
{
if
!
client
.
IsURLAvailable
(
addr
)
{
log
.
Warn
(
"failed to dial address, but may connect later"
,
"addr"
,
addr
)
return
nil
,
fmt
.
Errorf
(
"address unavailable (%s)"
,
addr
)
...
...
op-service/
backoff
/operation.go
→
op-service/
retry
/operation.go
View file @
dade91a8
package
backoff
package
retry
import
(
"context"
...
...
op-service/
backoff
/operation_test.go
→
op-service/
retry
/operation_test.go
View file @
dade91a8
package
backoff
package
retry
import
(
"context"
...
...
op-service/
backoff
/strategies.go
→
op-service/
retry
/strategies.go
View file @
dade91a8
package
backoff
package
retry
import
(
"math"
...
...
@@ -16,35 +16,34 @@ type Strategy interface {
// ExponentialStrategy performs exponential backoff. The exponential backoff
// function is min(e.Min + (2^attempt * 1000) + randBetween(0, e.MaxJitter), e.Max)
type
ExponentialStrategy
struct
{
// Min is the minimum amount of time to wait between attempts
in ms
.
Min
float64
// Min is the minimum amount of time to wait between attempts.
Min
time
.
Duration
// Max is the maximum amount of time to wait between attempts
in ms
.
Max
float64
// Max is the maximum amount of time to wait between attempts.
Max
time
.
Duration
// MaxJitter is the maximum amount of random jitter to insert between
// attempts in ms.
MaxJitter
int
// MaxJitter is the maximum amount of random jitter to insert between attempts.
MaxJitter
time
.
Duration
}
func
(
e
*
ExponentialStrategy
)
Duration
(
attempt
int
)
time
.
Duration
{
var
jitter
int
var
jitter
time
.
Duration
if
e
.
MaxJitter
>
0
{
jitter
=
rand
.
Intn
(
e
.
MaxJitter
)
jitter
=
time
.
Duration
(
rand
.
Int63n
(
e
.
MaxJitter
.
Nanoseconds
())
)
}
dur
:=
e
.
Min
+
(
math
.
Pow
(
2
,
float64
(
attempt
))
*
1000
)
dur
+=
float64
(
jitter
)
dur
:=
e
.
Min
+
time
.
Duration
(
int
(
math
.
Pow
(
2
,
float64
(
attempt
))
*
1000
))
*
time
.
Millisecond
dur
+=
jitter
if
dur
>
e
.
Max
{
return
time
.
Millisecond
*
time
.
Duration
(
e
.
Max
)
return
e
.
Max
}
return
time
.
Millisecond
*
time
.
Duration
(
dur
)
return
dur
}
func
Exponential
()
Strategy
{
return
&
ExponentialStrategy
{
Max
:
10000
,
MaxJitter
:
250
,
Max
:
time
.
Duration
(
10000
*
time
.
Millisecond
)
,
MaxJitter
:
time
.
Duration
(
250
*
time
.
Millisecond
)
,
}
}
...
...
op-service/
backoff
/strategies_test.go
→
op-service/
retry
/strategies_test.go
View file @
dade91a8
package
backoff
package
retry
import
(
"testing"
...
...
@@ -9,13 +9,13 @@ import (
func
TestExponential
(
t
*
testing
.
T
)
{
strategy
:=
&
ExponentialStrategy
{
Min
:
3000
,
Max
:
10000
,
Min
:
3000
*
time
.
Millisecond
,
Max
:
10000
*
time
.
Millisecond
,
MaxJitter
:
0
,
}
durations
:=
[]
int
{
4
,
5
,
7
,
10
,
10
}
durations
:=
[]
time
.
Duration
{
4
,
5
,
7
,
10
,
10
}
for
i
,
dur
:=
range
durations
{
require
.
Equal
(
t
,
time
.
Millisecond
*
time
.
Duration
(
dur
*
1000
)
,
strategy
.
Duration
(
i
))
require
.
Equal
(
t
,
dur
*
time
.
Second
,
strategy
.
Duration
(
i
))
}
}
op-service/txmgr/txmgr.go
View file @
dade91a8
...
...
@@ -17,7 +17,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-service/
backoff
"
"github.com/ethereum-optimism/optimism/op-service/
retry
"
"github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
)
...
...
@@ -176,7 +176,7 @@ func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*typ
ctx
,
cancel
=
context
.
WithTimeout
(
ctx
,
m
.
cfg
.
TxSendTimeout
)
defer
cancel
()
}
tx
,
err
:=
backoff
.
Do
(
ctx
,
30
,
backoff
.
Fixed
(
2
*
time
.
Second
),
func
()
(
*
types
.
Transaction
,
error
)
{
tx
,
err
:=
retry
.
Do
(
ctx
,
30
,
retry
.
Fixed
(
2
*
time
.
Second
),
func
()
(
*
types
.
Transaction
,
error
)
{
tx
,
err
:=
m
.
craftTx
(
ctx
,
candidate
)
if
err
!=
nil
{
m
.
l
.
Warn
(
"Failed to create a transaction, will retry"
,
"err"
,
err
)
...
...
packages/common-ts/package.json
View file @
dade91a8
...
...
@@ -46,7 +46,7 @@
"express-prom-bundle"
:
"^6.4.1"
,
"lodash"
:
"^4.17.21"
,
"morgan"
:
"^1.10.0"
,
"pino"
:
"^
6.11.3
"
,
"pino"
:
"^
8.15.0
"
,
"pino-multi-stream"
:
"^5.3.0"
,
"pino-sentry"
:
"^0.14.0"
,
"prom-client"
:
"^13.1.0"
...
...
packages/common-ts/src/common/logger.ts
View file @
dade91a8
...
...
@@ -11,7 +11,7 @@ export const logLevels = [
'
error
'
,
'
fatal
'
,
]
as
const
export
type
LogLevel
=
typeof
logLevels
[
number
]
export
type
LogLevel
=
(
typeof
logLevels
)
[
number
]
export
interface
LoggerOptions
{
name
:
string
...
...
packages/contracts-bedrock/scripts/slither.sh
View file @
dade91a8
#!/
bin/
bash
#!/
usr/bin/env
bash
rm
-rf
artifacts forge-artifacts
...
...
packages/contracts-bedrock/scripts/verify-foundry-install.sh
View file @
dade91a8
#!/
bin/
bash
#!/
usr/bin/env
bash
if
!
command
-v
forge &> /dev/null
then
...
...
packages/sdk/.depcheckrc
View file @
dade91a8
...
...
@@ -12,6 +12,7 @@ ignores: [
"chai",
"ts-node",
"typedoc",
"typescript",
"ethereum-waffle",
"nyc"
]
packages/sdk/package.json
View file @
dade91a8
...
...
@@ -41,30 +41,31 @@
"@ethersproject/transactions"
:
"^5.7.0"
,
"@nomiclabs/hardhat-ethers"
:
"^2.0.2"
,
"@nomiclabs/hardhat-waffle"
:
"^2.0.1"
,
"@types/chai"
:
"^4.3.5"
,
"@types/chai-as-promised"
:
"^7.1.5"
,
"@types/mocha"
:
"^10.0.1"
,
"@types/node"
:
"^20.5.0"
,
"chai-as-promised"
:
"^7.1.1"
,
"ethereum-waffle"
:
"^4.0.10"
,
"ethers"
:
"^5.7.
0
"
,
"ethers"
:
"^5.7.
2
"
,
"hardhat"
:
"^2.9.6"
,
"hardhat-deploy"
:
"^0.11.4"
,
"isomorphic-fetch"
:
"^3.0.0"
,
"mocha"
:
"^10.
0
.0"
,
"mocha"
:
"^10.
2
.0"
,
"nyc"
:
"^15.1.0"
,
"ts-node"
:
"^10.9.1"
,
"typedoc"
:
"^0.22.13"
,
"viem"
:
"^0.3.30"
,
"vitest"
:
"^0.28.3"
,
"zod"
:
"^3.11.6"
"typedoc"
:
"^0.24.8"
,
"typescript"
:
"^5.1.6"
,
"viem"
:
"^1.6.0"
,
"vitest"
:
"^0.34.2"
,
"zod"
:
"^3.22.1"
},
"dependencies"
:
{
"@eth-optimism/contracts"
:
"0.6.0"
,
"@eth-optimism/contracts-bedrock"
:
"0.16.0"
,
"@eth-optimism/core-utils"
:
"0.12.3"
,
"@types/chai"
:
"^4.2.18"
,
"@types/chai-as-promised"
:
"^7.1.4"
,
"@types/mocha"
:
"^10.0.1"
,
"@types/node"
:
"^20.5.0"
,
"@eth-optimism/contracts-bedrock"
:
"workspace:*"
,
"@eth-optimism/core-utils"
:
"workspace:*"
,
"lodash"
:
"^4.17.21"
,
"merkletreejs"
:
"^0.
2.27
"
,
"merkletreejs"
:
"^0.
3.10
"
,
"rlp"
:
"^2.2.7"
},
"peerDependencies"
:
{
...
...
packages/web3js-plugin/CHANGELOG.md
View file @
dade91a8
# @eth-optimism/web3.js-plugin
## 0.1.2
### Patch Changes
-
[
#6873
](
https://github.com/ethereum-optimism/optimism/pull/6873
)
[
`fdab6caa7`
]
(https://github.com/ethereum-optimism/optimism/commit/fdab6caa7e6684b08882d2a766ccd727068c2b2f) Thanks
[
@spacesailor24
](
https://github.com/spacesailor24
)
! - Update code exmaples in README
## 0.1.1
### Patch Changes
...
...
packages/web3js-plugin/README.md
View file @
dade91a8
...
...
@@ -28,10 +28,10 @@ yarn add @eth-optimism/web3.js-plugin
```
typescript
import
Web3
from
'
web3
'
import
OptimismFeeEstimationPlugin
from
'
@eth-optimism/web3.js-plugin
'
import
{
OptimismPlugin
}
from
'
@eth-optimism/web3.js-plugin
'
const
web3
=
new
Web3
(
'
http://yourProvider.com
'
)
web3
.
registerPlugin
(
new
Optimism
FeeEstimation
Plugin
())
web3
.
registerPlugin
(
new
OptimismPlugin
())
```
You will now have access to the following functions under the
`op`
namespace, i.e.
`web3.op.someMethod`
...
...
@@ -76,12 +76,15 @@ async estimateFees(transaction: Transaction, returnFormat?: ReturnFormat)
```
typescript
import
Web3
from
'
web3
'
import
{
OptimismPlugin
}
from
'
@eth-optimism/web3.js-plugin
'
import
{
l2StandardBridgeABI
,
l2StandardBridgeAddress
,
}
from
'
@eth-optimism/contracts-ts
'
const
web3
=
new
Web3
(
'
https://mainnet.optimism.io
'
)
web3
.
registerPlugin
(
new
OptimismPlugin
())
const
l2BridgeContract
=
new
web3
.
eth
.
Contract
(
l2StandardBridgeABI
,
optimistAddress
[
420
]
...
...
@@ -117,12 +120,15 @@ console.log(totalFee) // 26608988767659n
```
typescript
import
Web3
from
'
web3
'
import
{
OptimismPlugin
}
from
'
@eth-optimism/web3.js-plugin
'
import
{
l2StandardBridgeABI
,
l2StandardBridgeAddress
,
}
from
'
@eth-optimism/contracts-ts
'
const
web3
=
new
Web3
(
'
https://mainnet.optimism.io
'
)
web3
.
registerPlugin
(
new
OptimismPlugin
())
const
l2BridgeContract
=
new
web3
.
eth
.
Contract
(
l2StandardBridgeABI
,
optimistAddress
[
420
]
...
...
packages/web3js-plugin/package.json
View file @
dade91a8
{
"name"
:
"@eth-optimism/web3.js-plugin"
,
"version"
:
"0.1.
1
"
,
"version"
:
"0.1.
2
"
,
"description"
:
"A Web3.js plugin for doing OP-Chain gas estimation"
,
"license"
:
"MIT"
,
"repository"
:
{
...
...
pnpm-lock.yaml
View file @
dade91a8
This diff is collapsed.
Click to expand it.
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