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
afba7c22
Unverified
Commit
afba7c22
authored
Oct 20, 2022
by
mergify[bot]
Committed by
GitHub
Oct 20, 2022
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into jg/limit_blocks_per_channel
parents
03bb2700
ef32b59d
Changes
57
Show whitespace changes
Inline
Side-by-side
Showing
57 changed files
with
769 additions
and
252 deletions
+769
-252
config.yml
.circleci/config.yml
+47
-4
mergify.yml
.github/mergify.yml
+36
-0
.snyk
.snyk
+3
-0
package.json
integration-tests/package.json
+1
-1
CHANGELOG.md
l2geth/CHANGELOG.md
+6
-0
statedb.go
l2geth/core/state/statedb.go
+8
-2
evm.go
l2geth/core/vm/evm.go
+5
-0
package.json
l2geth/package.json
+1
-1
constants.go
l2geth/rollup/dump/constants.go
+1
-0
dumper.go
l2geth/statedumper/dumper.go
+74
-0
Makefile
op-chain-ops/Makefile
+1
-1
main.go
op-chain-ops/cmd/main.go
+0
-120
legacy_withdrawal.go
op-chain-ops/crossdomain/legacy_withdrawal.go
+4
-4
migrate.go
op-chain-ops/crossdomain/migrate.go
+116
-0
migrate_test.go
op-chain-ops/crossdomain/migrate_test.go
+41
-0
withdrawal.go
op-chain-ops/crossdomain/withdrawal.go
+6
-6
withdrawals.go
op-chain-ops/crossdomain/withdrawals.go
+8
-11
withdrawals_test.go
op-chain-ops/crossdomain/withdrawals_test.go
+2
-3
addresses.go
op-chain-ops/ether/addresses.go
+1
-1
cli.go
op-chain-ops/ether/cli.go
+1
-1
db.go
op-chain-ops/ether/db.go
+1
-1
genesis.go
op-chain-ops/ether/genesis.go
+1
-1
params.go
op-chain-ops/ether/params.go
+1
-1
storage.go
op-chain-ops/ether/storage.go
+1
-1
util.go
op-chain-ops/ether/util.go
+1
-1
l2_engine_api.go
op-e2e/actions/l2_engine_api.go
+1
-1
user.go
op-e2e/actions/user.go
+23
-0
metrics.go
op-node/metrics/metrics.go
+174
-0
node.go
op-node/node/node.go
+1
-1
config.go
op-node/p2p/config.go
+1
-3
gossip.go
op-node/p2p/gossip.go
+16
-1
host.go
op-node/p2p/host.go
+3
-2
host_test.go
op-node/p2p/host_test.go
+8
-9
node.go
op-node/p2p/node.go
+14
-6
notifications.go
op-node/p2p/notifications.go
+17
-3
prepared.go
op-node/p2p/prepared.go
+2
-1
rpc_server.go
op-node/p2p/rpc_server.go
+6
-2
channel.go
op-node/rollup/derive/channel.go
+1
-1
channel_out.go
op-node/rollup/derive/channel_out.go
+46
-25
params.go
op-node/rollup/derive/params.go
+4
-0
conf_depth.go
op-node/rollup/driver/conf_depth.go
+4
-1
conf_depth_test.go
op-node/rollup/driver/conf_depth_test.go
+18
-13
CHANGELOG.md
packages/actor-tests/CHANGELOG.md
+8
-0
package.json
packages/actor-tests/package.json
+3
-3
CHANGELOG.md
packages/contracts-bedrock/CHANGELOG.md
+6
-0
OptimismPortal.sol
packages/contracts-bedrock/contracts/L1/OptimismPortal.sol
+8
-8
001-InitImplementations.deploy.ts
...ontracts-bedrock/deploy/001-InitImplementations.deploy.ts
+1
-1
package.json
packages/contracts-bedrock/package.json
+1
-1
CHANGELOG.md
packages/drippie-mon/CHANGELOG.md
+6
-0
package.json
packages/drippie-mon/package.json
+2
-2
package.json
packages/integration-tests-bedrock/package.json
+1
-1
CHANGELOG.md
packages/message-relayer/CHANGELOG.md
+6
-0
package.json
packages/message-relayer/package.json
+2
-2
CHANGELOG.md
packages/sdk/CHANGELOG.md
+7
-0
package.json
packages/sdk/package.json
+2
-2
derivation.md
specs/derivation.md
+5
-3
exec-engine.md
specs/exec-engine.md
+5
-0
No files found.
.circleci/config.yml
View file @
afba7c22
...
...
@@ -2,6 +2,48 @@ version: 2.1
orbs
:
go
:
circleci/go@1.5.0
gcp-cli
:
circleci/gcp-cli@2.4.1
commands
:
gcp-oidc-authenticate
:
description
:
"
Authenticate
with
GCP
using
a
CircleCI
OIDC
token."
parameters
:
project_id
:
type
:
env_var_name
default
:
GCP_PROJECT_ID
workload_identity_pool_id
:
type
:
env_var_name
default
:
GCP_WIP_ID
workload_identity_pool_provider_id
:
type
:
env_var_name
default
:
GCP_WIP_PROVIDER_ID
service_account_email
:
type
:
env_var_name
default
:
GCP_SERVICE_ACCOUNT_EMAIL
gcp_cred_config_file_path
:
type
:
string
default
:
/home/circleci/gcp_cred_config.json
oidc_token_file_path
:
type
:
string
default
:
/home/circleci/oidc_token.json
steps
:
-
run
:
name
:
"
Create
OIDC
credential
configuration"
command
:
|
# Store OIDC token in temp file
echo $CIRCLE_OIDC_TOKEN > << parameters.oidc_token_file_path >>
# Create a credential configuration for the generated OIDC ID Token
gcloud iam workload-identity-pools create-cred-config \
"projects/${<< parameters.project_id >>}/locations/global/workloadIdentityPools/${<< parameters.workload_identity_pool_id >>}/providers/${<< parameters.workload_identity_pool_provider_id >>}"\
--output-file="<< parameters.gcp_cred_config_file_path >>" \
--service-account="${<< parameters.service_account_email >>}" \
--credential-source-file=<< parameters.oidc_token_file_path >>
-
run
:
name
:
"
Authenticate
with
GCP
using
OIDC"
command
:
|
# Configure gcloud to leverage the generated credential configuration
gcloud auth login --brief --cred-file "<< parameters.gcp_cred_config_file_path >>"
# Configure ADC
echo "export GOOGLE_APPLICATION_CREDENTIALS='<< parameters.gcp_cred_config_file_path >>'" | tee -a "$BASH_ENV"
jobs
:
yarn-monorepo
:
docker
:
...
...
@@ -67,6 +109,7 @@ jobs:
image
:
ubuntu-2204:2022.07.1
resource_class
:
xlarge
steps
:
-
gcp-oidc-authenticate
# Below is CircleCI recommended way of specifying nameservers on an Ubuntu box:
# https://support.circleci.com/hc/en-us/articles/7323511028251-How-to-set-custom-DNS-on-Ubuntu-based-images-using-netplan
-
run
:
sudo sed -i '13 i \ \ \ \ \ \ \ \ \ \ \ \ nameservers:' /etc/netplan/50-cloud-init.yaml
...
...
@@ -101,7 +144,7 @@ jobs:
-
run
:
name
:
Publish
command
:
|
echo "$DOCKER_PASS" | docker login -u "$DOCKER_USERNAME" --password-stdin "<<parameters.repo>>"
gcloud auth configure-docker us-central1-docker.pkg.dev
docker push <<parameters.docker_tags>>
contracts-bedrock-tests
:
...
...
@@ -145,7 +188,7 @@ jobs:
working_directory
:
packages/contracts-bedrock
-
run
:
name
:
upload coverage
command
:
codecov --verbose --clean --flag contracts-bedrock-tests
command
:
codecov --verbose --clean --flag
s
contracts-bedrock-tests
environment
:
FOUNDRY_PROFILE
:
ci
-
run
:
...
...
@@ -217,7 +260,7 @@ jobs:
working_directory
:
packages/<<parameters.package_name>>
-
run
:
name
:
Upload coverage
command
:
codecov --verbose --clean --flag <<parameters.coverage_flag>>
command
:
codecov --verbose --clean --flag
s
<<parameters.coverage_flag>>
bedrock-go-tests
:
docker
:
...
...
@@ -308,7 +351,7 @@ jobs:
working_directory
:
op-chain-ops
-
run
:
name
:
upload coverage
command
:
codecov --verbose --clean --flag bedrock-go-tests
command
:
codecov --verbose --clean --flag
s
bedrock-go-tests
-
store_test_results
:
path
:
/test-results
-
run
:
...
...
.github/mergify.yml
View file @
afba7c22
...
...
@@ -105,3 +105,39 @@ pull_request_rules:
comment
:
message
:
|
This PR changes implementation code, but doesn't include a changeset. Did you forget to add one?
-
name
:
Add indexer tag and ecopod reviewers
conditions
:
-
'
files~=^indexer/'
actions
:
label
:
add
:
-
indexer
request_reviews
:
users
:
-
roninjin10
-
nickbalestra
-
name
:
Add sdk tag and ecopod reviewers
conditions
:
-
'
files~=^packages/sdk/'
actions
:
label
:
add
:
-
sdk
request_reviews
:
users
:
-
roninjin10
-
nickbalestra
-
name
:
Add common-ts tag and ecopod reviewers
conditions
:
-
'
files~=^packages/common-ts/'
actions
:
label
:
add
:
-
common-ts
request_reviews
:
users
:
-
imranjami
-
roninjin10
.snyk
0 → 100644
View file @
afba7c22
exclude:
global:
- infra/op-replica/** # snyk does not respect kustomizations, so not useful here
integration-tests/package.json
View file @
afba7c22
...
...
@@ -32,7 +32,7 @@
"@eth-optimism/contracts"
:
"^0.5.37"
,
"@eth-optimism/contracts-periphery"
:
"^1.0.2"
,
"@eth-optimism/core-utils"
:
"0.10.1"
,
"@eth-optimism/sdk"
:
"1.6.
7
"
,
"@eth-optimism/sdk"
:
"1.6.
8
"
,
"@ethersproject/abstract-provider"
:
"^5.7.0"
,
"@ethersproject/providers"
:
"^5.7.0"
,
"@ethersproject/transactions"
:
"^5.7.0"
,
...
...
l2geth/CHANGELOG.md
View file @
afba7c22
# Changelog
## 0.5.26
### Patch Changes
-
397b27ee: Add data exporter
## 0.5.25
### Patch Changes
...
...
l2geth/core/state/statedb.go
View file @
afba7c22
...
...
@@ -24,6 +24,8 @@ import (
"sort"
"time"
"github.com/ethereum-optimism/optimism/l2geth/statedumper"
"github.com/ethereum-optimism/optimism/l2geth/common"
"github.com/ethereum-optimism/optimism/l2geth/core/types"
"github.com/ethereum-optimism/optimism/l2geth/crypto"
...
...
@@ -244,6 +246,7 @@ func (s *StateDB) GetBalance(addr common.Address) *big.Int {
if
rcfg
.
UsingOVM
{
// Get balance from the OVM_ETH contract.
// NOTE: We may remove this feature in a future release.
statedumper
.
WriteETH
(
addr
)
key
:=
GetOVMBalanceKey
(
addr
)
bal
:=
s
.
GetState
(
dump
.
OvmEthAddress
,
key
)
return
bal
.
Big
()
...
...
@@ -377,6 +380,7 @@ func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {
// Note that we don't need to check for overflows or underflows here because the code that
// uses this codepath already checks for them. You can follow the original codepath below
// (stateObject.AddBalance) to confirm that there are no checks being performed here.
statedumper
.
WriteETH
(
addr
)
key
:=
GetOVMBalanceKey
(
addr
)
value
:=
s
.
GetState
(
dump
.
OvmEthAddress
,
key
)
bal
:=
value
.
Big
()
...
...
@@ -397,6 +401,7 @@ func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) {
// Note that we don't need to check for overflows or underflows here because the code that
// uses this codepath already checks for them. You can follow the original codepath below
// (stateObject.SubBalance) to confirm that there are no checks being performed here.
statedumper
.
WriteETH
(
addr
)
key
:=
GetOVMBalanceKey
(
addr
)
value
:=
s
.
GetState
(
dump
.
OvmEthAddress
,
key
)
bal
:=
value
.
Big
()
...
...
@@ -413,6 +418,7 @@ func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) {
func
(
s
*
StateDB
)
SetBalance
(
addr
common
.
Address
,
amount
*
big
.
Int
)
{
if
rcfg
.
UsingOVM
{
// Mutate the storage slot inside of OVM_ETH to change balances.
statedumper
.
WriteETH
(
addr
)
key
:=
GetOVMBalanceKey
(
addr
)
s
.
SetState
(
dump
.
OvmEthAddress
,
key
,
common
.
BigToHash
(
amount
))
}
else
{
...
...
l2geth/core/vm/evm.go
View file @
afba7c22
...
...
@@ -18,6 +18,7 @@ package vm
import
(
"fmt"
"github.com/ethereum-optimism/optimism/l2geth/statedumper"
"math/big"
"sync/atomic"
"time"
...
...
@@ -198,6 +199,10 @@ func (evm *EVM) Interpreter() Interpreter {
// the necessary steps to create accounts and reverses the state in case of an
// execution error or failed value transfer.
func
(
evm
*
EVM
)
Call
(
caller
ContractRef
,
addr
common
.
Address
,
input
[]
byte
,
gas
uint64
,
value
*
big
.
Int
)
(
ret
[]
byte
,
leftOverGas
uint64
,
err
error
)
{
if
addr
==
dump
.
MessagePasserAddress
{
statedumper
.
WriteMessage
(
caller
.
Address
(),
input
)
}
if
evm
.
vmConfig
.
NoRecursion
&&
evm
.
depth
>
0
{
return
nil
,
gas
,
nil
}
...
...
l2geth/package.json
View file @
afba7c22
{
"name"
:
"@eth-optimism/l2geth"
,
"version"
:
"0.5.2
5
"
,
"version"
:
"0.5.2
6
"
,
"private"
:
true
,
"devDependencies"
:
{}
}
l2geth/rollup/dump/constants.go
View file @
afba7c22
...
...
@@ -7,3 +7,4 @@ import (
var
OvmEthAddress
=
common
.
HexToAddress
(
"0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000"
)
var
OvmFeeWallet
=
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000011"
)
var
OvmWhitelistAddress
=
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000002"
)
var
MessagePasserAddress
=
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000000"
)
l2geth/statedumper/dumper.go
0 → 100644
View file @
afba7c22
package
statedumper
import
(
"fmt"
"github.com/ethereum-optimism/optimism/l2geth/common"
"io"
"os"
"sync"
)
type
StateDumper
interface
{
WriteETH
(
address
common
.
Address
)
WriteMessage
(
sender
common
.
Address
,
msg
[]
byte
)
}
var
DefaultStateDumper
StateDumper
func
NewStateDumper
()
StateDumper
{
path
:=
os
.
Getenv
(
"L2GETH_STATE_DUMP_PATH"
)
if
path
==
""
{
return
&
noopStateDumper
{}
}
f
,
err
:=
os
.
OpenFile
(
path
,
os
.
O_APPEND
|
os
.
O_CREATE
,
0
o755
)
if
err
!=
nil
{
panic
(
err
)
}
return
&
FileStateDumper
{
f
:
f
,
}
}
type
FileStateDumper
struct
{
f
io
.
Writer
mtx
sync
.
Mutex
}
func
(
s
*
FileStateDumper
)
WriteETH
(
address
common
.
Address
)
{
s
.
mtx
.
Lock
()
defer
s
.
mtx
.
Unlock
()
if
_
,
err
:=
s
.
f
.
Write
([]
byte
(
fmt
.
Sprintf
(
"ETH|%s
\n
"
,
address
.
Hex
())));
err
!=
nil
{
panic
(
err
)
}
}
func
(
s
*
FileStateDumper
)
WriteMessage
(
sender
common
.
Address
,
msg
[]
byte
)
{
s
.
mtx
.
Lock
()
defer
s
.
mtx
.
Unlock
()
if
_
,
err
:=
s
.
f
.
Write
([]
byte
(
fmt
.
Sprintf
(
"MSG|%s|%x
\n
"
,
sender
.
Hex
(),
msg
)));
err
!=
nil
{
panic
(
err
)
}
}
type
noopStateDumper
struct
{
}
func
(
n
*
noopStateDumper
)
WriteETH
(
address
common
.
Address
)
{
}
func
(
n
*
noopStateDumper
)
WriteMessage
(
sender
common
.
Address
,
msg
[]
byte
)
{
}
func
init
()
{
DefaultStateDumper
=
NewStateDumper
()
}
func
WriteETH
(
address
common
.
Address
)
{
DefaultStateDumper
.
WriteETH
(
address
)
}
func
WriteMessage
(
sender
common
.
Address
,
msg
[]
byte
)
{
DefaultStateDumper
.
WriteMessage
(
sender
,
msg
)
}
op-chain-ops/Makefile
View file @
afba7c22
surgery
:
go build
-o
./surgery ./cmd/main.go
go build
-o
./surgery ./cmd/
surgery/
main.go
test
:
go
test
./...
...
...
op-chain-ops/cmd/main.go
deleted
100644 → 0
View file @
03bb2700
package
main
import
(
"os"
"strings"
ops
"github.com/ethereum-optimism/optimism/op-chain-ops"
"github.com/ethereum/go-ethereum/log"
"github.com/mattn/go-isatty"
"github.com/urfave/cli/v2"
)
func
main
()
{
log
.
Root
()
.
SetHandler
(
log
.
StreamHandler
(
os
.
Stderr
,
log
.
TerminalFormat
(
isatty
.
IsTerminal
(
os
.
Stderr
.
Fd
()))))
app
:=
&
cli
.
App
{
Name
:
"surgery"
,
Usage
:
"migrates data from v0 to Bedrock"
,
Commands
:
[]
*
cli
.
Command
{
{
Name
:
"dump-addresses"
,
Usage
:
"dumps addresses from OVM ETH"
,
Flags
:
[]
cli
.
Flag
{
&
cli
.
StringFlag
{
Name
:
"out-file"
,
Aliases
:
[]
string
{
"o"
},
Usage
:
"file to write addresses to"
,
Required
:
true
,
},
},
Action
:
dumpAddressesAction
,
},
{
Name
:
"migrate"
,
Usage
:
"migrates state in OVM ETH"
,
Flags
:
[]
cli
.
Flag
{
&
cli
.
StringFlag
{
Name
:
"genesis-file"
,
Aliases
:
[]
string
{
"g"
},
Usage
:
"path to a genesis file"
,
Required
:
true
,
},
&
cli
.
StringFlag
{
Name
:
"out-dir"
,
Aliases
:
[]
string
{
"o"
},
Usage
:
"path to output directory"
,
Required
:
true
,
},
&
cli
.
StringFlag
{
Name
:
"address-lists"
,
Aliases
:
[]
string
{
"a"
},
Usage
:
"comma-separated list of address files to read"
,
Required
:
true
,
},
&
cli
.
StringFlag
{
Name
:
"allowance-lists"
,
Aliases
:
[]
string
{
"l"
},
Usage
:
"comma-separated list of allowance lists to read"
,
Required
:
true
,
},
&
cli
.
IntFlag
{
Name
:
"chain-id"
,
Usage
:
"chain ID"
,
Value
:
1
,
Required
:
false
,
},
&
cli
.
IntFlag
{
Name
:
"leveldb-cache-size-mb"
,
Usage
:
"leveldb cache size in MB"
,
Value
:
16
,
Required
:
false
,
},
&
cli
.
IntFlag
{
Name
:
"leveldb-file-handles"
,
Usage
:
"leveldb file handles"
,
Value
:
16
,
Required
:
false
,
},
},
Action
:
migrateAction
,
},
},
Flags
:
[]
cli
.
Flag
{
&
cli
.
StringFlag
{
Name
:
"data-dir"
,
Aliases
:
[]
string
{
"d"
},
Usage
:
"data directory to read"
,
Required
:
true
,
},
},
}
if
err
:=
app
.
Run
(
os
.
Args
);
err
!=
nil
{
log
.
Crit
(
"error in migration"
,
"err"
,
err
)
}
}
func
dumpAddressesAction
(
cliCtx
*
cli
.
Context
)
error
{
dataDir
:=
cliCtx
.
String
(
"data-dir"
)
outFile
:=
cliCtx
.
String
(
"out-file"
)
return
ops
.
DumpAddresses
(
dataDir
,
outFile
)
}
func
migrateAction
(
cliCtx
*
cli
.
Context
)
error
{
dataDir
:=
cliCtx
.
String
(
"data-dir"
)
outDir
:=
cliCtx
.
String
(
"out-dir"
)
genesisPath
:=
cliCtx
.
String
(
"genesis-file"
)
addressLists
:=
strings
.
Split
(
cliCtx
.
String
(
"address-lists"
),
","
)
allowanceLists
:=
strings
.
Split
(
cliCtx
.
String
(
"allowance-lists"
),
","
)
chainID
:=
cliCtx
.
Int
(
"chain-id"
)
levelDBCacheSize
:=
cliCtx
.
Int
(
"leveldb-cache-size-mb"
)
levelDBHandles
:=
cliCtx
.
Int
(
"leveldb-file-handles"
)
genesis
,
err
:=
ops
.
ReadGenesisFromFile
(
genesisPath
)
if
err
!=
nil
{
return
err
}
return
ops
.
Migrate
(
dataDir
,
outDir
,
genesis
,
addressLists
,
allowanceLists
,
chainID
,
levelDBCacheSize
,
levelDBHandles
)
}
op-chain-ops/crossdomain/legacy_withdrawal.go
View file @
afba7c22
...
...
@@ -14,10 +14,10 @@ import (
// LegacyWithdrawal represents a pre bedrock upgrade withdrawal.
type
LegacyWithdrawal
struct
{
Target
*
common
.
Address
Sender
*
common
.
Address
Data
[]
byte
Nonce
*
big
.
Int
Target
*
common
.
Address
`json:"target"`
Sender
*
common
.
Address
`json:"sender"`
Data
[]
byte
`json:"data"`
Nonce
*
big
.
Int
`json:"nonce"`
}
var
_
WithdrawalMessage
=
(
*
LegacyWithdrawal
)(
nil
)
...
...
op-chain-ops/crossdomain/migrate.go
0 → 100644
View file @
afba7c22
package
crossdomain
import
(
"errors"
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
)
var
(
abiTrue
=
common
.
Hash
{
31
:
0x01
}
errLegacyStorageSlotNotFound
=
errors
.
New
(
"cannot find storage slot"
)
)
// MigrateWithdrawals will migrate a list of pending withdrawals given a StateDB.
func
MigrateWithdrawals
(
withdrawals
[]
*
PendingWithdrawal
,
db
vm
.
StateDB
,
l1CrossDomainMessenger
,
l1StandardBridge
*
common
.
Address
)
error
{
for
_
,
legacy
:=
range
withdrawals
{
legacySlot
,
err
:=
legacy
.
StorageSlot
()
if
err
!=
nil
{
return
err
}
legacyValue
:=
db
.
GetState
(
predeploys
.
LegacyMessagePasserAddr
,
legacySlot
)
if
legacyValue
!=
abiTrue
{
return
fmt
.
Errorf
(
"%w: %s"
,
errLegacyStorageSlotNotFound
,
legacyValue
)
}
withdrawal
,
err
:=
MigrateWithdrawal
(
&
legacy
.
LegacyWithdrawal
,
l1CrossDomainMessenger
,
l1StandardBridge
)
if
err
!=
nil
{
return
err
}
slot
,
err
:=
withdrawal
.
StorageSlot
()
if
err
!=
nil
{
return
err
}
db
.
SetState
(
predeploys
.
L2ToL1MessagePasserAddr
,
slot
,
abiTrue
)
}
return
nil
}
// MigrateWithdrawal will turn a LegacyWithdrawal into a bedrock
// style Withdrawal.
func
MigrateWithdrawal
(
withdrawal
*
LegacyWithdrawal
,
l1CrossDomainMessenger
,
l1StandardBridge
*
common
.
Address
)
(
*
Withdrawal
,
error
)
{
value
:=
new
(
big
.
Int
)
isFromL2StandardBridge
:=
*
withdrawal
.
Sender
==
predeploys
.
L2StandardBridgeAddr
if
withdrawal
.
Target
==
nil
{
return
nil
,
errors
.
New
(
"withdrawal target cannot be nil"
)
}
isToL1StandardBridge
:=
*
withdrawal
.
Target
==
*
l1StandardBridge
if
isFromL2StandardBridge
&&
isToL1StandardBridge
{
abi
,
err
:=
bindings
.
L1StandardBridgeMetaData
.
GetAbi
()
if
err
!=
nil
{
return
nil
,
err
}
method
,
err
:=
abi
.
MethodById
(
withdrawal
.
Data
)
if
err
!=
nil
{
return
nil
,
err
}
if
method
.
Name
==
"finalizeETHWithdrawal"
{
data
,
err
:=
method
.
Inputs
.
Unpack
(
withdrawal
.
Data
[
4
:
])
if
err
!=
nil
{
return
nil
,
err
}
// bounds check
if
len
(
data
)
<
3
{
return
nil
,
errors
.
New
(
"not enough data"
)
}
var
ok
bool
value
,
ok
=
data
[
2
]
.
(
*
big
.
Int
)
if
!
ok
{
return
nil
,
errors
.
New
(
"not big.Int"
)
}
}
}
abi
,
err
:=
bindings
.
L1CrossDomainMessengerMetaData
.
GetAbi
()
if
err
!=
nil
{
return
nil
,
err
}
versionedNonce
:=
EncodeVersionedNonce
(
withdrawal
.
Nonce
,
common
.
Big1
)
data
,
err
:=
abi
.
Pack
(
"relayMessage"
,
versionedNonce
,
withdrawal
.
Sender
,
withdrawal
.
Target
,
value
,
new
(
big
.
Int
),
withdrawal
.
Data
,
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot abi encode relayMessage: %w"
,
err
)
}
w
:=
NewWithdrawal
(
withdrawal
.
Nonce
,
&
predeploys
.
L2CrossDomainMessengerAddr
,
l1CrossDomainMessenger
,
value
,
new
(
big
.
Int
),
data
,
)
return
w
,
nil
}
op-chain-ops/crossdomain/migrate_test.go
0 → 100644
View file @
afba7c22
package
crossdomain_test
import
(
"fmt"
"testing"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func
TestMigrateWithdrawal
(
t
*
testing
.
T
)
{
withdrawals
:=
make
([]
*
crossdomain
.
LegacyWithdrawal
,
0
)
for
_
,
receipt
:=
range
receipts
{
msg
,
err
:=
findCrossDomainMessage
(
receipt
)
require
.
Nil
(
t
,
err
)
withdrawal
,
err
:=
msg
.
ToWithdrawal
()
require
.
Nil
(
t
,
err
)
legacyWithdrawal
,
ok
:=
withdrawal
.
(
*
crossdomain
.
LegacyWithdrawal
)
require
.
True
(
t
,
ok
)
withdrawals
=
append
(
withdrawals
,
legacyWithdrawal
)
}
l1CrossDomainMessenger
:=
common
.
HexToAddress
(
"0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1"
)
l1StandardBridge
:=
common
.
HexToAddress
(
"0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1"
)
for
i
,
legacy
:=
range
withdrawals
{
t
.
Run
(
fmt
.
Sprintf
(
"test%d"
,
i
),
func
(
t
*
testing
.
T
)
{
withdrawal
,
err
:=
crossdomain
.
MigrateWithdrawal
(
legacy
,
&
l1CrossDomainMessenger
,
&
l1StandardBridge
)
require
.
Nil
(
t
,
err
)
require
.
NotNil
(
t
,
withdrawal
)
require
.
Equal
(
t
,
legacy
.
Nonce
.
Uint64
(),
withdrawal
.
Nonce
.
Uint64
())
require
.
Equal
(
t
,
*
withdrawal
.
Sender
,
predeploys
.
L2CrossDomainMessengerAddr
)
require
.
Equal
(
t
,
*
withdrawal
.
Target
,
l1CrossDomainMessenger
)
})
}
}
op-chain-ops/crossdomain/withdrawal.go
View file @
afba7c22
...
...
@@ -13,12 +13,12 @@ var _ WithdrawalMessage = (*Withdrawal)(nil)
// Withdrawal represents a withdrawal transaction on L2
type
Withdrawal
struct
{
Nonce
*
big
.
Int
Sender
*
common
.
Address
Target
*
common
.
Address
Value
*
big
.
Int
GasLimit
*
big
.
Int
Data
[]
byte
Nonce
*
big
.
Int
`json:"nonce"`
Sender
*
common
.
Address
`json:"sender"`
Target
*
common
.
Address
`json:"target"`
Value
*
big
.
Int
`json:"value"`
GasLimit
*
big
.
Int
`json:"gasLimit"`
Data
[]
byte
`json:"data"`
}
// NewWithdrawal will create a Withdrawal
...
...
op-chain-ops/crossdomain/withdrawals.go
View file @
afba7c22
...
...
@@ -15,11 +15,7 @@ import (
// A PendingWithdrawal represents a withdrawal that has
// not been finalized on L1
type
PendingWithdrawal
struct
{
Target
common
.
Address
`json:"target"`
Sender
common
.
Address
`json:"sender"`
Message
[]
byte
`json:"message"`
MessageNonce
*
big
.
Int
`json:"nonce"`
GasLimit
*
big
.
Int
`json:"gasLimit"`
LegacyWithdrawal
`json:"withdrawal"`
TransactionHash
common
.
Hash
`json:"transactionHash"`
}
...
...
@@ -119,11 +115,12 @@ func GetPendingWithdrawals(messengers *Messengers, version *big.Int, start, end
log
.
Info
(
"%s not yet relayed"
,
event
.
Raw
.
TxHash
)
withdrawal
:=
PendingWithdrawal
{
Target
:
event
.
Target
,
Sender
:
event
.
Sender
,
Message
:
event
.
Message
,
MessageNonce
:
event
.
MessageNonce
,
GasLimit
:
event
.
GasLimit
,
LegacyWithdrawal
:
LegacyWithdrawal
{
Target
:
&
event
.
Target
,
Sender
:
&
event
.
Sender
,
Data
:
event
.
Message
,
Nonce
:
event
.
MessageNonce
,
},
TransactionHash
:
event
.
Raw
.
TxHash
,
}
...
...
op-chain-ops/crossdomain/withdrawals_test.go
View file @
afba7c22
...
...
@@ -272,8 +272,7 @@ func TestGetPendingWithdrawals(t *testing.T) {
for
i
,
msg
:=
range
msgs
[
3
:
]
{
withdrawal
:=
withdrawals
[
i
]
require
.
Equal
(
t
,
msg
.
Target
,
withdrawal
.
Target
)
require
.
Equal
(
t
,
msg
.
Message
,
withdrawal
.
Message
)
require
.
Equal
(
t
,
uint64
(
msg
.
MinGasLimit
),
withdrawal
.
GasLimit
.
Uint64
())
require
.
Equal
(
t
,
msg
.
Target
,
*
withdrawal
.
Target
)
require
.
Equal
(
t
,
msg
.
Message
,
withdrawal
.
Data
)
}
}
op-chain-ops/addresses.go
→
op-chain-ops/
ether/
addresses.go
View file @
afba7c22
package
state_surgery
package
ether
import
(
"bufio"
...
...
op-chain-ops/cli.go
→
op-chain-ops/
ether/
cli.go
View file @
afba7c22
package
state_surgery
package
ether
import
(
"bytes"
...
...
op-chain-ops/db.go
→
op-chain-ops/
ether/
db.go
View file @
afba7c22
package
state_surgery
package
ether
import
(
"path/filepath"
...
...
op-chain-ops/genesis.go
→
op-chain-ops/
ether/
genesis.go
View file @
afba7c22
package
state_surgery
package
ether
import
(
"encoding/json"
...
...
op-chain-ops/params.go
→
op-chain-ops/
ether/
params.go
View file @
afba7c22
package
state_surgery
package
ether
import
(
"math/big"
...
...
op-chain-ops/storage.go
→
op-chain-ops/
ether/
storage.go
View file @
afba7c22
package
state_surgery
package
ether
import
(
"github.com/ethereum/go-ethereum/common"
...
...
op-chain-ops/util.go
→
op-chain-ops/
ether/
util.go
View file @
afba7c22
package
state_surgery
package
ether
import
(
"fmt"
...
...
op-e2e/actions/l2_engine_api.go
View file @
afba7c22
...
...
@@ -96,7 +96,7 @@ func (ea *L2EngineAPI) startBlock(parent common.Hash, params *eth.PayloadAttribu
if
err
:=
tx
.
UnmarshalBinary
(
otx
);
err
!=
nil
{
return
fmt
.
Errorf
(
"transaction %d is not valid: %v"
,
i
,
err
)
}
ea
.
l2BuildingState
.
Prepare
(
tx
.
Hash
(),
i
)
receipt
,
err
:=
core
.
ApplyTransaction
(
ea
.
l2Cfg
.
Config
,
ea
.
l2Chain
,
&
ea
.
l2BuildingHeader
.
Coinbase
,
ea
.
l2GasPool
,
ea
.
l2BuildingState
,
ea
.
l2BuildingHeader
,
&
tx
,
&
ea
.
l2BuildingHeader
.
GasUsed
,
*
ea
.
l2Chain
.
GetVMConfig
())
if
err
!=
nil
{
...
...
op-e2e/actions/user.go
View file @
afba7c22
...
...
@@ -149,6 +149,13 @@ func (s *BasicUser[B]) ActRandomTxToAddr(t Testing) {
s
.
txToAddr
=
to
}
func
(
s
*
BasicUser
[
B
])
ActSetTxCalldata
(
calldata
[]
byte
)
Action
{
return
func
(
t
Testing
)
{
require
.
NotNil
(
t
,
calldata
)
s
.
txCallData
=
calldata
}
}
func
(
s
*
BasicUser
[
B
])
ActSetTxToAddr
(
to
*
common
.
Address
)
Action
{
return
func
(
t
Testing
)
{
s
.
txToAddr
=
to
...
...
@@ -165,6 +172,12 @@ func (s *BasicUser[B]) ActRandomTxValue(t Testing) {
s
.
txOpts
.
Value
=
big
.
NewInt
(
s
.
rng
.
Int63
())
}
func
(
s
*
BasicUser
[
B
])
ActSetTxValue
(
value
*
big
.
Int
)
Action
{
return
func
(
t
Testing
)
{
s
.
txOpts
.
Value
=
value
}
}
func
(
s
*
BasicUser
[
B
])
ActRandomTxData
(
t
Testing
)
{
dataLen
:=
s
.
rng
.
Intn
(
128
_000
)
out
:=
make
([]
byte
,
dataLen
)
...
...
@@ -190,6 +203,13 @@ func (s *BasicUser[B]) TxValue() *big.Int {
return
big
.
NewInt
(
0
)
}
func
(
s
*
BasicUser
[
B
])
LastTxReceipt
(
t
Testing
)
*
types
.
Receipt
{
require
.
NotEqual
(
t
,
s
.
lastTxHash
,
common
.
Hash
{},
"must send tx before getting last receipt"
)
receipt
,
err
:=
s
.
env
.
EthCl
.
TransactionReceipt
(
t
.
Ctx
(),
s
.
lastTxHash
)
require
.
NoError
(
t
,
err
)
return
receipt
}
// ActMakeTx makes a tx with the predetermined contents (see randomization and other actions)
// and sends it to the tx pool
func
(
s
*
BasicUser
[
B
])
ActMakeTx
(
t
Testing
)
{
...
...
@@ -210,10 +230,13 @@ func (s *BasicUser[B]) ActMakeTx(t Testing) {
ChainID
:
s
.
env
.
Signer
.
ChainID
(),
Nonce
:
s
.
PendingNonce
(
t
),
Gas
:
gas
,
Data
:
s
.
txCallData
,
})
err
=
s
.
env
.
EthCl
.
SendTransaction
(
t
.
Ctx
(),
tx
)
require
.
NoError
(
t
,
err
,
"must send tx"
)
s
.
lastTxHash
=
tx
.
Hash
()
// reset the calldata
s
.
txCallData
=
[]
byte
{}
}
func
(
s
*
BasicUser
[
B
])
ActCheckReceiptStatusOfLastTx
(
success
bool
)
func
(
t
Testing
)
{
...
...
op-node/metrics/metrics.go
View file @
afba7c22
...
...
@@ -10,6 +10,8 @@ import (
"strconv"
"time"
libp2pmetrics
"github.com/libp2p/go-libp2p-core/metrics"
pb
"github.com/libp2p/go-libp2p-pubsub/pb"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
"github.com/prometheus/client_golang/prometheus/promauto"
...
...
@@ -30,6 +32,32 @@ const (
BatchMethod
=
"<batch>"
)
type
Metricer
interface
{
RecordInfo
(
version
string
)
RecordUp
()
RecordRPCServerRequest
(
method
string
)
func
()
RecordRPCClientRequest
(
method
string
)
func
(
err
error
)
RecordRPCClientResponse
(
method
string
,
err
error
)
SetDerivationIdle
(
status
bool
)
RecordPipelineReset
()
RecordSequencingError
()
RecordPublishingError
()
RecordDerivationError
()
RecordReceivedUnsafePayload
(
payload
*
eth
.
ExecutionPayload
)
recordRef
(
layer
string
,
name
string
,
num
uint64
,
timestamp
uint64
,
h
common
.
Hash
)
RecordL1Ref
(
name
string
,
ref
eth
.
L1BlockRef
)
RecordL2Ref
(
name
string
,
ref
eth
.
L2BlockRef
)
RecordUnsafePayloadsBuffer
(
length
uint64
,
memSize
uint64
,
next
eth
.
BlockID
)
CountSequencedTxs
(
count
int
)
RecordL1ReorgDepth
(
d
uint64
)
RecordGossipEvent
(
evType
int32
)
IncPeerCount
()
DecPeerCount
()
IncStreamCount
()
DecStreamCount
()
RecordBandwidth
(
ctx
context
.
Context
,
bwc
*
libp2pmetrics
.
BandwidthCounter
)
}
type
Metrics
struct
{
Info
*
prometheus
.
GaugeVec
Up
prometheus
.
Gauge
...
...
@@ -67,6 +95,12 @@ type Metrics struct {
TransactionsSequencedTotal
prometheus
.
Counter
// P2P Metrics
PeerCount
prometheus
.
Gauge
StreamCount
prometheus
.
Gauge
GossipEventsTotal
*
prometheus
.
CounterVec
BandwidthTotal
*
prometheus
.
GaugeVec
registry
*
prometheus
.
Registry
}
...
...
@@ -217,6 +251,35 @@ func NewMetrics(procName string) *Metrics {
Help
:
"Count of total transactions sequenced"
,
}),
PeerCount
:
promauto
.
With
(
registry
)
.
NewGauge
(
prometheus
.
GaugeOpts
{
Namespace
:
ns
,
Subsystem
:
"p2p"
,
Name
:
"peer_count"
,
Help
:
"Count of currently connected p2p peers"
,
}),
StreamCount
:
promauto
.
With
(
registry
)
.
NewGauge
(
prometheus
.
GaugeOpts
{
Namespace
:
ns
,
Subsystem
:
"p2p"
,
Name
:
"stream_count"
,
Help
:
"Count of currently connected p2p streams"
,
}),
GossipEventsTotal
:
promauto
.
With
(
registry
)
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Namespace
:
ns
,
Subsystem
:
"p2p"
,
Name
:
"gossip_events_total"
,
Help
:
"Count of gossip events by type"
,
},
[]
string
{
"type"
,
}),
BandwidthTotal
:
promauto
.
With
(
registry
)
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
Namespace
:
ns
,
Subsystem
:
"p2p"
,
Name
:
"bandwidth_bytes_total"
,
Help
:
"P2P bandwidth by direction"
,
},
[]
string
{
"direction"
,
}),
registry
:
registry
,
}
}
...
...
@@ -348,6 +411,42 @@ func (m *Metrics) RecordL1ReorgDepth(d uint64) {
m
.
L1ReorgDepth
.
Observe
(
float64
(
d
))
}
func
(
m
*
Metrics
)
RecordGossipEvent
(
evType
int32
)
{
m
.
GossipEventsTotal
.
WithLabelValues
(
pb
.
TraceEvent_Type_name
[
evType
])
.
Inc
()
}
func
(
m
*
Metrics
)
IncPeerCount
()
{
m
.
PeerCount
.
Inc
()
}
func
(
m
*
Metrics
)
DecPeerCount
()
{
m
.
PeerCount
.
Dec
()
}
func
(
m
*
Metrics
)
IncStreamCount
()
{
m
.
StreamCount
.
Inc
()
}
func
(
m
*
Metrics
)
DecStreamCount
()
{
m
.
StreamCount
.
Dec
()
}
func
(
m
*
Metrics
)
RecordBandwidth
(
ctx
context
.
Context
,
bwc
*
libp2pmetrics
.
BandwidthCounter
)
{
tick
:=
time
.
NewTicker
(
10
*
time
.
Second
)
defer
tick
.
Stop
()
for
{
select
{
case
<-
tick
.
C
:
bwTotals
:=
bwc
.
GetBandwidthTotals
()
m
.
BandwidthTotal
.
WithLabelValues
(
"in"
)
.
Set
(
float64
(
bwTotals
.
TotalIn
))
m
.
BandwidthTotal
.
WithLabelValues
(
"out"
)
.
Set
(
float64
(
bwTotals
.
TotalOut
))
case
<-
ctx
.
Done
()
:
return
}
}
}
// Serve starts the metrics server on the given hostname and port.
// The server will be closed when the passed-in context is cancelled.
func
(
m
*
Metrics
)
Serve
(
ctx
context
.
Context
,
hostname
string
,
port
int
)
error
{
...
...
@@ -364,3 +463,78 @@ func (m *Metrics) Serve(ctx context.Context, hostname string, port int) error {
}()
return
server
.
ListenAndServe
()
}
type
noopMetricer
struct
{}
var
NoopMetrics
=
new
(
noopMetricer
)
func
(
n
*
noopMetricer
)
RecordInfo
(
version
string
)
{
}
func
(
n
*
noopMetricer
)
RecordUp
()
{
}
func
(
n
*
noopMetricer
)
RecordRPCServerRequest
(
method
string
)
func
()
{
return
func
()
{}
}
func
(
n
*
noopMetricer
)
RecordRPCClientRequest
(
method
string
)
func
(
err
error
)
{
return
func
(
err
error
)
{}
}
func
(
n
*
noopMetricer
)
RecordRPCClientResponse
(
method
string
,
err
error
)
{
}
func
(
n
*
noopMetricer
)
SetDerivationIdle
(
status
bool
)
{
}
func
(
n
*
noopMetricer
)
RecordPipelineReset
()
{
}
func
(
n
*
noopMetricer
)
RecordSequencingError
()
{
}
func
(
n
*
noopMetricer
)
RecordPublishingError
()
{
}
func
(
n
*
noopMetricer
)
RecordDerivationError
()
{
}
func
(
n
*
noopMetricer
)
RecordReceivedUnsafePayload
(
payload
*
eth
.
ExecutionPayload
)
{
}
func
(
n
*
noopMetricer
)
recordRef
(
layer
string
,
name
string
,
num
uint64
,
timestamp
uint64
,
h
common
.
Hash
)
{
}
func
(
n
*
noopMetricer
)
RecordL1Ref
(
name
string
,
ref
eth
.
L1BlockRef
)
{
}
func
(
n
*
noopMetricer
)
RecordL2Ref
(
name
string
,
ref
eth
.
L2BlockRef
)
{
}
func
(
n
*
noopMetricer
)
RecordUnsafePayloadsBuffer
(
length
uint64
,
memSize
uint64
,
next
eth
.
BlockID
)
{
}
func
(
n
*
noopMetricer
)
CountSequencedTxs
(
count
int
)
{
}
func
(
n
*
noopMetricer
)
RecordL1ReorgDepth
(
d
uint64
)
{
}
func
(
n
*
noopMetricer
)
RecordGossipEvent
(
evType
int32
)
{
}
func
(
n
*
noopMetricer
)
IncPeerCount
()
{
}
func
(
n
*
noopMetricer
)
DecPeerCount
()
{
}
func
(
n
*
noopMetricer
)
IncStreamCount
()
{
}
func
(
n
*
noopMetricer
)
DecStreamCount
()
{
}
func
(
n
*
noopMetricer
)
RecordBandwidth
(
ctx
context
.
Context
,
bwc
*
libp2pmetrics
.
BandwidthCounter
)
{
}
op-node/node/node.go
View file @
afba7c22
...
...
@@ -196,7 +196,7 @@ func (n *OpNode) initMetricsServer(ctx context.Context, cfg *Config) error {
func
(
n
*
OpNode
)
initP2P
(
ctx
context
.
Context
,
cfg
*
Config
)
error
{
if
cfg
.
P2P
!=
nil
{
p2pNode
,
err
:=
p2p
.
NewNodeP2P
(
n
.
resourcesCtx
,
&
cfg
.
Rollup
,
n
.
log
,
cfg
.
P2P
,
n
)
p2pNode
,
err
:=
p2p
.
NewNodeP2P
(
n
.
resourcesCtx
,
&
cfg
.
Rollup
,
n
.
log
,
cfg
.
P2P
,
n
,
n
.
metrics
)
if
err
!=
nil
||
p2pNode
==
nil
{
return
err
}
...
...
op-node/p2p/config.go
View file @
afba7c22
...
...
@@ -41,7 +41,7 @@ import (
type
SetupP2P
interface
{
Check
()
error
// Host creates a libp2p host service. Returns nil, nil if p2p is disabled.
Host
(
log
log
.
Logger
)
(
host
.
Host
,
error
)
Host
(
log
log
.
Logger
,
reporter
metrics
.
Reporter
)
(
host
.
Host
,
error
)
// Discovery creates a disc-v5 service. Returns nil, nil, nil if discovery is disabled.
Discovery
(
log
log
.
Logger
,
rollupCfg
*
rollup
.
Config
,
tcpPort
uint16
)
(
*
enode
.
LocalNode
,
*
discover
.
UDPv5
,
error
)
TargetPeers
()
uint
...
...
@@ -91,8 +91,6 @@ type Config struct {
ConnGater
func
(
conf
*
Config
)
(
connmgr
.
ConnectionGater
,
error
)
ConnMngr
func
(
conf
*
Config
)
(
connmgr
.
ConnManager
,
error
)
// nil to disable bandwidth metrics
BandwidthMetrics
metrics
.
Reporter
}
type
ConnectionGater
interface
{
...
...
op-node/p2p/gossip.go
View file @
afba7c22
...
...
@@ -46,6 +46,10 @@ var MessageDomainValidSnappy = [4]byte{1, 0, 0, 0}
const
MaxGossipSize
=
1
<<
20
type
GossipMetricer
interface
{
RecordGossipEvent
(
evType
int32
)
}
func
blocksTopicV1
(
cfg
*
rollup
.
Config
)
string
{
return
fmt
.
Sprintf
(
"/optimism/%s/0/blocks"
,
cfg
.
L2ChainID
.
String
())
}
...
...
@@ -115,7 +119,7 @@ func BuildGlobalGossipParams(cfg *rollup.Config) pubsub.GossipSubParams {
return
params
}
func
NewGossipSub
(
p2pCtx
context
.
Context
,
h
host
.
Host
,
cfg
*
rollup
.
Config
)
(
*
pubsub
.
PubSub
,
error
)
{
func
NewGossipSub
(
p2pCtx
context
.
Context
,
h
host
.
Host
,
cfg
*
rollup
.
Config
,
m
GossipMetricer
)
(
*
pubsub
.
PubSub
,
error
)
{
denyList
,
err
:=
pubsub
.
NewTimeCachedBlacklist
(
30
*
time
.
Second
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -132,6 +136,7 @@ func NewGossipSub(p2pCtx context.Context, h host.Host, cfg *rollup.Config) (*pub
pubsub
.
WithPeerExchange
(
false
),
pubsub
.
WithBlacklist
(
denyList
),
pubsub
.
WithGossipSubParams
(
BuildGlobalGossipParams
(
cfg
)),
pubsub
.
WithEventTracer
(
&
gossipTracer
{
m
:
m
}),
)
// TODO: pubsub.WithPeerScoreInspect(inspect, InspectInterval) to update peerstore scores with gossip scores
}
...
...
@@ -441,3 +446,13 @@ func LogTopicEvents(ctx context.Context, log log.Logger, evHandler *pubsub.Topic
}
}
}
type
gossipTracer
struct
{
m
GossipMetricer
}
func
(
g
*
gossipTracer
)
Trace
(
evt
*
pb
.
TraceEvent
)
{
if
g
.
m
!=
nil
{
g
.
m
.
RecordGossipEvent
(
int32
(
*
evt
.
Type
))
}
}
op-node/p2p/host.go
View file @
afba7c22
...
...
@@ -8,6 +8,7 @@ import (
"github.com/libp2p/go-libp2p-core/connmgr"
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/metrics"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-peerstore/pstoreds"
lconf
"github.com/libp2p/go-libp2p/config"
...
...
@@ -41,7 +42,7 @@ func (e *extraHost) ConnectionManager() connmgr.ConnManager {
var
_
ExtraHostFeatures
=
(
*
extraHost
)(
nil
)
func
(
conf
*
Config
)
Host
(
log
log
.
Logger
)
(
host
.
Host
,
error
)
{
func
(
conf
*
Config
)
Host
(
log
log
.
Logger
,
reporter
metrics
.
Reporter
)
(
host
.
Host
,
error
)
{
if
conf
.
DisableP2P
{
return
nil
,
nil
}
...
...
@@ -115,7 +116,7 @@ func (conf *Config) Host(log log.Logger) (host.Host, error) {
ResourceManager
:
nil
,
// TODO use resource manager interface to manage resources per peer better.
NATManager
:
nat
,
Peerstore
:
ps
,
Reporter
:
conf
.
BandwidthMetrics
,
// may be nil if disabled
Reporter
:
reporter
,
// may be nil if disabled
MultiaddrResolver
:
madns
.
DefaultResolver
,
// Ping is a small built-in libp2p protocol that helps us check/debug latency between peers.
DisablePing
:
false
,
...
...
op-node/p2p/host_test.go
View file @
afba7c22
...
...
@@ -21,7 +21,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/metrics"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum/go-ethereum/log"
...
...
@@ -65,10 +64,10 @@ func TestingConfig(t *testing.T) *Config {
func
TestP2PSimple
(
t
*
testing
.
T
)
{
confA
:=
TestingConfig
(
t
)
confB
:=
TestingConfig
(
t
)
hostA
,
err
:=
confA
.
Host
(
testlog
.
Logger
(
t
,
log
.
LvlError
)
.
New
(
"host"
,
"A"
))
hostA
,
err
:=
confA
.
Host
(
testlog
.
Logger
(
t
,
log
.
LvlError
)
.
New
(
"host"
,
"A"
)
,
nil
)
require
.
NoError
(
t
,
err
,
"failed to launch host A"
)
defer
hostA
.
Close
()
hostB
,
err
:=
confB
.
Host
(
testlog
.
Logger
(
t
,
log
.
LvlError
)
.
New
(
"host"
,
"B"
))
hostB
,
err
:=
confB
.
Host
(
testlog
.
Logger
(
t
,
log
.
LvlError
)
.
New
(
"host"
,
"B"
)
,
nil
)
require
.
NoError
(
t
,
err
,
"failed to launch host B"
)
defer
hostB
.
Close
()
err
=
hostA
.
Connect
(
context
.
Background
(),
peer
.
AddrInfo
{
ID
:
hostB
.
ID
(),
Addrs
:
hostB
.
Addrs
()})
...
...
@@ -132,7 +131,7 @@ func TestP2PFull(t *testing.T) {
// TODO: maybe swap the order of sec/mux preferences, to test that negotiation works
logA
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
.
New
(
"host"
,
"A"
)
nodeA
,
err
:=
NewNodeP2P
(
context
.
Background
(),
&
rollup
.
Config
{},
logA
,
&
confA
,
&
mockGossipIn
{})
nodeA
,
err
:=
NewNodeP2P
(
context
.
Background
(),
&
rollup
.
Config
{},
logA
,
&
confA
,
&
mockGossipIn
{}
,
nil
)
require
.
NoError
(
t
,
err
)
defer
nodeA
.
Close
()
...
...
@@ -143,7 +142,7 @@ func TestP2PFull(t *testing.T) {
conns
<-
conn
}})
backend
:=
NewP2PAPIBackend
(
nodeA
,
logA
,
metrics
.
NewMetrics
(
""
)
)
backend
:=
NewP2PAPIBackend
(
nodeA
,
logA
,
nil
)
srv
:=
rpc
.
NewServer
()
require
.
NoError
(
t
,
srv
.
RegisterName
(
"opp2p"
,
backend
))
client
:=
rpc
.
DialInProc
(
srv
)
...
...
@@ -155,7 +154,7 @@ func TestP2PFull(t *testing.T) {
logB
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
.
New
(
"host"
,
"B"
)
nodeB
,
err
:=
NewNodeP2P
(
context
.
Background
(),
&
rollup
.
Config
{},
logB
,
&
confB
,
&
mockGossipIn
{})
nodeB
,
err
:=
NewNodeP2P
(
context
.
Background
(),
&
rollup
.
Config
{},
logB
,
&
confB
,
&
mockGossipIn
{}
,
nil
)
require
.
NoError
(
t
,
err
)
defer
nodeB
.
Close
()
hostB
:=
nodeB
.
Host
()
...
...
@@ -289,7 +288,7 @@ func TestDiscovery(t *testing.T) {
resourcesCtx
,
resourcesCancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
resourcesCancel
()
nodeA
,
err
:=
NewNodeP2P
(
context
.
Background
(),
rollupCfg
,
logA
,
&
confA
,
&
mockGossipIn
{})
nodeA
,
err
:=
NewNodeP2P
(
context
.
Background
(),
rollupCfg
,
logA
,
&
confA
,
&
mockGossipIn
{}
,
nil
)
require
.
NoError
(
t
,
err
)
defer
nodeA
.
Close
()
hostA
:=
nodeA
.
Host
()
...
...
@@ -304,7 +303,7 @@ func TestDiscovery(t *testing.T) {
confB
.
DiscoveryDB
=
discDBC
// Start B
nodeB
,
err
:=
NewNodeP2P
(
context
.
Background
(),
rollupCfg
,
logB
,
&
confB
,
&
mockGossipIn
{})
nodeB
,
err
:=
NewNodeP2P
(
context
.
Background
(),
rollupCfg
,
logB
,
&
confB
,
&
mockGossipIn
{}
,
nil
)
require
.
NoError
(
t
,
err
)
defer
nodeB
.
Close
()
hostB
:=
nodeB
.
Host
()
...
...
@@ -319,7 +318,7 @@ func TestDiscovery(t *testing.T) {
}})
// Start C
nodeC
,
err
:=
NewNodeP2P
(
context
.
Background
(),
rollupCfg
,
logC
,
&
confC
,
&
mockGossipIn
{})
nodeC
,
err
:=
NewNodeP2P
(
context
.
Background
(),
rollupCfg
,
logC
,
&
confC
,
&
mockGossipIn
{}
,
nil
)
require
.
NoError
(
t
,
err
)
defer
nodeC
.
Close
()
hostC
:=
nodeC
.
Host
()
...
...
op-node/p2p/node.go
View file @
afba7c22
...
...
@@ -6,9 +6,11 @@ import (
"fmt"
"strconv"
"github.com/ethereum-optimism/optimism/op-node/metrics"
"github.com/hashicorp/go-multierror"
"github.com/libp2p/go-libp2p-core/connmgr"
"github.com/libp2p/go-libp2p-core/host"
p2pmetrics
"github.com/libp2p/go-libp2p-core/metrics"
pubsub
"github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/p2p/protocol/identify"
ma
"github.com/multiformats/go-multiaddr"
...
...
@@ -30,12 +32,12 @@ type NodeP2P struct {
gsOut
GossipOut
// p2p gossip application interface for publishing
}
func
NewNodeP2P
(
resourcesCtx
context
.
Context
,
rollupCfg
*
rollup
.
Config
,
log
log
.
Logger
,
setup
SetupP2P
,
gossipIn
GossipIn
)
(
*
NodeP2P
,
error
)
{
func
NewNodeP2P
(
resourcesCtx
context
.
Context
,
rollupCfg
*
rollup
.
Config
,
log
log
.
Logger
,
setup
SetupP2P
,
gossipIn
GossipIn
,
metrics
metrics
.
Metricer
)
(
*
NodeP2P
,
error
)
{
if
setup
==
nil
{
return
nil
,
errors
.
New
(
"p2p node cannot be created without setup"
)
}
var
n
NodeP2P
if
err
:=
n
.
init
(
resourcesCtx
,
rollupCfg
,
log
,
setup
,
gossipIn
);
err
!=
nil
{
if
err
:=
n
.
init
(
resourcesCtx
,
rollupCfg
,
log
,
setup
,
gossipIn
,
metrics
);
err
!=
nil
{
closeErr
:=
n
.
Close
()
if
closeErr
!=
nil
{
log
.
Error
(
"failed to close p2p after starting with err"
,
"closeErr"
,
closeErr
,
"err"
,
err
)
...
...
@@ -48,10 +50,12 @@ func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.
return
&
n
,
nil
}
func
(
n
*
NodeP2P
)
init
(
resourcesCtx
context
.
Context
,
rollupCfg
*
rollup
.
Config
,
log
log
.
Logger
,
setup
SetupP2P
,
gossipIn
GossipIn
)
error
{
func
(
n
*
NodeP2P
)
init
(
resourcesCtx
context
.
Context
,
rollupCfg
*
rollup
.
Config
,
log
log
.
Logger
,
setup
SetupP2P
,
gossipIn
GossipIn
,
metrics
metrics
.
Metricer
)
error
{
bwc
:=
p2pmetrics
.
NewBandwidthCounter
()
var
err
error
// nil if disabled.
n
.
host
,
err
=
setup
.
Host
(
log
)
n
.
host
,
err
=
setup
.
Host
(
log
,
bwc
)
if
err
!=
nil
{
if
n
.
dv5Udp
!=
nil
{
n
.
dv5Udp
.
Close
()
...
...
@@ -66,10 +70,10 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l
n
.
connMgr
=
extra
.
ConnectionManager
()
}
// notify of any new connections/streams/etc.
n
.
host
.
Network
()
.
Notify
(
NewNetworkNotifier
(
log
))
n
.
host
.
Network
()
.
Notify
(
NewNetworkNotifier
(
log
,
metrics
))
// unregister identify-push handler. Only identifying on dial is fine, and more robust against spam
n
.
host
.
RemoveStreamHandler
(
identify
.
IDDelta
)
n
.
gs
,
err
=
NewGossipSub
(
resourcesCtx
,
n
.
host
,
rollupCfg
)
n
.
gs
,
err
=
NewGossipSub
(
resourcesCtx
,
n
.
host
,
rollupCfg
,
metrics
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to start gossipsub router: %w"
,
err
)
}
...
...
@@ -90,6 +94,10 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to start discv5: %w"
,
err
)
}
if
metrics
!=
nil
{
go
metrics
.
RecordBandwidth
(
resourcesCtx
,
bwc
)
}
}
return
nil
}
...
...
op-node/p2p/notifications.go
View file @
afba7c22
package
p2p
import
(
"github.com/ethereum-optimism/optimism/op-node/metrics"
"github.com/libp2p/go-libp2p-core/network"
ma
"github.com/multiformats/go-multiaddr"
"github.com/ethereum/go-ethereum/log"
)
// TODO: add metrics here as well
type
NotificationsMetricer
interface
{
IncPeerCount
()
DecPeerCount
()
IncStreamCount
()
DecStreamCount
()
}
type
notifications
struct
{
log
log
.
Logger
m
NotificationsMetricer
}
func
(
notif
*
notifications
)
Listen
(
n
network
.
Network
,
a
ma
.
Multiaddr
)
{
...
...
@@ -20,20 +27,27 @@ func (notif *notifications) ListenClose(n network.Network, a ma.Multiaddr) {
notif
.
log
.
Info
(
"stopped listening network address"
,
"addr"
,
a
)
}
func
(
notif
*
notifications
)
Connected
(
n
network
.
Network
,
v
network
.
Conn
)
{
notif
.
m
.
IncPeerCount
()
notif
.
log
.
Info
(
"connected to peer"
,
"peer"
,
v
.
RemotePeer
(),
"addr"
,
v
.
RemoteMultiaddr
())
}
func
(
notif
*
notifications
)
Disconnected
(
n
network
.
Network
,
v
network
.
Conn
)
{
notif
.
m
.
DecPeerCount
()
notif
.
log
.
Info
(
"disconnected from peer"
,
"peer"
,
v
.
RemotePeer
(),
"addr"
,
v
.
RemoteMultiaddr
())
}
func
(
notif
*
notifications
)
OpenedStream
(
n
network
.
Network
,
v
network
.
Stream
)
{
notif
.
m
.
IncStreamCount
()
c
:=
v
.
Conn
()
notif
.
log
.
Trace
(
"opened stream"
,
"protocol"
,
v
.
Protocol
(),
"peer"
,
c
.
RemotePeer
(),
"addr"
,
c
.
RemoteMultiaddr
())
}
func
(
notif
*
notifications
)
ClosedStream
(
n
network
.
Network
,
v
network
.
Stream
)
{
notif
.
m
.
DecStreamCount
()
c
:=
v
.
Conn
()
notif
.
log
.
Trace
(
"opened stream"
,
"protocol"
,
v
.
Protocol
(),
"peer"
,
c
.
RemotePeer
(),
"addr"
,
c
.
RemoteMultiaddr
())
}
func
NewNetworkNotifier
(
log
log
.
Logger
)
network
.
Notifiee
{
return
&
notifications
{
log
:
log
}
func
NewNetworkNotifier
(
log
log
.
Logger
,
m
metrics
.
Metricer
)
network
.
Notifiee
{
if
m
==
nil
{
m
=
metrics
.
NoopMetrics
}
return
&
notifications
{
log
:
log
,
m
:
m
}
}
op-node/p2p/prepared.go
View file @
afba7c22
...
...
@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/metrics"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/log"
...
...
@@ -38,7 +39,7 @@ func (p *Prepared) Check() error {
}
// Host creates a libp2p host service. Returns nil, nil if p2p is disabled.
func
(
p
*
Prepared
)
Host
(
log
log
.
Logger
)
(
host
.
Host
,
error
)
{
func
(
p
*
Prepared
)
Host
(
log
log
.
Logger
,
reporter
metrics
.
Reporter
)
(
host
.
Host
,
error
)
{
return
p
.
HostP2P
,
nil
}
...
...
op-node/p2p/rpc_server.go
View file @
afba7c22
...
...
@@ -54,12 +54,16 @@ type Node interface {
type
APIBackend
struct
{
node
Node
log
log
.
Logger
m
*
metrics
.
Metrics
m
metrics
.
Metricer
}
var
_
API
=
(
*
APIBackend
)(
nil
)
func
NewP2PAPIBackend
(
node
Node
,
log
log
.
Logger
,
m
*
metrics
.
Metrics
)
*
APIBackend
{
func
NewP2PAPIBackend
(
node
Node
,
log
log
.
Logger
,
m
metrics
.
Metricer
)
*
APIBackend
{
if
m
==
nil
{
m
=
metrics
.
NoopMetrics
}
return
&
APIBackend
{
node
:
node
,
log
:
log
,
...
...
op-node/rollup/derive/channel.go
View file @
afba7c22
...
...
@@ -138,7 +138,7 @@ func BatchReader(r io.Reader, l1InclusionBlock eth.L1BlockRef) (func() (BatchWit
if
err
!=
nil
{
return
nil
,
err
}
rlpReader
:=
rlp
.
NewStream
(
zr
,
10
_000_000
)
rlpReader
:=
rlp
.
NewStream
(
zr
,
MaxRLPBytesPerChannel
)
// Read each batch iteratively
return
func
()
(
BatchWithL1InclusionBlock
,
error
)
{
ret
:=
BatchWithL1InclusionBlock
{
...
...
op-node/rollup/derive/channel_out.go
View file @
afba7c22
...
...
@@ -5,6 +5,7 @@ import (
"compress/zlib"
"crypto/rand"
"errors"
"fmt"
"io"
"github.com/ethereum-optimism/optimism/op-node/rollup"
...
...
@@ -14,15 +15,14 @@ import (
)
var
ErrNotDepositTx
=
errors
.
New
(
"first transaction in block is not a deposit tx"
)
var
ErrTooManyRLPBytes
=
errors
.
New
(
"batch would cause RLP bytes to go over limit"
)
type
ChannelOut
struct
{
id
ChannelID
// Frame ID of the next frame to emit. Increment after emitting
frame
uint64
// How much we've pulled from the reader so far
offset
uint64
// scratch for temporary buffering
scratch
bytes
.
Buffer
// rlpLength is the uncompressed size of the channel. Must be less than MAX_RLP_BYTES_PER_CHANNEL
rlpLength
int
// Compressor stage. Write input data to it
compress
*
zlib
.
Writer
...
...
@@ -40,7 +40,7 @@ func NewChannelOut() (*ChannelOut, error) {
c
:=
&
ChannelOut
{
id
:
ChannelID
{},
// TODO: use GUID here instead of fully random data
frame
:
0
,
offset
:
0
,
rlpLength
:
0
,
}
_
,
err
:=
rand
.
Read
(
c
.
id
[
:
])
if
err
!=
nil
{
...
...
@@ -59,9 +59,8 @@ func NewChannelOut() (*ChannelOut, error) {
// TODO: reuse ChannelOut for performance
func
(
co
*
ChannelOut
)
Reset
()
error
{
co
.
frame
=
0
co
.
offset
=
0
co
.
rlpLength
=
0
co
.
buf
.
Reset
()
co
.
scratch
.
Reset
()
co
.
compress
.
Reset
(
&
co
.
buf
)
co
.
closed
=
false
_
,
err
:=
rand
.
Read
(
co
.
id
[
:
])
...
...
@@ -71,11 +70,33 @@ func (co *ChannelOut) Reset() error {
return
nil
}
// AddBlock adds a block to the channel. It returns an error
// if there is a problem adding the block. The only sentinel
// error that it returns is ErrTooManyRLPBytes. If this error
// is returned, the channel should be closed and a new one
// should be made.
func
(
co
*
ChannelOut
)
AddBlock
(
block
*
types
.
Block
)
error
{
if
co
.
closed
{
return
errors
.
New
(
"already closed"
)
}
return
blockToBatch
(
block
,
co
.
compress
)
batch
,
err
:=
blockToBatch
(
block
)
if
err
!=
nil
{
return
err
}
// We encode to a temporary buffer to determine the encoded length to
// ensure that the total size of all RLP elements is less than MAX_RLP_BYTES_PER_CHANNEL
var
buf
bytes
.
Buffer
if
err
:=
rlp
.
Encode
(
&
buf
,
batch
);
err
!=
nil
{
return
err
}
if
co
.
rlpLength
+
buf
.
Len
()
>
MaxRLPBytesPerChannel
{
return
fmt
.
Errorf
(
"could not add %d bytes to channel of %d bytes, max is %d. err: %w"
,
buf
.
Len
(),
co
.
rlpLength
,
MaxRLPBytesPerChannel
,
ErrTooManyRLPBytes
)
}
co
.
rlpLength
+=
buf
.
Len
()
_
,
err
=
io
.
Copy
(
co
.
compress
,
&
buf
)
return
err
}
// ReadyBytes returns the number of bytes that the channel out can immediately output into a frame.
...
...
@@ -141,35 +162,35 @@ func (co *ChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) error {
}
}
// blockToBatch
writes the raw block bytes (after batch encoding) to the writer
func
blockToBatch
(
block
*
types
.
Block
,
w
io
.
Writer
)
error
{
// blockToBatch
transforms a block into a batch object that can easily be RLP encoded.
func
blockToBatch
(
block
*
types
.
Block
)
(
*
BatchData
,
error
)
{
var
opaqueTxs
[]
hexutil
.
Bytes
for
_
,
tx
:=
range
block
.
Transactions
()
{
for
i
,
tx
:=
range
block
.
Transactions
()
{
if
tx
.
Type
()
==
types
.
DepositTxType
{
continue
}
otx
,
err
:=
tx
.
MarshalBinary
()
if
err
!=
nil
{
return
err
// TODO: wrap err
return
nil
,
fmt
.
Errorf
(
"could not encode tx %v in block %v: %w"
,
i
,
tx
.
Hash
(),
err
)
}
opaqueTxs
=
append
(
opaqueTxs
,
otx
)
}
l1InfoTx
:=
block
.
Transactions
()[
0
]
if
l1InfoTx
.
Type
()
!=
types
.
DepositTxType
{
return
ErrNotDepositTx
return
nil
,
ErrNotDepositTx
}
l1Info
,
err
:=
L1InfoDepositTxData
(
l1InfoTx
.
Data
())
if
err
!=
nil
{
return
err
// TODO: wrap err
return
nil
,
fmt
.
Errorf
(
"could not parse the L1 Info deposit: %w"
,
err
)
}
batch
:=
&
BatchData
{
BatchV1
{
return
&
BatchData
{
BatchV1
{
ParentHash
:
block
.
ParentHash
(),
EpochNum
:
rollup
.
Epoch
(
l1Info
.
Number
),
EpochHash
:
l1Info
.
BlockHash
,
Timestamp
:
block
.
Time
(),
Transactions
:
opaqueTxs
,
},
}
return
rlp
.
Encode
(
w
,
batch
)
},
nil
}
op-node/rollup/derive/params.go
View file @
afba7c22
...
...
@@ -15,6 +15,10 @@ const DerivationVersion0 = 0
// starting with the oldest channel.
const
MaxChannelBankSize
=
100
_000_000
// MaxRLPBytesPerChannel is the maximum amount of bytes that will be read from
// a channel. This limit is set when decoding the RLP.
const
MaxRLPBytesPerChannel
=
10
_000_000
// DuplicateErr is returned when a newly read frame is already known
var
DuplicateErr
=
errors
.
New
(
"duplicate frame"
)
...
...
op-node/rollup/driver/conf_depth.go
View file @
afba7c22
...
...
@@ -6,6 +6,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
)
// confDepth is an util that wraps the L1 input fetcher used in the pipeline,
...
...
@@ -30,7 +31,9 @@ func (c *confDepth) L1BlockRefByNumber(ctx context.Context, num uint64) (eth.L1B
// TODO: performance optimization: buffer the l1Unsafe, invalidate any reorged previous buffer content,
// and instantly return the origin by number from the buffer if we can.
if
num
==
0
||
c
.
depth
==
0
||
num
+
c
.
depth
<=
c
.
l1Head
()
.
Number
{
// Don't apply the conf depth is l1Head is empty (as it is during the startup case before the l1State is initialized).
l1Head
:=
c
.
l1Head
()
if
num
==
0
||
c
.
depth
==
0
||
num
+
c
.
depth
<=
l1Head
.
Number
||
l1Head
.
Hash
==
(
common
.
Hash
{})
{
return
c
.
L1Fetcher
.
L1BlockRefByNumber
(
ctx
,
num
)
}
return
eth
.
L1BlockRef
{},
ethereum
.
NotFound
...
...
op-node/rollup/driver/conf_depth_test.go
View file @
afba7c22
...
...
@@ -9,11 +9,15 @@ import (
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/testutils"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
)
var
exHash
=
common
.
Hash
{
0xff
}
type
confTest
struct
{
name
string
head
uint64
hash
common
.
Hash
// hash of head block
req
uint64
depth
uint64
pass
bool
...
...
@@ -21,7 +25,7 @@ type confTest struct {
func
(
ct
*
confTest
)
Run
(
t
*
testing
.
T
)
{
l1Fetcher
:=
&
testutils
.
MockL1Source
{}
l1Head
:=
eth
.
L1BlockRef
{
Number
:
ct
.
head
}
l1Head
:=
eth
.
L1BlockRef
{
Number
:
ct
.
head
,
Hash
:
ct
.
hash
}
l1HeadGetter
:=
func
()
eth
.
L1BlockRef
{
return
l1Head
}
cd
:=
NewConfDepth
(
ct
.
depth
,
l1HeadGetter
,
l1Fetcher
)
...
...
@@ -43,18 +47,19 @@ func TestConfDepth(t *testing.T) {
// note: we're not testing overflows.
// If a request is large enough to overflow the conf depth check, it's not returning anything anyway.
testCases
:=
[]
confTest
{
{
name
:
"zero conf future"
,
head
:
4
,
req
:
5
,
depth
:
0
,
pass
:
true
},
{
name
:
"zero conf present"
,
head
:
4
,
req
:
4
,
depth
:
0
,
pass
:
true
},
{
name
:
"zero conf past"
,
head
:
4
,
req
:
4
,
depth
:
0
,
pass
:
true
},
{
name
:
"one conf future"
,
head
:
4
,
req
:
5
,
depth
:
1
,
pass
:
false
},
{
name
:
"one conf present"
,
head
:
4
,
req
:
4
,
depth
:
1
,
pass
:
false
},
{
name
:
"one conf past"
,
head
:
4
,
req
:
3
,
depth
:
1
,
pass
:
true
},
{
name
:
"two conf future"
,
head
:
4
,
req
:
5
,
depth
:
2
,
pass
:
false
},
{
name
:
"two conf present"
,
head
:
4
,
req
:
4
,
depth
:
2
,
pass
:
false
},
{
name
:
"two conf not like 1"
,
head
:
4
,
req
:
3
,
depth
:
2
,
pass
:
false
},
{
name
:
"two conf pass"
,
head
:
4
,
req
:
2
,
depth
:
2
,
pass
:
true
},
{
name
:
"easy pass"
,
head
:
100
,
req
:
20
,
depth
:
5
,
pass
:
true
},
{
name
:
"genesis case"
,
head
:
0
,
req
:
0
,
depth
:
4
,
pass
:
true
},
{
name
:
"zero conf future"
,
head
:
4
,
hash
:
exHash
,
req
:
5
,
depth
:
0
,
pass
:
true
},
{
name
:
"zero conf present"
,
head
:
4
,
hash
:
exHash
,
req
:
4
,
depth
:
0
,
pass
:
true
},
{
name
:
"zero conf past"
,
head
:
4
,
hash
:
exHash
,
req
:
4
,
depth
:
0
,
pass
:
true
},
{
name
:
"one conf future"
,
head
:
4
,
hash
:
exHash
,
req
:
5
,
depth
:
1
,
pass
:
false
},
{
name
:
"one conf present"
,
head
:
4
,
hash
:
exHash
,
req
:
4
,
depth
:
1
,
pass
:
false
},
{
name
:
"one conf past"
,
head
:
4
,
hash
:
exHash
,
req
:
3
,
depth
:
1
,
pass
:
true
},
{
name
:
"two conf future"
,
head
:
4
,
hash
:
exHash
,
req
:
5
,
depth
:
2
,
pass
:
false
},
{
name
:
"two conf present"
,
head
:
4
,
hash
:
exHash
,
req
:
4
,
depth
:
2
,
pass
:
false
},
{
name
:
"two conf not like 1"
,
head
:
4
,
hash
:
exHash
,
req
:
3
,
depth
:
2
,
pass
:
false
},
{
name
:
"two conf pass"
,
head
:
4
,
hash
:
exHash
,
req
:
2
,
depth
:
2
,
pass
:
true
},
{
name
:
"easy pass"
,
head
:
100
,
hash
:
exHash
,
req
:
20
,
depth
:
5
,
pass
:
true
},
{
name
:
"genesis case"
,
head
:
0
,
hash
:
exHash
,
req
:
0
,
depth
:
4
,
pass
:
true
},
{
name
:
"no L1 state"
,
req
:
10
,
depth
:
4
,
pass
:
true
},
}
for
_
,
tc
:=
range
testCases
{
t
.
Run
(
tc
.
name
,
tc
.
Run
)
...
...
packages/actor-tests/CHANGELOG.md
View file @
afba7c22
# @eth-optimism/actor-tests
## 0.0.10
### Patch Changes
-
Updated dependencies
[
7d7d9ba8
]
-
@eth-optimism/contracts-bedrock@0.8.2
-
@eth-optimism/sdk@1.6.8
## 0.0.9
### Patch Changes
...
...
packages/actor-tests/package.json
View file @
afba7c22
{
"name"
:
"@eth-optimism/actor-tests"
,
"version"
:
"0.0.
9
"
,
"version"
:
"0.0.
10
"
,
"description"
:
"A library and suite of tests to stress test Optimism Bedrock."
,
"license"
:
"MIT"
,
"author"
:
""
,
...
...
@@ -18,9 +18,9 @@
"test:coverage"
:
"yarn test"
},
"dependencies"
:
{
"@eth-optimism/contracts-bedrock"
:
"0.8.
1
"
,
"@eth-optimism/contracts-bedrock"
:
"0.8.
2
"
,
"@eth-optimism/core-utils"
:
"^0.10.1"
,
"@eth-optimism/sdk"
:
"^1.6.
7
"
,
"@eth-optimism/sdk"
:
"^1.6.
8
"
,
"@types/chai"
:
"^4.2.18"
,
"@types/chai-as-promised"
:
"^7.1.4"
,
"async-mutex"
:
"^0.3.2"
,
...
...
packages/contracts-bedrock/CHANGELOG.md
View file @
afba7c22
# @eth-optimism/contracts-bedrock
## 0.8.2
### Patch Changes
-
7d7d9ba8: Moves initializers underneath constructors always
## 0.8.1
### Patch Changes
...
...
packages/contracts-bedrock/contracts/L1/OptimismPortal.sol
View file @
afba7c22
...
...
@@ -99,6 +99,14 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
initialize();
}
/**
* @notice Initializer;
*/
function initialize() public initializer {
l2Sender = DEFAULT_L2_SENDER;
__ResourceMetering_init();
}
/**
* @notice Accepts value so that users can send ETH directly to this contract and have the
* funds be deposited to their address on L2. This is intended as a convenience
...
...
@@ -214,14 +222,6 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
return _isOutputFinalized(proposal);
}
/**
* @notice Initializer;
*/
function initialize() public initializer {
l2Sender = DEFAULT_L2_SENDER;
__ResourceMetering_init();
}
/**
* @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in
* deriving deposit transactions. Note that if a deposit is made by a contract, its
...
...
packages/contracts-bedrock/deploy/001-InitImplementations.deploy.ts
View file @
afba7c22
...
...
@@ -7,7 +7,7 @@ import '@eth-optimism/hardhat-deploy-config'
const
upgradeABIs
=
{
L2OutputOracleProxy
:
async
(
deployConfig
)
=>
[
'
initialize(bytes32,
uint256
,address)
'
,
'
initialize(bytes32,
address
,address)
'
,
[
deployConfig
.
l2OutputOracleGenesisL2Output
,
deployConfig
.
l2OutputOracleProposer
,
...
...
packages/contracts-bedrock/package.json
View file @
afba7c22
{
"name"
:
"@eth-optimism/contracts-bedrock"
,
"version"
:
"0.8.
1
"
,
"version"
:
"0.8.
2
"
,
"description"
:
"Contracts for Optimism Specs"
,
"main"
:
"dist/index"
,
"types"
:
"dist/index"
,
...
...
packages/drippie-mon/CHANGELOG.md
View file @
afba7c22
# @eth-optimism/drippie-mon
## 0.3.19
### Patch Changes
-
@eth-optimism/sdk@1.6.8
## 0.3.18
### Patch Changes
...
...
packages/drippie-mon/package.json
View file @
afba7c22
{
"private"
:
true
,
"name"
:
"@eth-optimism/drippie-mon"
,
"version"
:
"0.3.1
8
"
,
"version"
:
"0.3.1
9
"
,
"description"
:
"[Optimism] Service for monitoring Drippie instances"
,
"main"
:
"dist/index"
,
"types"
:
"dist/index"
,
...
...
@@ -35,7 +35,7 @@
"@eth-optimism/common-ts"
:
"0.6.6"
,
"@eth-optimism/contracts-periphery"
:
"1.0.2"
,
"@eth-optimism/core-utils"
:
"0.10.1"
,
"@eth-optimism/sdk"
:
"1.6.
7
"
,
"@eth-optimism/sdk"
:
"1.6.
8
"
,
"ethers"
:
"^5.7.0"
},
"devDependencies"
:
{
...
...
packages/integration-tests-bedrock/package.json
View file @
afba7c22
...
...
@@ -29,7 +29,7 @@
"devDependencies"
:
{
"@eth-optimism/contracts"
:
"0.5.37"
,
"@eth-optimism/core-utils"
:
"0.10.1"
,
"@eth-optimism/sdk"
:
"1.6.
7
"
,
"@eth-optimism/sdk"
:
"1.6.
8
"
,
"@ethersproject/abstract-provider"
:
"^5.7.0"
,
"chai-as-promised"
:
"^7.1.1"
,
"chai"
:
"^4.3.4"
,
...
...
packages/message-relayer/CHANGELOG.md
View file @
afba7c22
# @eth-optimism/message-relayer
## 0.5.18
### Patch Changes
-
@eth-optimism/sdk@1.6.8
## 0.5.17
### Patch Changes
...
...
packages/message-relayer/package.json
View file @
afba7c22
{
"private"
:
true
,
"name"
:
"@eth-optimism/message-relayer"
,
"version"
:
"0.5.1
7
"
,
"version"
:
"0.5.1
8
"
,
"description"
:
"[Optimism] Service for automatically relaying L2 to L1 transactions"
,
"main"
:
"dist/index"
,
"types"
:
"dist/index"
,
...
...
@@ -33,7 +33,7 @@
"dependencies"
:
{
"@eth-optimism/common-ts"
:
"0.6.6"
,
"@eth-optimism/core-utils"
:
"0.10.1"
,
"@eth-optimism/sdk"
:
"1.6.
7
"
,
"@eth-optimism/sdk"
:
"1.6.
8
"
,
"ethers"
:
"^5.7.0"
},
"devDependencies"
:
{
...
...
packages/sdk/CHANGELOG.md
View file @
afba7c22
# @eth-optimism/sdk
## 1.6.8
### Patch Changes
-
Updated dependencies
[
7d7d9ba8
]
-
@eth-optimism/contracts-bedrock@0.8.2
## 1.6.7
### Patch Changes
...
...
packages/sdk/package.json
View file @
afba7c22
{
"name"
:
"@eth-optimism/sdk"
,
"version"
:
"1.6.
7
"
,
"version"
:
"1.6.
8
"
,
"description"
:
"[Optimism] Tools for working with Optimism"
,
"main"
:
"dist/index"
,
"types"
:
"dist/index"
,
...
...
@@ -50,7 +50,7 @@
"dependencies"
:
{
"@eth-optimism/contracts"
:
"0.5.37"
,
"@eth-optimism/core-utils"
:
"0.10.1"
,
"@eth-optimism/contracts-bedrock"
:
"0.8.
1
"
,
"@eth-optimism/contracts-bedrock"
:
"0.8.
2
"
,
"lodash"
:
"^4.17.21"
,
"merkletreejs"
:
"^0.2.27"
,
"rlp"
:
"^2.2.7"
...
...
specs/derivation.md
View file @
afba7c22
...
...
@@ -299,9 +299,8 @@ Batcher transactions are encoded as `version_byte ++ rollup_payload` (where `++`
| 0 |
`frame ...`
(one or more frames, concatenated) |
Unknown versions make the batcher transaction invalid (it must be ignored by the rollup node).
The
`rollup_payload`
may be right-padded with 0s, which will be ignored. It's allowed for them to be
interpreted as frames for channel 0, which must always be ignored.
All frames in a batcher transaction must be parseable. If any one frame fails to parse, the all frames in the
transaction are rejected.
> **TODO** specify batcher authentication (i.e. where do we store / make available the public keys of authorize batcher
> signers)
...
...
@@ -367,6 +366,9 @@ When decompressing a channel, we limit the amount of decompressed data to `MAX_R
humongous amount of data). If the decompressed data exceeds the limit, things proceeds as thought the channel contained
only the first
`MAX_RLP_BYTES_PER_CHANNEL`
decompressed bytes.
When decoding batches, all batches that can be completly decoded below
`MAX_RLP_BYTES_PER_CHANNEL`
will be accepted
even if the size of the channel is greater than
`MAX_RLP_BYTES_PER_CHANNEL`
.
While the above pseudocode implies that all batches are known in advance, it is possible to perform streaming
compression and decompression of RLP-encoded batches. This means it is possible to start including channel frames in a
[
batcher transaction
][
g-batcher-transaction
]
before we know how many batches (and how many frames) the channel will
...
...
specs/exec-engine.md
View file @
afba7c22
...
...
@@ -101,6 +101,11 @@ The `noTxPool` is optional as well, and extends the `transactions` meaning:
into the payload, after any of the
`transactions`
. This is the default behavior a L1 node implements.
-
If
`true`
, the execution engine must not change anything about the given list of
`transactions`
.
If the
`transactions`
field is present, the engine must execute the transactions in order and return
`STATUS_INVALID`
if there is an error processing the transactions. It must return
`STATUS_VALID`
if all of the transactions could
be executed without error.
**Note**
: The state transition rules have been modified such that deposits will never fail
so if
`engine_forkchoiceUpdatedV1`
returns
`STATUS_INVALID`
it is because a batched transaction is invalid.
[
rollup-driver
]:
rollup-node.md
### `engine_newPayloadV1`
...
...
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