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
c0298e37
Unverified
Commit
c0298e37
authored
May 01, 2023
by
mergify[bot]
Committed by
GitHub
May 01, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into jm/streamline-migration/phase2-finalize
parents
536178b0
5d711a05
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
577 additions
and
143 deletions
+577
-143
system_fpp_test.go
op-e2e/system_fpp_test.go
+3
-3
main.go
op-program/host/cmd/main.go
+1
-7
main_test.go
op-program/host/cmd/main_test.go
+22
-0
config.go
op-program/host/config/config.go
+10
-1
config_test.go
op-program/host/config/config_test.go
+8
-0
flags.go
op-program/host/flags/flags.go
+6
-0
host.go
op-program/host/host.go
+85
-39
host_test.go
op-program/host/host_test.go
+63
-0
hints.go
op-program/preimage/hints.go
+3
-1
oracle.go
op-program/preimage/oracle.go
+3
-1
IGnosisSafe.sol
...ages/contracts-bedrock/scripts/interfaces/IGnosisSafe.sol
+0
-0
LibSort.sol
packages/contracts-bedrock/scripts/libraries/LibSort.sol
+0
-0
DeleteOutput.s.sol
...ages/contracts-bedrock/scripts/outputs/DeleteOutput.s.sol
+188
-0
README.md
packages/contracts-bedrock/scripts/outputs/README.md
+38
-0
EnhancedScript.sol
...es/contracts-bedrock/scripts/universal/EnhancedScript.sol
+54
-0
GlobalConstants.sol
...s/contracts-bedrock/scripts/universal/GlobalConstants.sol
+23
-0
SafeBuilder.sol
packages/contracts-bedrock/scripts/universal/SafeBuilder.sol
+36
-76
PostSherlock.s.sol
...ges/contracts-bedrock/scripts/upgrades/PostSherlock.s.sol
+3
-3
PostSherlockL2.s.sol
...s/contracts-bedrock/scripts/upgrades/PostSherlockL2.s.sol
+2
-2
check-l2.ts
packages/contracts-bedrock/tasks/check-l2.ts
+29
-10
No files found.
op-e2e/system_fpp_test.go
View file @
c0298e37
...
@@ -108,7 +108,7 @@ func testVerifyL2OutputRoot(t *testing.T, detached bool) {
...
@@ -108,7 +108,7 @@ func testVerifyL2OutputRoot(t *testing.T, detached bool) {
// Check the FPP confirms the expected output
// Check the FPP confirms the expected output
t
.
Log
(
"Running fault proof in fetching mode"
)
t
.
Log
(
"Running fault proof in fetching mode"
)
err
=
opp
.
FaultProofProgram
(
log
,
fppConfig
)
err
=
opp
.
FaultProofProgram
(
ctx
,
log
,
fppConfig
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
t
.
Log
(
"Shutting down network"
)
t
.
Log
(
"Shutting down network"
)
...
@@ -124,13 +124,13 @@ func testVerifyL2OutputRoot(t *testing.T, detached bool) {
...
@@ -124,13 +124,13 @@ func testVerifyL2OutputRoot(t *testing.T, detached bool) {
// Should be able to rerun in offline mode using the pre-fetched images
// Should be able to rerun in offline mode using the pre-fetched images
fppConfig
.
L1URL
=
""
fppConfig
.
L1URL
=
""
fppConfig
.
L2URL
=
""
fppConfig
.
L2URL
=
""
err
=
opp
.
FaultProofProgram
(
log
,
fppConfig
)
err
=
opp
.
FaultProofProgram
(
ctx
,
log
,
fppConfig
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
// Check that a fault is detected if we provide an incorrect claim
// Check that a fault is detected if we provide an incorrect claim
t
.
Log
(
"Running fault proof with invalid claim"
)
t
.
Log
(
"Running fault proof with invalid claim"
)
fppConfig
.
L2Claim
=
common
.
Hash
{
0xaa
}
fppConfig
.
L2Claim
=
common
.
Hash
{
0xaa
}
err
=
opp
.
FaultProofProgram
(
log
,
fppConfig
)
err
=
opp
.
FaultProofProgram
(
ctx
,
log
,
fppConfig
)
if
detached
{
if
detached
{
require
.
Error
(
t
,
err
,
"exit status 1"
)
require
.
Error
(
t
,
err
,
"exit status 1"
)
}
else
{
}
else
{
...
...
op-program/host/cmd/main.go
View file @
c0298e37
package
main
package
main
import
(
import
(
"errors"
"fmt"
"fmt"
"os"
"os"
"github.com/ethereum-optimism/optimism/op-program/client/driver"
"github.com/ethereum-optimism/optimism/op-program/host"
"github.com/ethereum-optimism/optimism/op-program/host"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/host/flags"
"github.com/ethereum-optimism/optimism/op-program/host/flags"
...
@@ -37,12 +35,8 @@ var VersionWithMeta = func() string {
...
@@ -37,12 +35,8 @@ var VersionWithMeta = func() string {
func
main
()
{
func
main
()
{
args
:=
os
.
Args
args
:=
os
.
Args
if
err
:=
run
(
args
,
host
.
FaultProofProgram
);
errors
.
Is
(
err
,
driver
.
ErrClaimNotValid
)
{
if
err
:=
run
(
args
,
host
.
Main
);
err
!=
nil
{
log
.
Crit
(
"Claim is invalid"
,
"err"
,
err
)
}
else
if
err
!=
nil
{
log
.
Crit
(
"Application failed"
,
"err"
,
err
)
log
.
Crit
(
"Application failed"
,
"err"
,
err
)
}
else
{
log
.
Info
(
"Claim successfully verified"
)
}
}
}
}
...
...
op-program/host/cmd/main_test.go
View file @
c0298e37
...
@@ -232,6 +232,28 @@ func TestExec(t *testing.T) {
...
@@ -232,6 +232,28 @@ func TestExec(t *testing.T) {
})
})
}
}
func
TestServerMode
(
t
*
testing
.
T
)
{
t
.
Run
(
"DefaultFalse"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgs
())
require
.
False
(
t
,
cfg
.
ServerMode
)
})
t
.
Run
(
"Enabled"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
"--server"
))
require
.
True
(
t
,
cfg
.
ServerMode
)
})
t
.
Run
(
"EnabledWithArg"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
"--server=true"
))
require
.
True
(
t
,
cfg
.
ServerMode
)
})
t
.
Run
(
"DisabledWithArg"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
"--server=false"
))
require
.
False
(
t
,
cfg
.
ServerMode
)
})
t
.
Run
(
"InvalidArg"
,
func
(
t
*
testing
.
T
)
{
verifyArgsInvalid
(
t
,
"invalid boolean value
\"
foo
\"
for -server"
,
addRequiredArgs
(
"--server=foo"
))
})
}
func
verifyArgsInvalid
(
t
*
testing
.
T
,
messageContains
string
,
cliArgs
[]
string
)
{
func
verifyArgsInvalid
(
t
*
testing
.
T
,
messageContains
string
,
cliArgs
[]
string
)
{
_
,
_
,
err
:=
runWithArgs
(
cliArgs
)
_
,
_
,
err
:=
runWithArgs
(
cliArgs
)
require
.
ErrorContains
(
t
,
err
,
messageContains
)
require
.
ErrorContains
(
t
,
err
,
messageContains
)
...
...
op-program/host/config/config.go
View file @
c0298e37
...
@@ -25,6 +25,7 @@ var (
...
@@ -25,6 +25,7 @@ var (
ErrInvalidL2Claim
=
errors
.
New
(
"invalid l2 claim"
)
ErrInvalidL2Claim
=
errors
.
New
(
"invalid l2 claim"
)
ErrInvalidL2ClaimBlock
=
errors
.
New
(
"invalid l2 claim block number"
)
ErrInvalidL2ClaimBlock
=
errors
.
New
(
"invalid l2 claim block number"
)
ErrDataDirRequired
=
errors
.
New
(
"datadir must be specified when in non-fetching mode"
)
ErrDataDirRequired
=
errors
.
New
(
"datadir must be specified when in non-fetching mode"
)
ErrNoExecInServerMode
=
errors
.
New
(
"exec command must not be set when in server mode"
)
)
)
type
Config
struct
{
type
Config
struct
{
...
@@ -52,6 +53,10 @@ type Config struct {
...
@@ -52,6 +53,10 @@ type Config struct {
// ExecCmd specifies the client program to execute in a separate process.
// ExecCmd specifies the client program to execute in a separate process.
// If unset, the fault proof client is run in the same process.
// If unset, the fault proof client is run in the same process.
ExecCmd
string
ExecCmd
string
// ServerMode indicates that the program should run in pre-image server mode and wait for requests.
// No client program is run.
ServerMode
bool
}
}
func
(
c
*
Config
)
Check
()
error
{
func
(
c
*
Config
)
Check
()
error
{
...
@@ -82,6 +87,9 @@ func (c *Config) Check() error {
...
@@ -82,6 +87,9 @@ func (c *Config) Check() error {
if
!
c
.
FetchingEnabled
()
&&
c
.
DataDir
==
""
{
if
!
c
.
FetchingEnabled
()
&&
c
.
DataDir
==
""
{
return
ErrDataDirRequired
return
ErrDataDirRequired
}
}
if
c
.
ServerMode
&&
c
.
ExecCmd
!=
""
{
return
ErrNoExecInServerMode
}
return
nil
return
nil
}
}
...
@@ -149,7 +157,8 @@ func NewConfigFromCLI(ctx *cli.Context) (*Config, error) {
...
@@ -149,7 +157,8 @@ func NewConfigFromCLI(ctx *cli.Context) (*Config, error) {
L1URL
:
ctx
.
GlobalString
(
flags
.
L1NodeAddr
.
Name
),
L1URL
:
ctx
.
GlobalString
(
flags
.
L1NodeAddr
.
Name
),
L1TrustRPC
:
ctx
.
GlobalBool
(
flags
.
L1TrustRPC
.
Name
),
L1TrustRPC
:
ctx
.
GlobalBool
(
flags
.
L1TrustRPC
.
Name
),
L1RPCKind
:
sources
.
RPCProviderKind
(
ctx
.
GlobalString
(
flags
.
L1RPCProviderKind
.
Name
)),
L1RPCKind
:
sources
.
RPCProviderKind
(
ctx
.
GlobalString
(
flags
.
L1RPCProviderKind
.
Name
)),
ExecCmd
:
ctx
.
String
(
flags
.
Exec
.
Name
),
ExecCmd
:
ctx
.
GlobalString
(
flags
.
Exec
.
Name
),
ServerMode
:
ctx
.
GlobalBool
(
flags
.
Server
.
Name
),
},
nil
},
nil
}
}
...
...
op-program/host/config/config_test.go
View file @
c0298e37
...
@@ -142,6 +142,14 @@ func TestRequireDataDirInNonFetchingMode(t *testing.T) {
...
@@ -142,6 +142,14 @@ func TestRequireDataDirInNonFetchingMode(t *testing.T) {
require
.
ErrorIs
(
t
,
err
,
ErrDataDirRequired
)
require
.
ErrorIs
(
t
,
err
,
ErrDataDirRequired
)
}
}
func
TestRejectExecAndServerMode
(
t
*
testing
.
T
)
{
cfg
:=
validConfig
()
cfg
.
ServerMode
=
true
cfg
.
ExecCmd
=
"echo"
err
:=
cfg
.
Check
()
require
.
ErrorIs
(
t
,
err
,
ErrNoExecInServerMode
)
}
func
validConfig
()
*
Config
{
func
validConfig
()
*
Config
{
cfg
:=
NewConfig
(
validRollupConfig
,
validL2Genesis
,
validL1Head
,
validL2Head
,
validL2Claim
,
validL2ClaimBlockNum
)
cfg
:=
NewConfig
(
validRollupConfig
,
validL2Genesis
,
validL1Head
,
validL2Head
,
validL2Claim
,
validL2ClaimBlockNum
)
cfg
.
DataDir
=
"/tmp/configTest"
cfg
.
DataDir
=
"/tmp/configTest"
...
...
op-program/host/flags/flags.go
View file @
c0298e37
...
@@ -86,6 +86,11 @@ var (
...
@@ -86,6 +86,11 @@ var (
Usage
:
"Run the specified client program as a separate process detached from the host. Default is to run the client program in the host process."
,
Usage
:
"Run the specified client program as a separate process detached from the host. Default is to run the client program in the host process."
,
EnvVar
:
service
.
PrefixEnvVar
(
envVarPrefix
,
"EXEC"
),
EnvVar
:
service
.
PrefixEnvVar
(
envVarPrefix
,
"EXEC"
),
}
}
Server
=
cli
.
BoolFlag
{
Name
:
"server"
,
Usage
:
"Run in pre-image server mode without executing any client program."
,
EnvVar
:
service
.
PrefixEnvVar
(
envVarPrefix
,
"SERVER"
),
}
)
)
// Flags contains the list of configuration options available to the binary.
// Flags contains the list of configuration options available to the binary.
...
@@ -107,6 +112,7 @@ var programFlags = []cli.Flag{
...
@@ -107,6 +112,7 @@ var programFlags = []cli.Flag{
L1TrustRPC
,
L1TrustRPC
,
L1RPCProviderKind
,
L1RPCProviderKind
,
Exec
,
Exec
,
Server
,
}
}
func
init
()
{
func
init
()
{
...
...
op-program/host/host.go
View file @
c0298e37
...
@@ -13,6 +13,7 @@ import (
...
@@ -13,6 +13,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-node/sources"
cl
"github.com/ethereum-optimism/optimism/op-program/client"
cl
"github.com/ethereum-optimism/optimism/op-program/client"
"github.com/ethereum-optimism/optimism/op-program/client/driver"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/host/kvstore"
"github.com/ethereum-optimism/optimism/op-program/host/kvstore"
"github.com/ethereum-optimism/optimism/op-program/host/prefetcher"
"github.com/ethereum-optimism/optimism/op-program/host/prefetcher"
...
@@ -27,56 +28,36 @@ type L2Source struct {
...
@@ -27,56 +28,36 @@ type L2Source struct {
*
sources
.
DebugClient
*
sources
.
DebugClient
}
}
// FaultProofProgram is the programmatic entry-point for the fault proof program
func
Main
(
logger
log
.
Logger
,
cfg
*
config
.
Config
)
error
{
func
FaultProofProgram
(
logger
log
.
Logger
,
cfg
*
config
.
Config
)
error
{
if
err
:=
cfg
.
Check
();
err
!=
nil
{
if
err
:=
cfg
.
Check
();
err
!=
nil
{
return
fmt
.
Errorf
(
"invalid config: %w"
,
err
)
return
fmt
.
Errorf
(
"invalid config: %w"
,
err
)
}
}
cfg
.
Rollup
.
LogDescription
(
logger
,
chaincfg
.
L2ChainIDToNetworkName
)
cfg
.
Rollup
.
LogDescription
(
logger
,
chaincfg
.
L2ChainIDToNetworkName
)
ctx
:=
context
.
Background
()
ctx
:=
context
.
Background
()
var
kv
kvstore
.
KV
if
cfg
.
ServerMode
{
if
cfg
.
DataDir
==
""
{
preimageChan
:=
cl
.
CreatePreimageChannel
()
logger
.
Info
(
"Using in-memory storage"
)
hinterChan
:=
cl
.
CreateHinterChannel
()
kv
=
kvstore
.
NewMemKV
()
return
PreimageServer
(
ctx
,
logger
,
cfg
,
preimageChan
,
hinterChan
)
}
else
{
logger
.
Info
(
"Creating disk storage"
,
"datadir"
,
cfg
.
DataDir
)
if
err
:=
os
.
MkdirAll
(
cfg
.
DataDir
,
0755
);
err
!=
nil
{
return
fmt
.
Errorf
(
"creating datadir: %w"
,
err
)
}
kv
=
kvstore
.
NewDiskKV
(
cfg
.
DataDir
)
}
}
var
(
if
err
:=
FaultProofProgram
(
ctx
,
logger
,
cfg
);
errors
.
Is
(
err
,
driver
.
ErrClaimNotValid
)
{
getPreimage
func
(
key
common
.
Hash
)
([]
byte
,
error
)
log
.
Crit
(
"Claim is invalid"
,
"err"
,
err
)
hinter
func
(
hint
string
)
error
}
else
if
err
!=
nil
{
)
return
err
if
cfg
.
FetchingEnabled
()
{
prefetch
,
err
:=
makePrefetcher
(
ctx
,
logger
,
kv
,
cfg
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create prefetcher: %w"
,
err
)
}
getPreimage
=
func
(
key
common
.
Hash
)
([]
byte
,
error
)
{
return
prefetch
.
GetPreimage
(
ctx
,
key
)
}
hinter
=
prefetch
.
Hint
}
else
{
}
else
{
logger
.
Info
(
"Using offline mode. All required pre-images must be pre-populated."
)
log
.
Info
(
"Claim successfully verified"
)
getPreimage
=
kv
.
Get
hinter
=
func
(
hint
string
)
error
{
logger
.
Debug
(
"ignoring prefetch hint"
,
"hint"
,
hint
)
return
nil
}
}
}
return
nil
}
localPreimageSource
:=
kvstore
.
NewLocalPreimageSource
(
cfg
)
// FaultProofProgram is the programmatic entry-point for the fault proof program
splitter
:=
kvstore
.
NewPreimageSourceSplitter
(
localPreimageSource
.
Get
,
getPreimage
)
func
FaultProofProgram
(
ctx
context
.
Context
,
logger
log
.
Logger
,
cfg
*
config
.
Config
)
error
{
// Setup client I/O for preimage oracle interaction
// Setup client I/O for preimage oracle interaction
pClientRW
,
pHostRW
,
err
:=
oppio
.
CreateBidirectionalChannel
()
pClientRW
,
pHostRW
,
err
:=
oppio
.
CreateBidirectionalChannel
()
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create preimage pipe: %w"
,
err
)
return
fmt
.
Errorf
(
"failed to create preimage pipe: %w"
,
err
)
}
}
oracleServer
:=
preimage
.
NewOracleServer
(
pHostRW
)
launchOracleServer
(
logger
,
oracleServer
,
splitter
.
Get
)
defer
pHostRW
.
Close
()
defer
pHostRW
.
Close
()
// Setup client I/O for hint comms
// Setup client I/O for hint comms
...
@@ -84,9 +65,15 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
...
@@ -84,9 +65,15 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create hints pipe: %w"
,
err
)
return
fmt
.
Errorf
(
"failed to create hints pipe: %w"
,
err
)
}
}
defer
hHostRW
.
Close
()
hHost
:=
preimage
.
NewHintReader
(
hHostRW
)
go
func
()
{
routeHints
(
logger
,
hHost
,
hinter
)
defer
hHostRW
.
Close
()
err
:=
PreimageServer
(
ctx
,
logger
,
cfg
,
pHostRW
,
hHostRW
)
if
err
!=
nil
{
logger
.
Error
(
"preimage server failed"
,
"err"
,
err
)
}
logger
.
Debug
(
"Preimage server stopped"
)
}()
var
cmd
*
exec
.
Cmd
var
cmd
*
exec
.
Cmd
if
cfg
.
ExecCmd
!=
""
{
if
cfg
.
ExecCmd
!=
""
{
...
@@ -106,12 +93,61 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
...
@@ -106,12 +93,61 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
if
err
:=
cmd
.
Wait
();
err
!=
nil
{
if
err
:=
cmd
.
Wait
();
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to wait for child program: %w"
,
err
)
return
fmt
.
Errorf
(
"failed to wait for child program: %w"
,
err
)
}
}
logger
.
Debug
(
"Client program completed successfully"
)
return
nil
return
nil
}
else
{
}
else
{
return
cl
.
RunProgram
(
logger
,
pClientRW
,
hClientRW
)
return
cl
.
RunProgram
(
logger
,
pClientRW
,
hClientRW
)
}
}
}
}
func
PreimageServer
(
ctx
context
.
Context
,
logger
log
.
Logger
,
cfg
*
config
.
Config
,
preimageChannel
oppio
.
FileChannel
,
hintChannel
oppio
.
FileChannel
)
error
{
logger
.
Info
(
"Starting preimage server"
)
var
kv
kvstore
.
KV
if
cfg
.
DataDir
==
""
{
logger
.
Info
(
"Using in-memory storage"
)
kv
=
kvstore
.
NewMemKV
()
}
else
{
logger
.
Info
(
"Creating disk storage"
,
"datadir"
,
cfg
.
DataDir
)
if
err
:=
os
.
MkdirAll
(
cfg
.
DataDir
,
0755
);
err
!=
nil
{
return
fmt
.
Errorf
(
"creating datadir: %w"
,
err
)
}
kv
=
kvstore
.
NewDiskKV
(
cfg
.
DataDir
)
}
var
(
getPreimage
kvstore
.
PreimageSource
hinter
preimage
.
HintHandler
)
if
cfg
.
FetchingEnabled
()
{
prefetch
,
err
:=
makePrefetcher
(
ctx
,
logger
,
kv
,
cfg
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create prefetcher: %w"
,
err
)
}
getPreimage
=
func
(
key
common
.
Hash
)
([]
byte
,
error
)
{
return
prefetch
.
GetPreimage
(
ctx
,
key
)
}
hinter
=
prefetch
.
Hint
}
else
{
logger
.
Info
(
"Using offline mode. All required pre-images must be pre-populated."
)
getPreimage
=
kv
.
Get
hinter
=
func
(
hint
string
)
error
{
logger
.
Debug
(
"ignoring prefetch hint"
,
"hint"
,
hint
)
return
nil
}
}
localPreimageSource
:=
kvstore
.
NewLocalPreimageSource
(
cfg
)
splitter
:=
kvstore
.
NewPreimageSourceSplitter
(
localPreimageSource
.
Get
,
getPreimage
)
preimageGetter
:=
splitter
.
Get
serverDone
:=
launchOracleServer
(
logger
,
preimageChannel
,
preimageGetter
)
hinterDone
:=
routeHints
(
logger
,
hintChannel
,
hinter
)
select
{
case
err
:=
<-
serverDone
:
return
err
case
err
:=
<-
hinterDone
:
return
err
}
}
func
makePrefetcher
(
ctx
context
.
Context
,
logger
log
.
Logger
,
kv
kvstore
.
KV
,
cfg
*
config
.
Config
)
(
*
prefetcher
.
Prefetcher
,
error
)
{
func
makePrefetcher
(
ctx
context
.
Context
,
logger
log
.
Logger
,
kv
kvstore
.
KV
,
cfg
*
config
.
Config
)
(
*
prefetcher
.
Prefetcher
,
error
)
{
logger
.
Info
(
"Connecting to L1 node"
,
"l1"
,
cfg
.
L1URL
)
logger
.
Info
(
"Connecting to L1 node"
,
"l1"
,
cfg
.
L1URL
)
l1RPC
,
err
:=
client
.
NewRPC
(
ctx
,
logger
,
cfg
.
L1URL
)
l1RPC
,
err
:=
client
.
NewRPC
(
ctx
,
logger
,
cfg
.
L1URL
)
...
@@ -139,8 +175,11 @@ func makePrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *
...
@@ -139,8 +175,11 @@ func makePrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *
return
prefetcher
.
NewPrefetcher
(
logger
,
l1Cl
,
l2DebugCl
,
kv
),
nil
return
prefetcher
.
NewPrefetcher
(
logger
,
l1Cl
,
l2DebugCl
,
kv
),
nil
}
}
func
routeHints
(
logger
log
.
Logger
,
hintReader
*
preimage
.
HintReader
,
hinter
func
(
hint
string
)
error
)
{
func
routeHints
(
logger
log
.
Logger
,
hHostRW
io
.
ReadWriter
,
hinter
preimage
.
HintHandler
)
chan
error
{
chErr
:=
make
(
chan
error
)
hintReader
:=
preimage
.
NewHintReader
(
hHostRW
)
go
func
()
{
go
func
()
{
defer
close
(
chErr
)
for
{
for
{
if
err
:=
hintReader
.
NextHint
(
hinter
);
err
!=
nil
{
if
err
:=
hintReader
.
NextHint
(
hinter
);
err
!=
nil
{
if
err
==
io
.
EOF
||
errors
.
Is
(
err
,
fs
.
ErrClosed
)
{
if
err
==
io
.
EOF
||
errors
.
Is
(
err
,
fs
.
ErrClosed
)
{
...
@@ -148,14 +187,19 @@ func routeHints(logger log.Logger, hintReader *preimage.HintReader, hinter func(
...
@@ -148,14 +187,19 @@ func routeHints(logger log.Logger, hintReader *preimage.HintReader, hinter func(
return
return
}
}
logger
.
Error
(
"pre-image hint router error"
,
"err"
,
err
)
logger
.
Error
(
"pre-image hint router error"
,
"err"
,
err
)
chErr
<-
err
return
return
}
}
}
}
}()
}()
return
chErr
}
}
func
launchOracleServer
(
logger
log
.
Logger
,
server
*
preimage
.
OracleServer
,
getter
func
(
key
common
.
Hash
)
([]
byte
,
error
))
{
func
launchOracleServer
(
logger
log
.
Logger
,
pHostRW
io
.
ReadWriteCloser
,
getter
preimage
.
PreimageGetter
)
chan
error
{
chErr
:=
make
(
chan
error
)
server
:=
preimage
.
NewOracleServer
(
pHostRW
)
go
func
()
{
go
func
()
{
defer
close
(
chErr
)
for
{
for
{
if
err
:=
server
.
NextPreimageRequest
(
getter
);
err
!=
nil
{
if
err
:=
server
.
NextPreimageRequest
(
getter
);
err
!=
nil
{
if
err
==
io
.
EOF
||
errors
.
Is
(
err
,
fs
.
ErrClosed
)
{
if
err
==
io
.
EOF
||
errors
.
Is
(
err
,
fs
.
ErrClosed
)
{
...
@@ -163,8 +207,10 @@ func launchOracleServer(logger log.Logger, server *preimage.OracleServer, getter
...
@@ -163,8 +207,10 @@ func launchOracleServer(logger log.Logger, server *preimage.OracleServer, getter
return
return
}
}
logger
.
Error
(
"pre-image server error"
,
"error"
,
err
)
logger
.
Error
(
"pre-image server error"
,
"error"
,
err
)
chErr
<-
err
return
return
}
}
}
}
}()
}()
return
chErr
}
}
op-program/host/host_test.go
0 → 100644
View file @
c0298e37
package
host
import
(
"context"
"errors"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-program/client"
"github.com/ethereum-optimism/optimism/op-program/client/l1"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/host/kvstore"
"github.com/ethereum-optimism/optimism/op-program/io"
"github.com/ethereum-optimism/optimism/op-program/preimage"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)
func
TestServerMode
(
t
*
testing
.
T
)
{
dir
:=
t
.
TempDir
()
l1Head
:=
common
.
Hash
{
0x11
}
cfg
:=
config
.
NewConfig
(
&
chaincfg
.
Goerli
,
config
.
OPGoerliChainConfig
,
l1Head
,
common
.
Hash
{
0x22
},
common
.
Hash
{
0x33
},
1000
)
cfg
.
DataDir
=
dir
cfg
.
ServerMode
=
true
preimageServer
,
preimageClient
,
err
:=
io
.
CreateBidirectionalChannel
()
require
.
NoError
(
t
,
err
)
defer
preimageClient
.
Close
()
hintServer
,
hintClient
,
err
:=
io
.
CreateBidirectionalChannel
()
require
.
NoError
(
t
,
err
)
defer
hintClient
.
Close
()
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlTrace
)
result
:=
make
(
chan
error
)
go
func
()
{
result
<-
PreimageServer
(
context
.
Background
(),
logger
,
cfg
,
preimageServer
,
hintServer
)
}()
pClient
:=
preimage
.
NewOracleClient
(
preimageClient
)
hClient
:=
preimage
.
NewHintWriter
(
hintClient
)
l1PreimageOracle
:=
l1
.
NewPreimageOracle
(
pClient
,
hClient
)
require
.
Equal
(
t
,
l1Head
.
Bytes
(),
pClient
.
Get
(
client
.
L1HeadLocalIndex
),
"Should get preimages"
)
// Should exit when a preimage is unavailable
require
.
Panics
(
t
,
func
()
{
l1PreimageOracle
.
HeaderByBlockHash
(
common
.
HexToHash
(
"0x1234"
))
},
"Preimage should not be available"
)
require
.
ErrorIs
(
t
,
waitFor
(
result
),
kvstore
.
ErrNotFound
)
}
func
waitFor
(
ch
chan
error
)
error
{
timeout
:=
time
.
After
(
30
*
time
.
Second
)
select
{
case
err
:=
<-
ch
:
return
err
case
<-
timeout
:
return
errors
.
New
(
"timed out"
)
}
}
op-program/preimage/hints.go
View file @
c0298e37
...
@@ -43,7 +43,9 @@ func NewHintReader(rw io.ReadWriter) *HintReader {
...
@@ -43,7 +43,9 @@ func NewHintReader(rw io.ReadWriter) *HintReader {
return
&
HintReader
{
rw
:
rw
}
return
&
HintReader
{
rw
:
rw
}
}
}
func
(
hr
*
HintReader
)
NextHint
(
router
func
(
hint
string
)
error
)
error
{
type
HintHandler
func
(
hint
string
)
error
func
(
hr
*
HintReader
)
NextHint
(
router
HintHandler
)
error
{
var
length
uint32
var
length
uint32
if
err
:=
binary
.
Read
(
hr
.
rw
,
binary
.
BigEndian
,
&
length
);
err
!=
nil
{
if
err
:=
binary
.
Read
(
hr
.
rw
,
binary
.
BigEndian
,
&
length
);
err
!=
nil
{
if
err
==
io
.
EOF
{
if
err
==
io
.
EOF
{
...
...
op-program/preimage/oracle.go
View file @
c0298e37
...
@@ -47,7 +47,9 @@ func NewOracleServer(rw io.ReadWriter) *OracleServer {
...
@@ -47,7 +47,9 @@ func NewOracleServer(rw io.ReadWriter) *OracleServer {
return
&
OracleServer
{
rw
:
rw
}
return
&
OracleServer
{
rw
:
rw
}
}
}
func
(
o
*
OracleServer
)
NextPreimageRequest
(
getPreimage
func
(
key
common
.
Hash
)
([]
byte
,
error
))
error
{
type
PreimageGetter
func
(
key
common
.
Hash
)
([]
byte
,
error
)
func
(
o
*
OracleServer
)
NextPreimageRequest
(
getPreimage
PreimageGetter
)
error
{
var
key
common
.
Hash
var
key
common
.
Hash
if
_
,
err
:=
io
.
ReadFull
(
o
.
rw
,
key
[
:
]);
err
!=
nil
{
if
_
,
err
:=
io
.
ReadFull
(
o
.
rw
,
key
[
:
]);
err
!=
nil
{
if
err
==
io
.
EOF
{
if
err
==
io
.
EOF
{
...
...
packages/contracts-bedrock/scripts/
upgrad
es/IGnosisSafe.sol
→
packages/contracts-bedrock/scripts/
interfac
es/IGnosisSafe.sol
View file @
c0298e37
File moved
packages/contracts-bedrock/scripts/
upgrad
es/LibSort.sol
→
packages/contracts-bedrock/scripts/
librari
es/LibSort.sol
View file @
c0298e37
File moved
packages/contracts-bedrock/scripts/outputs/DeleteOutput.s.sol
0 → 100644
View file @
c0298e37
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { LibSort } from "../libraries/LibSort.sol";
import { IGnosisSafe, Enum } from "../interfaces/IGnosisSafe.sol";
import { SafeBuilder } from "../universal/SafeBuilder.sol";
import { Types } from "../../contracts/libraries/Types.sol";
import { FeeVault } from "../../contracts/universal/FeeVault.sol";
import { L2OutputOracle } from "../../contracts/L1/L2OutputOracle.sol";
import { Predeploys } from "../../contracts/libraries/Predeploys.sol";
/**
* @title DeleteOutput
* @notice Deletes an output root from the L2OutputOracle.
* @notice Example usage is provided in the README documentation.
*/
contract DeleteOutput is SafeBuilder {
/**
* @notice A set of contract addresses for the script.
*/
struct ContractSet {
address Safe;
address ProxyAdmin;
address L2OutputOracleProxy;
}
/**
* @notice A mapping of chainid to a ContractSet.
*/
mapping(uint256 => ContractSet) internal _contracts;
/**
* @notice The l2 output index we will delete.
*/
uint256 internal index;
/**
* @notice The address of the L2OutputOracle to target.
*/
address internal oracle;
/**
* @notice Place the contract addresses in storage for ux.
*/
function setUp() external {
_contracts[GOERLI] = ContractSet({
Safe: 0xBc1233d0C3e6B5d53Ab455cF65A6623F6dCd7e4f,
ProxyAdmin: 0x01d3670863c3F4b24D7b107900f0b75d4BbC6e0d,
L2OutputOracleProxy: 0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0
});
}
/**
* @notice Returns the ContractSet for the defined block chainid.
*
* @dev Reverts if no ContractSet is defined.
*/
function contracts() public view returns (ContractSet memory) {
ContractSet memory cs = _contracts[block.chainid];
if (cs.Safe == address(0) || cs.ProxyAdmin == address(0) || cs.L2OutputOracleProxy == address(0)) {
revert("Missing Contract Set for the given block.chainid");
}
return cs;
}
/**
* @notice Executes the gnosis safe transaction to delete an L2 Output Root.
*/
function run(uint256 _index) external returns (bool) {
address _safe = contracts().Safe;
address _proxyAdmin = contracts().ProxyAdmin;
index = _index;
return run(_safe, _proxyAdmin);
}
/**
* @notice Follow up assertions to ensure that the script ran to completion.
*/
function _postCheck() internal view override {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
Types.OutputProposal memory proposal = l2oo.getL2Output(index);
require(proposal.l2BlockNumber == 0, "DeleteOutput: Output deletion failed.");
}
/**
* @notice Test coverage of the script.
*/
function test_script_succeeds() skipWhenNotForking external {
uint256 _index = getLatestIndex();
require(_index != 0, "DeleteOutput: No outputs to delete.");
index = _index;
address safe = contracts().Safe;
require(safe != address(0), "DeleteOutput: Invalid safe address.");
address proxyAdmin = contracts().ProxyAdmin;
require(proxyAdmin != address(0), "DeleteOutput: Invalid proxy admin address.");
address[] memory owners = IGnosisSafe(payable(safe)).getOwners();
for (uint256 i; i < owners.length; i++) {
address owner = owners[i];
vm.startBroadcast(owner);
bool success = _run(safe, proxyAdmin);
vm.stopBroadcast();
if (success) {
console.log("tx success");
break;
}
}
_postCheck();
}
function buildCalldata(address _proxyAdmin) internal view override returns (bytes memory) {
IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](1);
calls[0] = IMulticall3.Call3({
target: oracle,
allowFailure: false,
callData: abi.encodeCall(
L2OutputOracle.deleteL2Outputs,
(index)
)
});
return abi.encodeCall(IMulticall3.aggregate3, (calls));
}
/**
* @notice Computes the safe transaction hash.
*/
function computeSafeTransactionHash(uint256 _index) public returns (bytes32) {
ContractSet memory cs = contracts();
address _safe = cs.Safe;
address _proxyAdmin = cs.ProxyAdmin;
index = _index;
oracle = cs.L2OutputOracleProxy;
return _getTransactionHash(_safe, _proxyAdmin);
}
/**
* @notice Returns the challenger for the L2OutputOracle.
*/
function getChallenger() public view returns (address) {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
return l2oo.CHALLENGER();
}
/**
* @notice Returns the L2 Block Number for the given index.
*/
function getL2BlockNumber(uint256 _index) public view returns (uint256) {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
return l2oo.getL2Output(_index).l2BlockNumber;
}
/**
* @notice Returns the output root for the given index.
*/
function getOutputFromIndex(uint256 _index) public view returns (bytes32) {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
return l2oo.getL2Output(_index).outputRoot;
}
/**
* @notice Returns the output root with the corresponding to the L2 Block Number.
*/
function getOutputFromL2BlockNumber(uint256 l2BlockNumber) public view returns (bytes32) {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
return l2oo.getL2OutputAfter(l2BlockNumber).outputRoot;
}
/**
* @notice Returns the latest l2 output index.
*/
function getLatestIndex() public view returns (uint256) {
L2OutputOracle l2oo = L2OutputOracle(contracts().L2OutputOracleProxy);
return l2oo.latestOutputIndex();
}
}
packages/contracts-bedrock/scripts/outputs/README.md
0 → 100644
View file @
c0298e37
## L2 Output Oracle Scripts
A collection of scripts to interact with the L2OutputOracle.
### Output Deletion
[
DeleteOutput
](
./DeleteOutput.s.sol
)
contains a variety of functions that deal
with deleting an output root from the
[
L2OutputOracle
](
../../contracts/L1/L2OutputOracle.sol
)
.
To delete an output root, the script can be run as follows, where
`<L2_OUTPUT_INDEX>`
is
the index of the posted output to delete.
```
bash
$
forge script scripts/output/DeleteOutput.s.sol
\
--sig
"run(uint256)"
\
--rpc-url
$ETH_RPC_URL
\
--broadcast
\
--private-key
$PRIVATE_KEY
\
<L2_OUTPUT_INDEX>
```
To find and confirm the output index, there are a variety of helper functions that
can be run using the script
`--sig`
flag, passing the function signatures in as arguments.
These are outlined below.
### Retrieving an L2 Block Number
The output's associated L2 block number can be retrieved using the following command, where
`<L2_OUTPUT_INDEX>`
is the index of the output in the
[
L2OutputOracle
](
../../contracts/L1/L2OutputOracle.sol
)
.
```
bash
$
forge script scripts/output/DeleteOutput.s.sol
\
--sig
"getL2BlockNumber(uint256)"
\
--rpc-url
$ETH_RPC_URL
\
<L2_OUTPUT_INDEX>
```
packages/contracts-bedrock/scripts/universal/EnhancedScript.sol
0 → 100644
View file @
c0298e37
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { Script } from "forge-std/Script.sol";
import { Semver } from "../../contracts/universal/Semver.sol";
/**
* @title EnhancedScript
* @notice Enhances forge-std' Script.sol with some additional application-specific functionality.
* Logs simulation links using Tenderly.
*/
abstract contract EnhancedScript is Script {
/**
* @notice Helper function used to compute the hash of Semver's version string to be used in a
* comparison.
*/
function _versionHash(address _addr) internal view returns (bytes32) {
return keccak256(bytes(Semver(_addr).version()));
}
/**
* @notice Log a tenderly simulation link. The TENDERLY_USERNAME and TENDERLY_PROJECT
* environment variables will be used if they are present. The vm is staticcall'ed
* because of a compiler issue with the higher level ABI.
*/
function logSimulationLink(address _to, bytes memory _data, address _from) public view {
(, bytes memory projData) = VM_ADDRESS.staticcall(
abi.encodeWithSignature("envOr(string,string)", "TENDERLY_PROJECT", "TENDERLY_PROJECT")
);
string memory proj = abi.decode(projData, (string));
(, bytes memory userData) = VM_ADDRESS.staticcall(
abi.encodeWithSignature("envOr(string,string)", "TENDERLY_USERNAME", "TENDERLY_USERNAME")
);
string memory username = abi.decode(userData, (string));
string memory str = string.concat(
"https://dashboard.tenderly.co/",
username,
"/",
proj,
"/simulator/new?network=",
vm.toString(block.chainid),
"&contractAddress=",
vm.toString(_to),
"&rawFunctionInput=",
vm.toString(_data),
"&from=",
vm.toString(_from)
);
console.log(str);
}
}
packages/contracts-bedrock/scripts/universal/GlobalConstants.sol
0 → 100644
View file @
c0298e37
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
/**
* @title GlobalConstants
* @notice A set of constants.
*/
contract GlobalConstants {
/**
* @notice Mainnet chain id.
*/
uint256 constant MAINNET = 1;
/**
* @notice Goerli chain id.
*/
uint256 constant GOERLI = 5;
/**
* @notice Optimism Goerli chain id.
*/
uint256 constant OP_GOERLI = 420;
}
packages/contracts-bedrock/scripts/u
pgrades
/SafeBuilder.sol
→
packages/contracts-bedrock/scripts/u
niversal
/SafeBuilder.sol
View file @
c0298e37
...
@@ -2,11 +2,12 @@
...
@@ -2,11 +2,12 @@
pragma solidity 0.8.15;
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { console } from "forge-std/console.sol";
import { Script } from "forge-std/Script.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { IGnosisSafe, Enum } from "./IGnosisSafe.sol";
import { LibSort } from "./LibSort.sol";
import { LibSort } from "../libraries/LibSort.sol";
import { Semver } from "../../contracts/universal/Semver.sol";
import { IGnosisSafe, Enum } from "../interfaces/IGnosisSafe.sol";
import { EnhancedScript } from "../universal/EnhancedScript.sol";
import { GlobalConstants } from "../universal/GlobalConstants.sol";
import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
/**
/**
...
@@ -21,22 +22,7 @@ import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
...
@@ -21,22 +22,7 @@ import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
* for the most simple user experience when using automation and no indexer.
* for the most simple user experience when using automation and no indexer.
* Run the command without the `--broadcast` flag and it will print a tenderly URL.
* Run the command without the `--broadcast` flag and it will print a tenderly URL.
*/
*/
abstract contract SafeBuilder is Script {
abstract contract SafeBuilder is EnhancedScript, GlobalConstants {
/**
* @notice Mainnet chain id.
*/
uint256 constant MAINNET = 1;
/**
* @notice Goerli chain id.
*/
uint256 constant GOERLI = 5;
/**
* @notice Optimism Goerli chain id.
*/
uint256 constant OP_GOERLI = 420;
/**
/**
* @notice Interface for multicall3.
* @notice Interface for multicall3.
*/
*/
...
@@ -50,7 +36,7 @@ abstract contract SafeBuilder is Script {
...
@@ -50,7 +36,7 @@ abstract contract SafeBuilder is Script {
/**
/**
* @notice The entrypoint to this script.
* @notice The entrypoint to this script.
*/
*/
function run(address _safe, address _proxyAdmin)
external
returns (bool) {
function run(address _safe, address _proxyAdmin)
public
returns (bool) {
vm.startBroadcast();
vm.startBroadcast();
bool success = _run(_safe, _proxyAdmin);
bool success = _run(_safe, _proxyAdmin);
if (success) _postCheck();
if (success) _postCheck();
...
@@ -58,12 +44,19 @@ abstract contract SafeBuilder is Script {
...
@@ -58,12 +44,19 @@ abstract contract SafeBuilder is Script {
}
}
/**
/**
* @notice The implementation of the upgrade. Split into its own function
* @notice Follow up assertions to ensure that the script ran to completion.
* to allow for testability. This is subject to a race condition if
* the nonce changes by a different transaction finalizing while not
* all of the signers have used this script.
*/
*/
function _run(address _safe, address _proxyAdmin) public returns (bool) {
function _postCheck() internal virtual view;
/**
* @notice Creates the calldata
*/
function buildCalldata(address _proxyAdmin) internal virtual view returns (bytes memory);
/**
* @notice Internal helper function to compute the safe transaction hash.
*/
function _getTransactionHash(address _safe, address _proxyAdmin) internal returns (bytes32) {
// Ensure that the required contracts exist
// Ensure that the required contracts exist
require(address(multicall).code.length > 0, "multicall3 not deployed");
require(address(multicall).code.length > 0, "multicall3 not deployed");
require(_safe.code.length > 0, "no code at safe address");
require(_safe.code.length > 0, "no code at safe address");
...
@@ -88,6 +81,23 @@ abstract contract SafeBuilder is Script {
...
@@ -88,6 +81,23 @@ abstract contract SafeBuilder is Script {
_nonce: nonce
_nonce: nonce
});
});
return hash;
}
/**
* @notice The implementation of the upgrade. Split into its own function
* to allow for testability. This is subject to a race condition if
* the nonce changes by a different transaction finalizing while not
* all of the signers have used this script.
*/
function _run(address _safe, address _proxyAdmin) public returns (bool) {
IGnosisSafe safe = IGnosisSafe(payable(_safe));
bytes memory data = buildCalldata(_proxyAdmin);
// Compute the safe transaction hash
bytes32 hash = _getTransactionHash(_safe, _proxyAdmin);
// Send a transaction to approve the hash
// Send a transaction to approve the hash
safe.approveHash(hash);
safe.approveHash(hash);
...
@@ -158,52 +168,6 @@ abstract contract SafeBuilder is Script {
...
@@ -158,52 +168,6 @@ abstract contract SafeBuilder is Script {
return false;
return false;
}
}
/**
* @notice Log a tenderly simulation link. The TENDERLY_USERNAME and TENDERLY_PROJECT
* environment variables will be used if they are present. The vm is staticcall'ed
* because of a compiler issue with the higher level ABI.
*/
function logSimulationLink(address _to, bytes memory _data, address _from) public view {
(, bytes memory projData) = VM_ADDRESS.staticcall(
abi.encodeWithSignature("envOr(string,string)", "TENDERLY_PROJECT", "TENDERLY_PROJECT")
);
string memory proj = abi.decode(projData, (string));
(, bytes memory userData) = VM_ADDRESS.staticcall(
abi.encodeWithSignature("envOr(string,string)", "TENDERLY_USERNAME", "TENDERLY_USERNAME")
);
string memory username = abi.decode(userData, (string));
string memory str = string.concat(
"https://dashboard.tenderly.co/",
username,
"/",
proj,
"/simulator/new?network=",
vm.toString(block.chainid),
"&contractAddress=",
vm.toString(_to),
"&rawFunctionInput=",
vm.toString(_data),
"&from=",
vm.toString(_from)
);
console.log(str);
}
/**
* @notice Follow up assertions to ensure that the script ran to completion.
*/
function _postCheck() internal virtual view;
/**
* @notice Helper function used to compute the hash of Semver's version string to be used in a
* comparison.
*/
function _versionHash(address _addr) internal view returns (bytes32) {
return keccak256(bytes(Semver(_addr).version()));
}
/**
/**
* @notice Builds the signatures by tightly packing them together.
* @notice Builds the signatures by tightly packing them together.
* Ensures that they are sorted.
* Ensures that they are sorted.
...
@@ -226,9 +190,5 @@ abstract contract SafeBuilder is Script {
...
@@ -226,9 +190,5 @@ abstract contract SafeBuilder is Script {
return signatures;
return signatures;
}
}
/**
* @notice Creates the calldata
*/
function buildCalldata(address _proxyAdmin) internal virtual view returns (bytes memory);
}
}
packages/contracts-bedrock/scripts/upgrades/PostSherlock.s.sol
View file @
c0298e37
...
@@ -2,10 +2,10 @@
...
@@ -2,10 +2,10 @@
pragma solidity 0.8.15;
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { console } from "forge-std/console.sol";
import { SafeBuilder } from "./SafeBuilder.sol";
import { SafeBuilder } from ".
./universal
/SafeBuilder.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { IGnosisSafe, Enum } from "./IGnosisSafe.sol";
import { IGnosisSafe, Enum } from ".
./interfaces
/IGnosisSafe.sol";
import { LibSort } from "./LibSort.sol";
import { LibSort } from ".
./libraries
/LibSort.sol";
import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
import { Constants } from "../../contracts/libraries/Constants.sol";
import { Constants } from "../../contracts/libraries/Constants.sol";
import { SystemConfig } from "../../contracts/L1/SystemConfig.sol";
import { SystemConfig } from "../../contracts/L1/SystemConfig.sol";
...
...
packages/contracts-bedrock/scripts/upgrades/PostSherlockL2.s.sol
View file @
c0298e37
...
@@ -2,8 +2,8 @@
...
@@ -2,8 +2,8 @@
pragma solidity 0.8.15;
pragma solidity 0.8.15;
import { console } from "forge-std/console.sol";
import { console } from "forge-std/console.sol";
import { SafeBuilder } from "./SafeBuilder.sol";
import { SafeBuilder } from ".
./universal
/SafeBuilder.sol";
import { IGnosisSafe, Enum } from "./IGnosisSafe.sol";
import { IGnosisSafe, Enum } from ".
./libraries
/IGnosisSafe.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol";
import { Predeploys } from "../../contracts/libraries/Predeploys.sol";
import { Predeploys } from "../../contracts/libraries/Predeploys.sol";
import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
import { ProxyAdmin } from "../../contracts/universal/ProxyAdmin.sol";
...
...
packages/contracts-bedrock/tasks/check-l2.ts
View file @
c0298e37
...
@@ -33,14 +33,37 @@ const checkPredeploys = async (
...
@@ -33,14 +33,37 @@ const checkPredeploys = async (
provider
:
providers
.
Provider
provider
:
providers
.
Provider
)
=>
{
)
=>
{
console
.
log
(
'
Checking predeploys are configured correctly
'
)
console
.
log
(
'
Checking predeploys are configured correctly
'
)
const
admin
=
hre
.
ethers
.
utils
.
hexConcat
([
'
0x000000000000000000000000
'
,
predeploys
.
ProxyAdmin
,
])
const
codeReq
=
[]
const
slotReq
=
[]
// First loop for requests
for
(
let
i
=
0
;
i
<
2048
;
i
++
)
{
for
(
let
i
=
0
;
i
<
2048
;
i
++
)
{
const
num
=
hre
.
ethers
.
utils
.
hexZeroPad
(
'
0x
'
+
i
.
toString
(
16
),
2
)
const
num
=
hre
.
ethers
.
utils
.
hexZeroPad
(
'
0x
'
+
i
.
toString
(
16
),
2
)
const
addr
=
hre
.
ethers
.
utils
.
getAddress
(
const
addr
=
hre
.
ethers
.
utils
.
getAddress
(
hre
.
ethers
.
utils
.
hexConcat
([
prefix
,
num
])
hre
.
ethers
.
utils
.
hexConcat
([
prefix
,
num
])
)
)
const
code
=
await
provider
.
getCode
(
addr
)
codeReq
.
push
(
provider
.
getCode
(
addr
))
if
(
code
===
'
0x
'
)
{
slotReq
.
push
(
provider
.
getStorageAt
(
addr
,
adminSlot
))
}
// Wait for all requests to finish
// The `JsonRpcBatchProvider` will batch requests in the background.
const
codeRes
=
await
Promise
.
all
(
codeReq
)
const
slotRes
=
await
Promise
.
all
(
slotReq
)
// Second loop for response checks
for
(
let
i
=
0
;
i
<
2048
;
i
++
)
{
const
num
=
hre
.
ethers
.
utils
.
hexZeroPad
(
'
0x
'
+
i
.
toString
(
16
),
2
)
const
addr
=
hre
.
ethers
.
utils
.
getAddress
(
hre
.
ethers
.
utils
.
hexConcat
([
prefix
,
num
])
)
if
(
codeRes
[
i
]
===
'
0x
'
)
{
throw
new
Error
(
`no code found at
${
addr
}
`
)
throw
new
Error
(
`no code found at
${
addr
}
`
)
}
}
...
@@ -52,13 +75,7 @@ const checkPredeploys = async (
...
@@ -52,13 +75,7 @@ const checkPredeploys = async (
continue
continue
}
}
const
slot
=
await
provider
.
getStorageAt
(
addr
,
adminSlot
)
if
(
slotRes
[
i
]
!==
admin
)
{
const
admin
=
hre
.
ethers
.
utils
.
hexConcat
([
'
0x000000000000000000000000
'
,
predeploys
.
ProxyAdmin
,
])
if
(
admin
!==
slot
)
{
throw
new
Error
(
`incorrect admin slot in
${
addr
}
`
)
throw
new
Error
(
`incorrect admin slot in
${
addr
}
`
)
}
}
...
@@ -686,7 +703,9 @@ task('check-l2', 'Checks a freshly migrated L2 system for correct migration')
...
@@ -686,7 +703,9 @@ task('check-l2', 'Checks a freshly migrated L2 system for correct migration')
if
(
args
.
l2RpcUrl
!==
''
)
{
if
(
args
.
l2RpcUrl
!==
''
)
{
console
.
log
(
'
Using CLI URL for provider instead of hardhat network
'
)
console
.
log
(
'
Using CLI URL for provider instead of hardhat network
'
)
const
provider
=
new
hre
.
ethers
.
providers
.
JsonRpcProvider
(
args
.
l2RpcUrl
)
const
provider
=
new
hre
.
ethers
.
providers
.
JsonRpcBatchProvider
(
args
.
l2RpcUrl
)
signer
=
Wallet
.
createRandom
().
connect
(
provider
)
signer
=
Wallet
.
createRandom
().
connect
(
provider
)
}
}
...
...
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