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
50564d43
Unverified
Commit
50564d43
authored
Nov 14, 2024
by
Matthew Slipper
Committed by
GitHub
Nov 14, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
op-deployer: Support forking live chains (#12918)
parent
ae78b73d
Changes
28
Show whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
483 additions
and
737 deletions
+483
-737
cheatcodes_forking.go
op-chain-ops/script/cheatcodes_forking.go
+1
-9
db.go
op-chain-ops/script/forking/db.go
+3
-1
state.go
op-chain-ops/script/forking/state.go
+16
-2
script.go
op-chain-ops/script/script.go
+12
-1
script_test.go
op-chain-ops/script/script_test.go
+2
-2
with.go
op-chain-ops/script/with.go
+2
-2
apply.go
op-deployer/pkg/deployer/apply.go
+134
-88
delayed_weth.go
op-deployer/pkg/deployer/bootstrap/delayed_weth.go
+1
-1
dispute_game.go
op-deployer/pkg/deployer/bootstrap/dispute_game.go
+1
-1
mips.go
op-deployer/pkg/deployer/bootstrap/mips.go
+1
-1
opcm.go
op-deployer/pkg/deployer/bootstrap/opcm.go
+1
-1
semvers.go
op-deployer/pkg/deployer/inspect/semvers.go
+0
-1
apply_test.go
op-deployer/pkg/deployer/integration_test/apply_test.go
+54
-154
alt_da_test.go
op-deployer/pkg/deployer/opcm/alt_da_test.go
+0
-1
delayed_weth_test.go
op-deployer/pkg/deployer/opcm/delayed_weth_test.go
+0
-1
deployOutput_v160.json
op-deployer/pkg/deployer/opcm/deployOutput_v160.json
+0
-77
dispute_game_test.go
op-deployer/pkg/deployer/opcm/dispute_game_test.go
+0
-1
mips_test.go
op-deployer/pkg/deployer/opcm/mips_test.go
+0
-1
opchain.go
op-deployer/pkg/deployer/opcm/opchain.go
+38
-186
env.go
op-deployer/pkg/deployer/pipeline/env.go
+0
-1
implementations.go
op-deployer/pkg/deployer/pipeline/implementations.go
+0
-2
l2genesis.go
op-deployer/pkg/deployer/pipeline/l2genesis.go
+7
-8
opchain.go
op-deployer/pkg/deployer/pipeline/opchain.go
+29
-185
standard.go
op-deployer/pkg/deployer/standard/standard.go
+1
-1
host.go
op-deployer/pkg/env/host.go
+6
-6
DeployOPChain.s.sol
...ages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol
+1
-1
ReadImplementationAddresses.s.sol
...-bedrock/scripts/deploy/ReadImplementationAddresses.s.sol
+166
-0
publish-artifacts.sh
packages/contracts-bedrock/scripts/ops/publish-artifacts.sh
+7
-2
No files found.
op-chain-ops/script/cheatcodes_forking.go
View file @
50564d43
...
...
@@ -53,15 +53,7 @@ func (c *CheatCodesPrecompile) CreateSelectFork_84d52b7a(urlOrAlias string, txHa
// createSelectFork implements vm.createSelectFork:
// https://book.getfoundry.sh/cheatcodes/create-select-fork
func
(
c
*
CheatCodesPrecompile
)
createSelectFork
(
opts
...
ForkOption
)
(
*
big
.
Int
,
error
)
{
src
,
err
:=
c
.
h
.
onFork
(
opts
...
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to setup fork source: %w"
,
err
)
}
id
,
err
:=
c
.
h
.
state
.
CreateSelectFork
(
src
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to create-select fork: %w"
,
err
)
}
return
id
.
U256
()
.
ToBig
(),
nil
return
c
.
h
.
CreateSelectFork
(
opts
...
)
}
// ActiveFork implements vm.activeFork:
...
...
op-chain-ops/script/forking/db.go
View file @
50564d43
...
...
@@ -53,7 +53,9 @@ func NewForkDB(source ForkSource) *ForkDB {
// fakeRoot is just a marker; every account we load into the fork-db has this storage-root.
// When opening a storage-trie, we sanity-check we have this root, or an empty trie.
// And then just return the same global trie view for storage reads/writes.
var
fakeRoot
=
common
.
Hash
{
0
:
42
}
// It needs to be set to EmptyRootHash to avoid contract collision errors when
// deploying contracts, since Geth checks the storage root prior to deployment.
var
fakeRoot
=
types
.
EmptyRootHash
func
(
f
*
ForkDB
)
OpenTrie
(
root
common
.
Hash
)
(
state
.
Trie
,
error
)
{
if
f
.
active
.
stateRoot
!=
root
{
...
...
op-chain-ops/script/forking/state.go
View file @
50564d43
...
...
@@ -54,8 +54,6 @@ func NewForkableState(base VMStateDB) *ForkableState {
addresses
.
DefaultSenderAddr
:
ForkID
{},
addresses
.
VMAddr
:
ForkID
{},
addresses
.
ConsoleAddr
:
ForkID
{},
addresses
.
ScriptDeployer
:
ForkID
{},
addresses
.
ForgeDeployer
:
ForkID
{},
},
fallback
:
base
,
idCounter
:
0
,
...
...
@@ -194,11 +192,27 @@ func (fst *ForkableState) MakePersistent(addr common.Address) {
fst
.
persistent
[
addr
]
=
fst
.
activeFork
}
// MakeExcluded excludes an account from forking. This is useful for things like scripts, which
// should always use the fallback state.
func
(
fst
*
ForkableState
)
MakeExcluded
(
addr
common
.
Address
)
{
fst
.
persistent
[
addr
]
=
ForkID
{}
}
// RevokePersistent is like vm.revokePersistent, it undoes a previous vm.makePersistent.
func
(
fst
*
ForkableState
)
RevokePersistent
(
addr
common
.
Address
)
{
delete
(
fst
.
persistent
,
addr
)
}
// RevokeExcluded undoes MakeExcluded. It will panic if the account was marked as
// persistent in a different fork.
func
(
fst
*
ForkableState
)
RevokeExcluded
(
addr
common
.
Address
)
{
forkID
,
ok
:=
fst
.
persistent
[
addr
]
if
ok
&&
forkID
!=
(
ForkID
{})
{
panic
(
fmt
.
Sprintf
(
"cannot revoke excluded account %s since it was made persistent in fork %q"
,
addr
,
forkID
))
}
delete
(
fst
.
persistent
,
addr
)
}
// IsPersistent is like vm.isPersistent, it checks if an account persists across forks.
func
(
fst
*
ForkableState
)
IsPersistent
(
addr
common
.
Address
)
bool
{
_
,
ok
:=
fst
.
persistent
[
addr
]
...
...
op-chain-ops/script/script.go
View file @
50564d43
...
...
@@ -9,7 +9,6 @@ import (
"math/big"
"github.com/ethereum-optimism/optimism/op-chain-ops/script/addresses"
"github.com/holiman/uint256"
"github.com/ethereum/go-ethereum/accounts/abi"
...
...
@@ -850,3 +849,15 @@ func (h *Host) RememberOnLabel(label, srcFile, contract string) error {
})
return
nil
}
func
(
h
*
Host
)
CreateSelectFork
(
opts
...
ForkOption
)
(
*
big
.
Int
,
error
)
{
src
,
err
:=
h
.
onFork
(
opts
...
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to setup fork source: %w"
,
err
)
}
id
,
err
:=
h
.
state
.
CreateSelectFork
(
src
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to create-select fork: %w"
,
err
)
}
return
id
.
U256
()
.
ToBig
(),
nil
}
op-chain-ops/script/script_test.go
View file @
50564d43
...
...
@@ -282,8 +282,8 @@ func TestForkingScript(t *testing.T) {
addr
,
err
:=
h
.
LoadContract
(
"ScriptExample.s.sol"
,
"ForkTester"
)
require
.
NoError
(
t
,
err
)
h
.
AllowCheatcodes
(
addr
)
// Make this script
persistent
so it doesn't call the fork RPC.
h
.
state
.
Make
Persistent
(
addr
)
// Make this script
excluded
so it doesn't call the fork RPC.
h
.
state
.
Make
Excluded
(
addr
)
t
.
Logf
(
"allowing %s to access cheatcodes"
,
addr
)
input
:=
bytes4
(
"run()"
)
...
...
op-chain-ops/script/with.go
View file @
50564d43
...
...
@@ -34,7 +34,7 @@ func WithScript[B any](h *Host, name string, contract string) (b *B, cleanup fun
addr
:=
crypto
.
CreateAddress
(
deployer
,
deployNonce
)
h
.
Label
(
addr
,
contract
)
h
.
AllowCheatcodes
(
addr
)
// before constructor execution, give our script cheatcode access
h
.
state
.
Make
Persistent
(
addr
)
// scripts are persistent across forks
h
.
state
.
Make
Excluded
(
addr
)
// scripts are persistent across forks
// init bindings (with ABI check)
bindings
,
err
:=
MakeBindings
[
B
](
h
.
ScriptBackendFn
(
addr
),
func
(
abiDef
string
)
bool
{
...
...
op-deployer/pkg/deployer/apply.go
View file @
50564d43
...
...
@@ -7,11 +7,15 @@ import (
"math/big"
"strings"
"github.com/ethereum-optimism/optimism/op-chain-ops/foundry"
"github.com/ethereum-optimism/optimism/op-chain-ops/script"
"github.com/ethereum-optimism/optimism/op-chain-ops/script/forking"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/env"
"github.com/ethereum-optimism/optimism/op-chain-ops/foundry"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster"
"github.com/ethereum/go-ethereum/common"
...
...
@@ -104,50 +108,43 @@ func Apply(ctx context.Context, cfg ApplyConfig) error {
return
fmt
.
Errorf
(
"failed to read state: %w"
,
err
)
}
var
l1Client
*
ethclient
.
Client
var
deployer
common
.
Address
var
bcaster
broadcaster
.
Broadcaster
var
startingNonce
uint64
if
intent
.
DeploymentStrategy
==
state
.
DeploymentStrategyLive
{
if
err
:=
cfg
.
CheckLive
();
err
!=
nil
{
return
fmt
.
Errorf
(
"invalid config for apply: %w"
,
err
)
}
l1Client
,
err
=
ethclient
.
Dial
(
cfg
.
L1RPCUrl
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to connect to L1 RPC: %w"
,
err
)
if
err
:=
ApplyPipeline
(
ctx
,
ApplyPipelineOpts
{
L1RPCUrl
:
cfg
.
L1RPCUrl
,
DeployerPrivateKey
:
cfg
.
privateKeyECDSA
,
Intent
:
intent
,
State
:
st
,
Logger
:
cfg
.
Logger
,
StateWriter
:
pipeline
.
WorkdirStateWriter
(
cfg
.
Workdir
),
});
err
!=
nil
{
return
err
}
chainID
,
err
:=
l1Client
.
ChainID
(
ctx
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to get chain ID: %w"
,
err
)
}
return
nil
}
signer
:=
opcrypto
.
SignerFnFromBind
(
opcrypto
.
PrivateKeySignerFn
(
cfg
.
privateKeyECDSA
,
chainID
))
deployer
=
crypto
.
PubkeyToAddress
(
cfg
.
privateKeyECDSA
.
PublicKey
)
type
pipelineStage
struct
{
name
string
apply
func
()
error
}
bcaster
,
err
=
broadcaster
.
NewKeyedBroadcaster
(
broadcaster
.
KeyedBroadcasterOpts
{
Logger
:
cfg
.
Logger
,
ChainID
:
new
(
big
.
Int
)
.
SetUint64
(
intent
.
L1ChainID
),
Client
:
l1Client
,
Signer
:
signer
,
From
:
deployer
,
})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create broadcaster: %w"
,
err
)
}
type
ApplyPipelineOpts
struct
{
L1RPCUrl
string
DeployerPrivateKey
*
ecdsa
.
PrivateKey
Intent
*
state
.
Intent
State
*
state
.
State
Logger
log
.
Logger
StateWriter
pipeline
.
StateWriter
}
startingNonce
,
err
=
l1Client
.
NonceAt
(
ctx
,
deployer
,
nil
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to get starting nonce: %w"
,
err
)
}
}
else
{
deployer
=
common
.
Address
{
0x01
}
bcaster
=
broadcaster
.
NoopBroadcaster
()
}
func
ApplyPipeline
(
ctx
context
.
Context
,
opts
ApplyPipelineOpts
,
)
error
{
intent
:=
opts
.
Intent
st
:=
opts
.
State
progressor
:=
func
(
curr
,
total
int64
)
{
cfg
.
Logger
.
Info
(
"artifacts download progress"
,
"current"
,
curr
,
"total"
,
total
)
opts
.
Logger
.
Info
(
"artifacts download progress"
,
"current"
,
curr
,
"total"
,
total
)
}
l1ArtifactsFS
,
cleanupL1
,
err
:=
artifacts
.
Download
(
ctx
,
intent
.
L1ContractsLocator
,
progressor
)
...
...
@@ -156,7 +153,7 @@ func Apply(ctx context.Context, cfg ApplyConfig) error {
}
defer
func
()
{
if
err
:=
cleanupL1
();
err
!=
nil
{
cfg
.
Logger
.
Warn
(
"failed to clean up L1 artifacts"
,
"err"
,
err
)
opts
.
Logger
.
Warn
(
"failed to clean up L1 artifacts"
,
"err"
,
err
)
}
}()
...
...
@@ -166,7 +163,7 @@ func Apply(ctx context.Context, cfg ApplyConfig) error {
}
defer
func
()
{
if
err
:=
cleanupL2
();
err
!=
nil
{
cfg
.
Logger
.
Warn
(
"failed to clean up L2 artifacts"
,
"err"
,
err
)
opts
.
Logger
.
Warn
(
"failed to clean up L2 artifacts"
,
"err"
,
err
)
}
}()
...
...
@@ -175,52 +172,101 @@ func Apply(ctx context.Context, cfg ApplyConfig) error {
L2
:
l2ArtifactsFS
,
}
l1Host
,
err
:=
env
.
DefaultScriptHost
(
bcaster
,
cfg
.
Logger
,
deployer
,
bundle
.
L1
,
startingNonce
)
var
deployer
common
.
Address
var
bcaster
broadcaster
.
Broadcaster
var
l1Client
*
ethclient
.
Client
var
l1Host
*
script
.
Host
if
intent
.
DeploymentStrategy
==
state
.
DeploymentStrategyLive
{
l1RPC
,
err
:=
rpc
.
Dial
(
opts
.
L1RPCUrl
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to connect to L1 RPC: %w"
,
err
)
}
l1Client
=
ethclient
.
NewClient
(
l1RPC
)
chainID
,
err
:=
l1Client
.
ChainID
(
ctx
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to get chain ID: %w"
,
err
)
}
signer
:=
opcrypto
.
SignerFnFromBind
(
opcrypto
.
PrivateKeySignerFn
(
opts
.
DeployerPrivateKey
,
chainID
))
deployer
=
crypto
.
PubkeyToAddress
(
opts
.
DeployerPrivateKey
.
PublicKey
)
bcaster
,
err
=
broadcaster
.
NewKeyedBroadcaster
(
broadcaster
.
KeyedBroadcasterOpts
{
Logger
:
opts
.
Logger
,
ChainID
:
new
(
big
.
Int
)
.
SetUint64
(
intent
.
L1ChainID
),
Client
:
l1Client
,
Signer
:
signer
,
From
:
deployer
,
})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create broadcaster: %w"
,
err
)
}
l1Host
,
err
=
env
.
DefaultScriptHost
(
bcaster
,
opts
.
Logger
,
deployer
,
bundle
.
L1
,
script
.
WithForkHook
(
func
(
cfg
*
script
.
ForkConfig
)
(
forking
.
ForkSource
,
error
)
{
src
,
err
:=
forking
.
RPCSourceByNumber
(
cfg
.
URLOrAlias
,
l1RPC
,
*
cfg
.
BlockNumber
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to create RPC fork source: %w"
,
err
)
}
return
forking
.
Cache
(
src
),
nil
}),
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create L1 script host: %w"
,
err
)
}
env
:=
&
pipeline
.
Env
{
StateWriter
:
pipeline
.
WorkdirStateWriter
(
cfg
.
Workdir
),
latest
,
err
:=
l1Client
.
HeaderByNumber
(
ctx
,
nil
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to get latest block: %w"
,
err
)
}
if
_
,
err
:=
l1Host
.
CreateSelectFork
(
script
.
ForkWithURLOrAlias
(
"main"
),
script
.
ForkWithBlockNumberU256
(
latest
.
Number
),
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to select fork: %w"
,
err
)
}
}
else
{
deployer
=
common
.
Address
{
0x01
}
bcaster
=
broadcaster
.
NoopBroadcaster
()
l1Host
,
err
=
env
.
DefaultScriptHost
(
bcaster
,
opts
.
Logger
,
deployer
,
bundle
.
L1
,
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create L1 script host: %w"
,
err
)
}
}
pEnv
:=
&
pipeline
.
Env
{
StateWriter
:
opts
.
StateWriter
,
L1ScriptHost
:
l1Host
,
L1Client
:
l1Client
,
Logger
:
cfg
.
Logger
,
Logger
:
opts
.
Logger
,
Broadcaster
:
bcaster
,
Deployer
:
deployer
,
}
if
err
:=
ApplyPipeline
(
ctx
,
env
,
bundle
,
intent
,
st
);
err
!=
nil
{
return
err
}
return
nil
}
type
pipelineStage
struct
{
name
string
apply
func
()
error
}
func
ApplyPipeline
(
ctx
context
.
Context
,
env
*
pipeline
.
Env
,
bundle
pipeline
.
ArtifactsBundle
,
intent
*
state
.
Intent
,
st
*
state
.
State
,
)
error
{
pline
:=
[]
pipelineStage
{
{
"init"
,
func
()
error
{
if
intent
.
DeploymentStrategy
==
state
.
DeploymentStrategyLive
{
return
pipeline
.
InitLiveStrategy
(
ctx
,
e
nv
,
intent
,
st
)
return
pipeline
.
InitLiveStrategy
(
ctx
,
pE
nv
,
intent
,
st
)
}
else
{
return
pipeline
.
InitGenesisStrategy
(
e
nv
,
intent
,
st
)
return
pipeline
.
InitGenesisStrategy
(
pE
nv
,
intent
,
st
)
}
}},
{
"deploy-superchain"
,
func
()
error
{
return
pipeline
.
DeploySuperchain
(
e
nv
,
intent
,
st
)
return
pipeline
.
DeploySuperchain
(
pE
nv
,
intent
,
st
)
}},
{
"deploy-implementations"
,
func
()
error
{
return
pipeline
.
DeployImplementations
(
e
nv
,
intent
,
st
)
return
pipeline
.
DeployImplementations
(
pE
nv
,
intent
,
st
)
}},
}
...
...
@@ -230,21 +276,17 @@ func ApplyPipeline(
pline
=
append
(
pline
,
pipelineStage
{
fmt
.
Sprintf
(
"deploy-opchain-%s"
,
chainID
.
Hex
()),
func
()
error
{
if
intent
.
DeploymentStrategy
==
state
.
DeploymentStrategyLive
{
return
pipeline
.
DeployOPChainLiveStrategy
(
ctx
,
env
,
bundle
,
intent
,
st
,
chainID
)
}
else
{
return
pipeline
.
DeployOPChainGenesisStrategy
(
env
,
intent
,
st
,
chainID
)
}
return
pipeline
.
DeployOPChain
(
pEnv
,
intent
,
st
,
chainID
)
},
},
pipelineStage
{
fmt
.
Sprintf
(
"deploy-alt-da-%s"
,
chainID
.
Hex
()),
func
()
error
{
return
pipeline
.
DeployAltDA
(
e
nv
,
intent
,
st
,
chainID
)
return
pipeline
.
DeployAltDA
(
pE
nv
,
intent
,
st
,
chainID
)
},
},
pipelineStage
{
fmt
.
Sprintf
(
"generate-l2-genesis-%s"
,
chainID
.
Hex
()),
func
()
error
{
return
pipeline
.
GenerateL2Genesis
(
e
nv
,
intent
,
bundle
,
st
,
chainID
)
return
pipeline
.
GenerateL2Genesis
(
pE
nv
,
intent
,
bundle
,
st
,
chainID
)
},
})
}
...
...
@@ -257,9 +299,9 @@ func ApplyPipeline(
fmt
.
Sprintf
(
"set-start-block-%s"
,
chainID
.
Hex
()),
func
()
error
{
if
intent
.
DeploymentStrategy
==
state
.
DeploymentStrategyLive
{
return
pipeline
.
SetStartBlockLiveStrategy
(
ctx
,
e
nv
,
st
,
chainID
)
return
pipeline
.
SetStartBlockLiveStrategy
(
ctx
,
pE
nv
,
st
,
chainID
)
}
else
{
return
pipeline
.
SetStartBlockGenesisStrategy
(
e
nv
,
st
,
chainID
)
return
pipeline
.
SetStartBlockGenesisStrategy
(
pE
nv
,
st
,
chainID
)
}
},
})
...
...
@@ -271,23 +313,27 @@ func ApplyPipeline(
if
err
:=
stage
.
apply
();
err
!=
nil
{
return
fmt
.
Errorf
(
"error in pipeline stage apply: %w"
,
err
)
}
dump
,
err
:=
env
.
L1ScriptHost
.
StateDump
()
if
intent
.
DeploymentStrategy
==
state
.
DeploymentStrategyGenesis
{
dump
,
err
:=
pEnv
.
L1ScriptHost
.
StateDump
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to dump state: %w"
,
err
)
}
st
.
L1StateDump
=
&
state
.
GzipData
[
foundry
.
ForgeAllocs
]{
Data
:
dump
,
}
if
_
,
err
:=
env
.
Broadcaster
.
Broadcast
(
ctx
);
err
!=
nil
{
}
if
_
,
err
:=
pEnv
.
Broadcaster
.
Broadcast
(
ctx
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to broadcast stage %s: %w"
,
stage
.
name
,
err
)
}
if
err
:=
e
nv
.
StateWriter
.
WriteState
(
st
);
err
!=
nil
{
if
err
:=
pE
nv
.
StateWriter
.
WriteState
(
st
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to write state: %w"
,
err
)
}
}
st
.
AppliedIntent
=
intent
if
err
:=
e
nv
.
StateWriter
.
WriteState
(
st
);
err
!=
nil
{
if
err
:=
pE
nv
.
StateWriter
.
WriteState
(
st
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to write state: %w"
,
err
)
}
...
...
op-deployer/pkg/deployer/bootstrap/delayed_weth.go
View file @
50564d43
...
...
@@ -159,11 +159,11 @@ func DelayedWETH(ctx context.Context, cfg DelayedWETHConfig) error {
lgr
,
chainDeployer
,
artifactsFS
,
nonce
,
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create script host: %w"
,
err
)
}
host
.
SetNonce
(
chainDeployer
,
nonce
)
var
release
string
if
cfg
.
ArtifactsLocator
.
IsTag
()
{
...
...
op-deployer/pkg/deployer/bootstrap/dispute_game.go
View file @
50564d43
...
...
@@ -162,11 +162,11 @@ func DisputeGame(ctx context.Context, cfg DisputeGameConfig) error {
lgr
,
chainDeployer
,
artifactsFS
,
nonce
,
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create script host: %w"
,
err
)
}
host
.
SetNonce
(
chainDeployer
,
nonce
)
var
release
string
if
cfg
.
ArtifactsLocator
.
IsTag
()
{
...
...
op-deployer/pkg/deployer/bootstrap/mips.go
View file @
50564d43
...
...
@@ -157,11 +157,11 @@ func MIPS(ctx context.Context, cfg MIPSConfig) error {
lgr
,
chainDeployer
,
artifactsFS
,
nonce
,
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create script host: %w"
,
err
)
}
host
.
SetNonce
(
chainDeployer
,
nonce
)
var
release
string
if
cfg
.
ArtifactsLocator
.
IsTag
()
{
...
...
op-deployer/pkg/deployer/bootstrap/opcm.go
View file @
50564d43
...
...
@@ -193,11 +193,11 @@ func OPCM(ctx context.Context, cfg OPCMConfig) error {
lgr
,
chainDeployer
,
artifactsFS
,
nonce
,
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create script host: %w"
,
err
)
}
host
.
SetNonce
(
chainDeployer
,
nonce
)
var
release
string
if
cfg
.
ArtifactsLocator
.
IsTag
()
{
...
...
op-deployer/pkg/deployer/inspect/semvers.go
View file @
50564d43
...
...
@@ -72,7 +72,6 @@ func L2SemversCLI(cliCtx *cli.Context) error {
l
,
common
.
Address
{
19
:
0x01
},
artifactsFS
,
0
,
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create script host: %w"
,
err
)
...
...
op-deployer/pkg/deployer/integration_test/apply_test.go
View file @
50564d43
...
...
@@ -3,6 +3,7 @@ package integration_test
import
(
"bytes"
"context"
"crypto/rand"
"encoding/hex"
"fmt"
"log/slog"
...
...
@@ -17,19 +18,13 @@ import (
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts"
"github.com/ethereum-optimism/optimism/op-chain-ops/script"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/testutil"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/env"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard"
"github.com/ethereum-optimism/optimism/op-service/testutils/anvil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/pipeline"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/testutil"
"github.com/ethereum-optimism/optimism/op-service/testutils/anvil"
"github.com/ethereum/go-ethereum/crypto"
op_e2e
"github.com/ethereum-optimism/optimism/op-e2e"
...
...
@@ -37,7 +32,6 @@ import (
"github.com/ethereum-optimism/optimism/op-chain-ops/devkeys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
opcrypto
"github.com/ethereum-optimism/optimism/op-service/crypto"
"github.com/ethereum-optimism/optimism/op-service/predeploys"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum-optimism/optimism/op-service/testutils/kurtosisutil"
...
...
@@ -106,36 +100,25 @@ func TestEndToEndApply(t *testing.T) {
require
.
NoError
(
t
,
err
)
pk
,
err
:=
dk
.
Secret
(
depKey
)
require
.
NoError
(
t
,
err
)
signer
:=
opcrypto
.
SignerFnFromBind
(
opcrypto
.
PrivateKeySignerFn
(
pk
,
l1ChainID
))
l2ChainID1
:=
uint256
.
NewInt
(
1
)
l2ChainID2
:=
uint256
.
NewInt
(
2
)
deployerAddr
,
err
:=
dk
.
Address
(
depKey
)
require
.
NoError
(
t
,
err
)
loc
,
_
:=
testutil
.
LocalArtifacts
(
t
)
bcaster
,
err
:=
broadcaster
.
NewKeyedBroadcaster
(
broadcaster
.
KeyedBroadcasterOpts
{
Logger
:
log
.
NewLogger
(
log
.
DiscardHandler
()),
ChainID
:
l1ChainID
,
Client
:
l1Client
,
Signer
:
signer
,
From
:
deployerAddr
,
})
require
.
NoError
(
t
,
err
)
env
,
bundle
,
_
:=
createEnv
(
t
,
lgr
,
l1Client
,
bcaster
,
deployerAddr
)
intent
,
st
:=
newIntent
(
t
,
l1ChainID
,
dk
,
l2ChainID1
,
loc
,
loc
)
cg
:=
ethClientCodeGetter
(
ctx
,
l1Client
)
t
.
Run
(
"initial chain"
,
func
(
t
*
testing
.
T
)
{
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
env
,
bundle
,
intent
,
st
,
deployer
.
ApplyPipelineOpts
{
L1RPCUrl
:
rpcURL
,
DeployerPrivateKey
:
pk
,
Intent
:
intent
,
State
:
st
,
Logger
:
lgr
,
StateWriter
:
pipeline
.
NoopStateWriter
(),
},
))
validateSuperchainDeployment
(
t
,
st
,
cg
)
...
...
@@ -145,15 +128,18 @@ func TestEndToEndApply(t *testing.T) {
t
.
Run
(
"subsequent chain"
,
func
(
t
*
testing
.
T
)
{
// create a new environment with wiped state to ensure we can continue using the
// state from the previous deployment
env
,
bundle
,
_
=
createEnv
(
t
,
lgr
,
l1Client
,
bcaster
,
deployerAddr
)
intent
.
Chains
=
append
(
intent
.
Chains
,
newChainIntent
(
t
,
dk
,
l1ChainID
,
l2ChainID2
))
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
env
,
bundle
,
intent
,
st
,
deployer
.
ApplyPipelineOpts
{
L1RPCUrl
:
rpcURL
,
DeployerPrivateKey
:
pk
,
Intent
:
intent
,
State
:
st
,
Logger
:
lgr
,
StateWriter
:
pipeline
.
NoopStateWriter
(),
},
))
validateOPChainDeployment
(
t
,
cg
,
st
,
intent
)
...
...
@@ -191,24 +177,11 @@ func TestApplyExistingOPCM(t *testing.T) {
dk
,
err
:=
devkeys
.
NewMnemonicDevKeys
(
devkeys
.
TestMnemonic
)
require
.
NoError
(
t
,
err
)
// index 0 from Anvil's test set
p
riv
,
err
:=
crypto
.
HexToECDSA
(
"ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
)
p
k
,
err
:=
crypto
.
HexToECDSA
(
"ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
)
require
.
NoError
(
t
,
err
)
signer
:=
opcrypto
.
SignerFnFromBind
(
opcrypto
.
PrivateKeySignerFn
(
priv
,
l1ChainID
))
deployerAddr
:=
common
.
HexToAddress
(
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
)
l2ChainID
:=
uint256
.
NewInt
(
1
)
bcaster
,
err
:=
broadcaster
.
NewKeyedBroadcaster
(
broadcaster
.
KeyedBroadcasterOpts
{
Logger
:
lgr
,
ChainID
:
l1ChainID
,
Client
:
l1Client
,
Signer
:
signer
,
From
:
deployerAddr
,
})
require
.
NoError
(
t
,
err
)
env
,
bundle
,
_
:=
createEnv
(
t
,
lgr
,
l1Client
,
bcaster
,
deployerAddr
)
intent
,
st
:=
newIntent
(
t
,
l1ChainID
,
...
...
@@ -217,13 +190,20 @@ func TestApplyExistingOPCM(t *testing.T) {
artifacts
.
DefaultL1ContractsLocator
,
artifacts
.
DefaultL2ContractsLocator
,
)
// Define a new create2 salt to avoid contract address collisions
_
,
err
=
rand
.
Read
(
st
.
Create2Salt
[
:
])
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
env
,
bundle
,
intent
,
st
,
deployer
.
ApplyPipelineOpts
{
L1RPCUrl
:
runner
.
RPCUrl
(),
DeployerPrivateKey
:
pk
,
Intent
:
intent
,
State
:
st
,
Logger
:
lgr
,
StateWriter
:
pipeline
.
NoopStateWriter
(),
},
))
validateOPChainDeployment
(
t
,
ethClientCodeGetter
(
ctx
,
l1Client
),
st
,
intent
)
...
...
@@ -236,18 +216,12 @@ func TestL2BlockTimeOverride(t *testing.T) {
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
env
,
bundle
,
intent
,
st
:=
setupGenesisChain
(
t
)
opts
,
intent
,
st
:=
setupGenesisChain
(
t
)
intent
.
GlobalDeployOverrides
=
map
[
string
]
interface
{}{
"l2BlockTime"
:
float64
(
3
),
}
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
env
,
bundle
,
intent
,
st
,
))
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
opts
))
cfg
,
err
:=
state
.
CombineDeployConfig
(
intent
,
intent
.
Chains
[
0
],
st
,
st
.
Chains
[
0
])
require
.
NoError
(
t
,
err
)
...
...
@@ -260,16 +234,9 @@ func TestApplyGenesisStrategy(t *testing.T) {
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
env
,
bundle
,
intent
,
st
:=
setupGenesisChain
(
t
)
intent
.
DeploymentStrategy
=
state
.
DeploymentStrategyGenesis
opts
,
intent
,
st
:=
setupGenesisChain
(
t
)
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
env
,
bundle
,
intent
,
st
,
))
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
opts
))
cg
:=
stateDumpCodeGetter
(
st
)
validateSuperchainDeployment
(
t
,
st
,
cg
)
...
...
@@ -287,7 +254,7 @@ func TestProofParamOverrides(t *testing.T) {
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
env
,
bundle
,
intent
,
st
:=
setupGenesisChain
(
t
)
opts
,
intent
,
st
:=
setupGenesisChain
(
t
)
intent
.
GlobalDeployOverrides
=
map
[
string
]
any
{
"withdrawalDelaySeconds"
:
standard
.
WithdrawalDelaySeconds
+
1
,
"minProposalSizeBytes"
:
standard
.
MinProposalSizeBytes
+
1
,
...
...
@@ -304,13 +271,7 @@ func TestProofParamOverrides(t *testing.T) {
"dangerouslyAllowCustomDisputeParameters"
:
true
,
}
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
env
,
bundle
,
intent
,
st
,
))
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
opts
))
allocs
:=
st
.
L1StateDump
.
Data
.
Accounts
chainState
:=
st
.
Chains
[
0
]
...
...
@@ -390,16 +351,10 @@ func TestInteropDeployment(t *testing.T) {
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
env
,
bundle
,
intent
,
st
:=
setupGenesisChain
(
t
)
opts
,
intent
,
st
:=
setupGenesisChain
(
t
)
intent
.
UseInterop
=
true
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
env
,
bundle
,
intent
,
st
,
))
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
opts
))
chainState
:=
st
.
Chains
[
0
]
depManagerSlot
:=
common
.
HexToHash
(
"0x1708e077affb93e89be2665fb0fb72581be66f84dc00d25fed755ae911905b1c"
)
...
...
@@ -414,7 +369,7 @@ func TestAltDADeployment(t *testing.T) {
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
env
,
bundle
,
intent
,
st
:=
setupGenesisChain
(
t
)
opts
,
intent
,
st
:=
setupGenesisChain
(
t
)
altDACfg
:=
genesis
.
AltDADeployConfig
{
UseAltDA
:
true
,
DACommitmentType
:
altda
.
KeccakCommitmentString
,
...
...
@@ -425,13 +380,7 @@ func TestAltDADeployment(t *testing.T) {
}
intent
.
Chains
[
0
]
.
DangerousAltDAConfig
=
altDACfg
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
env
,
bundle
,
intent
,
st
,
))
require
.
NoError
(
t
,
deployer
.
ApplyPipeline
(
ctx
,
opts
))
chainState
:=
st
.
Chains
[
0
]
require
.
NotEmpty
(
t
,
chainState
.
DataAvailabilityChallengeProxyAddress
)
...
...
@@ -450,23 +399,9 @@ func TestAltDADeployment(t *testing.T) {
func
TestInvalidL2Genesis
(
t
*
testing
.
T
)
{
op_e2e
.
InitParallel
(
t
)
lgr
:=
testlog
.
Logger
(
t
,
slog
.
LevelDebug
)
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
depKey
:=
new
(
deployerKey
)
l1ChainID
:=
big
.
NewInt
(
77799777
)
dk
,
err
:=
devkeys
.
NewMnemonicDevKeys
(
devkeys
.
TestMnemonic
)
require
.
NoError
(
t
,
err
)
l2ChainID1
:=
uint256
.
NewInt
(
1
)
deployerAddr
,
err
:=
dk
.
Address
(
depKey
)
require
.
NoError
(
t
,
err
)
loc
,
_
:=
testutil
.
LocalArtifacts
(
t
)
// these tests were generated by grepping all usages of the deploy
// config in L2Genesis.s.sol.
tests
:=
[]
struct
{
...
...
@@ -512,26 +447,18 @@ func TestInvalidL2Genesis(t *testing.T) {
}
for
_
,
tt
:=
range
tests
{
t
.
Run
(
tt
.
name
,
func
(
t
*
testing
.
T
)
{
env
,
bundle
,
_
:=
createEnv
(
t
,
lgr
,
nil
,
broadcaster
.
NoopBroadcaster
(),
deployerAddr
)
intent
,
st
:=
newIntent
(
t
,
l1ChainID
,
dk
,
l2ChainID1
,
loc
,
loc
)
intent
.
Chains
=
append
(
intent
.
Chains
,
newChainIntent
(
t
,
dk
,
l1ChainID
,
l2ChainID1
))
opts
,
intent
,
_
:=
setupGenesisChain
(
t
)
intent
.
DeploymentStrategy
=
state
.
DeploymentStrategyGenesis
intent
.
GlobalDeployOverrides
=
tt
.
overrides
err
:=
deployer
.
ApplyPipeline
(
ctx
,
env
,
bundle
,
intent
,
st
,
)
err
:=
deployer
.
ApplyPipeline
(
ctx
,
opts
)
require
.
Error
(
t
,
err
)
require
.
ErrorContains
(
t
,
err
,
"failed to combine L2 init config"
)
})
}
}
func
setupGenesisChain
(
t
*
testing
.
T
)
(
*
pipeline
.
Env
,
pipeline
.
ArtifactsBundle
,
*
state
.
Intent
,
*
state
.
State
)
{
func
setupGenesisChain
(
t
*
testing
.
T
)
(
deployer
.
ApplyPipelineOpts
,
*
state
.
Intent
,
*
state
.
State
)
{
lgr
:=
testlog
.
Logger
(
t
,
slog
.
LevelDebug
)
depKey
:=
new
(
deployerKey
)
...
...
@@ -541,51 +468,24 @@ func setupGenesisChain(t *testing.T) (*pipeline.Env, pipeline.ArtifactsBundle, *
l2ChainID1
:=
uint256
.
NewInt
(
1
)
deployerAddr
,
err
:=
dk
.
Address
(
depKey
)
priv
,
err
:=
dk
.
Secret
(
depKey
)
require
.
NoError
(
t
,
err
)
loc
,
_
:=
testutil
.
LocalArtifacts
(
t
)
env
,
bundle
,
_
:=
createEnv
(
t
,
lgr
,
nil
,
broadcaster
.
NoopBroadcaster
(),
deployerAddr
)
intent
,
st
:=
newIntent
(
t
,
l1ChainID
,
dk
,
l2ChainID1
,
loc
,
loc
)
intent
.
Chains
=
append
(
intent
.
Chains
,
newChainIntent
(
t
,
dk
,
l1ChainID
,
l2ChainID1
))
intent
.
DeploymentStrategy
=
state
.
DeploymentStrategyGenesis
return
env
,
bundle
,
intent
,
st
}
func
createEnv
(
t
*
testing
.
T
,
lgr
log
.
Logger
,
l1Client
*
ethclient
.
Client
,
bcaster
broadcaster
.
Broadcaster
,
deployerAddr
common
.
Address
,
)
(
*
pipeline
.
Env
,
pipeline
.
ArtifactsBundle
,
*
script
.
Host
)
{
_
,
artifactsFS
:=
testutil
.
LocalArtifacts
(
t
)
host
,
err
:=
env
.
DefaultScriptHost
(
bcaster
,
lgr
,
deployerAddr
,
artifactsFS
,
0
,
)
require
.
NoError
(
t
,
err
)
env
:=
&
pipeline
.
Env
{
StateWriter
:
pipeline
.
NoopStateWriter
(),
L1ScriptHost
:
host
,
L1Client
:
l1Client
,
Broadcaster
:
bcaster
,
Deployer
:
deployerAddr
,
opts
:=
deployer
.
ApplyPipelineOpts
{
DeployerPrivateKey
:
priv
,
Intent
:
intent
,
State
:
st
,
Logger
:
lgr
,
StateWriter
:
pipeline
.
NoopStateWriter
(),
}
bundle
:=
pipeline
.
ArtifactsBundle
{
L1
:
artifactsFS
,
L2
:
artifactsFS
,
}
return
env
,
bundle
,
host
return
opts
,
intent
,
st
}
func
addrFor
(
t
*
testing
.
T
,
dk
*
devkeys
.
MnemonicDevKeys
,
key
devkeys
.
Key
)
common
.
Address
{
...
...
op-deployer/pkg/deployer/opcm/alt_da_test.go
View file @
50564d43
...
...
@@ -21,7 +21,6 @@ func TestDeployAltDA(t *testing.T) {
testlog
.
Logger
(
t
,
log
.
LevelInfo
),
common
.
Address
{
'D'
},
artifacts
,
0
,
)
require
.
NoError
(
t
,
err
)
...
...
op-deployer/pkg/deployer/opcm/delayed_weth_test.go
View file @
50564d43
...
...
@@ -22,7 +22,6 @@ func TestDeployDelayedWETH(t *testing.T) {
testlog
.
Logger
(
t
,
log
.
LevelInfo
),
common
.
Address
{
'D'
},
artifacts
,
0
,
)
require
.
NoError
(
t
,
err
)
...
...
op-deployer/pkg/deployer/opcm/deployOutput_v160.json
deleted
100644 → 0
View file @
ae78b73d
[
{
"type"
:
"function"
,
"name"
:
"decodeOutput"
,
"inputs"
:
[],
"outputs"
:
[
{
"name"
:
"output"
,
"indexed"
:
false
,
"type"
:
"tuple"
,
"components"
:
[
{
"name"
:
"opChainProxyAdmin"
,
"type"
:
"address"
},
{
"name"
:
"addressManager"
,
"type"
:
"address"
},
{
"name"
:
"l1ERC721BridgeProxy"
,
"type"
:
"address"
},
{
"name"
:
"systemConfigProxy"
,
"type"
:
"address"
},
{
"name"
:
"optimismMintableERC20FactoryProxy"
,
"type"
:
"address"
},
{
"name"
:
"l1StandardBridgeProxy"
,
"type"
:
"address"
},
{
"name"
:
"l1CrossDomainMessengerProxy"
,
"type"
:
"address"
},
{
"name"
:
"optimismPortalProxy"
,
"type"
:
"address"
},
{
"name"
:
"disputeGameFactoryProxy"
,
"type"
:
"address"
},
{
"name"
:
"anchorStateRegistryProxy"
,
"type"
:
"address"
},
{
"name"
:
"anchorStateRegistryImpl"
,
"type"
:
"address"
},
{
"name"
:
"faultDisputeGame"
,
"type"
:
"address"
,
"internalType"
:
"contract FaultDisputeGame"
},
{
"name"
:
"permissionedDisputeGame"
,
"type"
:
"address"
},
{
"name"
:
"delayedWETHPermissionedGameProxy"
,
"type"
:
"address"
},
{
"name"
:
"delayedWETHPermissionlessGameProxy"
,
"type"
:
"address"
}
]
}
]
}
]
\ No newline at end of file
op-deployer/pkg/deployer/opcm/dispute_game_test.go
View file @
50564d43
...
...
@@ -21,7 +21,6 @@ func TestDeployDisputeGame(t *testing.T) {
testlog
.
Logger
(
t
,
log
.
LevelInfo
),
common
.
Address
{
'D'
},
artifacts
,
0
,
)
require
.
NoError
(
t
,
err
)
...
...
op-deployer/pkg/deployer/opcm/mips_test.go
View file @
50564d43
...
...
@@ -20,7 +20,6 @@ func TestDeployMIPS(t *testing.T) {
testlog
.
Logger
(
t
,
log
.
LevelInfo
),
common
.
Address
{
'D'
},
artifacts
,
0
,
)
require
.
NoError
(
t
,
err
)
...
...
op-deployer/pkg/deployer/opcm/opchain.go
View file @
50564d43
package
opcm
import
(
"context
"
_
"embed
"
"fmt"
"math/big"
"strings"
_
"embed"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster"
"github.com/ethereum-optimism/optimism/op-chain-ops/foundry"
"github.com/ethereum-optimism/optimism/op-chain-ops/script"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/holiman/uint256"
)
// PermissionedGameStartingAnchorRoots is a root of bytes32(hex"dead") for the permissioned game at block 0,
...
...
@@ -25,48 +15,6 @@ var PermissionedGameStartingAnchorRoots = []byte{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x20
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x01
,
0xde
,
0xad
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
}
// opcmRolesBase is an internal struct used to pass the roles to OPCM. See opcmDeployInputV160 for more info.
type
opcmRolesBase
struct
{
OpChainProxyAdminOwner
common
.
Address
SystemConfigOwner
common
.
Address
Batcher
common
.
Address
UnsafeBlockSigner
common
.
Address
Proposer
common
.
Address
Challenger
common
.
Address
}
type
opcmDeployInputBase
struct
{
BasefeeScalar
uint32
BlobBasefeeScalar
uint32
L2ChainId
*
big
.
Int
StartingAnchorRoots
[]
byte
SaltMixer
string
GasLimit
uint64
DisputeGameType
uint32
DisputeAbsolutePrestate
common
.
Hash
DisputeMaxGameDepth
*
big
.
Int
DisputeSplitDepth
*
big
.
Int
DisputeClockExtension
uint64
DisputeMaxClockDuration
uint64
}
// opcmDeployInputV160 is the input struct for the deploy method of the OPStackManager contract. We
// define a separate struct here to match what the OPSM contract expects.
type
opcmDeployInputV160
struct
{
opcmDeployInputBase
Roles
opcmRolesBase
}
type
opcmRolesIsthmus
struct
{
opcmRolesBase
FeeAdmin
common
.
Address
}
type
opcmDeployInputIsthmus
struct
{
opcmDeployInputBase
Roles
opcmRolesIsthmus
}
type
DeployOPChainInputV160
struct
{
OpChainProxyAdminOwner
common
.
Address
SystemConfigOwner
common
.
Address
...
...
@@ -99,49 +47,11 @@ func (input *DeployOPChainInputV160) StartingAnchorRoots() []byte {
return
PermissionedGameStartingAnchorRoots
}
func
DeployOPChainInputV160DeployCalldata
(
input
DeployOPChainInputV160
)
any
{
return
opcmDeployInputV160
{
Roles
:
opcmRolesBase
{
OpChainProxyAdminOwner
:
input
.
OpChainProxyAdminOwner
,
SystemConfigOwner
:
input
.
SystemConfigOwner
,
Batcher
:
input
.
Batcher
,
UnsafeBlockSigner
:
input
.
UnsafeBlockSigner
,
Proposer
:
input
.
Proposer
,
Challenger
:
input
.
Challenger
,
},
opcmDeployInputBase
:
opcmDeployInputBase
{
BasefeeScalar
:
input
.
BasefeeScalar
,
BlobBasefeeScalar
:
input
.
BlobBaseFeeScalar
,
L2ChainId
:
input
.
L2ChainId
,
StartingAnchorRoots
:
input
.
StartingAnchorRoots
(),
SaltMixer
:
input
.
SaltMixer
,
GasLimit
:
input
.
GasLimit
,
DisputeGameType
:
input
.
DisputeGameType
,
DisputeAbsolutePrestate
:
input
.
DisputeAbsolutePrestate
,
DisputeMaxGameDepth
:
new
(
big
.
Int
)
.
SetUint64
(
input
.
DisputeMaxGameDepth
),
DisputeSplitDepth
:
new
(
big
.
Int
)
.
SetUint64
(
input
.
DisputeSplitDepth
),
DisputeClockExtension
:
input
.
DisputeClockExtension
,
DisputeMaxClockDuration
:
input
.
DisputeMaxClockDuration
,
},
}
}
type
DeployOPChainInputIsthmus
struct
{
DeployOPChainInputV160
SystemConfigFeeAdmin
common
.
Address
}
func
DeployOPChainInputIsthmusDeployCalldata
(
input
DeployOPChainInputIsthmus
)
any
{
v160Data
:=
DeployOPChainInputV160DeployCalldata
(
input
.
DeployOPChainInputV160
)
.
(
opcmDeployInputV160
)
return
opcmDeployInputIsthmus
{
Roles
:
opcmRolesIsthmus
{
opcmRolesBase
:
v160Data
.
Roles
,
FeeAdmin
:
input
.
SystemConfigFeeAdmin
,
},
opcmDeployInputBase
:
v160Data
.
opcmDeployInputBase
,
}
}
type
DeployOPChainOutput
struct
{
OpChainProxyAdmin
common
.
Address
AddressManager
common
.
Address
...
...
@@ -210,116 +120,58 @@ func deployOPChain[T any](host *script.Host, input T) (DeployOPChainOutput, erro
return
dco
,
nil
}
// decodeOutputABIJSONV160 defines an ABI for a fake method called "decodeOutput" that returns the
// DeployOutput struct. This allows the code in the deployer to decode directly into a struct
// using Geth's ABI library.
//
//go:embed deployOutput_v160.json
var
decodeOutputABIJSONV160
string
var
decodeOutputABIV160
abi
.
ABI
func
DeployOPChainRawV160
(
ctx
context
.
Context
,
l1
*
ethclient
.
Client
,
bcast
broadcaster
.
Broadcaster
,
deployer
common
.
Address
,
artifacts
foundry
.
StatDirFs
,
input
DeployOPChainInputV160
,
)
(
DeployOPChainOutput
,
error
)
{
return
deployOPChainRaw
(
ctx
,
l1
,
bcast
,
deployer
,
artifacts
,
input
.
OpcmProxy
,
DeployOPChainInputV160DeployCalldata
(
input
))
type
ReadImplementationAddressesInput
struct
{
DeployOPChainOutput
OpcmProxy
common
.
Address
Release
string
}
func
DeployOPChainRawIsthmus
(
ctx
context
.
Context
,
l1
*
ethclient
.
Client
,
bcast
broadcaster
.
Broadcaster
,
deployer
common
.
Address
,
artifacts
foundry
.
StatDirFs
,
input
DeployOPChainInputIsthmus
,
)
(
DeployOPChainOutput
,
error
)
{
return
deployOPChainRaw
(
ctx
,
l1
,
bcast
,
deployer
,
artifacts
,
input
.
OpcmProxy
,
DeployOPChainInputIsthmusDeployCalldata
(
input
))
type
ReadImplementationAddressesOutput
struct
{
DelayedWETH
common
.
Address
OptimismPortal
common
.
Address
SystemConfig
common
.
Address
L1CrossDomainMessenger
common
.
Address
L1ERC721Bridge
common
.
Address
L1StandardBridge
common
.
Address
OptimismMintableERC20Factory
common
.
Address
DisputeGameFactory
common
.
Address
MipsSingleton
common
.
Address
PreimageOracleSingleton
common
.
Address
}
// DeployOPChainRaw deploys an OP Chain using a raw call to a pre-deployed OPSM contract.
func
deployOPChainRaw
(
ctx
context
.
Context
,
l1
*
ethclient
.
Client
,
bcast
broadcaster
.
Broadcaster
,
deployer
common
.
Address
,
artifacts
foundry
.
StatDirFs
,
opcmProxyAddress
common
.
Address
,
input
any
,
)
(
DeployOPChainOutput
,
error
)
{
var
out
DeployOPChainOutput
type
ReadImplementationAddressesScript
struct
{
Run
func
(
input
,
output
common
.
Address
)
error
}
artifactsFS
:=
&
foundry
.
ArtifactsFS
{
FS
:
artifacts
}
opcmArtifacts
,
err
:=
artifactsFS
.
ReadArtifact
(
"OPContractsManager.sol"
,
"OPContractsManager"
)
if
err
!=
nil
{
return
out
,
fmt
.
Errorf
(
"failed to read OPStackManager artifact: %w"
,
err
)
}
func
ReadImplementationAddresses
(
host
*
script
.
Host
,
input
ReadImplementationAddressesInput
)
(
ReadImplementationAddressesOutput
,
error
)
{
var
rio
ReadImplementationAddressesOutput
inputAddr
:=
host
.
NewScriptAddress
()
outputAddr
:=
host
.
NewScriptAddress
()
opcmABI
:=
opcmArtifacts
.
ABI
calldata
,
err
:=
opcmABI
.
Pack
(
"deploy"
,
input
)
cleanupInput
,
err
:=
script
.
WithPrecompileAtAddress
[
*
ReadImplementationAddressesInput
](
host
,
inputAddr
,
&
input
)
if
err
!=
nil
{
return
out
,
fmt
.
Errorf
(
"failed to pack deploy input
: %w"
,
err
)
return
rio
,
fmt
.
Errorf
(
"failed to insert ReadImplementationAddressesInput precompile
: %w"
,
err
)
}
defer
cleanupInput
()
host
.
Label
(
inputAddr
,
"ReadImplementationAddressesInput"
)
nonce
,
err
:=
l1
.
NonceAt
(
ctx
,
deployer
,
nil
)
cleanupOutput
,
err
:=
script
.
WithPrecompileAtAddress
[
*
ReadImplementationAddressesOutput
](
host
,
outputAddr
,
&
rio
,
script
.
WithFieldSetter
[
*
ReadImplementationAddressesOutput
])
if
err
!=
nil
{
return
out
,
fmt
.
Errorf
(
"failed to read nonc
e: %w"
,
err
)
return
rio
,
fmt
.
Errorf
(
"failed to insert ReadImplementationAddressesOutput precompil
e: %w"
,
err
)
}
defer
cleanupOutput
()
host
.
Label
(
outputAddr
,
"ReadImplementationAddressesOutput"
)
bcast
.
Hook
(
script
.
Broadcast
{
From
:
deployer
,
To
:
opcmProxyAddress
,
Input
:
calldata
,
Value
:
(
*
hexutil
.
U256
)(
uint256
.
NewInt
(
0
)),
// use hardcoded 19MM gas for now since this is roughly what we've seen this deployment cost.
GasUsed
:
19
_000_000
,
Type
:
script
.
BroadcastCall
,
Nonce
:
nonce
,
})
results
,
err
:=
bcast
.
Broadcast
(
ctx
)
deployScript
,
cleanupDeploy
,
err
:=
script
.
WithScript
[
ReadImplementationAddressesScript
](
host
,
"ReadImplementationAddresses.s.sol"
,
"ReadImplementationAddresses"
)
if
err
!=
nil
{
return
out
,
fmt
.
Errorf
(
"failed to broadcast OP chain deployment: %w"
,
err
)
}
deployedEvent
:=
opcmABI
.
Events
[
"Deployed"
]
res
:=
results
[
0
]
for
_
,
log
:=
range
res
.
Receipt
.
Logs
{
if
log
.
Topics
[
0
]
!=
deployedEvent
.
ID
{
continue
}
type
EventData
struct
{
DeployOutput
[]
byte
}
var
data
EventData
if
err
:=
opcmABI
.
UnpackIntoInterface
(
&
data
,
"Deployed"
,
log
.
Data
);
err
!=
nil
{
return
out
,
fmt
.
Errorf
(
"failed to unpack Deployed event: %w"
,
err
)
}
type
OutputData
struct
{
Output
DeployOPChainOutput
}
var
outData
OutputData
if
err
:=
decodeOutputABIV160
.
UnpackIntoInterface
(
&
outData
,
"decodeOutput"
,
data
.
DeployOutput
);
err
!=
nil
{
return
out
,
fmt
.
Errorf
(
"failed to unpack DeployOutput: %w"
,
err
)
return
rio
,
fmt
.
Errorf
(
"failed to load ReadImplementationAddresses script: %w"
,
err
)
}
defer
cleanupDeploy
()
return
outData
.
Output
,
nil
if
err
:=
deployScript
.
Run
(
inputAddr
,
outputAddr
);
err
!=
nil
{
return
rio
,
fmt
.
Errorf
(
"failed to run ReadImplementationAddresses script: %w"
,
err
)
}
return
out
,
fmt
.
Errorf
(
"failed to find Deployed event"
)
}
func
init
()
{
var
err
error
decodeOutputABIV160
,
err
=
abi
.
JSON
(
strings
.
NewReader
(
decodeOutputABIJSONV160
))
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"failed to parse decodeOutput ABI: %v"
,
err
))
}
return
rio
,
nil
}
op-deployer/pkg/deployer/pipeline/env.go
View file @
50564d43
...
...
@@ -23,7 +23,6 @@ type Env struct {
L1ScriptHost
*
script
.
Host
L1Client
*
ethclient
.
Client
Broadcaster
broadcaster
.
Broadcaster
Host
*
script
.
Host
Deployer
common
.
Address
Logger
log
.
Logger
}
...
...
op-deployer/pkg/deployer/pipeline/implementations.go
View file @
50564d43
...
...
@@ -58,8 +58,6 @@ func DeployImplementations(env *Env, intent *state.Intent, st *state.State) erro
return
fmt
.
Errorf
(
"error merging proof params from overrides: %w"
,
err
)
}
env
.
L1ScriptHost
.
ImportState
(
st
.
L1StateDump
.
Data
)
dio
,
err
:=
opcm
.
DeployImplementations
(
env
.
L1ScriptHost
,
opcm
.
DeployImplementationsInput
{
...
...
op-deployer/pkg/deployer/pipeline/l2genesis.go
View file @
50564d43
...
...
@@ -3,7 +3,7 @@ package pipeline
import
(
"fmt"
env2
"github.com/ethereum-optimism/optimism/op-deployer/pkg/env"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/env"
"github.com/ethereum-optimism/optimism/op-chain-ops/foundry"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster"
...
...
@@ -13,8 +13,8 @@ import (
"github.com/ethereum/go-ethereum/common"
)
func
GenerateL2Genesis
(
e
nv
*
Env
,
intent
*
state
.
Intent
,
bundle
ArtifactsBundle
,
st
*
state
.
State
,
chainID
common
.
Hash
)
error
{
lgr
:=
e
nv
.
Logger
.
New
(
"stage"
,
"generate-l2-genesis"
)
func
GenerateL2Genesis
(
pE
nv
*
Env
,
intent
*
state
.
Intent
,
bundle
ArtifactsBundle
,
st
*
state
.
State
,
chainID
common
.
Hash
)
error
{
lgr
:=
pE
nv
.
Logger
.
New
(
"stage"
,
"generate-l2-genesis"
)
thisIntent
,
err
:=
intent
.
Chain
(
chainID
)
if
err
!=
nil
{
...
...
@@ -38,12 +38,11 @@ func GenerateL2Genesis(env *Env, intent *state.Intent, bundle ArtifactsBundle, s
return
fmt
.
Errorf
(
"failed to combine L2 init config: %w"
,
err
)
}
host
,
err
:=
env
2
.
DefaultScriptHost
(
host
,
err
:=
env
.
DefaultScriptHost
(
broadcaster
.
NoopBroadcaster
(),
e
nv
.
Logger
,
e
nv
.
Deployer
,
pE
nv
.
Logger
,
pE
nv
.
Deployer
,
bundle
.
L2
,
0
,
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create L2 script host: %w"
,
err
)
...
...
@@ -60,7 +59,7 @@ func GenerateL2Genesis(env *Env, intent *state.Intent, bundle ArtifactsBundle, s
return
fmt
.
Errorf
(
"failed to call L2Genesis script: %w"
,
err
)
}
host
.
Wipe
(
e
nv
.
Deployer
)
host
.
Wipe
(
pE
nv
.
Deployer
)
dump
,
err
:=
host
.
StateDump
()
if
err
!=
nil
{
...
...
op-deployer/pkg/deployer/pipeline/opchain.go
View file @
50564d43
package
pipeline
import
(
"context"
"encoding/hex"
"errors"
"fmt"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard"
"github.com/ethereum-optimism/optimism/op-service/jsonutil"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)
func
DeployOPChain
LiveStrategy
(
ctx
context
.
Context
,
env
*
Env
,
bundle
ArtifactsBundle
,
intent
*
state
.
Intent
,
st
*
state
.
State
,
chainID
common
.
Hash
)
error
{
lgr
:=
env
.
Logger
.
New
(
"stage"
,
"deploy-opchain"
,
"strategy"
,
"live"
)
func
DeployOPChain
(
env
*
Env
,
intent
*
state
.
Intent
,
st
*
state
.
State
,
chainID
common
.
Hash
)
error
{
lgr
:=
env
.
Logger
.
New
(
"stage"
,
"deploy-opchain"
)
if
!
shouldDeployOPChain
(
st
,
chainID
)
{
lgr
.
Info
(
"opchain deployment not needed"
)
...
...
@@ -31,6 +24,7 @@ func DeployOPChainLiveStrategy(ctx context.Context, env *Env, bundle ArtifactsBu
return
fmt
.
Errorf
(
"failed to get chain intent: %w"
,
err
)
}
var
opcmAddr
common
.
Address
var
deployFunc
func
()
(
opcm
.
DeployOPChainOutput
,
error
)
switch
intent
.
L1ContractsLocator
.
Tag
{
case
standard
.
ContractsV160Tag
,
standard
.
ContractsV170Beta1L2Tag
:
...
...
@@ -40,13 +34,8 @@ func DeployOPChainLiveStrategy(ctx context.Context, env *Env, bundle ArtifactsBu
return
opcm
.
DeployOPChainOutput
{},
fmt
.
Errorf
(
"error making deploy OP chain input: %w"
,
err
)
}
return
opcm
.
DeployOPChainRawV160
(
ctx
,
env
.
L1Client
,
env
.
Broadcaster
,
env
.
Deployer
,
bundle
.
L1
,
input
,
)
opcmAddr
=
input
.
OpcmProxy
return
opcm
.
DeployOPChainV160
(
env
.
L1ScriptHost
,
input
)
}
default
:
deployFunc
=
func
()
(
opcm
.
DeployOPChainOutput
,
error
)
{
...
...
@@ -55,165 +44,47 @@ func DeployOPChainLiveStrategy(ctx context.Context, env *Env, bundle ArtifactsBu
return
opcm
.
DeployOPChainOutput
{},
fmt
.
Errorf
(
"error making deploy OP chain input: %w"
,
err
)
}
return
opcm
.
DeployOPChainRawIsthmus
(
ctx
,
env
.
L1Client
,
env
.
Broadcaster
,
env
.
Deployer
,
bundle
.
L1
,
input
,
)
opcmAddr
=
input
.
OpcmProxy
return
opcm
.
DeployOPChainIsthmus
(
env
.
L1ScriptHost
,
input
)
}
}
var
dco
opcm
.
DeployOPChainOutput
lgr
.
Info
(
"deploying OP chain using
existing OPCM"
,
"id"
,
chainID
.
Hex
(),
"opcmAddress"
,
st
.
ImplementationsDeployment
.
OpcmProxyAddress
.
Hex
())
lgr
.
Info
(
"deploying OP chain using
local allocs"
,
"id"
,
chainID
.
Hex
())
dco
,
err
=
deployFunc
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error deploying OP chain: %w"
,
err
)
}
st
.
Chains
=
append
(
st
.
Chains
,
makeChainState
(
chainID
,
dco
))
opcmProxyAddress
:=
st
.
ImplementationsDeployment
.
OpcmProxyAddress
err
=
conditionallySetImplementationAddresses
(
ctx
,
env
.
L1Client
,
intent
,
st
,
dco
,
opcmProxyAddress
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to set implementation addresses: %w"
,
err
)
}
return
nil
}
// Only try to set the implementation addresses if we reused existing implementations from a release tag.
// The reason why these addresses could be empty is because only DeployOPChain.s.sol is invoked as part of the pipeline.
func
conditionallySetImplementationAddresses
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
intent
*
state
.
Intent
,
st
*
state
.
State
,
dco
opcm
.
DeployOPChainOutput
,
opcmProxyAddress
common
.
Address
)
error
{
if
!
intent
.
L1ContractsLocator
.
IsTag
()
{
return
nil
}
block
,
err
:=
client
.
BlockByNumber
(
ctx
,
nil
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to get latest block by number: %w"
,
err
)
}
currentBlockHash
:=
block
.
Hash
()
errCh
:=
make
(
chan
error
,
8
)
setImplementationAddressTasks
:=
[]
func
(){
func
()
{
setEIP1967ImplementationAddress
(
ctx
,
client
,
errCh
,
dco
.
DelayedWETHPermissionedGameProxy
,
currentBlockHash
,
&
st
.
ImplementationsDeployment
.
DelayedWETHImplAddress
)
},
func
()
{
setEIP1967ImplementationAddress
(
ctx
,
client
,
errCh
,
dco
.
OptimismPortalProxy
,
currentBlockHash
,
&
st
.
ImplementationsDeployment
.
OptimismPortalImplAddress
)
},
func
()
{
setEIP1967ImplementationAddress
(
ctx
,
client
,
errCh
,
dco
.
SystemConfigProxy
,
currentBlockHash
,
&
st
.
ImplementationsDeployment
.
SystemConfigImplAddress
)
},
func
()
{
setRDPImplementationAddress
(
ctx
,
client
,
errCh
,
dco
.
AddressManager
,
&
st
.
ImplementationsDeployment
.
L1CrossDomainMessengerImplAddress
,
"OVM_L1CrossDomainMessenger"
)
},
func
()
{
setEIP1967ImplementationAddress
(
ctx
,
client
,
errCh
,
dco
.
L1ERC721BridgeProxy
,
currentBlockHash
,
&
st
.
ImplementationsDeployment
.
L1ERC721BridgeImplAddress
)
},
func
()
{
setEIP1967ImplementationAddress
(
ctx
,
client
,
errCh
,
dco
.
L1StandardBridgeProxy
,
currentBlockHash
,
&
st
.
ImplementationsDeployment
.
L1StandardBridgeImplAddress
)
},
func
()
{
setEIP1967ImplementationAddress
(
ctx
,
client
,
errCh
,
dco
.
OptimismMintableERC20FactoryProxy
,
currentBlockHash
,
&
st
.
ImplementationsDeployment
.
OptimismMintableERC20FactoryImplAddress
)
},
func
()
{
setEIP1967ImplementationAddress
(
ctx
,
client
,
errCh
,
dco
.
DisputeGameFactoryProxy
,
currentBlockHash
,
&
st
.
ImplementationsDeployment
.
DisputeGameFactoryImplAddress
)
},
func
()
{
setMipsSingletonAddress
(
ctx
,
client
,
intent
.
L1ContractsLocator
,
errCh
,
opcmProxyAddress
,
&
st
.
ImplementationsDeployment
.
MipsSingletonAddress
)
setPreimageOracleAddress
(
ctx
,
client
,
errCh
,
st
.
ImplementationsDeployment
.
MipsSingletonAddress
,
&
st
.
ImplementationsDeployment
.
PreimageOracleSingletonAddress
)
},
}
for
_
,
task
:=
range
setImplementationAddressTasks
{
go
task
()
}
var
lastTaskErr
error
for
i
:=
0
;
i
<
len
(
setImplementationAddressTasks
);
i
++
{
taskErr
:=
<-
errCh
if
taskErr
!=
nil
{
lastTaskErr
=
taskErr
}
}
if
lastTaskErr
!=
nil
{
return
fmt
.
Errorf
(
"failed to set implementation addresses: %w"
,
lastTaskErr
)
}
return
nil
}
func
setMipsSingletonAddress
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
l1ArtifactsLocator
*
artifacts
.
Locator
,
errCh
chan
error
,
opcmProxyAddress
common
.
Address
,
singletonAddress
*
common
.
Address
)
{
if
!
l1ArtifactsLocator
.
IsTag
()
{
errCh
<-
errors
.
New
(
"L1 contracts locator is not a tag, cannot set MIPS singleton address"
)
return
}
opcmContract
:=
opcm
.
NewContract
(
opcmProxyAddress
,
client
)
mipsSingletonAddress
,
err
:=
opcmContract
.
GetOPCMImplementationAddress
(
ctx
,
l1ArtifactsLocator
.
Tag
,
"MIPS"
)
if
err
==
nil
{
*
singletonAddress
=
mipsSingletonAddress
}
errCh
<-
err
}
func
setPreimageOracleAddress
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
errCh
chan
error
,
mipsSingletonAddress
common
.
Address
,
preimageOracleAddress
*
common
.
Address
)
{
opcmContract
:=
opcm
.
NewContract
(
mipsSingletonAddress
,
client
)
preimageOracle
,
err
:=
opcmContract
.
GenericAddressGetter
(
ctx
,
"oracle"
)
if
err
==
nil
{
*
preimageOracleAddress
=
preimageOracle
}
errCh
<-
err
}
func
DeployOPChainGenesisStrategy
(
env
*
Env
,
intent
*
state
.
Intent
,
st
*
state
.
State
,
chainID
common
.
Hash
)
error
{
lgr
:=
env
.
Logger
.
New
(
"stage"
,
"deploy-opchain"
,
"strategy"
,
"genesis"
)
if
!
shouldDeployOPChain
(
st
,
chainID
)
{
lgr
.
Info
(
"opchain deployment not needed"
)
return
nil
}
thisIntent
,
err
:=
intent
.
Chain
(
chainID
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to get chain intent: %w"
,
err
)
}
var
deployFunc
func
()
(
opcm
.
DeployOPChainOutput
,
error
)
switch
intent
.
L1ContractsLocator
.
Tag
{
case
standard
.
ContractsV160Tag
,
standard
.
ContractsV170Beta1L2Tag
:
deployFunc
=
func
()
(
opcm
.
DeployOPChainOutput
,
error
)
{
input
,
err
:=
makeDCIV160
(
intent
,
thisIntent
,
chainID
,
st
)
if
err
!=
nil
{
return
opcm
.
DeployOPChainOutput
{},
fmt
.
Errorf
(
"error making deploy OP chain input: %w"
,
err
)
}
return
opcm
.
DeployOPChainV160
(
env
.
L1ScriptHost
,
input
)
}
default
:
deployFunc
=
func
()
(
opcm
.
DeployOPChainOutput
,
error
)
{
input
,
err
:=
makeDCIIsthmus
(
intent
,
thisIntent
,
chainID
,
st
)
if
err
!=
nil
{
return
opcm
.
DeployOPChainOutput
{},
fmt
.
Errorf
(
"error making deploy OP chain input: %w"
,
err
)
var
release
string
if
intent
.
L1ContractsLocator
.
IsTag
()
{
release
=
intent
.
L1ContractsLocator
.
Tag
}
else
{
release
=
"dev"
}
return
opcm
.
DeployOPChainIsthmus
(
env
.
L1ScriptHost
,
input
)
}
readInput
:=
opcm
.
ReadImplementationAddressesInput
{
DeployOPChainOutput
:
dco
,
OpcmProxy
:
opcmAddr
,
Release
:
release
,
}
env
.
L1ScriptHost
.
ImportState
(
st
.
L1StateDump
.
Data
)
var
dco
opcm
.
DeployOPChainOutput
lgr
.
Info
(
"deploying OP chain using local allocs"
,
"id"
,
chainID
.
Hex
())
dco
,
err
=
deployFunc
()
impls
,
err
:=
opcm
.
ReadImplementationAddresses
(
env
.
L1ScriptHost
,
readInput
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"
error deploying OP chain
: %w"
,
err
)
return
fmt
.
Errorf
(
"
failed to read implementation addresses
: %w"
,
err
)
}
st
.
Chains
=
append
(
st
.
Chains
,
makeChainState
(
chainID
,
dco
))
st
.
ImplementationsDeployment
.
DelayedWETHImplAddress
=
impls
.
DelayedWETH
st
.
ImplementationsDeployment
.
OptimismPortalImplAddress
=
impls
.
OptimismPortal
st
.
ImplementationsDeployment
.
SystemConfigImplAddress
=
impls
.
SystemConfig
st
.
ImplementationsDeployment
.
L1CrossDomainMessengerImplAddress
=
impls
.
L1CrossDomainMessenger
st
.
ImplementationsDeployment
.
L1ERC721BridgeImplAddress
=
impls
.
L1ERC721Bridge
st
.
ImplementationsDeployment
.
L1StandardBridgeImplAddress
=
impls
.
L1StandardBridge
st
.
ImplementationsDeployment
.
OptimismMintableERC20FactoryImplAddress
=
impls
.
OptimismMintableERC20Factory
st
.
ImplementationsDeployment
.
DisputeGameFactoryImplAddress
=
impls
.
DisputeGameFactory
st
.
ImplementationsDeployment
.
MipsSingletonAddress
=
impls
.
MipsSingleton
st
.
ImplementationsDeployment
.
PreimageOracleSingletonAddress
=
impls
.
PreimageOracleSingleton
return
nil
}
...
...
@@ -301,33 +172,6 @@ func makeChainState(chainID common.Hash, dco opcm.DeployOPChainOutput) *state.Ch
}
}
func
setRDPImplementationAddress
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
errCh
chan
error
,
addressManager
common
.
Address
,
implAddress
*
common
.
Address
,
getNameArg
string
)
{
if
*
implAddress
!=
(
common
.
Address
{})
{
errCh
<-
nil
return
}
addressManagerContract
:=
opcm
.
NewContract
(
addressManager
,
client
)
address
,
err
:=
addressManagerContract
.
GetAddressByNameViaAddressManager
(
ctx
,
getNameArg
)
if
err
==
nil
{
*
implAddress
=
address
}
errCh
<-
err
}
func
setEIP1967ImplementationAddress
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
,
errCh
chan
error
,
proxy
common
.
Address
,
currentBlockHash
common
.
Hash
,
implAddress
*
common
.
Address
)
{
if
*
implAddress
!=
(
common
.
Address
{})
{
errCh
<-
nil
return
}
storageValue
,
err
:=
client
.
StorageAtHash
(
ctx
,
proxy
,
genesis
.
ImplementationSlot
,
currentBlockHash
)
if
err
==
nil
{
*
implAddress
=
common
.
HexToAddress
(
hex
.
EncodeToString
(
storageValue
))
}
errCh
<-
err
}
func
shouldDeployOPChain
(
st
*
state
.
State
,
chainID
common
.
Hash
)
bool
{
for
_
,
chain
:=
range
st
.
Chains
{
if
chain
.
ID
==
chainID
{
...
...
op-deployer/pkg/deployer/standard/standard.go
View file @
50564d43
...
...
@@ -172,7 +172,7 @@ func SystemOwnerAddrFor(chainID uint64) (common.Address, error) {
func
ArtifactsURLForTag
(
tag
string
)
(
*
url
.
URL
,
error
)
{
switch
tag
{
case
"op-contracts/v1.6.0"
:
return
url
.
Parse
(
standardArtifactsURL
(
"
ee07c78c3d8d4cd8f7a933c050f5afeebaa281b57b226cc6f092b19de2a8d61f
"
))
return
url
.
Parse
(
standardArtifactsURL
(
"
3a27c6dc0cb61b36feaac26def98c64b4a48ec8f5c5ba6965e8ae3157606043c
"
))
case
"op-contracts/v1.7.0-beta.1+l2-contracts"
:
return
url
.
Parse
(
standardArtifactsURL
(
"b0fb1f6f674519d637cff39a22187a5993d7f81a6d7b7be6507a0b50a5e38597"
))
default
:
...
...
op-deployer/pkg/env/host.go
View file @
50564d43
...
...
@@ -16,7 +16,7 @@ func DefaultScriptHost(
lgr
log
.
Logger
,
deployer
common
.
Address
,
artifacts
foundry
.
StatDirFs
,
startingNonce
uint64
,
additionalOpts
...
script
.
HostOption
,
)
(
*
script
.
Host
,
error
)
{
scriptCtx
:=
script
.
DefaultContext
scriptCtx
.
Sender
=
deployer
...
...
@@ -26,16 +26,16 @@ func DefaultScriptHost(
&
foundry
.
ArtifactsFS
{
FS
:
artifacts
},
nil
,
scriptCtx
,
append
([]
script
.
HostOption
{
script
.
WithBroadcastHook
(
bcaster
.
Hook
),
script
.
WithIsolatedBroadcasts
(),
script
.
WithCreate2Deployer
(),
},
additionalOpts
...
)
...
,
)
if
err
:=
h
.
EnableCheats
();
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to enable cheats: %w"
,
err
)
}
h
.
SetNonce
(
deployer
,
startingNonce
)
return
h
,
nil
}
packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol
View file @
50564d43
...
...
@@ -235,7 +235,7 @@ contract DeployOPChainOutput is BaseDeployIO {
IDelayedWETH internal _delayedWETHPermissionedGameProxy;
IDelayedWETH internal _delayedWETHPermissionlessGameProxy;
function set(bytes4 _sel, address _addr) public {
function set(bytes4 _sel, address _addr) public
virtual
{
require(_addr != address(0), "DeployOPChainOutput: cannot set zero address");
// forgefmt: disable-start
if (_sel == this.opChainProxyAdmin.selector) _opChainProxyAdmin = IProxyAdmin(_addr) ;
...
...
packages/contracts-bedrock/scripts/deploy/ReadImplementationAddresses.s.sol
0 → 100644
View file @
50564d43
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { BaseDeployIO } from "scripts/deploy/BaseDeployIO.sol";
import { IProxy } from "src/universal/interfaces/IProxy.sol";
import { Script } from "forge-std/Script.sol";
import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
import { DeployOPChainOutput } from "scripts/deploy/DeployOPChain.s.sol";
import { IMIPS } from "src/cannon/interfaces/IMIPS.sol";
import { OPContractsManager } from "src/L1/OPContractsManager.sol";
import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol";
import { IStaticL1ChugSplashProxy } from "src/legacy/interfaces/IL1ChugSplashProxy.sol";
contract ReadImplementationAddressesInput is DeployOPChainOutput {
OPContractsManager internal _opcmProxy;
string internal _release;
function set(bytes4 _sel, address _addr) public override {
require(_addr != address(0), "ReadImplementationAddressesInput: cannot set zero address");
if (_sel == this.opcmProxy.selector) _opcmProxy = OPContractsManager(_addr);
else if (_sel == this.addressManager.selector) _addressManager = IAddressManager(_addr);
else super.set(_sel, _addr);
}
function set(bytes4 _sel, string memory _val) public {
if (_sel == this.release.selector) _release = _val;
else revert("ReadImplementationAddressesInput: unknown selector");
}
function opcmProxy() public view returns (OPContractsManager) {
DeployUtils.assertValidContractAddress(address(_opcmProxy));
return _opcmProxy;
}
function release() public view returns (string memory) {
require(bytes(_release).length != 0, "ReadImplementationAddressesInput: release not set");
return _release;
}
}
contract ReadImplementationAddressesOutput is BaseDeployIO {
address internal _delayedWETH;
address internal _optimismPortal;
address internal _systemConfig;
address internal _l1CrossDomainMessenger;
address internal _l1ERC721Bridge;
address internal _l1StandardBridge;
address internal _optimismMintableERC20Factory;
address internal _disputeGameFactory;
address internal _mipsSingleton;
address internal _preimageOracleSingleton;
function set(bytes4 _sel, address _addr) public {
require(_addr != address(0), "ReadImplementationAddressesOutput: cannot set zero address");
if (_sel == this.delayedWETH.selector) _delayedWETH = _addr;
else if (_sel == this.optimismPortal.selector) _optimismPortal = _addr;
else if (_sel == this.systemConfig.selector) _systemConfig = _addr;
else if (_sel == this.l1CrossDomainMessenger.selector) _l1CrossDomainMessenger = _addr;
else if (_sel == this.l1ERC721Bridge.selector) _l1ERC721Bridge = _addr;
else if (_sel == this.l1StandardBridge.selector) _l1StandardBridge = _addr;
else if (_sel == this.optimismMintableERC20Factory.selector) _optimismMintableERC20Factory = _addr;
else if (_sel == this.disputeGameFactory.selector) _disputeGameFactory = _addr;
else if (_sel == this.mipsSingleton.selector) _mipsSingleton = _addr;
else if (_sel == this.preimageOracleSingleton.selector) _preimageOracleSingleton = _addr;
else revert("ReadImplementationAddressesOutput: unknown selector");
}
function delayedWETH() public view returns (address) {
require(_delayedWETH != address(0), "ReadImplementationAddressesOutput: delayedWETH not set");
return _delayedWETH;
}
function optimismPortal() public view returns (address) {
require(_optimismPortal != address(0), "ReadImplementationAddressesOutput: optimismPortal not set");
return _optimismPortal;
}
function systemConfig() public view returns (address) {
require(_systemConfig != address(0), "ReadImplementationAddressesOutput: systemConfig not set");
return _systemConfig;
}
function l1CrossDomainMessenger() public view returns (address) {
require(
_l1CrossDomainMessenger != address(0), "ReadImplementationAddressesOutput: l1CrossDomainMessenger not set"
);
return _l1CrossDomainMessenger;
}
function l1ERC721Bridge() public view returns (address) {
require(_l1ERC721Bridge != address(0), "ReadImplementationAddressesOutput: l1ERC721Bridge not set");
return _l1ERC721Bridge;
}
function l1StandardBridge() public view returns (address) {
require(_l1StandardBridge != address(0), "ReadImplementationAddressesOutput: l1StandardBridge not set");
return _l1StandardBridge;
}
function optimismMintableERC20Factory() public view returns (address) {
require(
_optimismMintableERC20Factory != address(0),
"ReadImplementationAddressesOutput: optimismMintableERC20Factory not set"
);
return _optimismMintableERC20Factory;
}
function disputeGameFactory() public view returns (address) {
require(_disputeGameFactory != address(0), "ReadImplementationAddressesOutput: disputeGameFactory not set");
return _disputeGameFactory;
}
function mipsSingleton() public view returns (address) {
require(_mipsSingleton != address(0), "ReadImplementationAddressesOutput: mipsSingleton not set");
return _mipsSingleton;
}
function preimageOracleSingleton() public view returns (address) {
require(
_preimageOracleSingleton != address(0), "ReadImplementationAddressesOutput: preimageOracleSingleton not set"
);
return _preimageOracleSingleton;
}
}
contract ReadImplementationAddresses is Script {
function run(ReadImplementationAddressesInput _rii, ReadImplementationAddressesOutput _rio) public {
address[6] memory eip1967Proxies = [
address(_rii.delayedWETHPermissionedGameProxy()),
address(_rii.optimismPortalProxy()),
address(_rii.systemConfigProxy()),
address(_rii.l1ERC721BridgeProxy()),
address(_rii.optimismMintableERC20FactoryProxy()),
address(_rii.disputeGameFactoryProxy())
];
bytes4[6] memory sels = [
_rio.delayedWETH.selector,
_rio.optimismPortal.selector,
_rio.systemConfig.selector,
_rio.l1ERC721Bridge.selector,
_rio.optimismMintableERC20Factory.selector,
_rio.disputeGameFactory.selector
];
for (uint256 i = 0; i < eip1967Proxies.length; i++) {
IProxy proxy = IProxy(payable(eip1967Proxies[i]));
vm.prank(address(0));
_rio.set(sels[i], proxy.implementation());
}
vm.prank(address(0));
address l1SBImpl = IStaticL1ChugSplashProxy(address(_rii.l1StandardBridgeProxy())).getImplementation();
vm.prank(address(0));
_rio.set(_rio.l1StandardBridge.selector, l1SBImpl);
(address mipsLogic,) = _rii.opcmProxy().implementations(_rii.release(), "MIPS");
_rio.set(_rio.mipsSingleton.selector, mipsLogic);
IAddressManager am = _rii.addressManager();
_rio.set(_rio.l1CrossDomainMessenger.selector, am.getAddress("OVM_L1CrossDomainMessenger"));
address preimageOracle = address(IMIPS(mipsLogic).oracle());
_rio.set(_rio.preimageOracleSingleton.selector, preimageOracle);
}
}
packages/contracts-bedrock/scripts/ops/publish-artifacts.sh
View file @
50564d43
...
...
@@ -44,7 +44,11 @@ else
tar
=
"tar"
fi
"
$tar
"
-czf
"
$archive_name
"
artifacts forge-artifacts cache
rm
-f
COMMIT
commit
=
$(
git rev-parse HEAD
)
echo
"
$commit
"
>
COMMIT
"
$tar
"
-czf
"
$archive_name
"
artifacts forge-artifacts cache COMMIT
du
-sh
"
$archive_name
"
|
awk
'{$1=$1};1'
# trim leading whitespace
echoerr
"> Done."
...
...
@@ -53,3 +57,4 @@ gcloud storage cp "$archive_name" "gs://$DEPLOY_BUCKET/$archive_name"
echoerr
"> Done."
rm
"
$archive_name
"
rm
COMMIT
\ No newline at end of file
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