From 1a237256dc576742bb989468b1499c42adfd9eae Mon Sep 17 00:00:00 2001 From: Ethen Pociask Date: Mon, 11 Sep 2023 12:50:06 -0700 Subject: [PATCH 001/374] [indexer.risk_mitigations] [indexer] Added Write Timeouts & Closure Handling --- indexer/api/api.go | 2 ++ indexer/cmd/indexer/cli.go | 14 ++++++++++++-- indexer/config/config.go | 7 ++++--- indexer/indexer.toml | 1 + 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/indexer/api/api.go b/indexer/api/api.go index 261ce1e14b97..41c8f75866e1 100644 --- a/indexer/api/api.go +++ b/indexer/api/api.go @@ -6,6 +6,7 @@ import ( "net/http" "runtime/debug" "sync" + "time" "github.com/ethereum-optimism/optimism/indexer/api/routes" "github.com/ethereum-optimism/optimism/indexer/config" @@ -46,6 +47,7 @@ func NewApi(logger log.Logger, bv database.BridgeTransfersView, serverConfig con promRecorder := metrics.NewPromHTTPRecorder(mr, MetricsNamespace) apiRouter.Use(chiMetricsMiddleware(promRecorder)) + apiRouter.Use(middleware.Timeout(time.Duration(serverConfig.WriteTimeout) * time.Second)) apiRouter.Use(middleware.Recoverer) apiRouter.Use(middleware.Heartbeat("/healthz")) diff --git a/indexer/cmd/indexer/cli.go b/indexer/cmd/indexer/cli.go index e21b84b57db7..3b77cd5915c5 100644 --- a/indexer/cmd/indexer/cli.go +++ b/indexer/cmd/indexer/cli.go @@ -36,7 +36,12 @@ func runIndexer(ctx *cli.Context) error { log.Error("failed to connect to database", "err", err) return err } - defer db.Close() + defer func() { + err := db.Close() + if err != nil { + log.Error("failed to close database", "err", err) + } + }() indexer, err := indexer.NewIndexer(log, db, cfg.Chain, cfg.RPCs, cfg.HTTPServer, cfg.MetricsServer) if err != nil { @@ -60,7 +65,12 @@ func runApi(ctx *cli.Context) error { log.Error("failed to connect to database", "err", err) return err } - defer db.Close() + defer func() { + err := db.Close() + if err != nil { + log.Error("failed to close database", "err", err) + } + }() api := api.NewApi(log, db.BridgeTransfers, cfg.HTTPServer, cfg.MetricsServer) return api.Start(ctx.Context) diff --git a/indexer/config/config.go b/indexer/config/config.go index 940d278dcc17..4b77091d5b47 100644 --- a/indexer/config/config.go +++ b/indexer/config/config.go @@ -96,10 +96,11 @@ type DBConfig struct { Password string `toml:"password"` } -// Configures the a server +// Configures the server type ServerConfig struct { - Host string `toml:"host"` - Port int `toml:"port"` + Host string `toml:"host"` + Port int `toml:"port"` + WriteTimeout int `toml:"timeout"` } // LoadConfig loads the `indexer.toml` config file from a given path diff --git a/indexer/indexer.toml b/indexer/indexer.toml index 1cf4bd5e5105..547497dd5629 100644 --- a/indexer/indexer.toml +++ b/indexer/indexer.toml @@ -35,6 +35,7 @@ name = "$INDEXER_DB_NAME" [http] host = "127.0.0.1" port = 8080 +timeout = 10 [metrics] host = "127.0.0.1" From 3fcb8b2ccb75f81890d5e6b269ae4acb5ca967d6 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 16 Oct 2023 11:24:42 +1000 Subject: [PATCH 002/374] op-challenger: Introduce fault dispute game contract wrapper that uses batch calls. --- .../game/fault/contracts/faultdisputegame.go | 105 +++++++++++ .../game/fault/contracts/multicall.go | 168 ++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 op-challenger/game/fault/contracts/faultdisputegame.go create mode 100644 op-challenger/game/fault/contracts/multicall.go diff --git a/op-challenger/game/fault/contracts/faultdisputegame.go b/op-challenger/game/fault/contracts/faultdisputegame.go new file mode 100644 index 000000000000..16f344fcc9ca --- /dev/null +++ b/op-challenger/game/fault/contracts/faultdisputegame.go @@ -0,0 +1,105 @@ +package contracts + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +type FaultDisputeGameContract struct { + multiCaller *MultiCaller + addr common.Address + abi *abi.ABI +} + +func NewFaultDisputeGameContract(addr common.Address, caller *MultiCaller) (*FaultDisputeGameContract, error) { + fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to load fault dispute game ABI: %w", err) + } + + return &FaultDisputeGameContract{ + multiCaller: caller, + abi: fdgAbi, + addr: addr, + }, nil +} + +func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (*big.Int, error) { + result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "MAX_GAME_DEPTH")) + if err != nil { + return nil, fmt.Errorf("failed to fetch max game depth: %w", err) + } + return result.GetBigInt(0), nil +} + +func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.GameStatus, error) { + result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "status")) + if err != nil { + return 0, fmt.Errorf("failed to fetch claim count: %w", err) + } + return gameTypes.GameStatusFromUint8(result.GetUint8(0)) +} + +func (f *FaultDisputeGameContract) GetClaimCount(ctx context.Context) (uint64, error) { + result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "claimDataLen")) + if err != nil { + return 0, fmt.Errorf("failed to fetch claim count: %w", err) + } + return result.GetBigInt(0).Uint64(), nil +} + +func (f *FaultDisputeGameContract) GetClaim(ctx context.Context, idx uint64) (types.Claim, error) { + result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "claimData", new(big.Int).SetUint64(idx))) + if err != nil { + return types.Claim{}, fmt.Errorf("failed to fetch claim %v: %w", idx, err) + } + return f.decodeClaim(result, int(idx)), nil +} + +func (f *FaultDisputeGameContract) GetAllClaims(ctx context.Context) ([]types.Claim, error) { + count, err := f.GetClaimCount(ctx) + if err != nil { + return nil, fmt.Errorf("failed to load claim count: %w", err) + } + + calls := make([]*ContractCall, count) + for i := uint64(0); i < count; i++ { + calls[i] = NewContractCall(f.abi, f.addr, "claimData", new(big.Int).SetUint64(i)) + } + + results, err := f.multiCaller.CallLatest(ctx, calls...) + if err != nil { + return nil, fmt.Errorf("failed to fetch claim data: %w", err) + } + + var claims []types.Claim + for idx, result := range results { + claims = append(claims, f.decodeClaim(result, idx)) + } + return claims, nil +} + +func (f *FaultDisputeGameContract) decodeClaim(result *CallResult, contractIndex int) types.Claim { + parentIndex := result.GetUint32(0) + countered := result.GetBool(1) + claim := result.GetHash(2) + position := result.GetBigInt(3) + clock := result.GetBigInt(4) + return types.Claim{ + ClaimData: types.ClaimData{ + Value: claim, + Position: types.NewPositionFromGIndex(position), + }, + Countered: countered, + Clock: clock.Uint64(), + ContractIndex: contractIndex, + ParentContractIndex: int(parentIndex), + } +} diff --git a/op-challenger/game/fault/contracts/multicall.go b/op-challenger/game/fault/contracts/multicall.go new file mode 100644 index 000000000000..83d666e95abb --- /dev/null +++ b/op-challenger/game/fault/contracts/multicall.go @@ -0,0 +1,168 @@ +package contracts + +import ( + "context" + "fmt" + "io" + "math/big" + + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum/go-ethereum" + "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/rpc" +) + +type EthRpc interface { + CallContext(ctx context.Context, out interface{}, method string, args ...interface{}) error + BatchCallContext(ctx context.Context, b []rpc.BatchElem) error +} + +type ContractCall struct { + Abi *abi.ABI + Addr common.Address + Method string + Args []interface{} +} + +func NewContractCall(abi *abi.ABI, addr common.Address, method string, args ...interface{}) *ContractCall { + return &ContractCall{ + Abi: abi, + Addr: addr, + Method: method, + Args: args, + } +} + +func (c *ContractCall) ToCallArgs() (interface{}, error) { + data, err := c.Abi.Pack(c.Method, c.Args...) + if err != nil { + return nil, fmt.Errorf("failed to pack arguments: %w", err) + } + msg := ethereum.CallMsg{ + To: &c.Addr, + Data: data, + } + return toCallArg(msg), nil +} + +func (c *ContractCall) Unpack(hex hexutil.Bytes) ([]interface{}, error) { + out, err := c.Abi.Unpack(c.Method, hex) + if err != nil { + return nil, fmt.Errorf("failed to unpack claim data: %w", err) + } + return out, nil +} + +type CallResult struct { + out []interface{} +} + +func (c *CallResult) GetUint8(i int) uint8 { + return *abi.ConvertType(c.out[i], new(uint8)).(*uint8) +} + +func (c *CallResult) GetUint32(i int) uint32 { + return *abi.ConvertType(c.out[i], new(uint32)).(*uint32) +} + +func (c *CallResult) GetBool(i int) bool { + return *abi.ConvertType(c.out[i], new(bool)).(*bool) +} + +func (c *CallResult) GetHash(i int) common.Hash { + return *abi.ConvertType(c.out[i], new([32]byte)).(*[32]byte) +} + +func (c *CallResult) GetBigInt(i int) *big.Int { + return *abi.ConvertType(c.out[i], new(*big.Int)).(**big.Int) +} + +type MultiCaller struct { + rpc EthRpc + batchSize int +} + +func NewMultiCaller(rpc EthRpc, batchSize int) *MultiCaller { + return &MultiCaller{ + rpc: rpc, + batchSize: batchSize, + } +} + +func (m *MultiCaller) SingleCallLatest(ctx context.Context, call *ContractCall) (*CallResult, error) { + results, err := m.CallLatest(ctx, call) + if err != nil { + return nil, err + } + return results[0], nil +} + +func (m *MultiCaller) CallLatest(ctx context.Context, calls ...*ContractCall) ([]*CallResult, error) { + keys := make([]interface{}, len(calls)) + for i := 0; i < len(calls); i++ { + args, err := calls[i].ToCallArgs() + if err != nil { + return nil, err + } + keys[i] = args + } + fetcher := sources.NewIterativeBatchCall[interface{}, *hexutil.Bytes]( + keys, + func(args interface{}) (*hexutil.Bytes, rpc.BatchElem) { + out := new(hexutil.Bytes) + return out, rpc.BatchElem{ + Method: "eth_call", + Args: []interface{}{args, "latest"}, + Result: &out, + } + }, + m.rpc.BatchCallContext, + m.rpc.CallContext, + m.batchSize) + for { + if err := fetcher.Fetch(ctx); err == io.EOF { + break + } else if err != nil { + return nil, fmt.Errorf("failed to fetch claims: %w", err) + } + } + results, err := fetcher.Result() + if err != nil { + return nil, fmt.Errorf("failed to get batch call results: %w", err) + } + + callResults := make([]*CallResult, len(results)) + for i, result := range results { + call := calls[i] + out, err := call.Unpack(*result) + if err != nil { + return nil, fmt.Errorf("failed to unpack result: %w", err) + } + callResults[i] = &CallResult{ + out: out, + } + } + return callResults, nil +} + +func toCallArg(msg ethereum.CallMsg) interface{} { + arg := map[string]interface{}{ + "from": msg.From, + "to": msg.To, + } + if len(msg.Data) > 0 { + arg["data"] = hexutil.Bytes(msg.Data) + } + if msg.Value != nil { + arg["value"] = (*hexutil.Big)(msg.Value) + } + if msg.Gas != 0 { + arg["gas"] = hexutil.Uint64(msg.Gas) + } + if msg.GasPrice != nil { + arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice) + } + return arg +} From 757e8e43d0d68ce783869fc20c99a9f6b76c3cd9 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 16 Oct 2023 13:44:40 +1000 Subject: [PATCH 003/374] op-challenger: Use new contract wrapper for read calls. --- op-challenger/game/fault/agent.go | 6 ++--- op-challenger/game/fault/agent_test.go | 2 +- .../game/fault/contracts/faultdisputegame.go | 22 ++++++++++++++--- .../game/fault/contracts/multicall.go | 2 ++ op-challenger/game/fault/player.go | 24 +++++++++---------- op-challenger/game/fault/player_test.go | 4 ++-- op-challenger/game/fault/register.go | 4 ++-- 7 files changed, 40 insertions(+), 24 deletions(-) diff --git a/op-challenger/game/fault/agent.go b/op-challenger/game/fault/agent.go index a650a3b2a095..f589f9c78aa1 100644 --- a/op-challenger/game/fault/agent.go +++ b/op-challenger/game/fault/agent.go @@ -25,7 +25,7 @@ type Responder interface { } type ClaimLoader interface { - FetchClaims(ctx context.Context) ([]types.Claim, error) + GetAllClaims(ctx context.Context) ([]types.Claim, error) } type Agent struct { @@ -136,7 +136,7 @@ func (a *Agent) tryResolve(ctx context.Context) bool { var errNoResolvableClaims = errors.New("no resolvable claims") func (a *Agent) tryResolveClaims(ctx context.Context) error { - claims, err := a.loader.FetchClaims(ctx) + claims, err := a.loader.GetAllClaims(ctx) if err != nil { return fmt.Errorf("failed to fetch claims: %w", err) } @@ -189,7 +189,7 @@ func (a *Agent) resolveClaims(ctx context.Context) error { // newGameFromContracts initializes a new game state from the state in the contract func (a *Agent) newGameFromContracts(ctx context.Context) (types.Game, error) { - claims, err := a.loader.FetchClaims(ctx) + claims, err := a.loader.GetAllClaims(ctx) if err != nil { return nil, fmt.Errorf("failed to fetch claims: %w", err) } diff --git a/op-challenger/game/fault/agent_test.go b/op-challenger/game/fault/agent_test.go index c6b1904c74b1..44e3bb6313cb 100644 --- a/op-challenger/game/fault/agent_test.go +++ b/op-challenger/game/fault/agent_test.go @@ -124,7 +124,7 @@ type stubClaimLoader struct { claims []types.Claim } -func (s *stubClaimLoader) FetchClaims(ctx context.Context) ([]types.Claim, error) { +func (s *stubClaimLoader) GetAllClaims(ctx context.Context) ([]types.Claim, error) { s.callCount++ return s.claims, nil } diff --git a/op-challenger/game/fault/contracts/faultdisputegame.go b/op-challenger/game/fault/contracts/faultdisputegame.go index 16f344fcc9ca..6d5defde87af 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame.go +++ b/op-challenger/game/fault/contracts/faultdisputegame.go @@ -31,12 +31,28 @@ func NewFaultDisputeGameContract(addr common.Address, caller *MultiCaller) (*Fau }, nil } -func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (*big.Int, error) { +func (f *FaultDisputeGameContract) GetGameDuration(ctx context.Context) (uint64, error) { + result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "GAME_DURATION")) + if err != nil { + return 0, fmt.Errorf("failed to fetch game duration: %w", err) + } + return result.GetBigInt(0).Uint64(), nil +} + +func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, error) { result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "MAX_GAME_DEPTH")) if err != nil { - return nil, fmt.Errorf("failed to fetch max game depth: %w", err) + return 0, fmt.Errorf("failed to fetch max game depth: %w", err) + } + return result.GetBigInt(0).Uint64(), nil +} + +func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { + result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "ABSOLUTE_PRESTATE")) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to fetch absolute prestate hash: %w", err) } - return result.GetBigInt(0), nil + return result.GetHash(0), nil } func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.GameStatus, error) { diff --git a/op-challenger/game/fault/contracts/multicall.go b/op-challenger/game/fault/contracts/multicall.go index 83d666e95abb..ec285bb2af15 100644 --- a/op-challenger/game/fault/contracts/multicall.go +++ b/op-challenger/game/fault/contracts/multicall.go @@ -14,6 +14,8 @@ import ( "github.com/ethereum/go-ethereum/rpc" ) +// Note: All of this stuff would wind up moving to somewhere in op-service so it can be easily reused. + type EthRpc interface { CallContext(ctx context.Context, out interface{}, method string, args ...interface{}) error BatchCallContext(ctx context.Context, b []rpc.BatchElem) error diff --git a/op-challenger/game/fault/player.go b/op-challenger/game/fault/player.go index f3d1917cd8e0..ba7188dc9bee 100644 --- a/op-challenger/game/fault/player.go +++ b/op-challenger/game/fault/player.go @@ -5,22 +5,22 @@ import ( "context" "fmt" - "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-challenger/config" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/responder" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/txmgr" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" ) type actor func(ctx context.Context) error type GameInfo interface { - GetGameStatus(context.Context) (gameTypes.GameStatus, error) + GetStatus(context.Context) (gameTypes.GameStatus, error) GetClaimCount(context.Context) (uint64, error) } @@ -42,18 +42,16 @@ func NewGamePlayer( dir string, addr common.Address, txMgr txmgr.TxManager, - client bind.ContractCaller, + client *ethclient.Client, creator resourceCreator, ) (*GamePlayer, error) { logger = logger.New("game", addr) - contract, err := bindings.NewFaultDisputeGameCaller(addr, client) + loader, err := contracts.NewFaultDisputeGameContract(addr, contracts.NewMultiCaller(client.Client(), 100)) if err != nil { - return nil, fmt.Errorf("failed to bind the fault dispute game contract: %w", err) + return nil, fmt.Errorf("failed to create fault dispute game contract wrapper: %w", err) } - loader := NewLoader(contract) - - status, err := loader.GetGameStatus(ctx) + status, err := loader.GetStatus(ctx) if err != nil { return nil, fmt.Errorf("failed to fetch game status: %w", err) } @@ -72,7 +70,7 @@ func NewGamePlayer( }, nil } - gameDepth, err := loader.FetchGameDepth(ctx) + gameDepth, err := loader.GetMaxGameDepth(ctx) if err != nil { return nil, fmt.Errorf("failed to fetch the game depth: %w", err) } @@ -114,7 +112,7 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) gameTypes.GameStatus { if err := g.act(ctx); err != nil { g.logger.Error("Error when acting on game", "err", err) } - status, err := g.loader.GetGameStatus(ctx) + status, err := g.loader.GetStatus(ctx) if err != nil { g.logger.Warn("Unable to retrieve game status", "err", err) return gameTypes.GameStatusInProgress @@ -148,7 +146,7 @@ func (g *GamePlayer) logGameStatus(ctx context.Context, status gameTypes.GameSta } type PrestateLoader interface { - FetchAbsolutePrestateHash(ctx context.Context) (common.Hash, error) + GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) } // ValidateAbsolutePrestate validates the absolute prestate of the fault game. @@ -157,7 +155,7 @@ func ValidateAbsolutePrestate(ctx context.Context, trace types.TraceProvider, lo if err != nil { return fmt.Errorf("failed to get the trace provider's absolute prestate: %w", err) } - onchainPrestate, err := loader.FetchAbsolutePrestateHash(ctx) + onchainPrestate, err := loader.GetAbsolutePrestateHash(ctx) if err != nil { return fmt.Errorf("failed to get the onchain absolute prestate: %w", err) } diff --git a/op-challenger/game/fault/player_test.go b/op-challenger/game/fault/player_test.go index 3ed906c94f62..7375e2146d8a 100644 --- a/op-challenger/game/fault/player_test.go +++ b/op-challenger/game/fault/player_test.go @@ -181,7 +181,7 @@ func (s *stubGameState) Act(ctx context.Context) error { return s.actErr } -func (s *stubGameState) GetGameStatus(ctx context.Context) (gameTypes.GameStatus, error) { +func (s *stubGameState) GetStatus(ctx context.Context) (gameTypes.GameStatus, error) { return s.status, nil } @@ -234,7 +234,7 @@ func newMockPrestateLoader(prestateError bool, prestate common.Hash) *mockLoader prestate: prestate, } } -func (m *mockLoader) FetchAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { +func (m *mockLoader) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { if m.prestateError { return common.Hash{}, mockLoaderError } diff --git a/op-challenger/game/fault/register.go b/op-challenger/game/fault/register.go index 26816907695e..54748bc99797 100644 --- a/op-challenger/game/fault/register.go +++ b/op-challenger/game/fault/register.go @@ -12,8 +12,8 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/txmgr" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" ) @@ -33,7 +33,7 @@ func RegisterGameTypes( m metrics.Metricer, cfg *config.Config, txMgr txmgr.TxManager, - client bind.ContractCaller, + client *ethclient.Client, ) { if cfg.TraceTypeEnabled(config.TraceTypeCannon) { resourceCreator := func(addr common.Address, gameDepth uint64, dir string) (faultTypes.TraceProvider, faultTypes.OracleUpdater, error) { From e8ab03d2985cc338c76c51ffc4882b5debc03cf6 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 16 Oct 2023 15:16:27 +1000 Subject: [PATCH 004/374] op-challenger: Add some tests that confirm the abi matches. --- .../game/fault/contracts/faultdisputegame.go | 2 +- .../fault/contracts/faultdisputegame_test.go | 122 ++++++++++++++++++ .../game/fault/contracts/multicall.go | 2 +- 3 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 op-challenger/game/fault/contracts/faultdisputegame_test.go diff --git a/op-challenger/game/fault/contracts/faultdisputegame.go b/op-challenger/game/fault/contracts/faultdisputegame.go index 6d5defde87af..d838c4aeda18 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame.go +++ b/op-challenger/game/fault/contracts/faultdisputegame.go @@ -58,7 +58,7 @@ func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context) func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.GameStatus, error) { result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "status")) if err != nil { - return 0, fmt.Errorf("failed to fetch claim count: %w", err) + return 0, fmt.Errorf("failed to fetch status: %w", err) } return gameTypes.GameStatusFromUint8(result.GetUint8(0)) } diff --git a/op-challenger/game/fault/contracts/faultdisputegame_test.go b/op-challenger/game/fault/contracts/faultdisputegame_test.go new file mode 100644 index 000000000000..179525012601 --- /dev/null +++ b/op-challenger/game/fault/contracts/faultdisputegame_test.go @@ -0,0 +1,122 @@ +package contracts + +import ( + "context" + "encoding/json" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "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/rpc" + "github.com/stretchr/testify/require" +) + +func TestGetStatus(t *testing.T) { + stubRpc, game := setup(t) + stubRpc.SetResponse("status", nil, []interface{}{types.GameStatusChallengerWon}) + status, err := game.GetStatus(context.Background()) + require.NoError(t, err) + require.Equal(t, types.GameStatusChallengerWon, status) +} + +func TestGetClaim(t *testing.T) { + stubRpc, game := setup(t) + idx := big.NewInt(2) + parentIndex := uint32(1) + countered := true + value := common.Hash{0xab} + position := big.NewInt(2) + clock := big.NewInt(1234) + stubRpc.SetResponse("claimData", []interface{}{idx}, []interface{}{parentIndex, countered, value, position, clock}) + status, err := game.GetClaim(context.Background(), idx.Uint64()) + require.NoError(t, err) + require.Equal(t, faultTypes.Claim{ + ClaimData: faultTypes.ClaimData{ + Value: value, + Position: faultTypes.NewPositionFromGIndex(position), + }, + Countered: true, + Clock: 1234, + ContractIndex: int(idx.Uint64()), + ParentContractIndex: 1, + }, status) +} + +type abiBasedRpc struct { + t *testing.T + abi *abi.ABI + addr common.Address + + expectedArgs map[string][]interface{} + outputs map[string][]interface{} +} + +func setup(t *testing.T) (*abiBasedRpc, *FaultDisputeGameContract) { + fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() + require.NoError(t, err) + address := common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB") + + stubRpc := &abiBasedRpc{ + t: t, + abi: fdgAbi, + addr: address, + expectedArgs: make(map[string][]interface{}), + outputs: make(map[string][]interface{}), + } + caller := NewMultiCaller(stubRpc, 1) + game, err := NewFaultDisputeGameContract(address, caller) + require.NoError(t, err) + return stubRpc, game +} + +func (l *abiBasedRpc) SetResponse(method string, expected []interface{}, output []interface{}) { + if expected == nil { + expected = []interface{}{} + } + if output == nil { + output = []interface{}{} + } + l.expectedArgs[method] = expected + l.outputs[method] = output +} + +func (l *abiBasedRpc) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { + panic("Not implemented") +} + +func (l *abiBasedRpc) CallContext(ctx context.Context, out interface{}, method string, args ...interface{}) error { + require.Equal(l.t, "eth_call", method) + require.Len(l.t, args, 2) + require.Equal(l.t, "latest", args[1]) + callOpts, ok := args[0].(map[string]any) + require.True(l.t, ok) + require.Equal(l.t, &l.addr, callOpts["to"]) + data, ok := callOpts["data"].(hexutil.Bytes) + require.True(l.t, ok) + abiMethod, err := l.abi.MethodById(data[0:4]) + require.NoError(l.t, err) + + args, err = abiMethod.Inputs.Unpack(data[4:]) + require.NoError(l.t, err) + require.Len(l.t, args, len(abiMethod.Inputs)) + expectedArgs, ok := l.expectedArgs[abiMethod.Name] + require.True(l.t, ok) + require.EqualValues(l.t, expectedArgs, args, "Unexpected args") + + outputs, ok := l.outputs[abiMethod.Name] + require.True(l.t, ok) + output, err := abiMethod.Outputs.Pack(outputs...) + require.NoError(l.t, err) + + // I admit I do not understand Go reflection. + // So leverage json.Unmarshal to set the out value correctly. + j, err := json.Marshal(hexutil.Bytes(output)) + require.NoError(l.t, err) + require.NoError(l.t, json.Unmarshal(j, out)) + return nil +} diff --git a/op-challenger/game/fault/contracts/multicall.go b/op-challenger/game/fault/contracts/multicall.go index ec285bb2af15..67c07ebb1ddc 100644 --- a/op-challenger/game/fault/contracts/multicall.go +++ b/op-challenger/game/fault/contracts/multicall.go @@ -52,7 +52,7 @@ func (c *ContractCall) ToCallArgs() (interface{}, error) { func (c *ContractCall) Unpack(hex hexutil.Bytes) ([]interface{}, error) { out, err := c.Abi.Unpack(c.Method, hex) if err != nil { - return nil, fmt.Errorf("failed to unpack claim data: %w", err) + return nil, fmt.Errorf("failed to unpack data: %w", err) } return out, nil } From 8c688bc1d9b4ee4ea9dbfdf0a1d3591389d4da7d Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 23 Oct 2023 10:25:20 +1000 Subject: [PATCH 005/374] Move batching and multicall logic to a new package in op-service Add BoundContract to simplify creating method calls. --- .../game/fault/contracts/faultdisputegame.go | 30 +++---- .../fault/contracts/faultdisputegame_test.go | 3 +- op-challenger/game/fault/player.go | 3 +- op-service/sources/{ => batching}/batching.go | 2 +- .../sources/{ => batching}/batching_test.go | 2 +- op-service/sources/batching/call.go | 87 +++++++++++++++++++ .../sources/batching}/multicall.go | 70 +-------------- op-service/sources/batching/types.go | 11 +++ op-service/sources/debug_client.go | 5 +- op-service/sources/receipts.go | 5 +- op-service/sources/types.go | 5 -- 11 files changed, 126 insertions(+), 97 deletions(-) rename op-service/sources/{ => batching}/batching.go (99%) rename op-service/sources/{ => batching}/batching_test.go (99%) create mode 100644 op-service/sources/batching/call.go rename {op-challenger/game/fault/contracts => op-service/sources/batching}/multicall.go (56%) create mode 100644 op-service/sources/batching/types.go diff --git a/op-challenger/game/fault/contracts/faultdisputegame.go b/op-challenger/game/fault/contracts/faultdisputegame.go index d838c4aeda18..78d451700e1b 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame.go +++ b/op-challenger/game/fault/contracts/faultdisputegame.go @@ -8,17 +8,16 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" - "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum/go-ethereum/common" ) type FaultDisputeGameContract struct { - multiCaller *MultiCaller - addr common.Address - abi *abi.ABI + multiCaller *batching.MultiCaller + contract *batching.BoundContract } -func NewFaultDisputeGameContract(addr common.Address, caller *MultiCaller) (*FaultDisputeGameContract, error) { +func NewFaultDisputeGameContract(addr common.Address, caller *batching.MultiCaller) (*FaultDisputeGameContract, error) { fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() if err != nil { return nil, fmt.Errorf("failed to load fault dispute game ABI: %w", err) @@ -26,13 +25,12 @@ func NewFaultDisputeGameContract(addr common.Address, caller *MultiCaller) (*Fau return &FaultDisputeGameContract{ multiCaller: caller, - abi: fdgAbi, - addr: addr, + contract: batching.NewBoundContract(fdgAbi, addr), }, nil } func (f *FaultDisputeGameContract) GetGameDuration(ctx context.Context) (uint64, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "GAME_DURATION")) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("GAME_DURATION")) if err != nil { return 0, fmt.Errorf("failed to fetch game duration: %w", err) } @@ -40,7 +38,7 @@ func (f *FaultDisputeGameContract) GetGameDuration(ctx context.Context) (uint64, } func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "MAX_GAME_DEPTH")) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("MAX_GAME_DEPTH")) if err != nil { return 0, fmt.Errorf("failed to fetch max game depth: %w", err) } @@ -48,7 +46,7 @@ func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, } func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "ABSOLUTE_PRESTATE")) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("ABSOLUTE_PRESTATE")) if err != nil { return common.Hash{}, fmt.Errorf("failed to fetch absolute prestate hash: %w", err) } @@ -56,7 +54,7 @@ func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context) } func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.GameStatus, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "status")) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("status")) if err != nil { return 0, fmt.Errorf("failed to fetch status: %w", err) } @@ -64,7 +62,7 @@ func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.Gam } func (f *FaultDisputeGameContract) GetClaimCount(ctx context.Context) (uint64, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "claimDataLen")) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("claimDataLen")) if err != nil { return 0, fmt.Errorf("failed to fetch claim count: %w", err) } @@ -72,7 +70,7 @@ func (f *FaultDisputeGameContract) GetClaimCount(ctx context.Context) (uint64, e } func (f *FaultDisputeGameContract) GetClaim(ctx context.Context, idx uint64) (types.Claim, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, NewContractCall(f.abi, f.addr, "claimData", new(big.Int).SetUint64(idx))) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("claimData", new(big.Int).SetUint64(idx))) if err != nil { return types.Claim{}, fmt.Errorf("failed to fetch claim %v: %w", idx, err) } @@ -85,9 +83,9 @@ func (f *FaultDisputeGameContract) GetAllClaims(ctx context.Context) ([]types.Cl return nil, fmt.Errorf("failed to load claim count: %w", err) } - calls := make([]*ContractCall, count) + calls := make([]*batching.ContractCall, count) for i := uint64(0); i < count; i++ { - calls[i] = NewContractCall(f.abi, f.addr, "claimData", new(big.Int).SetUint64(i)) + calls[i] = f.contract.Call("claimData", new(big.Int).SetUint64(i)) } results, err := f.multiCaller.CallLatest(ctx, calls...) @@ -102,7 +100,7 @@ func (f *FaultDisputeGameContract) GetAllClaims(ctx context.Context) ([]types.Cl return claims, nil } -func (f *FaultDisputeGameContract) decodeClaim(result *CallResult, contractIndex int) types.Claim { +func (f *FaultDisputeGameContract) decodeClaim(result *batching.CallResult, contractIndex int) types.Claim { parentIndex := result.GetUint32(0) countered := result.GetBool(1) claim := result.GetHash(2) diff --git a/op-challenger/game/fault/contracts/faultdisputegame_test.go b/op-challenger/game/fault/contracts/faultdisputegame_test.go index 179525012601..a28a1220d018 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame_test.go +++ b/op-challenger/game/fault/contracts/faultdisputegame_test.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/bindings" faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -68,7 +69,7 @@ func setup(t *testing.T) (*abiBasedRpc, *FaultDisputeGameContract) { expectedArgs: make(map[string][]interface{}), outputs: make(map[string][]interface{}), } - caller := NewMultiCaller(stubRpc, 1) + caller := batching.NewMultiCaller(stubRpc, 1) game, err := NewFaultDisputeGameContract(address, caller) require.NoError(t, err) return stubRpc, game diff --git a/op-challenger/game/fault/player.go b/op-challenger/game/fault/player.go index ba7188dc9bee..10c64df4d195 100644 --- a/op-challenger/game/fault/player.go +++ b/op-challenger/game/fault/player.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" @@ -46,7 +47,7 @@ func NewGamePlayer( creator resourceCreator, ) (*GamePlayer, error) { logger = logger.New("game", addr) - loader, err := contracts.NewFaultDisputeGameContract(addr, contracts.NewMultiCaller(client.Client(), 100)) + loader, err := contracts.NewFaultDisputeGameContract(addr, batching.NewMultiCaller(client.Client(), 100)) if err != nil { return nil, fmt.Errorf("failed to create fault dispute game contract wrapper: %w", err) } diff --git a/op-service/sources/batching.go b/op-service/sources/batching/batching.go similarity index 99% rename from op-service/sources/batching.go rename to op-service/sources/batching/batching.go index 958185ac32bb..0cf88f702704 100644 --- a/op-service/sources/batching.go +++ b/op-service/sources/batching/batching.go @@ -1,4 +1,4 @@ -package sources +package batching import ( "context" diff --git a/op-service/sources/batching_test.go b/op-service/sources/batching/batching_test.go similarity index 99% rename from op-service/sources/batching_test.go rename to op-service/sources/batching/batching_test.go index 4d79e3e1f4e6..c2880dd0c92b 100644 --- a/op-service/sources/batching_test.go +++ b/op-service/sources/batching/batching_test.go @@ -1,4 +1,4 @@ -package sources +package batching import ( "context" diff --git a/op-service/sources/batching/call.go b/op-service/sources/batching/call.go new file mode 100644 index 000000000000..9328d419c0f1 --- /dev/null +++ b/op-service/sources/batching/call.go @@ -0,0 +1,87 @@ +package batching + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +type BoundContract struct { + abi *abi.ABI + addr common.Address +} + +func NewBoundContract(abi *abi.ABI, addr common.Address) *BoundContract { + return &BoundContract{ + abi: abi, + addr: addr, + } +} + +func (b *BoundContract) Call(method string, args ...interface{}) *ContractCall { + return NewContractCall(b.abi, b.addr, method, args...) +} + +type ContractCall struct { + Abi *abi.ABI + Addr common.Address + Method string + Args []interface{} +} + +func NewContractCall(abi *abi.ABI, addr common.Address, method string, args ...interface{}) *ContractCall { + return &ContractCall{ + Abi: abi, + Addr: addr, + Method: method, + Args: args, + } +} + +func (c *ContractCall) ToCallArgs() (interface{}, error) { + data, err := c.Abi.Pack(c.Method, c.Args...) + if err != nil { + return nil, fmt.Errorf("failed to pack arguments: %w", err) + } + msg := ethereum.CallMsg{ + To: &c.Addr, + Data: data, + } + return toCallArg(msg), nil +} + +func (c *ContractCall) Unpack(hex hexutil.Bytes) ([]interface{}, error) { + out, err := c.Abi.Unpack(c.Method, hex) + if err != nil { + return nil, fmt.Errorf("failed to unpack data: %w", err) + } + return out, nil +} + +type CallResult struct { + out []interface{} +} + +func (c *CallResult) GetUint8(i int) uint8 { + return *abi.ConvertType(c.out[i], new(uint8)).(*uint8) +} + +func (c *CallResult) GetUint32(i int) uint32 { + return *abi.ConvertType(c.out[i], new(uint32)).(*uint32) +} + +func (c *CallResult) GetBool(i int) bool { + return *abi.ConvertType(c.out[i], new(bool)).(*bool) +} + +func (c *CallResult) GetHash(i int) common.Hash { + return *abi.ConvertType(c.out[i], new([32]byte)).(*[32]byte) +} + +func (c *CallResult) GetBigInt(i int) *big.Int { + return *abi.ConvertType(c.out[i], new(*big.Int)).(**big.Int) +} diff --git a/op-challenger/game/fault/contracts/multicall.go b/op-service/sources/batching/multicall.go similarity index 56% rename from op-challenger/game/fault/contracts/multicall.go rename to op-service/sources/batching/multicall.go index 67c07ebb1ddc..e4ac34d3f7bf 100644 --- a/op-challenger/game/fault/contracts/multicall.go +++ b/op-service/sources/batching/multicall.go @@ -1,86 +1,20 @@ -package contracts +package batching import ( "context" "fmt" "io" - "math/big" - "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum/go-ethereum" - "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/rpc" ) -// Note: All of this stuff would wind up moving to somewhere in op-service so it can be easily reused. - type EthRpc interface { CallContext(ctx context.Context, out interface{}, method string, args ...interface{}) error BatchCallContext(ctx context.Context, b []rpc.BatchElem) error } -type ContractCall struct { - Abi *abi.ABI - Addr common.Address - Method string - Args []interface{} -} - -func NewContractCall(abi *abi.ABI, addr common.Address, method string, args ...interface{}) *ContractCall { - return &ContractCall{ - Abi: abi, - Addr: addr, - Method: method, - Args: args, - } -} - -func (c *ContractCall) ToCallArgs() (interface{}, error) { - data, err := c.Abi.Pack(c.Method, c.Args...) - if err != nil { - return nil, fmt.Errorf("failed to pack arguments: %w", err) - } - msg := ethereum.CallMsg{ - To: &c.Addr, - Data: data, - } - return toCallArg(msg), nil -} - -func (c *ContractCall) Unpack(hex hexutil.Bytes) ([]interface{}, error) { - out, err := c.Abi.Unpack(c.Method, hex) - if err != nil { - return nil, fmt.Errorf("failed to unpack data: %w", err) - } - return out, nil -} - -type CallResult struct { - out []interface{} -} - -func (c *CallResult) GetUint8(i int) uint8 { - return *abi.ConvertType(c.out[i], new(uint8)).(*uint8) -} - -func (c *CallResult) GetUint32(i int) uint32 { - return *abi.ConvertType(c.out[i], new(uint32)).(*uint32) -} - -func (c *CallResult) GetBool(i int) bool { - return *abi.ConvertType(c.out[i], new(bool)).(*bool) -} - -func (c *CallResult) GetHash(i int) common.Hash { - return *abi.ConvertType(c.out[i], new([32]byte)).(*[32]byte) -} - -func (c *CallResult) GetBigInt(i int) *big.Int { - return *abi.ConvertType(c.out[i], new(*big.Int)).(**big.Int) -} - type MultiCaller struct { rpc EthRpc batchSize int @@ -110,7 +44,7 @@ func (m *MultiCaller) CallLatest(ctx context.Context, calls ...*ContractCall) ([ } keys[i] = args } - fetcher := sources.NewIterativeBatchCall[interface{}, *hexutil.Bytes]( + fetcher := NewIterativeBatchCall[interface{}, *hexutil.Bytes]( keys, func(args interface{}) (*hexutil.Bytes, rpc.BatchElem) { out := new(hexutil.Bytes) diff --git a/op-service/sources/batching/types.go b/op-service/sources/batching/types.go new file mode 100644 index 000000000000..4bd0cc2048d6 --- /dev/null +++ b/op-service/sources/batching/types.go @@ -0,0 +1,11 @@ +package batching + +import ( + "context" + + "github.com/ethereum/go-ethereum/rpc" +) + +type BatchCallContextFn func(ctx context.Context, b []rpc.BatchElem) error + +type CallContextFn func(ctx context.Context, result any, method string, args ...any) error diff --git a/op-service/sources/debug_client.go b/op-service/sources/debug_client.go index db5a782281f1..e9bb2ca579a7 100644 --- a/op-service/sources/debug_client.go +++ b/op-service/sources/debug_client.go @@ -4,16 +4,17 @@ import ( "context" "fmt" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/rawdb" ) type DebugClient struct { - callContext CallContextFn + callContext batching.CallContextFn } -func NewDebugClient(callContext CallContextFn) *DebugClient { +func NewDebugClient(callContext batching.CallContextFn) *DebugClient { return &DebugClient{callContext} } diff --git a/op-service/sources/receipts.go b/op-service/sources/receipts.go index e3c8a8713b06..b255ea70454c 100644 --- a/op-service/sources/receipts.go +++ b/op-service/sources/receipts.go @@ -6,6 +6,7 @@ import ( "io" "sync" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -369,7 +370,7 @@ type receiptsFetchingJob struct { receiptHash common.Hash txHashes []common.Hash - fetcher *IterativeBatchCall[common.Hash, *types.Receipt] + fetcher *batching.IterativeBatchCall[common.Hash, *types.Receipt] result types.Receipts } @@ -398,7 +399,7 @@ type ReceiptsRequester interface { func (job *receiptsFetchingJob) runFetcher(ctx context.Context) error { if job.fetcher == nil { // start new work - job.fetcher = NewIterativeBatchCall[common.Hash, *types.Receipt]( + job.fetcher = batching.NewIterativeBatchCall[common.Hash, *types.Receipt]( job.txHashes, makeReceiptRequest, job.client.BatchCallContext, diff --git a/op-service/sources/types.go b/op-service/sources/types.go index a3a9bbc949e7..94ba65be30a1 100644 --- a/op-service/sources/types.go +++ b/op-service/sources/types.go @@ -1,7 +1,6 @@ package sources import ( - "context" "fmt" "math/big" "strings" @@ -18,10 +17,6 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" ) -type BatchCallContextFn func(ctx context.Context, b []rpc.BatchElem) error - -type CallContextFn func(ctx context.Context, result any, method string, args ...any) error - // Note: these types are used, instead of the geth types, to enable: // - batched calls of many block requests (standard bindings do extra uncle-header fetches, cannot be batched nicely) // - ignore uncle data (does not even exist anymore post-Merge) From 16d65a68ae3e771e62e629d65f82c20785ded324 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 23 Oct 2023 11:06:48 +1000 Subject: [PATCH 006/374] Add more tests --- .../game/fault/contracts/faultdisputegame.go | 25 +++- .../fault/contracts/faultdisputegame_test.go | 141 ++++++++---------- op-service/sources/batching/call.go | 4 + op-service/sources/batching/test/stubs.go | 79 ++++++++++ 4 files changed, 165 insertions(+), 84 deletions(-) create mode 100644 op-service/sources/batching/test/stubs.go diff --git a/op-challenger/game/fault/contracts/faultdisputegame.go b/op-challenger/game/fault/contracts/faultdisputegame.go index 78d451700e1b..889dac4e56d5 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame.go +++ b/op-challenger/game/fault/contracts/faultdisputegame.go @@ -12,6 +12,15 @@ import ( "github.com/ethereum/go-ethereum/common" ) +const ( + methodGameDuration = "GAME_DURATION" + methodMaxGameDepth = "MAX_GAME_DEPTH" + methodAbsolutePrestate = "ABSOLUTE_PRESTATE" + methodStatus = "status" + methodClaimCount = "claimDataLen" + methodClaim = "claimData" +) + type FaultDisputeGameContract struct { multiCaller *batching.MultiCaller contract *batching.BoundContract @@ -30,15 +39,15 @@ func NewFaultDisputeGameContract(addr common.Address, caller *batching.MultiCall } func (f *FaultDisputeGameContract) GetGameDuration(ctx context.Context) (uint64, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("GAME_DURATION")) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodGameDuration)) if err != nil { return 0, fmt.Errorf("failed to fetch game duration: %w", err) } - return result.GetBigInt(0).Uint64(), nil + return result.GetUint64(0), nil } func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("MAX_GAME_DEPTH")) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodMaxGameDepth)) if err != nil { return 0, fmt.Errorf("failed to fetch max game depth: %w", err) } @@ -46,7 +55,7 @@ func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, } func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("ABSOLUTE_PRESTATE")) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodAbsolutePrestate)) if err != nil { return common.Hash{}, fmt.Errorf("failed to fetch absolute prestate hash: %w", err) } @@ -54,7 +63,7 @@ func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context) } func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.GameStatus, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("status")) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodStatus)) if err != nil { return 0, fmt.Errorf("failed to fetch status: %w", err) } @@ -62,7 +71,7 @@ func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.Gam } func (f *FaultDisputeGameContract) GetClaimCount(ctx context.Context) (uint64, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("claimDataLen")) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodClaimCount)) if err != nil { return 0, fmt.Errorf("failed to fetch claim count: %w", err) } @@ -70,7 +79,7 @@ func (f *FaultDisputeGameContract) GetClaimCount(ctx context.Context) (uint64, e } func (f *FaultDisputeGameContract) GetClaim(ctx context.Context, idx uint64) (types.Claim, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call("claimData", new(big.Int).SetUint64(idx))) + result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodClaim, new(big.Int).SetUint64(idx))) if err != nil { return types.Claim{}, fmt.Errorf("failed to fetch claim %v: %w", idx, err) } @@ -85,7 +94,7 @@ func (f *FaultDisputeGameContract) GetAllClaims(ctx context.Context) ([]types.Cl calls := make([]*batching.ContractCall, count) for i := uint64(0); i < count; i++ { - calls[i] = f.contract.Call("claimData", new(big.Int).SetUint64(i)) + calls[i] = f.contract.Call(methodClaim, new(big.Int).SetUint64(i)) } results, err := f.multiCaller.CallLatest(ctx, calls...) diff --git a/op-challenger/game/fault/contracts/faultdisputegame_test.go b/op-challenger/game/fault/contracts/faultdisputegame_test.go index a28a1220d018..d9c8c7cbca79 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame_test.go +++ b/op-challenger/game/fault/contracts/faultdisputegame_test.go @@ -2,7 +2,6 @@ package contracts import ( "context" - "encoding/json" "math/big" "testing" @@ -10,19 +9,71 @@ import ( faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/sources/batching" - "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rpc" "github.com/stretchr/testify/require" ) -func TestGetStatus(t *testing.T) { - stubRpc, game := setup(t) - stubRpc.SetResponse("status", nil, []interface{}{types.GameStatusChallengerWon}) - status, err := game.GetStatus(context.Background()) - require.NoError(t, err) - require.Equal(t, types.GameStatusChallengerWon, status) +func TestSimpleGetters(t *testing.T) { + tests := []struct { + method string + args []interface{} + result interface{} + expected interface{} // Defaults to expecting the same as result + call func(game *FaultDisputeGameContract) (any, error) + }{ + { + method: methodStatus, + result: types.GameStatusChallengerWon, + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetStatus(context.Background()) + }, + }, + { + method: methodGameDuration, + result: uint64(5566), + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetGameDuration(context.Background()) + }, + }, + { + method: methodMaxGameDepth, + result: big.NewInt(128), + expected: uint64(128), + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetMaxGameDepth(context.Background()) + }, + }, + { + method: methodAbsolutePrestate, + result: common.Hash{0xab}, + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetAbsolutePrestateHash(context.Background()) + }, + }, + { + method: methodClaimCount, + result: big.NewInt(9876), + expected: uint64(9876), + call: func(game *FaultDisputeGameContract) (any, error) { + return game.GetClaimCount(context.Background()) + }, + }, + } + for _, test := range tests { + test := test + t.Run(test.method, func(t *testing.T) { + stubRpc, game := setup(t) + stubRpc.SetResponse(test.method, nil, []interface{}{test.result}) + status, err := test.call(game) + require.NoError(t, err) + expected := test.expected + if expected == nil { + expected = test.result + } + require.Equal(t, expected, status) + }) + } } func TestGetClaim(t *testing.T) { @@ -33,7 +84,7 @@ func TestGetClaim(t *testing.T) { value := common.Hash{0xab} position := big.NewInt(2) clock := big.NewInt(1234) - stubRpc.SetResponse("claimData", []interface{}{idx}, []interface{}{parentIndex, countered, value, position, clock}) + stubRpc.SetResponse(methodClaim, []interface{}{idx}, []interface{}{parentIndex, countered, value, position, clock}) status, err := game.GetClaim(context.Background(), idx.Uint64()) require.NoError(t, err) require.Equal(t, faultTypes.Claim{ @@ -48,76 +99,14 @@ func TestGetClaim(t *testing.T) { }, status) } -type abiBasedRpc struct { - t *testing.T - abi *abi.ABI - addr common.Address - - expectedArgs map[string][]interface{} - outputs map[string][]interface{} -} - -func setup(t *testing.T) (*abiBasedRpc, *FaultDisputeGameContract) { +func setup(t *testing.T) (*test.AbiBasedRpc, *FaultDisputeGameContract) { fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() require.NoError(t, err) address := common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB") - stubRpc := &abiBasedRpc{ - t: t, - abi: fdgAbi, - addr: address, - expectedArgs: make(map[string][]interface{}), - outputs: make(map[string][]interface{}), - } - caller := batching.NewMultiCaller(stubRpc, 1) + stubRpc := test.NewAbiBasedRpc(t, fdgAbi, address) + caller := batching.NewMultiCaller(stubRpc, 100) game, err := NewFaultDisputeGameContract(address, caller) require.NoError(t, err) return stubRpc, game } - -func (l *abiBasedRpc) SetResponse(method string, expected []interface{}, output []interface{}) { - if expected == nil { - expected = []interface{}{} - } - if output == nil { - output = []interface{}{} - } - l.expectedArgs[method] = expected - l.outputs[method] = output -} - -func (l *abiBasedRpc) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { - panic("Not implemented") -} - -func (l *abiBasedRpc) CallContext(ctx context.Context, out interface{}, method string, args ...interface{}) error { - require.Equal(l.t, "eth_call", method) - require.Len(l.t, args, 2) - require.Equal(l.t, "latest", args[1]) - callOpts, ok := args[0].(map[string]any) - require.True(l.t, ok) - require.Equal(l.t, &l.addr, callOpts["to"]) - data, ok := callOpts["data"].(hexutil.Bytes) - require.True(l.t, ok) - abiMethod, err := l.abi.MethodById(data[0:4]) - require.NoError(l.t, err) - - args, err = abiMethod.Inputs.Unpack(data[4:]) - require.NoError(l.t, err) - require.Len(l.t, args, len(abiMethod.Inputs)) - expectedArgs, ok := l.expectedArgs[abiMethod.Name] - require.True(l.t, ok) - require.EqualValues(l.t, expectedArgs, args, "Unexpected args") - - outputs, ok := l.outputs[abiMethod.Name] - require.True(l.t, ok) - output, err := abiMethod.Outputs.Pack(outputs...) - require.NoError(l.t, err) - - // I admit I do not understand Go reflection. - // So leverage json.Unmarshal to set the out value correctly. - j, err := json.Marshal(hexutil.Bytes(output)) - require.NoError(l.t, err) - require.NoError(l.t, json.Unmarshal(j, out)) - return nil -} diff --git a/op-service/sources/batching/call.go b/op-service/sources/batching/call.go index 9328d419c0f1..712a4c40070b 100644 --- a/op-service/sources/batching/call.go +++ b/op-service/sources/batching/call.go @@ -74,6 +74,10 @@ func (c *CallResult) GetUint32(i int) uint32 { return *abi.ConvertType(c.out[i], new(uint32)).(*uint32) } +func (c *CallResult) GetUint64(i int) uint64 { + return *abi.ConvertType(c.out[i], new(uint64)).(*uint64) +} + func (c *CallResult) GetBool(i int) bool { return *abi.ConvertType(c.out[i], new(bool)).(*bool) } diff --git a/op-service/sources/batching/test/stubs.go b/op-service/sources/batching/test/stubs.go new file mode 100644 index 000000000000..ec766df50b9c --- /dev/null +++ b/op-service/sources/batching/test/stubs.go @@ -0,0 +1,79 @@ +package test + +import ( + "context" + "encoding/json" + "testing" + + "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/rpc" + "github.com/stretchr/testify/require" +) + +type AbiBasedRpc struct { + t *testing.T + abi *abi.ABI + addr common.Address + + expectedArgs map[string][]interface{} + outputs map[string][]interface{} +} + +func NewAbiBasedRpc(t *testing.T, contractAbi *abi.ABI, addr common.Address) *AbiBasedRpc { + return &AbiBasedRpc{ + t: t, + abi: contractAbi, + addr: addr, + expectedArgs: make(map[string][]interface{}), + outputs: make(map[string][]interface{}), + } +} + +func (l *AbiBasedRpc) SetResponse(method string, expected []interface{}, output []interface{}) { + if expected == nil { + expected = []interface{}{} + } + if output == nil { + output = []interface{}{} + } + l.expectedArgs[method] = expected + l.outputs[method] = output +} + +func (l *AbiBasedRpc) BatchCallContext(_ context.Context, b []rpc.BatchElem) error { + panic("Not implemented") +} + +func (l *AbiBasedRpc) CallContext(_ context.Context, out interface{}, method string, args ...interface{}) error { + require.Equal(l.t, "eth_call", method) + require.Len(l.t, args, 2) + require.Equal(l.t, "latest", args[1]) + callOpts, ok := args[0].(map[string]any) + require.True(l.t, ok) + require.Equal(l.t, &l.addr, callOpts["to"]) + data, ok := callOpts["data"].(hexutil.Bytes) + require.True(l.t, ok) + abiMethod, err := l.abi.MethodById(data[0:4]) + require.NoError(l.t, err) + + args, err = abiMethod.Inputs.Unpack(data[4:]) + require.NoError(l.t, err) + require.Len(l.t, args, len(abiMethod.Inputs)) + expectedArgs, ok := l.expectedArgs[abiMethod.Name] + require.Truef(l.t, ok, "Unexpected call to %v", abiMethod.Name) + require.EqualValues(l.t, expectedArgs, args, "Unexpected args") + + outputs, ok := l.outputs[abiMethod.Name] + require.True(l.t, ok) + output, err := abiMethod.Outputs.Pack(outputs...) + require.NoError(l.t, err) + + // I admit I do not understand Go reflection. + // So leverage json.Unmarshal to set the out value correctly. + j, err := json.Marshal(hexutil.Bytes(output)) + require.NoError(l.t, err) + require.NoError(l.t, json.Unmarshal(j, out)) + return nil +} From b00a3d120b911321a2e18312350806d5b48370a8 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 23 Oct 2023 11:45:14 +1000 Subject: [PATCH 007/374] Add test for GetAllClaims --- .../fault/contracts/faultdisputegame_test.go | 58 ++++++++++++++++++- op-service/sources/batching/test/stubs.go | 56 +++++++++++++----- 2 files changed, 97 insertions(+), 17 deletions(-) diff --git a/op-challenger/game/fault/contracts/faultdisputegame_test.go b/op-challenger/game/fault/contracts/faultdisputegame_test.go index d9c8c7cbca79..107648e15c1b 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame_test.go +++ b/op-challenger/game/fault/contracts/faultdisputegame_test.go @@ -2,6 +2,7 @@ package contracts import ( "context" + "math" "math/big" "testing" @@ -99,13 +100,68 @@ func TestGetClaim(t *testing.T) { }, status) } +func TestGetAllClaims(t *testing.T) { + stubRpc, game := setup(t) + claim0 := faultTypes.Claim{ + ClaimData: faultTypes.ClaimData{ + Value: common.Hash{0xaa}, + Position: faultTypes.NewPositionFromGIndex(big.NewInt(1)), + }, + Countered: true, + Clock: 1234, + ContractIndex: 0, + ParentContractIndex: math.MaxUint32, + } + claim1 := faultTypes.Claim{ + ClaimData: faultTypes.ClaimData{ + Value: common.Hash{0xab}, + Position: faultTypes.NewPositionFromGIndex(big.NewInt(2)), + }, + Countered: true, + Clock: 4455, + ContractIndex: 1, + ParentContractIndex: 0, + } + claim2 := faultTypes.Claim{ + ClaimData: faultTypes.ClaimData{ + Value: common.Hash{0xbb}, + Position: faultTypes.NewPositionFromGIndex(big.NewInt(6)), + }, + Countered: false, + Clock: 7777, + ContractIndex: 2, + ParentContractIndex: 1, + } + expectedClaims := []faultTypes.Claim{claim0, claim1, claim2} + stubRpc.SetResponse(methodClaimCount, nil, []interface{}{big.NewInt(int64(len(expectedClaims)))}) + for _, claim := range expectedClaims { + expectGetClaim(stubRpc, claim) + } + claims, err := game.GetAllClaims(context.Background()) + require.NoError(t, err) + require.Equal(t, expectedClaims, claims) +} + +func expectGetClaim(stubRpc *test.AbiBasedRpc, claim faultTypes.Claim) { + stubRpc.SetResponse( + methodClaim, + []interface{}{big.NewInt(int64(claim.ContractIndex))}, + []interface{}{ + uint32(claim.ParentContractIndex), + claim.Countered, + claim.Value, + claim.Position.ToGIndex(), + big.NewInt(int64(claim.Clock)), + }) +} + func setup(t *testing.T) (*test.AbiBasedRpc, *FaultDisputeGameContract) { fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() require.NoError(t, err) address := common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB") stubRpc := test.NewAbiBasedRpc(t, fdgAbi, address) - caller := batching.NewMultiCaller(stubRpc, 100) + caller := batching.NewMultiCaller(stubRpc, 1) game, err := NewFaultDisputeGameContract(address, caller) require.NoError(t, err) return stubRpc, game diff --git a/op-service/sources/batching/test/stubs.go b/op-service/sources/batching/test/stubs.go index ec766df50b9c..d8a19f64f196 100644 --- a/op-service/sources/batching/test/stubs.go +++ b/op-service/sources/batching/test/stubs.go @@ -3,6 +3,7 @@ package test import ( "context" "encoding/json" + "fmt" "testing" "github.com/ethereum/go-ethereum/accounts/abi" @@ -10,24 +11,33 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rpc" "github.com/stretchr/testify/require" + "golang.org/x/exp/slices" ) +type expectedCall struct { + args []interface{} + packedArgs []byte + outputs []interface{} +} + +func (e *expectedCall) String() string { + return fmt.Sprintf("{args: %v, outputs: %v}", e.args, e.outputs) +} + type AbiBasedRpc struct { t *testing.T abi *abi.ABI addr common.Address - expectedArgs map[string][]interface{} - outputs map[string][]interface{} + expectedCalls map[string][]*expectedCall } func NewAbiBasedRpc(t *testing.T, contractAbi *abi.ABI, addr common.Address) *AbiBasedRpc { return &AbiBasedRpc{ - t: t, - abi: contractAbi, - addr: addr, - expectedArgs: make(map[string][]interface{}), - outputs: make(map[string][]interface{}), + t: t, + abi: contractAbi, + addr: addr, + expectedCalls: make(map[string][]*expectedCall), } } @@ -38,8 +48,15 @@ func (l *AbiBasedRpc) SetResponse(method string, expected []interface{}, output if output == nil { output = []interface{}{} } - l.expectedArgs[method] = expected - l.outputs[method] = output + abiMethod, ok := l.abi.Methods[method] + require.Truef(l.t, ok, "No method: %v", method) + packedArgs, err := abiMethod.Inputs.Pack(expected...) + require.NoErrorf(l.t, err, "Invalid expected arguments for method %v: %v", method, expected) + l.expectedCalls[method] = append(l.expectedCalls[method], &expectedCall{ + args: expected, + packedArgs: packedArgs, + outputs: output, + }) } func (l *AbiBasedRpc) BatchCallContext(_ context.Context, b []rpc.BatchElem) error { @@ -58,17 +75,24 @@ func (l *AbiBasedRpc) CallContext(_ context.Context, out interface{}, method str abiMethod, err := l.abi.MethodById(data[0:4]) require.NoError(l.t, err) - args, err = abiMethod.Inputs.Unpack(data[4:]) + argData := data[4:] + args, err = abiMethod.Inputs.Unpack(argData) require.NoError(l.t, err) require.Len(l.t, args, len(abiMethod.Inputs)) - expectedArgs, ok := l.expectedArgs[abiMethod.Name] + + expectedCalls, ok := l.expectedCalls[abiMethod.Name] require.Truef(l.t, ok, "Unexpected call to %v", abiMethod.Name) - require.EqualValues(l.t, expectedArgs, args, "Unexpected args") + var call *expectedCall + for _, candidate := range expectedCalls { + if slices.Equal(candidate.packedArgs, argData) { + call = candidate + break + } + } + require.NotNilf(l.t, call, "No expected calls to %v with arguments: %v\nExpected calls: %v", abiMethod.Name, args, expectedCalls) - outputs, ok := l.outputs[abiMethod.Name] - require.True(l.t, ok) - output, err := abiMethod.Outputs.Pack(outputs...) - require.NoError(l.t, err) + output, err := abiMethod.Outputs.Pack(call.outputs...) + require.NoErrorf(l.t, err, "Invalid outputs for method %v: %v", abiMethod.Name, call.outputs) // I admit I do not understand Go reflection. // So leverage json.Unmarshal to set the out value correctly. From 571b89fbd69f6ed864b4e72156c824f62d0b73b5 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 23 Oct 2023 11:49:12 +1000 Subject: [PATCH 008/374] Update stub to support batch calls. --- .../game/fault/contracts/faultdisputegame_test.go | 2 +- op-service/sources/batching/test/stubs.go | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/op-challenger/game/fault/contracts/faultdisputegame_test.go b/op-challenger/game/fault/contracts/faultdisputegame_test.go index 107648e15c1b..9e615986c87e 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame_test.go +++ b/op-challenger/game/fault/contracts/faultdisputegame_test.go @@ -161,7 +161,7 @@ func setup(t *testing.T) (*test.AbiBasedRpc, *FaultDisputeGameContract) { address := common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB") stubRpc := test.NewAbiBasedRpc(t, fdgAbi, address) - caller := batching.NewMultiCaller(stubRpc, 1) + caller := batching.NewMultiCaller(stubRpc, 100) game, err := NewFaultDisputeGameContract(address, caller) require.NoError(t, err) return stubRpc, game diff --git a/op-service/sources/batching/test/stubs.go b/op-service/sources/batching/test/stubs.go index d8a19f64f196..1be19f22932f 100644 --- a/op-service/sources/batching/test/stubs.go +++ b/op-service/sources/batching/test/stubs.go @@ -3,6 +3,7 @@ package test import ( "context" "encoding/json" + "errors" "fmt" "testing" @@ -59,8 +60,13 @@ func (l *AbiBasedRpc) SetResponse(method string, expected []interface{}, output }) } -func (l *AbiBasedRpc) BatchCallContext(_ context.Context, b []rpc.BatchElem) error { - panic("Not implemented") +func (l *AbiBasedRpc) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { + var errs []error + for _, elem := range b { + elem.Error = l.CallContext(ctx, elem.Result, elem.Method, elem.Args...) + errs = append(errs, elem.Error) + } + return errors.Join(errs...) } func (l *AbiBasedRpc) CallContext(_ context.Context, out interface{}, method string, args ...interface{}) error { From bb475da9d8d453599b67165619bb26bab2d1f8c2 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 23 Oct 2023 13:28:18 +1000 Subject: [PATCH 009/374] Use package alias --- .../game/fault/contracts/faultdisputegame_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/op-challenger/game/fault/contracts/faultdisputegame_test.go b/op-challenger/game/fault/contracts/faultdisputegame_test.go index 9e615986c87e..83c9647726b1 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame_test.go +++ b/op-challenger/game/fault/contracts/faultdisputegame_test.go @@ -10,7 +10,7 @@ import ( faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/sources/batching" - "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" + batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) @@ -142,7 +142,7 @@ func TestGetAllClaims(t *testing.T) { require.Equal(t, expectedClaims, claims) } -func expectGetClaim(stubRpc *test.AbiBasedRpc, claim faultTypes.Claim) { +func expectGetClaim(stubRpc *batchingTest.AbiBasedRpc, claim faultTypes.Claim) { stubRpc.SetResponse( methodClaim, []interface{}{big.NewInt(int64(claim.ContractIndex))}, @@ -155,12 +155,12 @@ func expectGetClaim(stubRpc *test.AbiBasedRpc, claim faultTypes.Claim) { }) } -func setup(t *testing.T) (*test.AbiBasedRpc, *FaultDisputeGameContract) { +func setup(t *testing.T) (*batchingTest.AbiBasedRpc, *FaultDisputeGameContract) { fdgAbi, err := bindings.FaultDisputeGameMetaData.GetAbi() require.NoError(t, err) address := common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB") - stubRpc := test.NewAbiBasedRpc(t, fdgAbi, address) + stubRpc := batchingTest.NewAbiBasedRpc(t, fdgAbi, address) caller := batching.NewMultiCaller(stubRpc, 100) game, err := NewFaultDisputeGameContract(address, caller) require.NoError(t, err) From 2375e5839f7762d7a8ff04f389b41a1f721816c8 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Mon, 18 Sep 2023 16:44:05 +0900 Subject: [PATCH 010/374] Implement span batch derivation --- .../batch_decoder/reassemble/reassemble.go | 8 +- op-node/rollup/derive/attributes_queue.go | 4 +- .../rollup/derive/attributes_queue_test.go | 6 +- op-node/rollup/derive/batch_queue.go | 137 +- op-node/rollup/derive/batch_queue_test.go | 647 +++++++++- op-node/rollup/derive/batches.go | 271 +++- op-node/rollup/derive/batches_test.go | 1119 ++++++++++++++++- op-node/rollup/derive/channel.go | 22 +- op-node/rollup/derive/channel_in_reader.go | 30 +- op-node/rollup/derive/engine_queue.go | 1 + op-node/rollup/derive/pipeline.go | 2 +- op-program/client/l2/engine.go | 8 + op-service/testutils/mock_l2.go | 18 +- 13 files changed, 2075 insertions(+), 198 deletions(-) diff --git a/op-node/cmd/batch_decoder/reassemble/reassemble.go b/op-node/cmd/batch_decoder/reassemble/reassemble.go index 18ebba79f15e..8472ba8c03ca 100644 --- a/op-node/cmd/batch_decoder/reassemble/reassemble.go +++ b/op-node/cmd/batch_decoder/reassemble/reassemble.go @@ -107,14 +107,18 @@ func processFrames(cfg *rollup.Config, id derive.ChannelID, frames []FrameWithMe var batches []derive.SingularBatch invalidBatches := false if ch.IsReady() { - br, err := derive.BatchReader(cfg, ch.Reader(), eth.L1BlockRef{}) + br, err := derive.BatchReader(ch.Reader()) if err == nil { for batch, err := br(); err != io.EOF; batch, err = br() { if err != nil { fmt.Printf("Error reading batch for channel %v. Err: %v\n", id.String(), err) invalidBatches = true } else { - batches = append(batches, batch.Batch.SingularBatch) + if batch.BatchType != derive.SingularBatchType { + batches = append(batches, batch.SingularBatch) + } else { + fmt.Printf("batch-type %d is not supported", batch.BatchType) + } } } } else { diff --git a/op-node/rollup/derive/attributes_queue.go b/op-node/rollup/derive/attributes_queue.go index 016c39d696b8..023fbb3dccda 100644 --- a/op-node/rollup/derive/attributes_queue.go +++ b/op-node/rollup/derive/attributes_queue.go @@ -32,7 +32,7 @@ type AttributesQueue struct { config *rollup.Config builder AttributesBuilder prev *BatchQueue - batch *BatchData + batch *SingularBatch } func NewAttributesQueue(log log.Logger, cfg *rollup.Config, builder AttributesBuilder, prev *BatchQueue) *AttributesQueue { @@ -71,7 +71,7 @@ func (aq *AttributesQueue) NextAttributes(ctx context.Context, l2SafeHead eth.L2 // createNextAttributes transforms a batch into a payload attributes. This sets `NoTxPool` and appends the batched transactions // to the attributes transaction list -func (aq *AttributesQueue) createNextAttributes(ctx context.Context, batch *BatchData, l2SafeHead eth.L2BlockRef) (*eth.PayloadAttributes, error) { +func (aq *AttributesQueue) createNextAttributes(ctx context.Context, batch *SingularBatch, l2SafeHead eth.L2BlockRef) (*eth.PayloadAttributes, error) { // sanity check parent hash if batch.ParentHash != l2SafeHead.Hash { return nil, NewResetError(fmt.Errorf("valid batch has bad parent hash %s, expected %s", batch.ParentHash, l2SafeHead.Hash)) diff --git a/op-node/rollup/derive/attributes_queue_test.go b/op-node/rollup/derive/attributes_queue_test.go index fef240c576bc..c5b2cde5eca6 100644 --- a/op-node/rollup/derive/attributes_queue_test.go +++ b/op-node/rollup/derive/attributes_queue_test.go @@ -42,13 +42,13 @@ func TestAttributesQueue(t *testing.T) { safeHead.L1Origin = l1Info.ID() safeHead.Time = l1Info.InfoTime - batch := NewSingularBatchData(SingularBatch{ + batch := SingularBatch{ ParentHash: safeHead.Hash, EpochNum: rollup.Epoch(l1Info.InfoNum), EpochHash: l1Info.InfoHash, Timestamp: safeHead.Time + cfg.BlockTime, Transactions: []eth.Data{eth.Data("foobar"), eth.Data("example")}, - }) + } parentL1Cfg := eth.SystemConfig{ BatcherAddr: common.Address{42}, @@ -80,7 +80,7 @@ func TestAttributesQueue(t *testing.T) { aq := NewAttributesQueue(testlog.Logger(t, log.LvlError), cfg, attrBuilder, nil) - actual, err := aq.createNextAttributes(context.Background(), batch, safeHead) + actual, err := aq.createNextAttributes(context.Background(), &batch, safeHead) require.NoError(t, err) require.Equal(t, attrs, *actual) diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index 5f57299879cb..30dd1441924b 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -29,7 +29,12 @@ import ( type NextBatchProvider interface { Origin() eth.L1BlockRef - NextBatch(ctx context.Context) (*BatchData, error) + NextBatch(ctx context.Context) (Batch, error) +} + +type SafeBlockFetcher interface { + L2BlockRefByNumber(context.Context, uint64) (eth.L2BlockRef, error) + PayloadByNumber(context.Context, uint64) (*eth.ExecutionPayload, error) } // BatchQueue contains a set of batches for every L1 block. @@ -42,16 +47,22 @@ type BatchQueue struct { l1Blocks []eth.L1BlockRef - // batches in order of when we've first seen them, grouped by L2 timestamp - batches map[uint64][]*BatchWithL1InclusionBlock + // batches in order of when we've first seen them + batches []*BatchWithL1InclusionBlock + + // nextSpan is cached SingularBatches derived from SpanBatch + nextSpan []*SingularBatch + + l2 SafeBlockFetcher } // NewBatchQueue creates a BatchQueue, which should be Reset(origin) before use. -func NewBatchQueue(log log.Logger, cfg *rollup.Config, prev NextBatchProvider) *BatchQueue { +func NewBatchQueue(log log.Logger, cfg *rollup.Config, prev NextBatchProvider, l2 SafeBlockFetcher) *BatchQueue { return &BatchQueue{ log: log, config: cfg, prev: prev, + l2: l2, } } @@ -59,7 +70,29 @@ func (bq *BatchQueue) Origin() eth.L1BlockRef { return bq.prev.Origin() } -func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) (*BatchData, error) { +func (bq *BatchQueue) popNextBatch(safeL2Head eth.L2BlockRef) *SingularBatch { + nextBatch := bq.nextSpan[0] + bq.nextSpan = bq.nextSpan[1:] + // Must set ParentHash before return. we can use safeL2Head because the parentCheck is verified in CheckBatch(). + nextBatch.ParentHash = safeL2Head.Hash + return nextBatch +} + +func (bq *BatchQueue) advanceEpoch(nextBatch *SingularBatch) { + if nextBatch.GetEpochNum() == rollup.Epoch(bq.l1Blocks[0].Number)+1 { + // Advance epoch if necessary + bq.l1Blocks = bq.l1Blocks[1:] + } +} + +func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) (*SingularBatch, error) { + if len(bq.nextSpan) > 0 { + // If there are cached singular batches, pop first one and return. + nextBatch := bq.popNextBatch(safeL2Head) + bq.advanceEpoch(nextBatch) + return nextBatch, nil + } + // Note: We use the origin that we will have to determine if it's behind. This is important // because it's the future origin that gets saved into the l1Blocks array. // We always update the origin of this stage if it is not the same so after the update code @@ -89,7 +122,7 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) } else if err != nil { return nil, err } else if !originBehind { - bq.AddBatch(batch, safeL2Head) + bq.AddBatch(ctx, batch, safeL2Head) } // Skip adding data unless we are up to date with the origin, but do fully @@ -111,43 +144,70 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) } else if err != nil { return nil, err } - return batch, nil + + var nextBatch *SingularBatch + switch batch.GetBatchType() { + case SingularBatchType: + singularBatch, ok := batch.(*SingularBatch) + if !ok { + return nil, NewCriticalError(errors.New("failed type assertion to SingularBatch")) + } + nextBatch = singularBatch + case SpanBatchType: + spanBatch, ok := batch.(*SpanBatch) + if !ok { + return nil, NewCriticalError(errors.New("failed type assertion to SpanBatch")) + } + // If next batch is SpanBatch, convert it to SingularBatches. + singularBatches, err := spanBatch.GetSingularBatches(bq.l1Blocks, safeL2Head) + if err != nil { + return nil, NewCriticalError(err) + } + bq.nextSpan = singularBatches + nextBatch = bq.popNextBatch(safeL2Head) + default: + return nil, NewCriticalError(fmt.Errorf("unrecognized batch type: %d", batch.GetBatchType())) + } + + bq.advanceEpoch(nextBatch) + return nextBatch, nil } func (bq *BatchQueue) Reset(ctx context.Context, base eth.L1BlockRef, _ eth.SystemConfig) error { // Copy over the Origin from the next stage // It is set in the engine queue (two stages away) such that the L2 Safe Head origin is the progress bq.origin = base - bq.batches = make(map[uint64][]*BatchWithL1InclusionBlock) + bq.batches = []*BatchWithL1InclusionBlock{} // Include the new origin as an origin to build on // Note: This is only for the initialization case. During normal resets we will later // throw out this block. bq.l1Blocks = bq.l1Blocks[:0] bq.l1Blocks = append(bq.l1Blocks, base) + bq.nextSpan = bq.nextSpan[:0] return io.EOF } -func (bq *BatchQueue) AddBatch(batch *BatchData, l2SafeHead eth.L2BlockRef) { +func (bq *BatchQueue) AddBatch(ctx context.Context, batch Batch, l2SafeHead eth.L2BlockRef) { if len(bq.l1Blocks) == 0 { - panic(fmt.Errorf("cannot add batch with timestamp %d, no origin was prepared", batch.Timestamp)) + panic(fmt.Errorf("cannot add batch with timestamp %d, no origin was prepared", batch.GetTimestamp())) } data := BatchWithL1InclusionBlock{ L1InclusionBlock: bq.origin, Batch: batch, } - validity := CheckBatch(bq.config, bq.log, bq.l1Blocks, l2SafeHead, &data) + validity := CheckBatch(ctx, bq.config, bq.log, bq.l1Blocks, l2SafeHead, &data, bq.l2) if validity == BatchDrop { return // if we do drop the batch, CheckBatch will log the drop reason with WARN level. } - bq.log.Debug("Adding batch", "batch_timestamp", batch.Timestamp, "parent_hash", batch.ParentHash, "batch_epoch", batch.Epoch(), "txs", len(batch.Transactions)) - bq.batches[batch.Timestamp] = append(bq.batches[batch.Timestamp], &data) + batch.LogContext(bq.log).Debug("Adding batch") + bq.batches = append(bq.batches, &data) } // deriveNextBatch derives the next batch to apply on top of the current L2 safe head, // following the validity rules imposed on consecutive batches, // based on currently available buffered batch and L1 origin information. // If no batch can be derived yet, then (nil, io.EOF) is returned. -func (bq *BatchQueue) deriveNextBatch(ctx context.Context, outOfData bool, l2SafeHead eth.L2BlockRef) (*BatchData, error) { +func (bq *BatchQueue) deriveNextBatch(ctx context.Context, outOfData bool, l2SafeHead eth.L2BlockRef) (Batch, error) { if len(bq.l1Blocks) == 0 { return nil, NewCriticalError(errors.New("cannot derive next batch, no origin was prepared")) } @@ -170,19 +230,15 @@ func (bq *BatchQueue) deriveNextBatch(ctx context.Context, outOfData bool, l2Saf // Go over all batches, in order of inclusion, and find the first batch we can accept. // We filter in-place by only remembering the batches that may be processed in the future, or those we are undecided on. var remaining []*BatchWithL1InclusionBlock - candidates := bq.batches[nextTimestamp] batchLoop: - for i, batch := range candidates { - validity := CheckBatch(bq.config, bq.log.New("batch_index", i), bq.l1Blocks, l2SafeHead, batch) + for i, batch := range bq.batches { + validity := CheckBatch(ctx, bq.config, bq.log.New("batch_index", i), bq.l1Blocks, l2SafeHead, batch, bq.l2) switch validity { case BatchFuture: - return nil, NewCriticalError(fmt.Errorf("found batch with timestamp %d marked as future batch, but expected timestamp %d", batch.Batch.Timestamp, nextTimestamp)) + remaining = append(remaining, batch) + continue case BatchDrop: - bq.log.Warn("dropping batch", - "batch_timestamp", batch.Batch.Timestamp, - "parent_hash", batch.Batch.ParentHash, - "batch_epoch", batch.Batch.Epoch(), - "txs", len(batch.Batch.Transactions), + batch.Batch.LogContext(bq.log).Warn("dropping batch", "l2_safe_head", l2SafeHead.ID(), "l2_safe_head_time", l2SafeHead.Time, ) @@ -191,29 +247,20 @@ batchLoop: nextBatch = batch // don't keep the current batch in the remaining items since we are processing it now, // but retain every batch we didn't get to yet. - remaining = append(remaining, candidates[i+1:]...) + remaining = append(remaining, bq.batches[i+1:]...) break batchLoop case BatchUndecided: - remaining = append(remaining, batch) - bq.batches[nextTimestamp] = remaining + remaining = append(remaining, bq.batches[i:]...) + bq.batches = remaining return nil, io.EOF default: return nil, NewCriticalError(fmt.Errorf("unknown batch validity type: %d", validity)) } } - // clean up if we remove the final batch for this timestamp - if len(remaining) == 0 { - delete(bq.batches, nextTimestamp) - } else { - bq.batches[nextTimestamp] = remaining - } + bq.batches = remaining if nextBatch != nil { - // advance epoch if necessary - if nextBatch.Batch.EpochNum == rollup.Epoch(epoch.Number)+1 { - bq.l1Blocks = bq.l1Blocks[1:] - } - bq.log.Info("Found next batch", "epoch", epoch, "batch_epoch", nextBatch.Batch.EpochNum, "batch_timestamp", nextBatch.Batch.Timestamp) + nextBatch.Batch.LogContext(bq.log).Info("Found next batch") return nextBatch.Batch, nil } @@ -243,15 +290,13 @@ batchLoop: // batch to ensure that we at least have one batch per epoch. if nextTimestamp < nextEpoch.Time || firstOfEpoch { bq.log.Info("Generating next batch", "epoch", epoch, "timestamp", nextTimestamp) - return NewSingularBatchData( - SingularBatch{ - ParentHash: l2SafeHead.Hash, - EpochNum: rollup.Epoch(epoch.Number), - EpochHash: epoch.Hash, - Timestamp: nextTimestamp, - Transactions: nil, - }, - ), nil + return &SingularBatch{ + ParentHash: l2SafeHead.Hash, + EpochNum: rollup.Epoch(epoch.Number), + EpochHash: epoch.Hash, + Timestamp: nextTimestamp, + Transactions: nil, + }, nil } // At this point we have auto generated every batch for the current epoch diff --git a/op-node/rollup/derive/batch_queue_test.go b/op-node/rollup/derive/batch_queue_test.go index 8bad5f22a6a6..dee33b866177 100644 --- a/op-node/rollup/derive/batch_queue_test.go +++ b/op-node/rollup/derive/batch_queue_test.go @@ -3,10 +3,14 @@ package derive import ( "context" "encoding/binary" + "errors" "io" + "math/big" "math/rand" "testing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" @@ -20,7 +24,7 @@ import ( type fakeBatchQueueInput struct { i int - batches []*BatchData + batches []Batch errors []error origin eth.L1BlockRef } @@ -29,7 +33,7 @@ func (f *fakeBatchQueueInput) Origin() eth.L1BlockRef { return f.origin } -func (f *fakeBatchQueueInput) NextBatch(ctx context.Context) (*BatchData, error) { +func (f *fakeBatchQueueInput) NextBatch(ctx context.Context) (Batch, error) { if f.i >= len(f.batches) { return nil, io.EOF } @@ -45,16 +49,74 @@ func mockHash(time uint64, layer uint8) common.Hash { return hash } -func b(timestamp uint64, epoch eth.L1BlockRef) *BatchData { +func b(chainId *big.Int, timestamp uint64, epoch eth.L1BlockRef) *SingularBatch { rng := rand.New(rand.NewSource(int64(timestamp))) - data := testutils.RandomData(rng, 20) - return NewSingularBatchData(SingularBatch{ + signer := types.NewLondonSigner(chainId) + tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) + txData, _ := tx.MarshalBinary() + return &SingularBatch{ ParentHash: mockHash(timestamp-2, 2), Timestamp: timestamp, EpochNum: rollup.Epoch(epoch.Number), EpochHash: epoch.Hash, - Transactions: []hexutil.Bytes{data}, - }) + Transactions: []hexutil.Bytes{txData}, + } +} + +func buildSpanBatches(t *testing.T, parent *eth.L2BlockRef, singularBatches []*SingularBatch, blockCounts []int, chainId *big.Int) []Batch { + var spanBatches []Batch + idx := 0 + for _, count := range blockCounts { + span := NewSpanBatch(singularBatches[idx : idx+count]) + spanBatches = append(spanBatches, span) + idx += count + } + return spanBatches +} + +func getSpanBatchTime(batchType int) *uint64 { + minTs := uint64(0) + if batchType == SpanBatchType { + return &minTs + } + return nil +} + +func l1InfoDepositTx(t *testing.T, l1BlockNum uint64) hexutil.Bytes { + l1Info := L1BlockInfo{ + Number: l1BlockNum, + BaseFee: big.NewInt(0), + } + infoData, err := l1Info.MarshalBinary() + require.NoError(t, err) + depositTx := &types.DepositTx{ + Data: infoData, + } + txData, err := types.NewTx(depositTx).MarshalBinary() + require.NoError(t, err) + return txData +} + +func singularBatchToPayload(t *testing.T, batch *SingularBatch, blockNumber uint64) eth.ExecutionPayload { + txs := []hexutil.Bytes{l1InfoDepositTx(t, uint64(batch.EpochNum))} + txs = append(txs, batch.Transactions...) + return eth.ExecutionPayload{ + BlockHash: mockHash(batch.Timestamp, 2), + ParentHash: batch.ParentHash, + BlockNumber: hexutil.Uint64(blockNumber), + Timestamp: hexutil.Uint64(batch.Timestamp), + Transactions: txs, + } +} + +func singularBatchToBlockRef(t *testing.T, batch *SingularBatch, blockNumber uint64) eth.L2BlockRef { + return eth.L2BlockRef{ + Hash: mockHash(batch.Timestamp, 2), + Number: blockNumber, + ParentHash: batch.ParentHash, + Time: batch.Timestamp, + L1Origin: eth.BlockID{Hash: batch.EpochHash, Number: uint64(batch.EpochNum)}, + } } func L1Chain(l1Times []uint64) []eth.L1BlockRef { @@ -73,10 +135,37 @@ func L1Chain(l1Times []uint64) []eth.L1BlockRef { return out } -// TestBatchQueueNewOrigin tests that the batch queue properly saves the new origin +func TestBatchQueue(t *testing.T) { + tests := []struct { + name string + f func(t *testing.T, batchType int) + }{ + {"BatchQueueNewOrigin", BatchQueueNewOrigin}, + {"BatchQueueEager", BatchQueueEager}, + {"BatchQueueInvalidInternalAdvance", BatchQueueInvalidInternalAdvance}, + {"BatchQueueMissing", BatchQueueMissing}, + {"BatchQueueAdvancedEpoch", BatchQueueAdvancedEpoch}, + {"BatchQueueShuffle", BatchQueueShuffle}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, SingularBatchType) + }) + } + + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, SpanBatchType) + }) + } +} + +// BatchQueueNewOrigin tests that the batch queue properly saves the new origin // when the safehead's origin is ahead of the pipeline's origin (as is after a reset). // This issue was fixed in https://github.com/ethereum-optimism/optimism/pull/3694 -func TestBatchQueueNewOrigin(t *testing.T) { +func BatchQueueNewOrigin(t *testing.T, batchType int) { log := testlog.Logger(t, log.LvlCrit) l1 := L1Chain([]uint64{10, 15, 20, 25}) safeHead := eth.L2BlockRef{ @@ -94,15 +183,16 @@ func TestBatchQueueNewOrigin(t *testing.T) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 2, + SpanBatchTime: getSpanBatchTime(batchType), } input := &fakeBatchQueueInput{ - batches: []*BatchData{nil}, + batches: []Batch{nil}, errors: []error{io.EOF}, origin: l1[0], } - bq := NewBatchQueue(log, cfg, input) + bq := NewBatchQueue(log, cfg, input, nil) _ = bq.Reset(context.Background(), l1[0], eth.SystemConfig{}) require.Equal(t, []eth.L1BlockRef{l1[0]}, bq.l1Blocks) @@ -133,11 +223,12 @@ func TestBatchQueueNewOrigin(t *testing.T) { require.Equal(t, l1[2], bq.origin) } -// TestBatchQueueEager adds a bunch of contiguous batches and asserts that +// BatchQueueEager adds a bunch of contiguous batches and asserts that // enough calls to `NextBatch` return all of those batches. -func TestBatchQueueEager(t *testing.T) { +func BatchQueueEager(t *testing.T, batchType int) { log := testlog.Logger(t, log.LvlCrit) l1 := L1Chain([]uint64{10, 20, 30}) + chainId := big.NewInt(1234) safeHead := eth.L2BlockRef{ Hash: mockHash(10, 2), Number: 0, @@ -153,41 +244,69 @@ func TestBatchQueueEager(t *testing.T) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 30, + SpanBatchTime: getSpanBatchTime(batchType), + L2ChainID: chainId, } - batches := []*BatchData{b(12, l1[0]), b(14, l1[0]), b(16, l1[0]), b(18, l1[0]), b(20, l1[0]), b(22, l1[0]), b(24, l1[1]), nil} - errors := []error{nil, nil, nil, nil, nil, nil, nil, io.EOF} + // expected output of BatchQueue.NextBatch() + expectedOutputBatches := []*SingularBatch{ + b(cfg.L2ChainID, 12, l1[0]), + b(cfg.L2ChainID, 14, l1[0]), + b(cfg.L2ChainID, 16, l1[0]), + b(cfg.L2ChainID, 18, l1[0]), + b(cfg.L2ChainID, 20, l1[0]), + b(cfg.L2ChainID, 22, l1[0]), + nil, + } + // expected error of BatchQueue.NextBatch() + expectedOutputErrors := []error{nil, nil, nil, nil, nil, nil, io.EOF} + // errors will be returned by fakeBatchQueueInput.NextBatch() + inputErrors := expectedOutputErrors + // batches will be returned by fakeBatchQueueInput + var inputBatches []Batch + if batchType == SpanBatchType { + spanBlockCounts := []int{1, 2, 3} + inputErrors = []error{nil, nil, nil, io.EOF} + inputBatches = buildSpanBatches(t, &safeHead, expectedOutputBatches, spanBlockCounts, chainId) + inputBatches = append(inputBatches, nil) + } else { + for _, singularBatch := range expectedOutputBatches { + inputBatches = append(inputBatches, singularBatch) + } + } input := &fakeBatchQueueInput{ - batches: batches, - errors: errors, + batches: inputBatches, + errors: inputErrors, origin: l1[0], } - bq := NewBatchQueue(log, cfg, input) + bq := NewBatchQueue(log, cfg, input, nil) _ = bq.Reset(context.Background(), l1[0], eth.SystemConfig{}) // Advance the origin input.origin = l1[1] - for i := 0; i < len(batches); i++ { + for i := 0; i < len(expectedOutputBatches); i++ { b, e := bq.NextBatch(context.Background(), safeHead) - require.ErrorIs(t, e, errors[i]) - require.Equal(t, batches[i], b) - - if b != nil { + require.ErrorIs(t, e, expectedOutputErrors[i]) + if b == nil { + require.Nil(t, expectedOutputBatches[i]) + } else { + require.Equal(t, expectedOutputBatches[i], b) safeHead.Number += 1 - safeHead.Time += 2 + safeHead.Time += cfg.BlockTime safeHead.Hash = mockHash(b.Timestamp, 2) safeHead.L1Origin = b.Epoch() } } } -// TestBatchQueueInvalidInternalAdvance asserts that we do not miss an epoch when generating batches. +// BatchQueueInvalidInternalAdvance asserts that we do not miss an epoch when generating batches. // This is a regression test for CLI-3378. -func TestBatchQueueInvalidInternalAdvance(t *testing.T) { +func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { log := testlog.Logger(t, log.LvlTrace) l1 := L1Chain([]uint64{10, 15, 20, 25, 30}) + chainId := big.NewInt(1234) safeHead := eth.L2BlockRef{ Hash: mockHash(10, 2), Number: 0, @@ -203,27 +322,54 @@ func TestBatchQueueInvalidInternalAdvance(t *testing.T) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 2, + SpanBatchTime: getSpanBatchTime(batchType), + L2ChainID: chainId, } - batches := []*BatchData{b(12, l1[0]), b(14, l1[0]), b(16, l1[0]), b(18, l1[0]), b(20, l1[0]), b(22, l1[0]), nil} - errors := []error{nil, nil, nil, nil, nil, nil, io.EOF} + // expected output of BatchQueue.NextBatch() + expectedOutputBatches := []*SingularBatch{ + b(cfg.L2ChainID, 12, l1[0]), + b(cfg.L2ChainID, 14, l1[0]), + b(cfg.L2ChainID, 16, l1[0]), + b(cfg.L2ChainID, 18, l1[0]), + b(cfg.L2ChainID, 20, l1[0]), + b(cfg.L2ChainID, 22, l1[0]), + nil, + } + // expected error of BatchQueue.NextBatch() + expectedOutputErrors := []error{nil, nil, nil, nil, nil, nil, io.EOF} + // errors will be returned by fakeBatchQueueInput.NextBatch() + inputErrors := expectedOutputErrors + // batches will be returned by fakeBatchQueueInput + var inputBatches []Batch + if batchType == SpanBatchType { + spanBlockCounts := []int{1, 2, 3} + inputErrors = []error{nil, nil, nil, io.EOF} + inputBatches = buildSpanBatches(t, &safeHead, expectedOutputBatches, spanBlockCounts, chainId) + inputBatches = append(inputBatches, nil) + } else { + for _, singularBatch := range expectedOutputBatches { + inputBatches = append(inputBatches, singularBatch) + } + } input := &fakeBatchQueueInput{ - batches: batches, - errors: errors, + batches: inputBatches, + errors: inputErrors, origin: l1[0], } - bq := NewBatchQueue(log, cfg, input) + bq := NewBatchQueue(log, cfg, input, nil) _ = bq.Reset(context.Background(), l1[0], eth.SystemConfig{}) // Load continuous batches for epoch 0 - for i := 0; i < len(batches); i++ { + for i := 0; i < len(expectedOutputBatches); i++ { b, e := bq.NextBatch(context.Background(), safeHead) - require.ErrorIs(t, e, errors[i]) - require.Equal(t, batches[i], b) - - if b != nil { + require.ErrorIs(t, e, expectedOutputErrors[i]) + if b == nil { + require.Nil(t, expectedOutputBatches[i]) + } else { + require.Equal(t, expectedOutputBatches[i], b) safeHead.Number += 1 safeHead.Time += 2 safeHead.Hash = mockHash(b.Timestamp, 2) @@ -276,9 +422,10 @@ func TestBatchQueueInvalidInternalAdvance(t *testing.T) { } -func TestBatchQueueMissing(t *testing.T) { +func BatchQueueMissing(t *testing.T, batchType int) { log := testlog.Logger(t, log.LvlCrit) l1 := L1Chain([]uint64{10, 15, 20, 25}) + chainId := big.NewInt(1234) safeHead := eth.L2BlockRef{ Hash: mockHash(10, 2), Number: 0, @@ -294,30 +441,49 @@ func TestBatchQueueMissing(t *testing.T) { BlockTime: 2, MaxSequencerDrift: 600, SeqWindowSize: 2, + SpanBatchTime: getSpanBatchTime(batchType), + L2ChainID: chainId, } - // The batches at 18 and 20 are skipped to stop 22 from being eagerly processed. + // The inputBatches at 18 and 20 are skipped to stop 22 from being eagerly processed. // This test checks that batch timestamp 12 & 14 are created, 16 is used, and 18 is advancing the epoch. - // Due to the large sequencer time drift 16 is perfectly valid to have epoch 0 as origin. - batches := []*BatchData{b(16, l1[0]), b(22, l1[1])} - errors := []error{nil, nil} + // Due to the large sequencer time drift 16 is perfectly valid to have epoch 0 as origin.a + + // expected output of BatchQueue.NextBatch() + expectedOutputBatches := []*SingularBatch{ + b(cfg.L2ChainID, 16, l1[0]), + b(cfg.L2ChainID, 22, l1[1]), + } + // errors will be returned by fakeBatchQueueInput.NextBatch() + inputErrors := []error{nil, nil} + // batches will be returned by fakeBatchQueueInput + var inputBatches []Batch + if batchType == SpanBatchType { + spanBlockCounts := []int{1, 1} + inputErrors = []error{nil, nil, nil, io.EOF} + inputBatches = buildSpanBatches(t, &safeHead, expectedOutputBatches, spanBlockCounts, chainId) + } else { + for _, singularBatch := range expectedOutputBatches { + inputBatches = append(inputBatches, singularBatch) + } + } input := &fakeBatchQueueInput{ - batches: batches, - errors: errors, + batches: inputBatches, + errors: inputErrors, origin: l1[0], } - bq := NewBatchQueue(log, cfg, input) + bq := NewBatchQueue(log, cfg, input, nil) _ = bq.Reset(context.Background(), l1[0], eth.SystemConfig{}) - for i := 0; i < len(batches); i++ { + for i := 0; i < len(expectedOutputBatches); i++ { b, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, NotEnoughData) require.Nil(t, b) } - // advance origin. Underlying stage still has no more batches + // advance origin. Underlying stage still has no more inputBatches // This is not enough to auto advance yet input.origin = l1[1] b, e := bq.NextBatch(context.Background(), safeHead) @@ -331,7 +497,7 @@ func TestBatchQueueMissing(t *testing.T) { b, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b.Timestamp, uint64(12)) - require.Empty(t, b.SingularBatch.Transactions) + require.Empty(t, b.Transactions) require.Equal(t, rollup.Epoch(0), b.EpochNum) safeHead.Number += 1 safeHead.Time += 2 @@ -341,7 +507,7 @@ func TestBatchQueueMissing(t *testing.T) { b, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b.Timestamp, uint64(14)) - require.Empty(t, b.SingularBatch.Transactions) + require.Empty(t, b.Transactions) require.Equal(t, rollup.Epoch(0), b.EpochNum) safeHead.Number += 1 safeHead.Time += 2 @@ -350,7 +516,7 @@ func TestBatchQueueMissing(t *testing.T) { // Check for the inputted batch at t = 16 b, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) - require.Equal(t, b, batches[0]) + require.Equal(t, b, expectedOutputBatches[0]) require.Equal(t, rollup.Epoch(0), b.EpochNum) safeHead.Number += 1 safeHead.Time += 2 @@ -367,6 +533,387 @@ func TestBatchQueueMissing(t *testing.T) { b, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b.Timestamp, uint64(18)) - require.Empty(t, b.SingularBatch.Transactions) + require.Empty(t, b.Transactions) require.Equal(t, rollup.Epoch(1), b.EpochNum) } + +// BatchQueueAdvancedEpoch tests that batch queue derives consecutive valid batches with advancing epochs. +// Batch queue's l1blocks list should be updated along epochs. +func BatchQueueAdvancedEpoch(t *testing.T, batchType int) { + log := testlog.Logger(t, log.LvlCrit) + l1 := L1Chain([]uint64{0, 6, 12, 18, 24}) // L1 block time: 6s + chainId := big.NewInt(1234) + safeHead := eth.L2BlockRef{ + Hash: mockHash(4, 2), + Number: 0, + ParentHash: common.Hash{}, + Time: 4, + L1Origin: l1[0].ID(), + SequenceNumber: 0, + } + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L2Time: 10, + }, + BlockTime: 2, + MaxSequencerDrift: 600, + SeqWindowSize: 30, + SpanBatchTime: getSpanBatchTime(batchType), + L2ChainID: chainId, + } + + // expected output of BatchQueue.NextBatch() + expectedOutputBatches := []*SingularBatch{ + // 3 L2 blocks per L1 block + b(cfg.L2ChainID, 6, l1[1]), + b(cfg.L2ChainID, 8, l1[1]), + b(cfg.L2ChainID, 10, l1[1]), + b(cfg.L2ChainID, 12, l1[2]), + b(cfg.L2ChainID, 14, l1[2]), + b(cfg.L2ChainID, 16, l1[2]), + b(cfg.L2ChainID, 18, l1[3]), + b(cfg.L2ChainID, 20, l1[3]), + b(cfg.L2ChainID, 22, l1[3]), + nil, + } + // expected error of BatchQueue.NextBatch() + expectedOutputErrors := []error{nil, nil, nil, nil, nil, nil, nil, nil, nil, io.EOF} + // errors will be returned by fakeBatchQueueInput.NextBatch() + inputErrors := expectedOutputErrors + // batches will be returned by fakeBatchQueueInput + var inputBatches []Batch + if batchType == SpanBatchType { + spanBlockCounts := []int{2, 2, 2, 3} + inputErrors = []error{nil, nil, nil, nil, io.EOF} + inputBatches = buildSpanBatches(t, &safeHead, expectedOutputBatches, spanBlockCounts, chainId) + inputBatches = append(inputBatches, nil) + } else { + for _, singularBatch := range expectedOutputBatches { + inputBatches = append(inputBatches, singularBatch) + } + } + + // ChannelInReader origin number + inputOriginNumber := 2 + input := &fakeBatchQueueInput{ + batches: inputBatches, + errors: inputErrors, + origin: l1[inputOriginNumber], + } + + bq := NewBatchQueue(log, cfg, input, nil) + _ = bq.Reset(context.Background(), l1[1], eth.SystemConfig{}) + + for i := 0; i < len(expectedOutputBatches); i++ { + expectedOutput := expectedOutputBatches[i] + if expectedOutput != nil && uint64(expectedOutput.EpochNum) == l1[inputOriginNumber].Number { + // Advance ChannelInReader origin if needed + inputOriginNumber += 1 + input.origin = l1[inputOriginNumber] + } + b, e := bq.NextBatch(context.Background(), safeHead) + require.ErrorIs(t, e, expectedOutputErrors[i]) + if b == nil { + require.Nil(t, expectedOutput) + } else { + require.Equal(t, expectedOutput, b) + require.Equal(t, bq.l1Blocks[0].Number, uint64(b.EpochNum)) + safeHead.Number += 1 + safeHead.Time += cfg.BlockTime + safeHead.Hash = mockHash(b.Timestamp, 2) + safeHead.L1Origin = b.Epoch() + } + } +} + +// BatchQueueShuffle tests batch queue can reorder shuffled valid batches +func BatchQueueShuffle(t *testing.T, batchType int) { + log := testlog.Logger(t, log.LvlCrit) + l1 := L1Chain([]uint64{0, 6, 12, 18, 24}) // L1 block time: 6s + chainId := big.NewInt(1234) + safeHead := eth.L2BlockRef{ + Hash: mockHash(4, 2), + Number: 0, + ParentHash: common.Hash{}, + Time: 4, + L1Origin: l1[0].ID(), + SequenceNumber: 0, + } + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L2Time: 10, + }, + BlockTime: 2, + MaxSequencerDrift: 600, + SeqWindowSize: 30, + SpanBatchTime: getSpanBatchTime(batchType), + L2ChainID: chainId, + } + + // expected output of BatchQueue.NextBatch() + expectedOutputBatches := []*SingularBatch{ + // 3 L2 blocks per L1 block + b(cfg.L2ChainID, 6, l1[1]), + b(cfg.L2ChainID, 8, l1[1]), + b(cfg.L2ChainID, 10, l1[1]), + b(cfg.L2ChainID, 12, l1[2]), + b(cfg.L2ChainID, 14, l1[2]), + b(cfg.L2ChainID, 16, l1[2]), + b(cfg.L2ChainID, 18, l1[3]), + b(cfg.L2ChainID, 20, l1[3]), + b(cfg.L2ChainID, 22, l1[3]), + } + // expected error of BatchQueue.NextBatch() + expectedOutputErrors := []error{nil, nil, nil, nil, nil, nil, nil, nil, nil, io.EOF} + // errors will be returned by fakeBatchQueueInput.NextBatch() + inputErrors := expectedOutputErrors + // batches will be returned by fakeBatchQueueInput + var inputBatches []Batch + if batchType == SpanBatchType { + spanBlockCounts := []int{2, 2, 2, 3} + inputErrors = []error{nil, nil, nil, nil, io.EOF} + inputBatches = buildSpanBatches(t, &safeHead, expectedOutputBatches, spanBlockCounts, chainId) + } else { + for _, singularBatch := range expectedOutputBatches { + inputBatches = append(inputBatches, singularBatch) + } + } + + // Shuffle the order of input batches + rand.Shuffle(len(inputBatches), func(i, j int) { + inputBatches[i], inputBatches[j] = inputBatches[j], inputBatches[i] + }) + inputBatches = append(inputBatches, nil) + + // ChannelInReader origin number + inputOriginNumber := 2 + input := &fakeBatchQueueInput{ + batches: inputBatches, + errors: inputErrors, + origin: l1[inputOriginNumber], + } + + bq := NewBatchQueue(log, cfg, input, nil) + _ = bq.Reset(context.Background(), l1[1], eth.SystemConfig{}) + + for i := 0; i < len(expectedOutputBatches); i++ { + expectedOutput := expectedOutputBatches[i] + if expectedOutput != nil && uint64(expectedOutput.EpochNum) == l1[inputOriginNumber].Number { + // Advance ChannelInReader origin if needed + inputOriginNumber += 1 + input.origin = l1[inputOriginNumber] + } + var b *SingularBatch + var e error + for j := 0; j < len(expectedOutputBatches); j++ { + // Multiple NextBatch() executions may be required because the order of input is shuffled + b, e = bq.NextBatch(context.Background(), safeHead) + if !errors.Is(e, NotEnoughData) { + break + } + } + require.ErrorIs(t, e, expectedOutputErrors[i]) + if b == nil { + require.Nil(t, expectedOutput) + } else { + require.Equal(t, expectedOutput, b) + require.Equal(t, bq.l1Blocks[0].Number, uint64(b.EpochNum)) + safeHead.Number += 1 + safeHead.Time += cfg.BlockTime + safeHead.Hash = mockHash(b.Timestamp, 2) + safeHead.L1Origin = b.Epoch() + } + } +} + +func TestBatchQueueOverlappingSpanBatch(t *testing.T) { + log := testlog.Logger(t, log.LvlCrit) + l1 := L1Chain([]uint64{10, 20, 30}) + chainId := big.NewInt(1234) + safeHead := eth.L2BlockRef{ + Hash: mockHash(10, 2), + Number: 0, + ParentHash: common.Hash{}, + Time: 10, + L1Origin: l1[0].ID(), + SequenceNumber: 0, + } + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L2Time: 10, + }, + BlockTime: 2, + MaxSequencerDrift: 600, + SeqWindowSize: 30, + SpanBatchTime: getSpanBatchTime(SpanBatchType), + L2ChainID: chainId, + } + + // expected output of BatchQueue.NextBatch() + expectedOutputBatches := []*SingularBatch{ + b(cfg.L2ChainID, 12, l1[0]), + b(cfg.L2ChainID, 14, l1[0]), + b(cfg.L2ChainID, 16, l1[0]), + b(cfg.L2ChainID, 18, l1[0]), + b(cfg.L2ChainID, 20, l1[0]), + b(cfg.L2ChainID, 22, l1[0]), + nil, + } + // expected error of BatchQueue.NextBatch() + expectedOutputErrors := []error{nil, nil, nil, nil, nil, nil, io.EOF} + // errors will be returned by fakeBatchQueueInput.NextBatch() + inputErrors := []error{nil, nil, nil, nil, io.EOF} + + // batches will be returned by fakeBatchQueueInput + var inputBatches []Batch + batchSize := 3 + for i := 0; i < len(expectedOutputBatches)-batchSize; i++ { + inputBatches = append(inputBatches, NewSpanBatch(expectedOutputBatches[i:i+batchSize])) + } + inputBatches = append(inputBatches, nil) + + input := &fakeBatchQueueInput{ + batches: inputBatches, + errors: inputErrors, + origin: l1[0], + } + + l2Client := testutils.MockL2Client{} + var nilErr error + for i, batch := range expectedOutputBatches { + if batch != nil { + blockRef := singularBatchToBlockRef(t, batch, uint64(i+1)) + payload := singularBatchToPayload(t, batch, uint64(i+1)) + l2Client.Mock.On("L2BlockRefByNumber", uint64(i+1)).Times(9999).Return(blockRef, &nilErr) + l2Client.Mock.On("PayloadByNumber", uint64(i+1)).Times(9999).Return(&payload, &nilErr) + } + } + + bq := NewBatchQueue(log, cfg, input, &l2Client) + _ = bq.Reset(context.Background(), l1[0], eth.SystemConfig{}) + // Advance the origin + input.origin = l1[1] + + for i := 0; i < len(expectedOutputBatches); i++ { + b, e := bq.NextBatch(context.Background(), safeHead) + require.ErrorIs(t, e, expectedOutputErrors[i]) + if b == nil { + require.Nil(t, expectedOutputBatches[i]) + } else { + require.Equal(t, expectedOutputBatches[i], b) + safeHead.Number += 1 + safeHead.Time += cfg.BlockTime + safeHead.Hash = mockHash(b.Timestamp, 2) + safeHead.L1Origin = b.Epoch() + } + } +} + +func TestBatchQueueComplex(t *testing.T) { + log := testlog.Logger(t, log.LvlCrit) + l1 := L1Chain([]uint64{0, 6, 12, 18, 24}) // L1 block time: 6s + chainId := big.NewInt(1234) + safeHead := eth.L2BlockRef{ + Hash: mockHash(4, 2), + Number: 0, + ParentHash: common.Hash{}, + Time: 4, + L1Origin: l1[0].ID(), + SequenceNumber: 0, + } + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L2Time: 10, + }, + BlockTime: 2, + MaxSequencerDrift: 600, + SeqWindowSize: 30, + SpanBatchTime: getSpanBatchTime(SpanBatchType), + L2ChainID: chainId, + } + + // expected output of BatchQueue.NextBatch() + expectedOutputBatches := []*SingularBatch{ + // 3 L2 blocks per L1 block + b(cfg.L2ChainID, 6, l1[1]), + b(cfg.L2ChainID, 8, l1[1]), + b(cfg.L2ChainID, 10, l1[1]), + b(cfg.L2ChainID, 12, l1[2]), + b(cfg.L2ChainID, 14, l1[2]), + b(cfg.L2ChainID, 16, l1[2]), + b(cfg.L2ChainID, 18, l1[3]), + b(cfg.L2ChainID, 20, l1[3]), + b(cfg.L2ChainID, 22, l1[3]), + } + // expected error of BatchQueue.NextBatch() + expectedOutputErrors := []error{nil, nil, nil, nil, nil, nil, nil, nil, nil, io.EOF} + // errors will be returned by fakeBatchQueueInput.NextBatch() + inputErrors := []error{nil, nil, nil, nil, nil, nil, io.EOF} + // batches will be returned by fakeBatchQueueInput + inputBatches := []Batch{ + NewSpanBatch(expectedOutputBatches[0:2]), // 6, 8 + expectedOutputBatches[2], // 10 + NewSpanBatch(expectedOutputBatches[1:4]), // 8, 10, 12 + expectedOutputBatches[4], // 14 + NewSpanBatch(expectedOutputBatches[4:6]), // 14, 16 + NewSpanBatch(expectedOutputBatches[6:9]), // 18, 20, 22 + } + + // Shuffle the order of input batches + rand.Shuffle(len(inputBatches), func(i, j int) { + inputBatches[i], inputBatches[j] = inputBatches[j], inputBatches[i] + }) + + inputBatches = append(inputBatches, nil) + + // ChannelInReader origin number + inputOriginNumber := 2 + input := &fakeBatchQueueInput{ + batches: inputBatches, + errors: inputErrors, + origin: l1[inputOriginNumber], + } + + l2Client := testutils.MockL2Client{} + var nilErr error + for i, batch := range expectedOutputBatches { + if batch != nil { + blockRef := singularBatchToBlockRef(t, batch, uint64(i+1)) + payload := singularBatchToPayload(t, batch, uint64(i+1)) + l2Client.Mock.On("L2BlockRefByNumber", uint64(i+1)).Times(9999).Return(blockRef, &nilErr) + l2Client.Mock.On("PayloadByNumber", uint64(i+1)).Times(9999).Return(&payload, &nilErr) + } + } + + bq := NewBatchQueue(log, cfg, input, &l2Client) + _ = bq.Reset(context.Background(), l1[1], eth.SystemConfig{}) + + for i := 0; i < len(expectedOutputBatches); i++ { + expectedOutput := expectedOutputBatches[i] + if expectedOutput != nil && uint64(expectedOutput.EpochNum) == l1[inputOriginNumber].Number { + // Advance ChannelInReader origin if needed + inputOriginNumber += 1 + input.origin = l1[inputOriginNumber] + } + var b *SingularBatch + var e error + for j := 0; j < len(expectedOutputBatches); j++ { + // Multiple NextBatch() executions may be required because the order of input is shuffled + b, e = bq.NextBatch(context.Background(), safeHead) + if !errors.Is(e, NotEnoughData) { + break + } + } + require.ErrorIs(t, e, expectedOutputErrors[i]) + if b == nil { + require.Nil(t, expectedOutput) + } else { + require.Equal(t, expectedOutput, b) + require.Equal(t, bq.l1Blocks[0].Number, uint64(b.EpochNum)) + safeHead.Number += 1 + safeHead.Time += cfg.BlockTime + safeHead.Hash = mockHash(b.Timestamp, 2) + safeHead.L1Origin = b.Epoch() + } + } +} diff --git a/op-node/rollup/derive/batches.go b/op-node/rollup/derive/batches.go index 7790e471d9dd..73020fa4079f 100644 --- a/op-node/rollup/derive/batches.go +++ b/op-node/rollup/derive/batches.go @@ -1,6 +1,9 @@ package derive import ( + "bytes" + "context" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/core/types" @@ -9,7 +12,7 @@ import ( type BatchWithL1InclusionBlock struct { L1InclusionBlock eth.L1BlockRef - Batch *BatchData + Batch Batch } type BatchValidity uint8 @@ -28,14 +31,37 @@ const ( // CheckBatch checks if the given batch can be applied on top of the given l2SafeHead, given the contextual L1 blocks the batch was included in. // The first entry of the l1Blocks should match the origin of the l2SafeHead. One or more consecutive l1Blocks should be provided. // In case of only a single L1 block, the decision whether a batch is valid may have to stay undecided. -func CheckBatch(cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1BlockRef, l2SafeHead eth.L2BlockRef, batch *BatchWithL1InclusionBlock) BatchValidity { +func CheckBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1BlockRef, + l2SafeHead eth.L2BlockRef, batch *BatchWithL1InclusionBlock, l2Fetcher SafeBlockFetcher) BatchValidity { + switch batch.Batch.GetBatchType() { + case SingularBatchType: + singularBatch, ok := batch.Batch.(*SingularBatch) + if !ok { + log.Error("failed type assertion to SingularBatch") + return BatchDrop + } + return checkSingularBatch(cfg, log, l1Blocks, l2SafeHead, singularBatch, batch.L1InclusionBlock) + case SpanBatchType: + spanBatch, ok := batch.Batch.(*SpanBatch) + if !ok { + log.Error("failed type assertion to SpanBatch") + return BatchDrop + } + if !cfg.IsSpanBatch(batch.Batch.GetTimestamp()) { + log.Warn("received SpanBatch before SpanBatch hard fork") + return BatchDrop + } + return checkSpanBatch(ctx, cfg, log, l1Blocks, l2SafeHead, spanBatch, batch.L1InclusionBlock, l2Fetcher) + default: + log.Warn("unrecognized batch type: %d", batch.Batch.GetBatchType()) + return BatchDrop + } +} + +// checkSingularBatch implements SingularBatch validation rule. +func checkSingularBatch(cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1BlockRef, l2SafeHead eth.L2BlockRef, batch *SingularBatch, l1InclusionBlock eth.L1BlockRef) BatchValidity { // add details to the log - log = log.New( - "batch_timestamp", batch.Batch.Timestamp, - "parent_hash", batch.Batch.ParentHash, - "batch_epoch", batch.Batch.Epoch(), - "txs", len(batch.Batch.Transactions), - ) + log = batch.LogContext(log) // sanity check we have consistent inputs if len(l1Blocks) == 0 { @@ -45,36 +71,36 @@ func CheckBatch(cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1BlockRef, l epoch := l1Blocks[0] nextTimestamp := l2SafeHead.Time + cfg.BlockTime - if batch.Batch.Timestamp > nextTimestamp { + if batch.Timestamp > nextTimestamp { log.Trace("received out-of-order batch for future processing after next batch", "next_timestamp", nextTimestamp) return BatchFuture } - if batch.Batch.Timestamp < nextTimestamp { + if batch.Timestamp < nextTimestamp { log.Warn("dropping batch with old timestamp", "min_timestamp", nextTimestamp) return BatchDrop } // dependent on above timestamp check. If the timestamp is correct, then it must build on top of the safe head. - if batch.Batch.ParentHash != l2SafeHead.Hash { + if batch.ParentHash != l2SafeHead.Hash { log.Warn("ignoring batch with mismatching parent hash", "current_safe_head", l2SafeHead.Hash) return BatchDrop } // Filter out batches that were included too late. - if uint64(batch.Batch.EpochNum)+cfg.SeqWindowSize < batch.L1InclusionBlock.Number { + if uint64(batch.EpochNum)+cfg.SeqWindowSize < l1InclusionBlock.Number { log.Warn("batch was included too late, sequence window expired") return BatchDrop } // Check the L1 origin of the batch batchOrigin := epoch - if uint64(batch.Batch.EpochNum) < epoch.Number { + if uint64(batch.EpochNum) < epoch.Number { log.Warn("dropped batch, epoch is too old", "minimum", epoch.ID()) // batch epoch too old return BatchDrop - } else if uint64(batch.Batch.EpochNum) == epoch.Number { + } else if uint64(batch.EpochNum) == epoch.Number { // Batch is sticking to the current epoch, continue. - } else if uint64(batch.Batch.EpochNum) == epoch.Number+1 { + } else if uint64(batch.EpochNum) == epoch.Number+1 { // With only 1 l1Block we cannot look at the next L1 Origin. // Note: This means that we are unable to determine validity of a batch // without more information. In this case we should bail out until we have @@ -90,19 +116,19 @@ func CheckBatch(cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1BlockRef, l return BatchDrop } - if batch.Batch.EpochHash != batchOrigin.Hash { + if batch.EpochHash != batchOrigin.Hash { log.Warn("batch is for different L1 chain, epoch hash does not match", "expected", batchOrigin.ID()) return BatchDrop } - if batch.Batch.Timestamp < batchOrigin.Time { - log.Warn("batch timestamp is less than L1 origin timestamp", "l2_timestamp", batch.Batch.Timestamp, "l1_timestamp", batchOrigin.Time, "origin", batchOrigin.ID()) + if batch.Timestamp < batchOrigin.Time { + log.Warn("batch timestamp is less than L1 origin timestamp", "l2_timestamp", batch.Timestamp, "l1_timestamp", batchOrigin.Time, "origin", batchOrigin.ID()) return BatchDrop } // Check if we ran out of sequencer time drift - if max := batchOrigin.Time + cfg.MaxSequencerDrift; batch.Batch.Timestamp > max { - if len(batch.Batch.Transactions) == 0 { + if max := batchOrigin.Time + cfg.MaxSequencerDrift; batch.Timestamp > max { + if len(batch.Transactions) == 0 { // If the sequencer is co-operating by producing an empty batch, // then allow the batch if it was the right thing to do to maintain the L2 time >= L1 time invariant. // We only check batches that do not advance the epoch, to ensure epoch advancement regardless of time drift is allowed. @@ -112,7 +138,7 @@ func CheckBatch(cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1BlockRef, l return BatchUndecided } nextOrigin := l1Blocks[1] - if batch.Batch.Timestamp >= nextOrigin.Time { // check if the next L1 origin could have been adopted + if batch.Timestamp >= nextOrigin.Time { // check if the next L1 origin could have been adopted log.Info("batch exceeded sequencer time drift without adopting next origin, and next L1 origin would have been valid") return BatchDrop } else { @@ -128,7 +154,7 @@ func CheckBatch(cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1BlockRef, l } // We can do this check earlier, but it's a more intensive one, so we do this last. - for i, txBytes := range batch.Batch.Transactions { + for i, txBytes := range batch.Transactions { if len(txBytes) == 0 { log.Warn("transaction data must not be empty, but found empty tx", "tx_index", i) return BatchDrop @@ -141,3 +167,204 @@ func CheckBatch(cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1BlockRef, l return BatchAccept } + +// checkSpanBatch implements SpanBatch validation rule. +func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1Blocks []eth.L1BlockRef, l2SafeHead eth.L2BlockRef, + batch *SpanBatch, l1InclusionBlock eth.L1BlockRef, l2Fetcher SafeBlockFetcher) BatchValidity { + // add details to the log + log = batch.LogContext(log) + + // sanity check we have consistent inputs + if len(l1Blocks) == 0 { + log.Warn("missing L1 block input, cannot proceed with batch checking") + return BatchUndecided + } + epoch := l1Blocks[0] + + nextTimestamp := l2SafeHead.Time + cfg.BlockTime + + if batch.GetTimestamp() > nextTimestamp { + log.Trace("received out-of-order batch for future processing after next batch", "next_timestamp", nextTimestamp) + return BatchFuture + } + if batch.GetBlockTimestamp(batch.GetBlockCount()-1) < nextTimestamp { + log.Warn("span batch has no new blocks after safe head") + return BatchDrop + } + + // finding parent block of the span batch. + // if the span batch does not overlap the current safe chain, parentBLock should be l2SafeHead. + parentNum := l2SafeHead.Number + parentBlock := l2SafeHead + if batch.GetTimestamp() < nextTimestamp { + if batch.GetTimestamp() > l2SafeHead.Time { + // batch timestamp cannot be between safe head and next timestamp + log.Warn("batch has misaligned timestamp") + return BatchDrop + } + if (l2SafeHead.Time-batch.GetTimestamp())%cfg.BlockTime != 0 { + log.Warn("batch has misaligned timestamp") + return BatchDrop + } + parentNum = l2SafeHead.Number - (l2SafeHead.Time-batch.GetTimestamp())/cfg.BlockTime - 1 + var err error + parentBlock, err = l2Fetcher.L2BlockRefByNumber(ctx, parentNum) + if err != nil { + log.Error("failed to fetch L2 block", "number", parentNum, "err", err) + // unable to validate the batch for now. retry later. + return BatchUndecided + } + } + if !batch.CheckParentHash(parentBlock.Hash) { + log.Warn("ignoring batch with mismatching parent hash", "parent_block", parentBlock.Hash) + return BatchDrop + } + + startEpochNum := uint64(batch.GetStartEpochNum()) + + // Filter out batches that were included too late. + if startEpochNum+cfg.SeqWindowSize < l1InclusionBlock.Number { + log.Warn("batch was included too late, sequence window expired") + return BatchDrop + } + + // Check the L1 origin of the batch + if startEpochNum > parentBlock.L1Origin.Number+1 { + log.Warn("batch is for future epoch too far ahead, while it has the next timestamp, so it must be invalid", "current_epoch", epoch.ID()) + return BatchDrop + } + + endEpochNum := batch.GetBlockEpochNum(batch.GetBlockCount() - 1) + originChecked := false + for _, l1Block := range l1Blocks { + if l1Block.Number == endEpochNum { + if !batch.CheckOriginHash(l1Block.Hash) { + log.Warn("batch is for different L1 chain, epoch hash does not match", "expected", l1Block.Hash) + return BatchDrop + } + originChecked = true + break + } + } + if !originChecked { + log.Info("need more l1 blocks to check entire origins of span batch") + return BatchUndecided + } + + if startEpochNum < parentBlock.L1Origin.Number { + log.Warn("dropped batch, epoch is too old", "minimum", parentBlock.ID()) + return BatchDrop + } + + originIdx := 0 + originAdvanced := false + if startEpochNum == parentBlock.L1Origin.Number+1 { + originAdvanced = true + } + + for i := 0; i < batch.GetBlockCount(); i++ { + if batch.GetBlockTimestamp(i) <= l2SafeHead.Time { + continue + } + var l1Origin eth.L1BlockRef + for j := originIdx; j < len(l1Blocks); j++ { + if batch.GetBlockEpochNum(i) == l1Blocks[j].Number { + l1Origin = l1Blocks[j] + originIdx = j + break + } + + } + if i > 0 { + originAdvanced = false + if batch.GetBlockEpochNum(i) > batch.GetBlockEpochNum(i-1) { + originAdvanced = true + } + } + blockTimestamp := batch.GetBlockTimestamp(i) + if blockTimestamp < l1Origin.Time { + log.Warn("block timestamp is less than L1 origin timestamp", "l2_timestamp", blockTimestamp, "l1_timestamp", l1Origin.Time, "origin", l1Origin.ID()) + return BatchDrop + } + + // Check if we ran out of sequencer time drift + if max := l1Origin.Time + cfg.MaxSequencerDrift; blockTimestamp > max { + if len(batch.GetBlockTransactions(i)) == 0 { + // If the sequencer is co-operating by producing an empty batch, + // then allow the batch if it was the right thing to do to maintain the L2 time >= L1 time invariant. + // We only check batches that do not advance the epoch, to ensure epoch advancement regardless of time drift is allowed. + if !originAdvanced { + if originIdx+1 >= len(l1Blocks) { + log.Info("without the next L1 origin we cannot determine yet if this empty batch that exceeds the time drift is still valid") + return BatchUndecided + } + if blockTimestamp >= l1Blocks[originIdx+1].Time { // check if the next L1 origin could have been adopted + log.Info("batch exceeded sequencer time drift without adopting next origin, and next L1 origin would have been valid") + return BatchDrop + } else { + log.Info("continuing with empty batch before late L1 block to preserve L2 time invariant") + } + } + } else { + // If the sequencer is ignoring the time drift rule, then drop the batch and force an empty batch instead, + // as the sequencer is not allowed to include anything past this point without moving to the next epoch. + log.Warn("batch exceeded sequencer time drift, sequencer must adopt new L1 origin to include transactions again", "max_time", max) + return BatchDrop + } + } + + for i, txBytes := range batch.GetBlockTransactions(i) { + if len(txBytes) == 0 { + log.Warn("transaction data must not be empty, but found empty tx", "tx_index", i) + return BatchDrop + } + if txBytes[0] == types.DepositTxType { + log.Warn("sequencers may not embed any deposits into batch data, but found tx that has one", "tx_index", i) + return BatchDrop + } + } + } + + // Check overlapped blocks + if batch.GetTimestamp() < nextTimestamp { + for i := uint64(0); i < l2SafeHead.Number-parentNum; i++ { + safeBlockNum := parentNum + i + 1 + safeBlockPayload, err := l2Fetcher.PayloadByNumber(ctx, safeBlockNum) + if err != nil { + log.Error("failed to fetch L2 block payload", "number", parentNum, "err", err) + // unable to validate the batch for now. retry later. + return BatchUndecided + } + safeBlockTxs := safeBlockPayload.Transactions + batchTxs := batch.GetBlockTransactions(int(i)) + // execution payload has deposit TXs, but batch does not. + depositCount := 0 + for _, tx := range safeBlockTxs { + if tx[0] == types.DepositTxType { + depositCount++ + } + } + if len(safeBlockTxs)-depositCount != len(batchTxs) { + log.Warn("overlapped block's tx count does not match", "safeBlockTxs", len(safeBlockTxs), "batchTxs", len(batchTxs)) + return BatchDrop + } + for j := 0; j < len(batchTxs); j++ { + if !bytes.Equal(safeBlockTxs[j+depositCount], batchTxs[j]) { + log.Warn("overlapped block's transaction does not match") + return BatchDrop + } + } + safeBlockRef, err := PayloadToBlockRef(safeBlockPayload, &cfg.Genesis) + if err != nil { + log.Error("failed to extract L2BlockRef from execution payload", "hash", safeBlockPayload.BlockHash, "err", err) + return BatchDrop + } + if safeBlockRef.L1Origin.Number != batch.GetBlockEpochNum(int(i)) { + log.Warn("overlapped block's L1 origin number does not match") + return BatchDrop + } + } + } + + return BatchAccept +} diff --git a/op-node/rollup/derive/batches_test.go b/op-node/rollup/derive/batches_test.go index cabcb6e4e147..a3948fa1a27a 100644 --- a/op-node/rollup/derive/batches_test.go +++ b/op-node/rollup/derive/batches_test.go @@ -1,6 +1,9 @@ package derive import ( + "context" + "errors" + "math/big" "math/rand" "testing" @@ -24,10 +27,19 @@ type ValidBatchTestCase struct { Expected BatchValidity } +type SpanBatchHardForkTestCase struct { + Name string + L1Blocks []eth.L1BlockRef + L2SafeHead eth.L2BlockRef + Batch BatchWithL1InclusionBlock + Expected BatchValidity + SpanBatchTime uint64 +} + var HashA = common.Hash{0x0a} var HashB = common.Hash{0x0b} -func TestValidBatch(t *testing.T) { +func TestValidSingularBatch(t *testing.T) { conf := rollup.Config{ Genesis: rollup.Genesis{ L2Time: 31, // a genesis time that itself does not align to make it more interesting @@ -174,13 +186,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2A1.ParentHash, EpochNum: rollup.Epoch(l2A1.L1Origin.Number), EpochHash: l2A1.L1Origin.Hash, Timestamp: l2A1.Time, Transactions: nil, - }), + }, }, Expected: BatchUndecided, }, @@ -190,13 +202,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2A1.ParentHash, EpochNum: rollup.Epoch(l2A1.L1Origin.Number), EpochHash: l2A1.L1Origin.Hash, Timestamp: l2A1.Time + 1, // 1 too high Transactions: nil, - }), + }, }, Expected: BatchFuture, }, @@ -206,13 +218,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2A1.ParentHash, EpochNum: rollup.Epoch(l2A1.L1Origin.Number), EpochHash: l2A1.L1Origin.Hash, Timestamp: l2A0.Time, // repeating the same time Transactions: nil, - }), + }, }, Expected: BatchDrop, }, @@ -222,13 +234,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2A1.ParentHash, EpochNum: rollup.Epoch(l2A1.L1Origin.Number), EpochHash: l2A1.L1Origin.Hash, Timestamp: l2A1.Time - 1, // block time is 2, so this is 1 too low Transactions: nil, - }), + }, }, Expected: BatchDrop, }, @@ -238,13 +250,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: testutils.RandomHash(rng), EpochNum: rollup.Epoch(l2A1.L1Origin.Number), EpochHash: l2A1.L1Origin.Hash, Timestamp: l2A1.Time, Transactions: nil, - }), + }, }, Expected: BatchDrop, }, @@ -254,13 +266,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1F, // included in 5th block after epoch of batch, while seq window is 4 - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2A1.ParentHash, EpochNum: rollup.Epoch(l2A1.L1Origin.Number), EpochHash: l2A1.L1Origin.Hash, Timestamp: l2A1.Time, Transactions: nil, - }), + }, }, Expected: BatchDrop, }, @@ -270,13 +282,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2B0, // we already moved on to B Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1C, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2B0.Hash, // build on top of safe head to continue EpochNum: rollup.Epoch(l2A3.L1Origin.Number), // epoch A is no longer valid EpochHash: l2A3.L1Origin.Hash, Timestamp: l2B0.Time + conf.BlockTime, // pass the timestamp check to get too epoch check Transactions: nil, - }), + }, }, Expected: BatchDrop, }, @@ -286,13 +298,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A3, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1C, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2B0.ParentHash, EpochNum: rollup.Epoch(l2B0.L1Origin.Number), EpochHash: l2B0.L1Origin.Hash, Timestamp: l2B0.Time, Transactions: nil, - }), + }, }, Expected: BatchUndecided, }, @@ -302,13 +314,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A3, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1D, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2B0.ParentHash, EpochNum: rollup.Epoch(l1C.Number), // invalid, we need to adopt epoch B before C EpochHash: l1C.Hash, Timestamp: l2B0.Time, Transactions: nil, - }), + }, }, Expected: BatchDrop, }, @@ -318,13 +330,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A3, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1C, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2B0.ParentHash, EpochNum: rollup.Epoch(l2B0.L1Origin.Number), EpochHash: l1A.Hash, // invalid, epoch hash should be l1B Timestamp: l2B0.Time, Transactions: nil, - }), + }, }, Expected: BatchDrop, }, @@ -334,13 +346,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A3, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 + Batch: &SingularBatch{ // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 ParentHash: l2A4.ParentHash, EpochNum: rollup.Epoch(l2A4.L1Origin.Number), EpochHash: l2A4.L1Origin.Hash, Timestamp: l2A4.Time, Transactions: []hexutil.Bytes{[]byte("sequencer should not include this tx")}, - }), + }, }, Expected: BatchDrop, }, @@ -350,13 +362,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2X0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1Z, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2Y0.ParentHash, EpochNum: rollup.Epoch(l2Y0.L1Origin.Number), EpochHash: l2Y0.L1Origin.Hash, Timestamp: l2Y0.Time, // valid, but more than 6 ahead of l1Y.Time Transactions: []hexutil.Bytes{[]byte("sequencer should not include this tx")}, - }), + }, }, Expected: BatchDrop, }, @@ -366,13 +378,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A3, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1BLate, - Batch: NewSingularBatchData(SingularBatch{ // l2A4 time < l1BLate time, so we cannot adopt origin B yet + Batch: &SingularBatch{ // l2A4 time < l1BLate time, so we cannot adopt origin B yet ParentHash: l2A4.ParentHash, EpochNum: rollup.Epoch(l2A4.L1Origin.Number), EpochHash: l2A4.L1Origin.Hash, Timestamp: l2A4.Time, Transactions: nil, - }), + }, }, Expected: BatchAccept, // accepted because empty & preserving L2 time invariant }, @@ -382,13 +394,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2X0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1Z, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2Y0.ParentHash, EpochNum: rollup.Epoch(l2Y0.L1Origin.Number), EpochHash: l2Y0.L1Origin.Hash, Timestamp: l2Y0.Time, // valid, but more than 6 ahead of l1Y.Time Transactions: nil, - }), + }, }, Expected: BatchAccept, // accepted because empty & still advancing epoch }, @@ -398,13 +410,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A3, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 + Batch: &SingularBatch{ // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 ParentHash: l2A4.ParentHash, EpochNum: rollup.Epoch(l2A4.L1Origin.Number), EpochHash: l2A4.L1Origin.Hash, Timestamp: l2A4.Time, Transactions: nil, - }), + }, }, Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time }, @@ -414,13 +426,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A3, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1C, - Batch: NewSingularBatchData(SingularBatch{ // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 + Batch: &SingularBatch{ // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 ParentHash: l2A4.ParentHash, EpochNum: rollup.Epoch(l2A4.L1Origin.Number), EpochHash: l2A4.L1Origin.Hash, Timestamp: l2A4.Time, Transactions: nil, - }), + }, }, Expected: BatchDrop, // dropped because it could have advanced the epoch to B }, @@ -430,7 +442,7 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2A1.ParentHash, EpochNum: rollup.Epoch(l2A1.L1Origin.Number), EpochHash: l2A1.L1Origin.Hash, @@ -438,7 +450,7 @@ func TestValidBatch(t *testing.T) { Transactions: []hexutil.Bytes{ []byte{}, // empty tx data }, - }), + }, }, Expected: BatchDrop, }, @@ -448,7 +460,7 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2A1.ParentHash, EpochNum: rollup.Epoch(l2A1.L1Origin.Number), EpochHash: l2A1.L1Origin.Hash, @@ -456,7 +468,7 @@ func TestValidBatch(t *testing.T) { Transactions: []hexutil.Bytes{ []byte{types.DepositTxType, 0}, // piece of data alike to a deposit }, - }), + }, }, Expected: BatchDrop, }, @@ -466,7 +478,7 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A0, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2A1.ParentHash, EpochNum: rollup.Epoch(l2A1.L1Origin.Number), EpochHash: l2A1.L1Origin.Hash, @@ -475,7 +487,7 @@ func TestValidBatch(t *testing.T) { []byte{0x02, 0x42, 0x13, 0x37}, []byte{0x02, 0xde, 0xad, 0xbe, 0xef}, }, - }), + }, }, Expected: BatchAccept, }, @@ -485,7 +497,7 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A3, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1C, - Batch: NewSingularBatchData(SingularBatch{ + Batch: &SingularBatch{ ParentHash: l2B0.ParentHash, EpochNum: rollup.Epoch(l2B0.L1Origin.Number), EpochHash: l2B0.L1Origin.Hash, @@ -494,7 +506,7 @@ func TestValidBatch(t *testing.T) { []byte{0x02, 0x42, 0x13, 0x37}, []byte{0x02, 0xde, 0xad, 0xbe, 0xef}, }, - }), + }, }, Expected: BatchAccept, }, @@ -504,13 +516,13 @@ func TestValidBatch(t *testing.T) { L2SafeHead: l2A2, Batch: BatchWithL1InclusionBlock{ L1InclusionBlock: l1B, - Batch: NewSingularBatchData(SingularBatch{ // we build l2B0', which starts a new epoch too early + Batch: &SingularBatch{ // we build l2B0', which starts a new epoch too early ParentHash: l2A2.Hash, EpochNum: rollup.Epoch(l2B0.L1Origin.Number), EpochHash: l2B0.L1Origin.Hash, Timestamp: l2A2.Time + conf.BlockTime, Transactions: nil, - }), + }, }, Expected: BatchDrop, }, @@ -521,7 +533,1026 @@ func TestValidBatch(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.Name, func(t *testing.T) { - validity := CheckBatch(&conf, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch) + ctx := context.Background() + validity := CheckBatch(ctx, &conf, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, nil) + require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") + }) + } +} + +func TestValidSpanBatch(t *testing.T) { + minTs := uint64(0) + conf := rollup.Config{ + Genesis: rollup.Genesis{ + L2Time: 31, // a genesis time that itself does not align to make it more interesting + }, + BlockTime: 2, + SeqWindowSize: 4, + MaxSequencerDrift: 6, + SpanBatchTime: &minTs, + // other config fields are ignored and can be left empty. + } + + rng := rand.New(rand.NewSource(1234)) + chainId := new(big.Int).SetUint64(rng.Uint64()) + signer := types.NewLondonSigner(chainId) + randTx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) + randTxData, _ := randTx.MarshalBinary() + l1A := testutils.RandomBlockRef(rng) + l1B := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l1A.Number + 1, + ParentHash: l1A.Hash, + Time: l1A.Time + 7, + } + l1C := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l1B.Number + 1, + ParentHash: l1B.Hash, + Time: l1B.Time + 7, + } + l1D := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l1C.Number + 1, + ParentHash: l1C.Hash, + Time: l1C.Time + 7, + } + l1E := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l1D.Number + 1, + ParentHash: l1D.Hash, + Time: l1D.Time + 7, + } + l1F := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l1E.Number + 1, + ParentHash: l1E.Hash, + Time: l1E.Time + 7, + } + + l2A0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: 100, + ParentHash: testutils.RandomHash(rng), + Time: l1A.Time, + L1Origin: l1A.ID(), + SequenceNumber: 0, + } + + l2A1 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2A0.Number + 1, + ParentHash: l2A0.Hash, + Time: l2A0.Time + conf.BlockTime, + L1Origin: l1A.ID(), + SequenceNumber: 1, + } + + l2A2 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2A1.Number + 1, + ParentHash: l2A1.Hash, + Time: l2A1.Time + conf.BlockTime, + L1Origin: l1A.ID(), + SequenceNumber: 2, + } + + l2A3 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2A2.Number + 1, + ParentHash: l2A2.Hash, + Time: l2A2.Time + conf.BlockTime, + L1Origin: l1A.ID(), + SequenceNumber: 3, + } + + l2B0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2A3.Number + 1, + ParentHash: l2A3.Hash, + Time: l2A3.Time + conf.BlockTime, // 8 seconds larger than l1A0, 1 larger than origin + L1Origin: l1B.ID(), + SequenceNumber: 0, + } + + l1X := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: 42, + ParentHash: testutils.RandomHash(rng), + Time: 10_000, + } + l1Y := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l1X.Number + 1, + ParentHash: l1X.Hash, + Time: l1X.Time + 12, + } + l1Z := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l1Y.Number + 1, + ParentHash: l1Y.Hash, + Time: l1Y.Time + 12, + } + l2X0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: 1000, + ParentHash: testutils.RandomHash(rng), + Time: 10_000 + 12 + 6 - 1, // add one block, and you get ahead of next l1 block by more than the drift + L1Origin: l1X.ID(), + SequenceNumber: 0, + } + l2Y0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2X0.Number + 1, + ParentHash: l2X0.Hash, + Time: l2X0.Time + conf.BlockTime, // exceeds sequencer time drift, forced to be empty block + L1Origin: l1Y.ID(), + SequenceNumber: 0, + } + + l2A4 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2A3.Number + 1, + ParentHash: l2A3.Hash, + Time: l2A3.Time + conf.BlockTime, // 4*2 = 8, higher than seq time drift + L1Origin: l1A.ID(), + SequenceNumber: 4, + } + + l1BLate := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l1A.Number + 1, + ParentHash: l1A.Hash, + Time: l2A4.Time + 1, // too late for l2A4 to adopt yet + } + + testCases := []ValidBatchTestCase{ + { + Name: "missing L1 info", + L1Blocks: []eth.L1BlockRef{}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchUndecided, + }, + { + Name: "future timestamp", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time + 1, // 1 too high + Transactions: nil, + }, + }), + }, + Expected: BatchFuture, + }, + { + Name: "old timestamp", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A0.Time, // repeating the same time + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "misaligned timestamp", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time - 1, // block time is 2, so this is 1 too low + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "invalid parent block hash", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: testutils.RandomHash(rng), + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "sequence window expired", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C, l1D, l1E, l1F}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1F, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "epoch too old, but good parent hash and timestamp", // repeat of now outdated l2A3 data + L1Blocks: []eth.L1BlockRef{l1B, l1C, l1D}, + L2SafeHead: l2B0, // we already moved on to B + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1C, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2B0.Hash, // build on top of safe head to continue + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), // epoch A is no longer valid + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2B0.Time + conf.BlockTime, // pass the timestamp check to get too epoch check + Transactions: nil, + }, + { + EpochNum: rollup.Epoch(l1B.Number), + EpochHash: l1B.Hash, // pass the l1 origin check + Timestamp: l2B0.Time + conf.BlockTime*2, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "insufficient L1 info for eager derivation", + L1Blocks: []eth.L1BlockRef{l1A}, // don't know about l1B yet + L2SafeHead: l2A3, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1C, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2B0.ParentHash, + EpochNum: rollup.Epoch(l2B0.L1Origin.Number), + EpochHash: l2B0.L1Origin.Hash, + Timestamp: l2B0.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchUndecided, + }, + { + Name: "epoch too new", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C, l1D}, + L2SafeHead: l2A3, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1D, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2B0.ParentHash, + EpochNum: rollup.Epoch(l1C.Number), // invalid, we need to adopt epoch B before C + EpochHash: l1C.Hash, + Timestamp: l2B0.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "epoch hash wrong", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A3, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1C, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2B0.ParentHash, + EpochNum: rollup.Epoch(l2B0.L1Origin.Number), + EpochHash: l1A.Hash, // invalid, epoch hash should be l1B + Timestamp: l2B0.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "epoch hash wrong - long span", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1C, + Batch: NewSpanBatch([]*SingularBatch{ + { // valid batch + ParentHash: l2A3.ParentHash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l1A.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + { + ParentHash: l2B0.ParentHash, + EpochNum: rollup.Epoch(l2B0.L1Origin.Number), + EpochHash: l1A.Hash, // invalid, epoch hash should be l1B + Timestamp: l2B0.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "sequencer time drift on same epoch with non-empty txs", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A3, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 + ParentHash: l2A4.ParentHash, + EpochNum: rollup.Epoch(l2A4.L1Origin.Number), + EpochHash: l2A4.L1Origin.Hash, + Timestamp: l2A4.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "sequencer time drift on same epoch with non-empty txs - long span", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { // valid batch + ParentHash: l2A3.ParentHash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + { // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 + ParentHash: l2A4.ParentHash, + EpochNum: rollup.Epoch(l2A4.L1Origin.Number), + EpochHash: l2A4.L1Origin.Hash, + Timestamp: l2A4.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "sequencer time drift on changing epoch with non-empty txs", + L1Blocks: []eth.L1BlockRef{l1X, l1Y, l1Z}, + L2SafeHead: l2X0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1Z, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2Y0.ParentHash, + EpochNum: rollup.Epoch(l2Y0.L1Origin.Number), + EpochHash: l2Y0.L1Origin.Hash, + Timestamp: l2Y0.Time, // valid, but more than 6 ahead of l1Y.Time + Transactions: []hexutil.Bytes{randTxData}, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "sequencer time drift on same epoch with empty txs and late next epoch", + L1Blocks: []eth.L1BlockRef{l1A, l1BLate}, + L2SafeHead: l2A3, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1BLate, + Batch: NewSpanBatch([]*SingularBatch{ + { // l2A4 time < l1BLate time, so we cannot adopt origin B yet + ParentHash: l2A4.ParentHash, + EpochNum: rollup.Epoch(l2A4.L1Origin.Number), + EpochHash: l2A4.L1Origin.Hash, + Timestamp: l2A4.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchAccept, // accepted because empty & preserving L2 time invariant + }, + { + Name: "sequencer time drift on changing epoch with empty txs", + L1Blocks: []eth.L1BlockRef{l1X, l1Y, l1Z}, + L2SafeHead: l2X0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1Z, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2Y0.ParentHash, + EpochNum: rollup.Epoch(l2Y0.L1Origin.Number), + EpochHash: l2Y0.L1Origin.Hash, + Timestamp: l2Y0.Time, // valid, but more than 6 ahead of l1Y.Time + Transactions: nil, + }, + }), + }, + Expected: BatchAccept, // accepted because empty & still advancing epoch + }, + { + Name: "sequencer time drift on same epoch with empty txs and no next epoch in sight yet", + L1Blocks: []eth.L1BlockRef{l1A}, + L2SafeHead: l2A3, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 + ParentHash: l2A4.ParentHash, + EpochNum: rollup.Epoch(l2A4.L1Origin.Number), + EpochHash: l2A4.L1Origin.Hash, + Timestamp: l2A4.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time + }, + { + Name: "sequencer time drift on same epoch with empty txs and no next epoch in sight yet - long span", + L1Blocks: []eth.L1BlockRef{l1A}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { // valid batch + ParentHash: l2A3.ParentHash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + { // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 + ParentHash: l2A4.ParentHash, + EpochNum: rollup.Epoch(l2A4.L1Origin.Number), + EpochHash: l2A4.L1Origin.Hash, + Timestamp: l2A4.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time + }, + { + Name: "sequencer time drift on same epoch with empty txs and but in-sight epoch that invalidates it", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, + L2SafeHead: l2A3, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1C, + Batch: NewSpanBatch([]*SingularBatch{ + { // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 + ParentHash: l2A4.ParentHash, + EpochNum: rollup.Epoch(l2A4.L1Origin.Number), + EpochHash: l2A4.L1Origin.Hash, + Timestamp: l2A4.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, // dropped because it could have advanced the epoch to B + }, + { + Name: "sequencer time drift on same epoch with empty txs and but in-sight epoch that invalidates it - long span", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1C, + Batch: NewSpanBatch([]*SingularBatch{ + { // valid batch + ParentHash: l2A3.ParentHash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + { // we build l2A4, which has a timestamp of 2*4 = 8 higher than l2A0 + ParentHash: l2A4.ParentHash, + EpochNum: rollup.Epoch(l2A4.L1Origin.Number), + EpochHash: l2A4.L1Origin.Hash, + Timestamp: l2A4.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, // dropped because it could have advanced the epoch to B + }, + { + Name: "empty tx included", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: []hexutil.Bytes{ + []byte{}, // empty tx data + }, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "deposit tx included", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: []hexutil.Bytes{ + []byte{types.DepositTxType, 0}, // piece of data alike to a deposit + }, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "valid batch same epoch", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + }), + }, + Expected: BatchAccept, + }, + { + Name: "valid batch changing epoch", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, + L2SafeHead: l2A3, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1C, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2B0.ParentHash, + EpochNum: rollup.Epoch(l2B0.L1Origin.Number), + EpochHash: l2B0.L1Origin.Hash, + Timestamp: l2B0.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + }), + }, + Expected: BatchAccept, + }, + { + Name: "batch with L2 time before L1 time", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { // we build l2B0, which starts a new epoch too early + ParentHash: l2A2.Hash, + EpochNum: rollup.Epoch(l2B0.L1Origin.Number), + EpochHash: l2B0.L1Origin.Hash, + Timestamp: l2A2.Time + conf.BlockTime, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "batch with L2 time before L1 time - long span", + L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, + L2SafeHead: l2A1, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { // valid batch + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A2.Time, + Transactions: nil, + }, + { // we build l2B0, which starts a new epoch too early + ParentHash: l2A2.Hash, + EpochNum: rollup.Epoch(l2B0.L1Origin.Number), + EpochHash: l2B0.L1Origin.Hash, + Timestamp: l2A2.Time + conf.BlockTime, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "valid overlapping batch", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A2.Time, + Transactions: nil, + }, + { + ParentHash: l2A2.Hash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchAccept, + }, + { + Name: "longer overlapping batch", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A0.Hash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: nil, + }, + { + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A2.Time, + Transactions: nil, + }, + { + ParentHash: l2A2.Hash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchAccept, + }, + { + Name: "fully overlapping batch", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A0.Hash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: nil, + }, + { + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A2.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "overlapping batch with invalid parent hash", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A0.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A2.Time, + Transactions: nil, + }, + { + ParentHash: l2A2.Hash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "overlapping batch with invalid origin number", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number) + 1, + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A2.Time, + Transactions: nil, + }, + { + ParentHash: l2A2.Hash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "overlapping batch with invalid tx", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A2.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + { + ParentHash: l2A2.Hash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + }, + { + Name: "overlapping batch l2 fetcher error", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A1, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A0.ParentHash, + EpochNum: rollup.Epoch(l2A0.L1Origin.Number), + EpochHash: l2A0.L1Origin.Hash, + Timestamp: l2A0.Time, + Transactions: nil, + }, + { + ParentHash: l2A0.Hash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: nil, + }, + { + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A2.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchUndecided, + }, + } + + // Log level can be increased for debugging purposes + logger := testlog.Logger(t, log.LvlError) + + l2Client := testutils.MockL2Client{} + var nilErr error + // will be return error for block #99 (parent of l2A0) + tempErr := errors.New("temp error") + l2Client.Mock.On("L2BlockRefByNumber", l2A0.Number-1).Times(9999).Return(eth.L2BlockRef{}, &tempErr) + l2Client.Mock.On("PayloadByNumber", l2A0.Number-1).Times(9999).Return(nil, &tempErr) + + // make payloads for L2 blocks and set as expected return value of MockL2Client + for _, l2Block := range []eth.L2BlockRef{l2A0, l2A1, l2A2, l2A3, l2A4, l2B0} { + l2Client.ExpectL2BlockRefByNumber(l2Block.Number, l2Block, nil) + txData := l1InfoDepositTx(t, l2Block.L1Origin.Number) + payload := eth.ExecutionPayload{ + ParentHash: l2Block.ParentHash, + BlockNumber: hexutil.Uint64(l2Block.Number), + Timestamp: hexutil.Uint64(l2Block.Time), + BlockHash: l2Block.Hash, + Transactions: []hexutil.Bytes{txData}, + } + l2Client.Mock.On("L2BlockRefByNumber", l2Block.Number).Times(9999).Return(l2Block, &nilErr) + l2Client.Mock.On("PayloadByNumber", l2Block.Number).Times(9999).Return(&payload, &nilErr) + } + + for _, testCase := range testCases { + t.Run(testCase.Name, func(t *testing.T) { + ctx := context.Background() + validity := CheckBatch(ctx, &conf, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, &l2Client) + require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") + }) + } +} + +func TestSpanBatchHardFork(t *testing.T) { + minTs := uint64(0) + conf := rollup.Config{ + Genesis: rollup.Genesis{ + L2Time: 31, // a genesis time that itself does not align to make it more interesting + }, + BlockTime: 2, + SeqWindowSize: 4, + MaxSequencerDrift: 6, + SpanBatchTime: &minTs, + // other config fields are ignored and can be left empty. + } + + rng := rand.New(rand.NewSource(1234)) + chainId := new(big.Int).SetUint64(rng.Uint64()) + signer := types.NewLondonSigner(chainId) + randTx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) + randTxData, _ := randTx.MarshalBinary() + l1A := testutils.RandomBlockRef(rng) + l1B := eth.L1BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l1A.Number + 1, + ParentHash: l1A.Hash, + Time: l1A.Time + 7, + } + + l2A0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: 100, + ParentHash: testutils.RandomHash(rng), + Time: l1A.Time, + L1Origin: l1A.ID(), + SequenceNumber: 0, + } + + l2A1 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2A0.Number + 1, + ParentHash: l2A0.Hash, + Time: l2A0.Time + conf.BlockTime, + L1Origin: l1A.ID(), + SequenceNumber: 1, + } + + testCases := []SpanBatchHardForkTestCase{ + { + Name: "singular batch before hard fork", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: &SingularBatch{ + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + }, + SpanBatchTime: l2A1.Time + 2, + Expected: BatchAccept, + }, + { + Name: "span batch before hard fork", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + }), + }, + SpanBatchTime: l2A1.Time + 2, + Expected: BatchDrop, + }, + { + Name: "singular batch after hard fork", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: &SingularBatch{ + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + }, + SpanBatchTime: l2A1.Time - 2, + Expected: BatchAccept, + }, + { + Name: "span batch after hard fork", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A1.ParentHash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + }), + }, + SpanBatchTime: l2A1.Time - 2, + Expected: BatchAccept, + }, + } + + // Log level can be increased for debugging purposes + logger := testlog.Logger(t, log.LvlInfo) + + for _, testCase := range testCases { + t.Run(testCase.Name, func(t *testing.T) { + rcfg := conf + rcfg.SpanBatchTime = &testCase.SpanBatchTime + ctx := context.Background() + validity := CheckBatch(ctx, &rcfg, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, nil) require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") }) } diff --git a/op-node/rollup/derive/channel.go b/op-node/rollup/derive/channel.go index 1d9a85cc9027..7bd67f184995 100644 --- a/op-node/rollup/derive/channel.go +++ b/op-node/rollup/derive/channel.go @@ -6,8 +6,6 @@ import ( "fmt" "io" - "github.com/ethereum-optimism/optimism/op-node/rollup" - "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/rlp" ) @@ -146,7 +144,9 @@ func (ch *Channel) Reader() io.Reader { // BatchReader provides a function that iteratively consumes batches from the reader. // The L1Inclusion block is also provided at creation time. -func BatchReader(cfg *rollup.Config, r io.Reader, l1InclusionBlock eth.L1BlockRef) (func() (BatchWithL1InclusionBlock, error), error) { +// Warning: the batch reader can read every batch-type. +// The caller of the batch-reader should filter the results. +func BatchReader(r io.Reader) (func() (*BatchData, error), error) { // Setup decompressor stage + RLP reader zr, err := zlib.NewReader(r) if err != nil { @@ -154,17 +154,11 @@ func BatchReader(cfg *rollup.Config, r io.Reader, l1InclusionBlock eth.L1BlockRe } rlpReader := rlp.NewStream(zr, MaxRLPBytesPerChannel) // Read each batch iteratively - return func() (BatchWithL1InclusionBlock, error) { - ret := BatchWithL1InclusionBlock{ - L1InclusionBlock: l1InclusionBlock, - } - err := rlpReader.Decode(&ret.Batch) - if err != nil { - return ret, err - } - if ret.Batch.BatchType == SpanBatchType && !cfg.IsSpanBatch(ret.L1InclusionBlock.Time) { - return ret, fmt.Errorf("cannot accept span-batch in L1 block with time %d", ret.L1InclusionBlock.Time) + return func() (*BatchData, error) { + var batchData BatchData + if err = rlpReader.Decode(&batchData); err != nil { + return nil, err } - return ret, nil + return &batchData, nil }, nil } diff --git a/op-node/rollup/derive/channel_in_reader.go b/op-node/rollup/derive/channel_in_reader.go index 7487326d99bf..1553bd9a6656 100644 --- a/op-node/rollup/derive/channel_in_reader.go +++ b/op-node/rollup/derive/channel_in_reader.go @@ -3,12 +3,12 @@ package derive import ( "bytes" "context" + "fmt" "io" - "github.com/ethereum-optimism/optimism/op-node/rollup" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/eth" ) @@ -21,7 +21,7 @@ type ChannelInReader struct { cfg *rollup.Config - nextBatchFn func() (BatchWithL1InclusionBlock, error) + nextBatchFn func() (*BatchData, error) prev *ChannelBank @@ -46,7 +46,7 @@ func (cr *ChannelInReader) Origin() eth.L1BlockRef { // TODO: Take full channel for better logging func (cr *ChannelInReader) WriteChannel(data []byte) error { - if f, err := BatchReader(cr.cfg, bytes.NewBuffer(data), cr.Origin()); err == nil { + if f, err := BatchReader(bytes.NewBuffer(data)); err == nil { cr.nextBatchFn = f cr.metrics.RecordChannelInputBytes(len(data)) return nil @@ -65,7 +65,7 @@ func (cr *ChannelInReader) NextChannel() { // NextBatch pulls out the next batch from the channel if it has it. // It returns io.EOF when it cannot make any more progress. // It will return a temporary error if it needs to be called again to advance some internal state. -func (cr *ChannelInReader) NextBatch(ctx context.Context) (*BatchData, error) { +func (cr *ChannelInReader) NextBatch(ctx context.Context) (Batch, error) { if cr.nextBatchFn == nil { if data, err := cr.prev.NextData(ctx); err == io.EOF { return nil, io.EOF @@ -80,7 +80,7 @@ func (cr *ChannelInReader) NextBatch(ctx context.Context) (*BatchData, error) { // TODO: can batch be non nil while err == io.EOF // This depends on the behavior of rlp.Stream - batch, err := cr.nextBatchFn() + batchData, err := cr.nextBatchFn() if err == io.EOF { cr.NextChannel() return nil, NotEnoughData @@ -89,7 +89,23 @@ func (cr *ChannelInReader) NextBatch(ctx context.Context) (*BatchData, error) { cr.NextChannel() return nil, NotEnoughData } - return batch.Batch, nil + switch batchData.BatchType { + case SingularBatchType: + return &batchData.SingularBatch, nil + case SpanBatchType: + if origin := cr.Origin(); !cr.cfg.IsSpanBatch(origin.Time) { + return nil, NewTemporaryError(fmt.Errorf("cannot accept span batch in L1 block %s at time %d", origin, origin.Time)) + } + // If the batch type is Span batch, derive block inputs from RawSpanBatch. + spanBatch, err := batchData.RawSpanBatch.derive(cr.cfg.BlockTime, cr.cfg.Genesis.L2Time, cr.cfg.L2ChainID) + if err != nil { + return nil, err + } + return spanBatch, nil + default: + // error is bubbled up to user, but pipeline can skip the batch and continue after. + return nil, NewTemporaryError(fmt.Errorf("unrecognized batch type: %w", err)) + } } func (cr *ChannelInReader) Reset(ctx context.Context, _ eth.L1BlockRef, _ eth.SystemConfig) error { diff --git a/op-node/rollup/derive/engine_queue.go b/op-node/rollup/derive/engine_queue.go index 775ab64a8959..b8cd3ae5917f 100644 --- a/op-node/rollup/derive/engine_queue.go +++ b/op-node/rollup/derive/engine_queue.go @@ -35,6 +35,7 @@ type Engine interface { PayloadByNumber(context.Context, uint64) (*eth.ExecutionPayload, error) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) L2BlockRefByHash(ctx context.Context, l2Hash common.Hash) (eth.L2BlockRef, error) + L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2BlockRef, error) SystemConfigL2Fetcher } diff --git a/op-node/rollup/derive/pipeline.go b/op-node/rollup/derive/pipeline.go index 7b017515b763..d054939f151d 100644 --- a/op-node/rollup/derive/pipeline.go +++ b/op-node/rollup/derive/pipeline.go @@ -90,7 +90,7 @@ func NewDerivationPipeline(log log.Logger, cfg *rollup.Config, l1Fetcher L1Fetch frameQueue := NewFrameQueue(log, l1Src) bank := NewChannelBank(log, cfg, frameQueue, l1Fetcher, metrics) chInReader := NewChannelInReader(cfg, log, bank, metrics) - batchQueue := NewBatchQueue(log, cfg, chInReader) + batchQueue := NewBatchQueue(log, cfg, chInReader, engine) attrBuilder := NewFetchingAttributesBuilder(cfg, l1Fetcher, engine) attributesQueue := NewAttributesQueue(log, cfg, attrBuilder, batchQueue) diff --git a/op-program/client/l2/engine.go b/op-program/client/l2/engine.go index 3ed4476b71ad..e6ffadebf470 100644 --- a/op-program/client/l2/engine.go +++ b/op-program/client/l2/engine.go @@ -109,6 +109,14 @@ func (o *OracleEngine) L2BlockRefByHash(ctx context.Context, l2Hash common.Hash) return derive.L2BlockToBlockRef(block, &o.rollupCfg.Genesis) } +func (o *OracleEngine) L2BlockRefByNumber(ctx context.Context, n uint64) (eth.L2BlockRef, error) { + hash := o.backend.GetCanonicalHash(n) + if hash == (common.Hash{}) { + return eth.L2BlockRef{}, ErrNotFound + } + return o.L2BlockRefByHash(ctx, hash) +} + func (o *OracleEngine) SystemConfigByL2Hash(ctx context.Context, hash common.Hash) (eth.SystemConfig, error) { payload, err := o.PayloadByHash(ctx, hash) if err != nil { diff --git a/op-service/testutils/mock_l2.go b/op-service/testutils/mock_l2.go index 18f5f4c82b1c..6b01b401a402 100644 --- a/op-service/testutils/mock_l2.go +++ b/op-service/testutils/mock_l2.go @@ -3,9 +3,8 @@ package testutils import ( "context" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum/go-ethereum/common" ) type MockL2Client struct { @@ -13,7 +12,8 @@ type MockL2Client struct { } func (c *MockL2Client) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) { - return c.Mock.MethodCalled("L2BlockRefByLabel", label).Get(0).(eth.L2BlockRef), nil + out := c.Mock.MethodCalled("L2BlockRefByLabel", label) + return out[0].(eth.L2BlockRef), *out[1].(*error) } func (m *MockL2Client) ExpectL2BlockRefByLabel(label eth.BlockLabel, ref eth.L2BlockRef, err error) { @@ -21,7 +21,8 @@ func (m *MockL2Client) ExpectL2BlockRefByLabel(label eth.BlockLabel, ref eth.L2B } func (c *MockL2Client) L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2BlockRef, error) { - return c.Mock.MethodCalled("L2BlockRefByNumber", num).Get(0).(eth.L2BlockRef), nil + out := c.Mock.MethodCalled("L2BlockRefByNumber", num) + return out[0].(eth.L2BlockRef), *out[1].(*error) } func (m *MockL2Client) ExpectL2BlockRefByNumber(num uint64, ref eth.L2BlockRef, err error) { @@ -29,7 +30,8 @@ func (m *MockL2Client) ExpectL2BlockRefByNumber(num uint64, ref eth.L2BlockRef, } func (c *MockL2Client) L2BlockRefByHash(ctx context.Context, hash common.Hash) (eth.L2BlockRef, error) { - return c.Mock.MethodCalled("L2BlockRefByHash", hash).Get(0).(eth.L2BlockRef), nil + out := c.Mock.MethodCalled("L2BlockRefByHash", hash) + return out[0].(eth.L2BlockRef), *out[1].(*error) } func (m *MockL2Client) ExpectL2BlockRefByHash(hash common.Hash, ref eth.L2BlockRef, err error) { @@ -37,7 +39,8 @@ func (m *MockL2Client) ExpectL2BlockRefByHash(hash common.Hash, ref eth.L2BlockR } func (m *MockL2Client) SystemConfigByL2Hash(ctx context.Context, hash common.Hash) (eth.SystemConfig, error) { - return m.Mock.MethodCalled("SystemConfigByL2Hash", hash).Get(0).(eth.SystemConfig), nil + out := m.Mock.MethodCalled("SystemConfigByL2Hash", hash) + return out[0].(eth.SystemConfig), *out[1].(*error) } func (m *MockL2Client) ExpectSystemConfigByL2Hash(hash common.Hash, cfg eth.SystemConfig, err error) { @@ -45,7 +48,8 @@ func (m *MockL2Client) ExpectSystemConfigByL2Hash(hash common.Hash, cfg eth.Syst } func (m *MockL2Client) OutputV0AtBlock(ctx context.Context, blockHash common.Hash) (*eth.OutputV0, error) { - return m.Mock.MethodCalled("OutputV0AtBlock", blockHash).Get(0).(*eth.OutputV0), nil + out := m.Mock.MethodCalled("OutputV0AtBlock", blockHash) + return out[0].(*eth.OutputV0), *out[1].(*error) } func (m *MockL2Client) ExpectOutputV0AtBlock(blockHash common.Hash, output *eth.OutputV0, err error) { From 1267baddd031bd4eece30f05ca85f2fa81541bc3 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Tue, 10 Oct 2023 19:30:46 +0900 Subject: [PATCH 011/374] Apply suggestions from code reivews Rename advanceEpoch() to advanceEpochMaybe() Set number of calls for L2 client mock and assert them in batch queue tests --- op-node/rollup/derive/batch_queue.go | 6 +-- op-node/rollup/derive/batch_queue_test.go | 52 ++++++++++++++++++----- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index 30dd1441924b..9805b1ee0103 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -78,7 +78,7 @@ func (bq *BatchQueue) popNextBatch(safeL2Head eth.L2BlockRef) *SingularBatch { return nextBatch } -func (bq *BatchQueue) advanceEpoch(nextBatch *SingularBatch) { +func (bq *BatchQueue) advanceEpochMaybe(nextBatch *SingularBatch) { if nextBatch.GetEpochNum() == rollup.Epoch(bq.l1Blocks[0].Number)+1 { // Advance epoch if necessary bq.l1Blocks = bq.l1Blocks[1:] @@ -89,7 +89,7 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) if len(bq.nextSpan) > 0 { // If there are cached singular batches, pop first one and return. nextBatch := bq.popNextBatch(safeL2Head) - bq.advanceEpoch(nextBatch) + bq.advanceEpochMaybe(nextBatch) return nextBatch, nil } @@ -169,7 +169,7 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) return nil, NewCriticalError(fmt.Errorf("unrecognized batch type: %d", batch.GetBatchType())) } - bq.advanceEpoch(nextBatch) + bq.advanceEpochMaybe(nextBatch) return nextBatch, nil } diff --git a/op-node/rollup/derive/batch_queue_test.go b/op-node/rollup/derive/batch_queue_test.go index dee33b866177..f2fbb1b65602 100644 --- a/op-node/rollup/derive/batch_queue_test.go +++ b/op-node/rollup/derive/batch_queue_test.go @@ -771,6 +771,13 @@ func TestBatchQueueOverlappingSpanBatch(t *testing.T) { inputBatches = append(inputBatches, NewSpanBatch(expectedOutputBatches[i:i+batchSize])) } inputBatches = append(inputBatches, nil) + // inputBatches: + // [ + // [12, 14, 16], // No overlap + // [14, 16, 18], // overlapped blocks: 14, 16 + // [16, 18, 20], // overlapped blocks: 16, 18 + // [18, 20, 22], // overlapped blocks: 18, 20 + // ] input := &fakeBatchQueueInput{ batches: inputBatches, @@ -784,8 +791,21 @@ func TestBatchQueueOverlappingSpanBatch(t *testing.T) { if batch != nil { blockRef := singularBatchToBlockRef(t, batch, uint64(i+1)) payload := singularBatchToPayload(t, batch, uint64(i+1)) - l2Client.Mock.On("L2BlockRefByNumber", uint64(i+1)).Times(9999).Return(blockRef, &nilErr) - l2Client.Mock.On("PayloadByNumber", uint64(i+1)).Times(9999).Return(&payload, &nilErr) + if i < 3 { + // In CheckBatch(), "L2BlockRefByNumber" is called when fetching the parent block of overlapped span batch + // so blocks at 12, 14, 16 should be called. + // CheckBatch() is called twice for a batch - before pushing to the queue, after popping from the queue + l2Client.Mock.On("L2BlockRefByNumber", uint64(i+1)).Times(2).Return(blockRef, &nilErr) + } + if i == 1 || i == 4 { + // In CheckBatch(), "PayloadByNumber" is called when fetching the overlapped blocks. + // blocks at 14, 20 are included in overlapped blocks once. + // CheckBatch() is called twice for a batch - before adding to the queue, after getting from the queue + l2Client.Mock.On("PayloadByNumber", uint64(i+1)).Times(2).Return(&payload, &nilErr) + } else if i == 2 || i == 3 { + // blocks at 16, 18 are included in overlapped blocks twice. + l2Client.Mock.On("PayloadByNumber", uint64(i+1)).Times(4).Return(&payload, &nilErr) + } } } @@ -807,6 +827,8 @@ func TestBatchQueueOverlappingSpanBatch(t *testing.T) { safeHead.L1Origin = b.Epoch() } } + + l2Client.Mock.AssertExpectations(t) } func TestBatchQueueComplex(t *testing.T) { @@ -851,12 +873,12 @@ func TestBatchQueueComplex(t *testing.T) { inputErrors := []error{nil, nil, nil, nil, nil, nil, io.EOF} // batches will be returned by fakeBatchQueueInput inputBatches := []Batch{ - NewSpanBatch(expectedOutputBatches[0:2]), // 6, 8 - expectedOutputBatches[2], // 10 - NewSpanBatch(expectedOutputBatches[1:4]), // 8, 10, 12 - expectedOutputBatches[4], // 14 - NewSpanBatch(expectedOutputBatches[4:6]), // 14, 16 - NewSpanBatch(expectedOutputBatches[6:9]), // 18, 20, 22 + NewSpanBatch(expectedOutputBatches[0:2]), // [6, 8] - no overlap + expectedOutputBatches[2], // [10] - no overlap + NewSpanBatch(expectedOutputBatches[1:4]), // [8, 10, 12] - overlapped blocks: 8 or 8, 10 + expectedOutputBatches[4], // [14] - no overlap + NewSpanBatch(expectedOutputBatches[4:6]), // [14, 16] - overlapped blocks: nothing or 14 + NewSpanBatch(expectedOutputBatches[6:9]), // [18, 20, 22] - no overlap } // Shuffle the order of input batches @@ -880,8 +902,16 @@ func TestBatchQueueComplex(t *testing.T) { if batch != nil { blockRef := singularBatchToBlockRef(t, batch, uint64(i+1)) payload := singularBatchToPayload(t, batch, uint64(i+1)) - l2Client.Mock.On("L2BlockRefByNumber", uint64(i+1)).Times(9999).Return(blockRef, &nilErr) - l2Client.Mock.On("PayloadByNumber", uint64(i+1)).Times(9999).Return(&payload, &nilErr) + if i == 0 || i == 3 { + // In CheckBatch(), "L2BlockRefByNumber" is called when fetching the parent block of overlapped span batch + // so blocks at 6, 8 could be called, depends on the order of batches + l2Client.Mock.On("L2BlockRefByNumber", uint64(i+1)).Return(blockRef, &nilErr).Maybe() + } + if i == 1 || i == 2 || i == 4 { + // In CheckBatch(), "PayloadByNumber" is called when fetching the overlapped blocks. + // so blocks at 14, 20 could be called, depends on the order of batches + l2Client.Mock.On("PayloadByNumber", uint64(i+1)).Return(&payload, &nilErr).Maybe() + } } } @@ -916,4 +946,6 @@ func TestBatchQueueComplex(t *testing.T) { safeHead.L1Origin = b.Epoch() } } + + l2Client.Mock.AssertExpectations(t) } From b81df0e69134f3054b967e76c079f5c8fda857b3 Mon Sep 17 00:00:00 2001 From: protolambda Date: Tue, 10 Oct 2023 23:35:59 +0200 Subject: [PATCH 012/374] op-node: sanity check l1Blocks length, fix import --- op-node/rollup/derive/batch_queue.go | 3 +++ op-node/rollup/derive/batch_queue_test.go | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index 9805b1ee0103..5f388a71a927 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -79,6 +79,9 @@ func (bq *BatchQueue) popNextBatch(safeL2Head eth.L2BlockRef) *SingularBatch { } func (bq *BatchQueue) advanceEpochMaybe(nextBatch *SingularBatch) { + if len(bq.l1Blocks) == 0 { + return + } if nextBatch.GetEpochNum() == rollup.Epoch(bq.l1Blocks[0].Number)+1 { // Advance epoch if necessary bq.l1Blocks = bq.l1Blocks[1:] diff --git a/op-node/rollup/derive/batch_queue_test.go b/op-node/rollup/derive/batch_queue_test.go index f2fbb1b65602..3580f78c40d6 100644 --- a/op-node/rollup/derive/batch_queue_test.go +++ b/op-node/rollup/derive/batch_queue_test.go @@ -9,10 +9,9 @@ import ( "math/rand" "testing" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" From d5f9ebfee20434b7154713622412ec0add0c8ffc Mon Sep 17 00:00:00 2001 From: protolambda Date: Tue, 24 Oct 2023 23:00:55 +0200 Subject: [PATCH 013/374] op-node: disallow empty span batches, implement review suggestions --- op-node/rollup/derive/batch_queue.go | 12 +++++-- op-node/rollup/derive/span_batch.go | 10 +++++- op-node/rollup/derive/span_batch_test.go | 42 ++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index 5f388a71a927..a340bc171bff 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -70,7 +70,12 @@ func (bq *BatchQueue) Origin() eth.L1BlockRef { return bq.prev.Origin() } +// popNextBatch pops the next batch from the current queued up span-batch nextSpan. +// The queue must be non-empty, or the function will panic. func (bq *BatchQueue) popNextBatch(safeL2Head eth.L2BlockRef) *SingularBatch { + if len(bq.nextSpan) == 0 { + panic("popping non-existent span-batch, invalid state") + } nextBatch := bq.nextSpan[0] bq.nextSpan = bq.nextSpan[1:] // Must set ParentHash before return. we can use safeL2Head because the parentCheck is verified in CheckBatch(). @@ -78,7 +83,7 @@ func (bq *BatchQueue) popNextBatch(safeL2Head eth.L2BlockRef) *SingularBatch { return nextBatch } -func (bq *BatchQueue) advanceEpochMaybe(nextBatch *SingularBatch) { +func (bq *BatchQueue) maybeAdvanceEpoch(nextBatch *SingularBatch) { if len(bq.l1Blocks) == 0 { return } @@ -92,7 +97,7 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) if len(bq.nextSpan) > 0 { // If there are cached singular batches, pop first one and return. nextBatch := bq.popNextBatch(safeL2Head) - bq.advanceEpochMaybe(nextBatch) + bq.maybeAdvanceEpoch(nextBatch) return nextBatch, nil } @@ -167,12 +172,13 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) return nil, NewCriticalError(err) } bq.nextSpan = singularBatches + // span-batches are non-empty, so the below pop is safe. nextBatch = bq.popNextBatch(safeL2Head) default: return nil, NewCriticalError(fmt.Errorf("unrecognized batch type: %d", batch.GetBatchType())) } - bq.advanceEpochMaybe(nextBatch) + bq.maybeAdvanceEpoch(nextBatch) return nextBatch, nil } diff --git a/op-node/rollup/derive/span_batch.go b/op-node/rollup/derive/span_batch.go index 81baf158bfee..d68d542ff957 100644 --- a/op-node/rollup/derive/span_batch.go +++ b/op-node/rollup/derive/span_batch.go @@ -27,6 +27,8 @@ import ( var ErrTooBigSpanBatchFieldSize = errors.New("batch would cause field bytes to go over limit") +var ErrEmptySpanBatch = errors.New("span-batch must not be empty") + type spanBatchPrefix struct { relTimestamp uint64 // Relative timestamp of the first block l1OriginNum uint64 // L1 origin number @@ -139,10 +141,13 @@ func (bp *spanBatchPrefix) decodePrefix(r *bytes.Reader) error { // decodeBlockCount parses data into bp.blockCount func (bp *spanBatchPayload) decodeBlockCount(r *bytes.Reader) error { blockCount, err := binary.ReadUvarint(r) - bp.blockCount = blockCount if err != nil { return fmt.Errorf("failed to read block count: %w", err) } + bp.blockCount = blockCount + if blockCount == 0 { + return ErrEmptySpanBatch + } return nil } @@ -362,6 +367,9 @@ func (b *RawSpanBatch) encodeBytes() ([]byte, error) { // derive converts RawSpanBatch into SpanBatch, which has a list of spanBatchElement. // We need chain config constants to derive values for making payload attributes. func (b *RawSpanBatch) derive(blockTime, genesisTimestamp uint64, chainID *big.Int) (*SpanBatch, error) { + if b.blockCount == 0 { + return nil, ErrEmptySpanBatch + } blockOriginNums := make([]uint64, b.blockCount) l1OriginBlockNumber := b.l1OriginNum for i := int(b.blockCount) - 1; i >= 0; i-- { diff --git a/op-node/rollup/derive/span_batch_test.go b/op-node/rollup/derive/span_batch_test.go index 3348b358a1cf..d2a0ac3f8d54 100644 --- a/op-node/rollup/derive/span_batch_test.go +++ b/op-node/rollup/derive/span_batch_test.go @@ -6,12 +6,15 @@ import ( "math/rand" "testing" - "github.com/ethereum-optimism/optimism/op-node/rollup" - "github.com/ethereum-optimism/optimism/op-service/testutils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" - "github.com/stretchr/testify/assert" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/testutils" ) func TestSpanBatchForBatchInterface(t *testing.T) { @@ -33,6 +36,39 @@ func TestSpanBatchForBatchInterface(t *testing.T) { assert.True(t, spanBatch.CheckParentHash(singularBatches[0].ParentHash)) } +func TestEmptySpanBatch(t *testing.T) { + rng := rand.New(rand.NewSource(0x77556691)) + chainID := big.NewInt(rng.Int63n(1000)) + spanTxs, err := newSpanBatchTxs(nil, chainID) + require.NoError(t, err) + + rawSpanBatch := RawSpanBatch{ + spanBatchPrefix: spanBatchPrefix{ + relTimestamp: uint64(rng.Uint32()), + l1OriginNum: rng.Uint64(), + parentCheck: testutils.RandomData(rng, 20), + l1OriginCheck: testutils.RandomData(rng, 20), + }, + spanBatchPayload: spanBatchPayload{ + blockCount: 0, + originBits: big.NewInt(0), + blockTxCounts: []uint64{}, + txs: spanTxs, + }, + } + + var buf bytes.Buffer + err = rawSpanBatch.encodeBlockCount(&buf) + assert.NoError(t, err) + + result := buf.Bytes() + r := bytes.NewReader(result) + var sb RawSpanBatch + + err = sb.decodeBlockCount(r) + require.ErrorIs(t, err, ErrEmptySpanBatch) +} + func TestSpanBatchOriginBits(t *testing.T) { rng := rand.New(rand.NewSource(0x77665544)) chainID := big.NewInt(rng.Int63n(1000)) From 2f8c136b1b86e0cd51d2f56ce798b044f1fcbf28 Mon Sep 17 00:00:00 2001 From: tre Date: Tue, 24 Oct 2023 17:01:55 -0700 Subject: [PATCH 014/374] config for optimism-goerli --- .../periphery-deploy-config/optimism-goerli.json | 10 +++++----- .../contracts-bedrock/scripts/DeployPeriphery.s.sol | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json b/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json index ecc0e38255af..a429b89f9a69 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json +++ b/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json @@ -1,6 +1,6 @@ { - "faucetAdmin": "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819", - "faucetDrippieOwner": "0xEa193Fd9565284E7534dDDA15b07B119e7792644", + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", "faucetDripV1Value": 20000000000000000000, "faucetDripV1Interval": 3600, "faucetDripV1Threshold": 100000000000000000000, @@ -11,14 +11,14 @@ "faucetAdminDripV1Threshold": 100000000000000000, "faucetAdminDripV1Value": 1000000000000000000, "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", - "faucetGelatoRecipient": "0x789e58a4B08A23a7f60141959C6ABbdC0D0C4Aba", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", "faucetGelatoBalanceV1DripInterval": 86400, "faucetGelatoBalanceV1Value": 1000000000000000000, "faucetGelatoThreshold": 100000000000000000, - "faucetOnchainAuthModuleAdmin": "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819", + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOnchainAuthModuleTtl": 86400, "faucetOnchainAuthModuleAmount": 1000000000000000000, - "faucetOffchainAuthModuleAdmin": "0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819", + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleAmount": 50000000000000000 } diff --git a/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol b/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol index 3cb7519832d5..9099a21a02ce 100644 --- a/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol +++ b/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol @@ -468,7 +468,7 @@ contract DeployPeriphery is Deployer { /// @notice installs the OnChain AuthModule on the Faucet contract. function installOnChainAuthModule() public broadcast { string memory moduleName = "OnChainAuthModule"; - Faucet faucet = Faucet(mustGetAddress("Faucet")); + Faucet faucet = Faucet(mustGetAddress("FaucetProxy")); AdminFaucetAuthModule onChainAuthModule = AdminFaucetAuthModule(mustGetAddress(moduleName)); if (faucet.isModuleEnabled(onChainAuthModule)) { console.log("%s already installed.", moduleName); @@ -488,7 +488,7 @@ contract DeployPeriphery is Deployer { /// @notice installs the OffChain AuthModule on the Faucet contract. function installOffChainAuthModule() public broadcast { string memory moduleName = "OffChainAuthModule"; - Faucet faucet = Faucet(mustGetAddress("Faucet")); + Faucet faucet = Faucet(mustGetAddress("FaucetProxy")); AdminFaucetAuthModule offChainAuthModule = AdminFaucetAuthModule(mustGetAddress(moduleName)); if (faucet.isModuleEnabled(offChainAuthModule)) { console.log("%s already installed.", moduleName); @@ -507,7 +507,7 @@ contract DeployPeriphery is Deployer { /// @notice installs all of the auth module in the faucet contract. function installFaucetAuthModulesConfigs() public { - Faucet faucet = Faucet(mustGetAddress("Faucet")); + Faucet faucet = Faucet(mustGetAddress("FaucetProxy")); console.log("Installing auth modules at %s", address(faucet)); installOnChainAuthModule(); installOffChainAuthModule(); From 460bb3f31cadf0bdc6b5f70c9a57ace068e06554 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Mon, 18 Sep 2023 16:48:09 +0900 Subject: [PATCH 015/374] Implement span batch submission for op-batcher --- op-batcher/batcher/channel.go | 4 +- op-batcher/batcher/channel_builder.go | 17 +- op-batcher/batcher/channel_builder_test.go | 253 ++++++++++++++------- op-batcher/batcher/channel_manager.go | 38 +++- op-batcher/batcher/channel_manager_test.go | 123 +++++++--- op-batcher/batcher/channel_test.go | 13 +- op-batcher/batcher/config.go | 3 + op-batcher/batcher/driver.go | 41 +++- op-batcher/batcher/service.go | 1 + op-batcher/flags/flags.go | 7 + op-e2e/actions/l2_batcher.go | 2 +- op-e2e/setup.go | 8 +- op-node/rollup/derive/channel_out.go | 173 +++++++++++--- op-node/rollup/derive/channel_out_test.go | 22 +- ops-bedrock/docker-compose.yml | 1 + 15 files changed, 524 insertions(+), 182 deletions(-) diff --git a/op-batcher/batcher/channel.go b/op-batcher/batcher/channel.go index d42679eb34d5..cd44f31a9c46 100644 --- a/op-batcher/batcher/channel.go +++ b/op-batcher/batcher/channel.go @@ -26,8 +26,8 @@ type channel struct { confirmedTransactions map[txID]eth.BlockID } -func newChannel(log log.Logger, metr metrics.Metricer, cfg ChannelConfig) (*channel, error) { - cb, err := newChannelBuilder(cfg) +func newChannel(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, spanBatchBuilder *derive.SpanBatchBuilder) (*channel, error) { + cb, err := newChannelBuilder(cfg, spanBatchBuilder) if err != nil { return nil, fmt.Errorf("creating new channel: %w", err) } diff --git a/op-batcher/batcher/channel_builder.go b/op-batcher/batcher/channel_builder.go index 551e5d96e672..33e236c2dd93 100644 --- a/op-batcher/batcher/channel_builder.go +++ b/op-batcher/batcher/channel_builder.go @@ -58,6 +58,9 @@ type ChannelConfig struct { // CompressorConfig contains the configuration for creating new compressors. CompressorConfig compressor.Config + + // BatchType indicates whether the channel uses SingularBatch or SpanBatch. + BatchType uint } // Check validates the [ChannelConfig] parameters. @@ -83,6 +86,10 @@ func (cc *ChannelConfig) Check() error { return fmt.Errorf("max frame size %d is less than the minimum 23", cc.MaxFrameSize) } + if cc.BatchType > derive.SpanBatchType { + return fmt.Errorf("unrecognized batch type: %d", cc.BatchType) + } + return nil } @@ -127,12 +134,12 @@ type channelBuilder struct { // newChannelBuilder creates a new channel builder or returns an error if the // channel out could not be created. -func newChannelBuilder(cfg ChannelConfig) (*channelBuilder, error) { +func newChannelBuilder(cfg ChannelConfig, spanBatchBuilder *derive.SpanBatchBuilder) (*channelBuilder, error) { c, err := cfg.CompressorConfig.NewCompressor() if err != nil { return nil, err } - co, err := derive.NewChannelOut(c) + co, err := derive.NewChannelOut(c, cfg.BatchType, spanBatchBuilder) if err != nil { return nil, err } @@ -194,12 +201,12 @@ func (c *channelBuilder) AddBlock(block *types.Block) (derive.L1BlockInfo, error return derive.L1BlockInfo{}, c.FullErr() } - batch, l1info, err := derive.BlockToBatch(block) + batch, l1info, err := derive.BlockToSingularBatch(block) if err != nil { return l1info, fmt.Errorf("converting block to batch: %w", err) } - if _, err = c.co.AddBatch(batch); errors.Is(err, derive.ErrTooManyRLPBytes) || errors.Is(err, derive.CompressorFullErr) { + if _, err = c.co.AddSingularBatch(batch); errors.Is(err, derive.ErrTooManyRLPBytes) || errors.Is(err, derive.CompressorFullErr) { c.setFullErr(err) return l1info, c.FullErr() } else if err != nil { @@ -252,7 +259,7 @@ func (c *channelBuilder) updateDurationTimeout(l1BlockNum uint64) { // derived from the batch's origin L1 block. The timeout is only moved forward // if the derived sequencer window timeout is earlier than the currently set // timeout. -func (c *channelBuilder) updateSwTimeout(batch *derive.BatchData) { +func (c *channelBuilder) updateSwTimeout(batch *derive.SingularBatch) { timeout := uint64(batch.EpochNum) + c.cfg.SeqWindowSize - c.cfg.SubSafetyMargin c.updateTimeout(timeout, ErrSeqWindowClose) } diff --git a/op-batcher/batcher/channel_builder_test.go b/op-batcher/batcher/channel_builder_test.go index 45ee5cef0bf0..51c3d76af380 100644 --- a/op-batcher/batcher/channel_builder_test.go +++ b/op-batcher/batcher/channel_builder_test.go @@ -32,6 +32,15 @@ var defaultTestChannelConfig = ChannelConfig{ TargetNumFrames: 1, ApproxComprRatio: 0.4, }, + BatchType: derive.SingularBatchType, +} + +func getSpanBatchBuilder(batchType uint) *derive.SpanBatchBuilder { + if batchType == derive.SpanBatchType { + chainId := big.NewInt(1234) + return derive.NewSpanBatchBuilder(uint64(0), uint64(0), chainId) + } + return nil } // TestChannelConfig_Check tests the [ChannelConfig] [Check] function. @@ -158,8 +167,9 @@ func newMiniL2BlockWithNumberParent(numTx int, number *big.Int, parent common.Ha // addTooManyBlocks adds blocks to the channel until it hits an error, // which is presumably ErrTooManyRLPBytes. func addTooManyBlocks(cb *channelBuilder) error { + rng := rand.New(rand.NewSource(1234)) for i := 0; i < 10_000; i++ { - block := newMiniL2Block(100) + block, _ := dtest.RandomL2Block(rng, 1000) _, err := cb.AddBlock(block) if err != nil { return err @@ -178,7 +188,7 @@ func FuzzDurationTimeoutZeroMaxChannelDuration(f *testing.F) { f.Fuzz(func(t *testing.T, l1BlockNum uint64) { channelConfig := defaultTestChannelConfig channelConfig.MaxChannelDuration = 0 - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) cb.timeout = 0 cb.updateDurationTimeout(l1BlockNum) @@ -201,7 +211,7 @@ func FuzzChannelBuilder_DurationZero(f *testing.F) { // Create the channel builder channelConfig := defaultTestChannelConfig channelConfig.MaxChannelDuration = maxChannelDuration - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Whenever the timeout is set to 0, the channel builder should have a duration timeout @@ -228,7 +238,7 @@ func FuzzDurationTimeoutMaxChannelDuration(f *testing.F) { // Create the channel builder channelConfig := defaultTestChannelConfig channelConfig.MaxChannelDuration = maxChannelDuration - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Whenever the timeout is greater than the l1BlockNum, @@ -262,7 +272,7 @@ func FuzzChannelCloseTimeout(f *testing.F) { channelConfig := defaultTestChannelConfig channelConfig.ChannelTimeout = channelTimeout channelConfig.SubSafetyMargin = subSafetyMargin - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Check the timeout @@ -290,7 +300,7 @@ func FuzzChannelZeroCloseTimeout(f *testing.F) { channelConfig := defaultTestChannelConfig channelConfig.ChannelTimeout = channelTimeout channelConfig.SubSafetyMargin = subSafetyMargin - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Check the timeout @@ -317,16 +327,12 @@ func FuzzSeqWindowClose(f *testing.F) { channelConfig := defaultTestChannelConfig channelConfig.SeqWindowSize = seqWindowSize channelConfig.SubSafetyMargin = subSafetyMargin - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Check the timeout cb.timeout = timeout - cb.updateSwTimeout(derive.NewSingularBatchData( - derive.SingularBatch{ - EpochNum: rollup.Epoch(epochNum), - }, - )) + cb.updateSwTimeout(&derive.SingularBatch{EpochNum: rollup.Epoch(epochNum)}) calculatedTimeout := epochNum + seqWindowSize - subSafetyMargin if timeout > calculatedTimeout && calculatedTimeout != 0 { cb.checkTimeout(calculatedTimeout) @@ -349,16 +355,12 @@ func FuzzSeqWindowZeroTimeoutClose(f *testing.F) { channelConfig := defaultTestChannelConfig channelConfig.SeqWindowSize = seqWindowSize channelConfig.SubSafetyMargin = subSafetyMargin - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Check the timeout cb.timeout = 0 - cb.updateSwTimeout(derive.NewSingularBatchData( - derive.SingularBatch{ - EpochNum: rollup.Epoch(epochNum), - }, - )) + cb.updateSwTimeout(&derive.SingularBatch{EpochNum: rollup.Epoch(epochNum)}) calculatedTimeout := epochNum + seqWindowSize - subSafetyMargin cb.checkTimeout(calculatedTimeout) if cb.timeout != 0 { @@ -367,12 +369,40 @@ func FuzzSeqWindowZeroTimeoutClose(f *testing.F) { }) } +func TestChannelBuilderBatchType(t *testing.T) { + tests := []struct { + name string + f func(t *testing.T, batchType uint) + }{ + {"ChannelBuilder_MaxRLPBytesPerChannel", ChannelBuilder_MaxRLPBytesPerChannel}, + {"ChannelBuilder_OutputFramesMaxFrameIndex", ChannelBuilder_OutputFramesMaxFrameIndex}, + {"ChannelBuilder_AddBlock", ChannelBuilder_AddBlock}, + {"ChannelBuilder_Reset", ChannelBuilder_Reset}, + {"ChannelBuilder_PendingFrames_TotalFrames", ChannelBuilder_PendingFrames_TotalFrames}, + {"ChannelBuilder_InputBytes", ChannelBuilder_InputBytes}, + {"ChannelBuilder_OutputBytes", ChannelBuilder_OutputBytes}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, derive.SingularBatchType) + }) + } + + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, derive.SpanBatchType) + }) + } +} + // TestChannelBuilder_NextFrame tests calling NextFrame on a ChannelBuilder with only one frame func TestChannelBuilder_NextFrame(t *testing.T) { channelConfig := defaultTestChannelConfig // Create a new channel builder - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Mock the internals of `channelBuilder.outputFrame` @@ -412,14 +442,14 @@ func TestChannelBuilder_OutputWrongFramePanic(t *testing.T) { channelConfig := defaultTestChannelConfig // Construct a channel builder - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Mock the internals of `channelBuilder.outputFrame` // to construct a single frame c, err := channelConfig.CompressorConfig.NewCompressor() require.NoError(t, err) - co, err := derive.NewChannelOut(c) + co, err := derive.NewChannelOut(c, derive.SingularBatchType, nil) require.NoError(t, err) var buf bytes.Buffer fn, err := co.OutputFrame(&buf, channelConfig.MaxFrameSize) @@ -445,7 +475,7 @@ func TestChannelBuilder_OutputFramesWorks(t *testing.T) { channelConfig.MaxFrameSize = 24 // Construct the channel builder - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) require.False(t, cb.IsFull()) require.Equal(t, 0, cb.PendingFrames()) @@ -480,17 +510,68 @@ func TestChannelBuilder_OutputFramesWorks(t *testing.T) { } } -// TestChannelBuilder_MaxRLPBytesPerChannel tests the [channelBuilder.OutputFrames] +// TestChannelBuilder_OutputFramesWorks tests the [ChannelBuilder] OutputFrames is successful. +func TestChannelBuilder_OutputFramesWorks_SpanBatch(t *testing.T) { + channelConfig := defaultTestChannelConfig + channelConfig.MaxFrameSize = 24 + channelConfig.CompressorConfig.TargetFrameSize = 50 + channelConfig.BatchType = derive.SpanBatchType + + // Construct the channel builder + cb, err := newChannelBuilder(channelConfig, getSpanBatchBuilder(derive.SpanBatchType)) + require.NoError(t, err) + require.False(t, cb.IsFull()) + require.Equal(t, 0, cb.PendingFrames()) + + // Calling OutputFrames without having called [AddBlock] + // should return no error + require.NoError(t, cb.OutputFrames()) + + // There should be no ready bytes yet + require.Equal(t, 0, cb.co.ReadyBytes()) + + // fill up + for { + err = addMiniBlock(cb) + if err == nil { + require.False(t, cb.IsFull()) + // There should be no ready bytes until the channel is full + require.Equal(t, cb.co.ReadyBytes(), 0) + } else { + require.ErrorIs(t, err, derive.CompressorFullErr) + break + } + } + + require.True(t, cb.IsFull()) + // Check how many ready bytes + // There should be more than the max frame size ready + require.Greater(t, uint64(cb.co.ReadyBytes()), channelConfig.MaxFrameSize) + require.Equal(t, 0, cb.PendingFrames()) + + // We should be able to output the frames + require.NoError(t, cb.OutputFrames()) + + // There should be many frames in the channel builder now + require.Greater(t, cb.PendingFrames(), 1) + for i := 0; i < cb.numFrames-1; i++ { + require.Len(t, cb.frames[i].data, int(channelConfig.MaxFrameSize)) + } + require.LessOrEqual(t, len(cb.frames[len(cb.frames)-1].data), int(channelConfig.MaxFrameSize)) +} + +// ChannelBuilder_MaxRLPBytesPerChannel tests the [channelBuilder.OutputFrames] // function errors when the max RLP bytes per channel is reached. -func TestChannelBuilder_MaxRLPBytesPerChannel(t *testing.T) { +func ChannelBuilder_MaxRLPBytesPerChannel(t *testing.T, batchType uint) { t.Parallel() channelConfig := defaultTestChannelConfig channelConfig.MaxFrameSize = derive.MaxRLPBytesPerChannel * 2 channelConfig.CompressorConfig.TargetFrameSize = derive.MaxRLPBytesPerChannel * 2 channelConfig.CompressorConfig.ApproxComprRatio = 1 + channelConfig.BatchType = batchType // Construct the channel builder - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, getSpanBatchBuilder(batchType)) require.NoError(t, err) // Add a block that overflows the [ChannelOut] @@ -498,61 +579,55 @@ func TestChannelBuilder_MaxRLPBytesPerChannel(t *testing.T) { require.ErrorIs(t, err, derive.ErrTooManyRLPBytes) } -// TestChannelBuilder_OutputFramesMaxFrameIndex tests the [ChannelBuilder.OutputFrames] +// ChannelBuilder_OutputFramesMaxFrameIndex tests the [ChannelBuilder.OutputFrames] // function errors when the max frame index is reached. -func TestChannelBuilder_OutputFramesMaxFrameIndex(t *testing.T) { +func ChannelBuilder_OutputFramesMaxFrameIndex(t *testing.T, batchType uint) { channelConfig := defaultTestChannelConfig channelConfig.MaxFrameSize = 24 - channelConfig.CompressorConfig.TargetNumFrames = math.MaxInt + channelConfig.CompressorConfig.TargetNumFrames = 6000 channelConfig.CompressorConfig.TargetFrameSize = 24 - channelConfig.CompressorConfig.ApproxComprRatio = 0 + channelConfig.CompressorConfig.ApproxComprRatio = 1 + channelConfig.BatchType = batchType + + rng := rand.New(rand.NewSource(123)) // Continuously add blocks until the max frame index is reached // This should cause the [channelBuilder.OutputFrames] function // to error - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, getSpanBatchBuilder(batchType)) require.NoError(t, err) require.False(t, cb.IsFull()) require.Equal(t, 0, cb.PendingFrames()) for { - lBlock := types.NewBlock(&types.Header{ - BaseFee: common.Big0, - Difficulty: common.Big0, - Number: common.Big0, - }, nil, nil, nil, trie.NewStackTrie(nil)) - l1InfoTx, _ := derive.L1InfoDeposit(0, eth.BlockToInfo(lBlock), eth.SystemConfig{}, false) - txs := []*types.Transaction{types.NewTx(l1InfoTx)} - a := types.NewBlock(&types.Header{ - Number: big.NewInt(0), - }, txs, nil, nil, trie.NewStackTrie(nil)) + a, _ := dtest.RandomL2Block(rng, 1) _, err = cb.AddBlock(a) - require.NoError(t, cb.co.Flush()) if cb.IsFull() { fullErr := cb.FullErr() - require.ErrorIs(t, fullErr, ErrMaxFrameIndex) + require.ErrorIs(t, fullErr, derive.CompressorFullErr) break } require.NoError(t, err) - _ = cb.OutputFrames() - // Flushing so we can construct new frames - _ = cb.co.Flush() } + + _ = cb.OutputFrames() + require.ErrorIs(t, cb.FullErr(), ErrMaxFrameIndex) } -// TestChannelBuilder_AddBlock tests the AddBlock function -func TestChannelBuilder_AddBlock(t *testing.T) { +// ChannelBuilder_AddBlock tests the AddBlock function +func ChannelBuilder_AddBlock(t *testing.T, batchType uint) { channelConfig := defaultTestChannelConfig + channelConfig.BatchType = batchType // Lower the max frame size so that we can batch - channelConfig.MaxFrameSize = 30 + channelConfig.MaxFrameSize = 20 // Configure the Input Threshold params so we observe a full channel - channelConfig.CompressorConfig.TargetFrameSize = 30 + channelConfig.CompressorConfig.TargetFrameSize = 20 channelConfig.CompressorConfig.TargetNumFrames = 2 channelConfig.CompressorConfig.ApproxComprRatio = 1 // Construct the channel builder - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, getSpanBatchBuilder(batchType)) require.NoError(t, err) // Add a nonsense block to the channel builder @@ -560,7 +635,11 @@ func TestChannelBuilder_AddBlock(t *testing.T) { require.NoError(t, cb.co.Flush()) // Check the fields reset in the AddBlock function - require.Equal(t, 74, cb.co.InputBytes()) + expectedInputBytes := 74 + if batchType == derive.SpanBatchType { + expectedInputBytes = 47 + } + require.Equal(t, expectedInputBytes, cb.co.InputBytes()) require.Equal(t, 1, len(cb.blocks)) require.Equal(t, 0, len(cb.frames)) require.True(t, cb.IsFull()) @@ -570,14 +649,18 @@ func TestChannelBuilder_AddBlock(t *testing.T) { require.ErrorIs(t, addMiniBlock(cb), derive.CompressorFullErr) } -// TestChannelBuilder_Reset tests the [Reset] function -func TestChannelBuilder_Reset(t *testing.T) { +// ChannelBuilder_Reset tests the [Reset] function +func ChannelBuilder_Reset(t *testing.T, batchType uint) { channelConfig := defaultTestChannelConfig + channelConfig.BatchType = batchType // Lower the max frame size so that we can batch channelConfig.MaxFrameSize = 24 + channelConfig.CompressorConfig.TargetNumFrames = 1 + channelConfig.CompressorConfig.TargetFrameSize = 24 + channelConfig.CompressorConfig.ApproxComprRatio = 1 - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, getSpanBatchBuilder(batchType)) require.NoError(t, err) // Add a nonsense block to the channel builder @@ -590,20 +673,16 @@ func TestChannelBuilder_Reset(t *testing.T) { // Timeout should be updated in the AddBlock internal call to `updateSwTimeout` timeout := uint64(100) + cb.cfg.SeqWindowSize - cb.cfg.SubSafetyMargin require.Equal(t, timeout, cb.timeout) - require.NoError(t, cb.fullErr) + require.Error(t, cb.fullErr) // Output frames so we can set the channel builder frames require.NoError(t, cb.OutputFrames()) - // Add another block to increment the block count - require.NoError(t, addMiniBlock(cb)) - require.NoError(t, cb.co.Flush()) - // Check the fields reset in the Reset function - require.Equal(t, 2, len(cb.blocks)) - require.Greater(t, len(cb.frames), 1) + require.Equal(t, 1, len(cb.blocks)) require.Equal(t, timeout, cb.timeout) - require.NoError(t, cb.fullErr) + require.Error(t, cb.fullErr) + require.Greater(t, len(cb.frames), 1) // Reset the channel builder require.NoError(t, cb.Reset()) @@ -622,7 +701,7 @@ func TestBuilderRegisterL1Block(t *testing.T) { channelConfig := defaultTestChannelConfig // Construct the channel builder - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Assert params modified in RegisterL1Block @@ -645,7 +724,7 @@ func TestBuilderRegisterL1BlockZeroMaxChannelDuration(t *testing.T) { channelConfig.MaxChannelDuration = 0 // Construct the channel builder - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Assert params modified in RegisterL1Block @@ -666,7 +745,7 @@ func TestFramePublished(t *testing.T) { channelConfig := defaultTestChannelConfig // Construct the channel builder - cb, err := newChannelBuilder(channelConfig) + cb, err := newChannelBuilder(channelConfig, nil) require.NoError(t, err) // Let's say the block number is fed in as 100 @@ -682,7 +761,7 @@ func TestFramePublished(t *testing.T) { require.Equal(t, uint64(1000), cb.timeout) } -func TestChannelBuilder_PendingFrames_TotalFrames(t *testing.T) { +func ChannelBuilder_PendingFrames_TotalFrames(t *testing.T, batchType uint) { const tnf = 8 rng := rand.New(rand.NewSource(94572314)) require := require.New(t) @@ -691,7 +770,8 @@ func TestChannelBuilder_PendingFrames_TotalFrames(t *testing.T) { cfg.MaxFrameSize = 1000 cfg.CompressorConfig.TargetNumFrames = tnf cfg.CompressorConfig.Kind = "shadow" - cb, err := newChannelBuilder(cfg) + cfg.BatchType = batchType + cb, err := newChannelBuilder(cfg, getSpanBatchBuilder(batchType)) require.NoError(err) // initial builder should be empty @@ -725,25 +805,40 @@ func TestChannelBuilder_PendingFrames_TotalFrames(t *testing.T) { } } -func TestChannelBuilder_InputBytes(t *testing.T) { +func ChannelBuilder_InputBytes(t *testing.T, batchType uint) { require := require.New(t) rng := rand.New(rand.NewSource(4982432)) - cb, _ := defaultChannelBuilderSetup(t) + cfg := defaultTestChannelConfig + cfg.BatchType = batchType + spanBatchBuilder := getSpanBatchBuilder(batchType) + cb, err := newChannelBuilder(cfg, getSpanBatchBuilder(batchType)) + require.NoError(err) require.Zero(cb.InputBytes()) var l int for i := 0; i < 5; i++ { block := newMiniL2Block(rng.Intn(32)) - l += blockBatchRlpSize(t, block) - + if batchType == derive.SingularBatchType { + l += blockBatchRlpSize(t, block) + } else { + singularBatch, _, err := derive.BlockToSingularBatch(block) + require.NoError(err) + spanBatchBuilder.AppendSingularBatch(singularBatch) + rawSpanBatch, err := spanBatchBuilder.GetRawSpanBatch() + require.NoError(err) + batch := derive.NewSpanBatchData(*rawSpanBatch) + var buf bytes.Buffer + require.NoError(batch.EncodeRLP(&buf)) + l = buf.Len() + } _, err := cb.AddBlock(block) require.NoError(err) require.Equal(cb.InputBytes(), l) } } -func TestChannelBuilder_OutputBytes(t *testing.T) { +func ChannelBuilder_OutputBytes(t *testing.T, batchType uint) { require := require.New(t) rng := rand.New(rand.NewSource(9860372)) cfg := defaultTestChannelConfig @@ -751,7 +846,8 @@ func TestChannelBuilder_OutputBytes(t *testing.T) { cfg.MaxFrameSize = 1000 cfg.CompressorConfig.TargetNumFrames = 16 cfg.CompressorConfig.ApproxComprRatio = 1.0 - cb, err := newChannelBuilder(cfg) + cfg.BatchType = batchType + cb, err := newChannelBuilder(cfg, getSpanBatchBuilder(batchType)) require.NoError(err, "newChannelBuilder") require.Zero(cb.OutputBytes()) @@ -778,17 +874,10 @@ func TestChannelBuilder_OutputBytes(t *testing.T) { require.Equal(cb.OutputBytes(), flen) } -func defaultChannelBuilderSetup(t *testing.T) (*channelBuilder, ChannelConfig) { - t.Helper() - cfg := defaultTestChannelConfig - cb, err := newChannelBuilder(cfg) - require.NoError(t, err, "newChannelBuilder") - return cb, cfg -} - func blockBatchRlpSize(t *testing.T, b *types.Block) int { t.Helper() - batch, _, err := derive.BlockToBatch(b) + singularBatch, _, err := derive.BlockToSingularBatch(b) + batch := derive.NewSingularBatchData(*singularBatch) require.NoError(t, err) var buf bytes.Buffer require.NoError(t, batch.EncodeRLP(&buf), "RLP-encoding batch") diff --git a/op-batcher/batcher/channel_manager.go b/op-batcher/batcher/channel_manager.go index 052b9dbe1e3c..dc00fab364e9 100644 --- a/op-batcher/batcher/channel_manager.go +++ b/op-batcher/batcher/channel_manager.go @@ -7,6 +7,7 @@ import ( "sync" "github.com/ethereum-optimism/optimism/op-batcher/metrics" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" @@ -28,12 +29,16 @@ type channelManager struct { log log.Logger metr metrics.Metricer cfg ChannelConfig + rcfg *rollup.Config // All blocks since the last request for new tx data. blocks []*types.Block // last block hash - for reorg detection tip common.Hash + // last block added to channel. nil at first. + lastProcessedBlock *eth.L2BlockRef + // channel to write new block data to currentChannel *channel // channels to read frame data from, for writing batches onchain @@ -45,18 +50,21 @@ type channelManager struct { closed bool } -func NewChannelManager(log log.Logger, metr metrics.Metricer, cfg ChannelConfig) *channelManager { +func NewChannelManager(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, rcfg *rollup.Config) *channelManager { return &channelManager{ - log: log, - metr: metr, - cfg: cfg, - txChannels: make(map[txID]*channel), + log: log, + metr: metr, + cfg: cfg, + rcfg: rcfg, + txChannels: make(map[txID]*channel), + lastProcessedBlock: nil, } } // Clear clears the entire state of the channel manager. -// It is intended to be used after an L2 reorg. -func (s *channelManager) Clear() { +// It is intended to be used before launching op-batcher and after an L2 reorg. +// Must set lastProcessedBlock as current L2 safe head fetched from L2 node. +func (s *channelManager) Clear(safeHead *eth.L2BlockRef) { s.mu.Lock() defer s.mu.Unlock() s.log.Trace("clearing channel manager state") @@ -66,6 +74,7 @@ func (s *channelManager) Clear() { s.currentChannel = nil s.channelQueue = nil s.txChannels = make(map[txID]*channel) + s.lastProcessedBlock = safeHead } // TxFailed records a transaction as failed. It will attempt to resubmit the data @@ -195,7 +204,19 @@ func (s *channelManager) ensureChannelWithSpace(l1Head eth.BlockID) error { return nil } - pc, err := newChannel(s.log, s.metr, s.cfg) + var spanBatchBuilder *derive.SpanBatchBuilder + if s.cfg.BatchType == derive.SpanBatchType { + if s.lastProcessedBlock == nil { + // TODO: we can remove "lastProcessedBlock" if we change the data-builder + // to append a singular-batch *with* the L2 metadata such as the L1-block-info seq-number; + // this helps determine whether or not the L1 origin changed in the first block of the span, + // without having to remember the last block from before the span. + return errors.New("last block is not initialized") + } + // Pass the current lastProcessedBlock as the parent + spanBatchBuilder = derive.NewSpanBatchBuilder(s.lastProcessedBlock.L1Origin.Number, s.rcfg.Genesis.L2Time, s.rcfg.L2ChainID) + } + pc, err := newChannel(s.log, s.metr, s.cfg, spanBatchBuilder) if err != nil { return fmt.Errorf("creating new channel: %w", err) } @@ -241,6 +262,7 @@ func (s *channelManager) processBlocks() error { blocksAdded += 1 latestL2ref = l2BlockRefFromBlockAndL1Info(block, l1info) s.metr.RecordL2BlockInChannel(block) + s.lastProcessedBlock = &latestL2ref // current block got added but channel is now full if s.currentChannel.IsFull() { break diff --git a/op-batcher/batcher/channel_manager_test.go b/op-batcher/batcher/channel_manager_test.go index 4621dde1bdb9..b68d13e4cc8b 100644 --- a/op-batcher/batcher/channel_manager_test.go +++ b/op-batcher/batcher/channel_manager_test.go @@ -9,21 +9,53 @@ import ( "github.com/ethereum-optimism/optimism/op-batcher/compressor" "github.com/ethereum-optimism/optimism/op-batcher/metrics" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" derivetest "github.com/ethereum-optimism/optimism/op-node/rollup/derive/test" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" ) -// TestChannelManagerReturnsErrReorg ensures that the channel manager +func TestChannelManagerBatchType(t *testing.T) { + tests := []struct { + name string + f func(t *testing.T, batchType uint) + }{ + {"ChannelManagerReturnsErrReorg", ChannelManagerReturnsErrReorg}, + {"ChannelManagerReturnsErrReorgWhenDrained", ChannelManagerReturnsErrReorgWhenDrained}, + {"ChannelManager_Clear", ChannelManager_Clear}, + {"ChannelManager_TxResend", ChannelManager_TxResend}, + {"ChannelManagerCloseBeforeFirstUse", ChannelManagerCloseBeforeFirstUse}, + {"ChannelManagerCloseNoPendingChannel", ChannelManagerCloseNoPendingChannel}, + {"ChannelManagerClosePendingChannel", ChannelManagerClosePendingChannel}, + {"ChannelManagerCloseAllTxsFailed", ChannelManagerCloseAllTxsFailed}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, derive.SingularBatchType) + }) + } + + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, derive.SpanBatchType) + }) + } +} + +// ChannelManagerReturnsErrReorg ensures that the channel manager // detects a reorg when it has cached L1 blocks. -func TestChannelManagerReturnsErrReorg(t *testing.T) { +func ChannelManagerReturnsErrReorg(t *testing.T, batchType uint) { log := testlog.Logger(t, log.LvlCrit) - m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{}) + m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{BatchType: batchType}, &rollup.Config{}) + m.Clear(ð.L2BlockRef{}) a := types.NewBlock(&types.Header{ Number: big.NewInt(0), @@ -49,9 +81,9 @@ func TestChannelManagerReturnsErrReorg(t *testing.T) { require.Equal(t, []*types.Block{a, b, c}, m.blocks) } -// TestChannelManagerReturnsErrReorgWhenDrained ensures that the channel manager +// ChannelManagerReturnsErrReorgWhenDrained ensures that the channel manager // detects a reorg even if it does not have any blocks inside it. -func TestChannelManagerReturnsErrReorgWhenDrained(t *testing.T) { +func ChannelManagerReturnsErrReorgWhenDrained(t *testing.T, batchType uint) { log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{ @@ -61,7 +93,11 @@ func TestChannelManagerReturnsErrReorgWhenDrained(t *testing.T) { TargetNumFrames: 1, ApproxComprRatio: 1.0, }, - }) + BatchType: batchType, + }, + &rollup.Config{}, + ) + m.Clear(ð.L2BlockRef{}) a := newMiniL2Block(0) x := newMiniL2BlockWithNumberParent(0, big.NewInt(1), common.Hash{0xff}) @@ -76,8 +112,8 @@ func TestChannelManagerReturnsErrReorgWhenDrained(t *testing.T) { require.ErrorIs(t, m.AddL2Block(x), ErrReorg) } -// TestChannelManager_Clear tests clearing the channel manager. -func TestChannelManager_Clear(t *testing.T) { +// ChannelManager_Clear tests clearing the channel manager. +func ChannelManager_Clear(t *testing.T, batchType uint) { require := require.New(t) // Create a channel manager @@ -96,7 +132,10 @@ func TestChannelManager_Clear(t *testing.T) { TargetNumFrames: 1, ApproxComprRatio: 1.0, }, - }) + BatchType: batchType, + }, + &rollup.Config{}, + ) // Channel Manager state should be empty by default require.Empty(m.blocks) @@ -104,6 +143,9 @@ func TestChannelManager_Clear(t *testing.T) { require.Nil(m.currentChannel) require.Empty(m.channelQueue) require.Empty(m.txChannels) + require.Nil(m.lastProcessedBlock) + // Set the last block + m.Clear(ð.L2BlockRef{}) // Add a block to the channel manager a, _ := derivetest.RandomL2Block(rng, 4) @@ -143,7 +185,8 @@ func TestChannelManager_Clear(t *testing.T) { require.Equal(b.Hash(), m.tip) // Clear the channel manager - m.Clear() + safeHead := testutils.RandomL2BlockRef(rng) + m.Clear(&safeHead) // Check that the entire channel manager state cleared require.Empty(m.blocks) @@ -151,9 +194,10 @@ func TestChannelManager_Clear(t *testing.T) { require.Nil(m.currentChannel) require.Empty(m.channelQueue) require.Empty(m.txChannels) + require.Equal(m.lastProcessedBlock, &safeHead) } -func TestChannelManager_TxResend(t *testing.T) { +func ChannelManager_TxResend(t *testing.T, batchType uint) { require := require.New(t) rng := rand.New(rand.NewSource(time.Now().UnixNano())) log := testlog.Logger(t, log.LvlError) @@ -165,7 +209,11 @@ func TestChannelManager_TxResend(t *testing.T) { TargetNumFrames: 1, ApproxComprRatio: 1.0, }, - }) + BatchType: batchType, + }, + &rollup.Config{}, + ) + m.Clear(ð.L2BlockRef{}) a, _ := derivetest.RandomL2Block(rng, 4) @@ -195,9 +243,9 @@ func TestChannelManager_TxResend(t *testing.T) { require.Len(fs, 1) } -// TestChannelManagerCloseBeforeFirstUse ensures that the channel manager +// ChannelManagerCloseBeforeFirstUse ensures that the channel manager // will not produce any frames if closed immediately. -func TestChannelManagerCloseBeforeFirstUse(t *testing.T) { +func ChannelManagerCloseBeforeFirstUse(t *testing.T, batchType uint) { require := require.New(t) rng := rand.New(rand.NewSource(time.Now().UnixNano())) log := testlog.Logger(t, log.LvlCrit) @@ -209,7 +257,11 @@ func TestChannelManagerCloseBeforeFirstUse(t *testing.T) { TargetFrameSize: 0, ApproxComprRatio: 1.0, }, - }) + BatchType: batchType, + }, + &rollup.Config{}, + ) + m.Clear(ð.L2BlockRef{}) a, _ := derivetest.RandomL2Block(rng, 4) @@ -222,10 +274,10 @@ func TestChannelManagerCloseBeforeFirstUse(t *testing.T) { require.ErrorIs(err, io.EOF, "Expected closed channel manager to contain no tx data") } -// TestChannelManagerCloseNoPendingChannel ensures that the channel manager +// ChannelManagerCloseNoPendingChannel ensures that the channel manager // can gracefully close with no pending channels, and will not emit any new // channel frames. -func TestChannelManagerCloseNoPendingChannel(t *testing.T) { +func ChannelManagerCloseNoPendingChannel(t *testing.T, batchType uint) { require := require.New(t) log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, @@ -237,7 +289,11 @@ func TestChannelManagerCloseNoPendingChannel(t *testing.T) { TargetNumFrames: 1, ApproxComprRatio: 1.0, }, - }) + BatchType: batchType, + }, + &rollup.Config{}, + ) + m.Clear(ð.L2BlockRef{}) a := newMiniL2Block(0) b := newMiniL2BlockWithNumberParent(0, big.NewInt(1), a.Hash()) @@ -261,10 +317,10 @@ func TestChannelManagerCloseNoPendingChannel(t *testing.T) { require.ErrorIs(err, io.EOF, "Expected closed channel manager to return no new tx data") } -// TestChannelManagerCloseNoPendingChannel ensures that the channel manager +// ChannelManagerCloseNoPendingChannel ensures that the channel manager // can gracefully close with a pending channel, and will not produce any // new channel frames after this point. -func TestChannelManagerClosePendingChannel(t *testing.T) { +func ChannelManagerClosePendingChannel(t *testing.T, batchType uint) { require := require.New(t) log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, @@ -272,13 +328,23 @@ func TestChannelManagerClosePendingChannel(t *testing.T) { MaxFrameSize: 1000, ChannelTimeout: 1000, CompressorConfig: compressor.Config{ - TargetNumFrames: 100, + TargetNumFrames: 1, TargetFrameSize: 1000, ApproxComprRatio: 1.0, }, - }) - - a := newMiniL2Block(50_000) + BatchType: batchType, + }, + &rollup.Config{}, + ) + m.Clear(ð.L2BlockRef{}) + + numTx := 50000 + if batchType == derive.SpanBatchType { + // Adjust number of txs to make 2 frames + // Encoding empty txs as span batch requires more data size because span batch encodes tx signature to fixed length + numTx = 20000 + } + a := newMiniL2Block(numTx) b := newMiniL2BlockWithNumberParent(10, big.NewInt(1), a.Hash()) err := m.AddL2Block(a) @@ -306,10 +372,10 @@ func TestChannelManagerClosePendingChannel(t *testing.T) { require.ErrorIs(err, io.EOF, "Expected closed channel manager to produce no more tx data") } -// TestChannelManagerCloseAllTxsFailed ensures that the channel manager +// ChannelManagerCloseAllTxsFailed ensures that the channel manager // can gracefully close after producing transaction frames if none of these // have successfully landed on chain. -func TestChannelManagerCloseAllTxsFailed(t *testing.T) { +func ChannelManagerCloseAllTxsFailed(t *testing.T, batchType uint) { require := require.New(t) log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, @@ -321,7 +387,10 @@ func TestChannelManagerCloseAllTxsFailed(t *testing.T) { TargetFrameSize: 1000, ApproxComprRatio: 1.0, }, - }) + BatchType: batchType, + }, &rollup.Config{}, + ) + m.Clear(ð.L2BlockRef{}) a := newMiniL2Block(50_000) diff --git a/op-batcher/batcher/channel_test.go b/op-batcher/batcher/channel_test.go index 0c5ce3b83bab..26f64204bc73 100644 --- a/op-batcher/batcher/channel_test.go +++ b/op-batcher/batcher/channel_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-batcher/metrics" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" @@ -20,7 +21,8 @@ func TestChannelTimeout(t *testing.T) { log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{ ChannelTimeout: 100, - }) + }, &rollup.Config{}) + m.Clear(ð.L2BlockRef{}) // Pending channel is nil so is cannot be timed out require.Nil(t, m.currentChannel) @@ -61,7 +63,8 @@ func TestChannelTimeout(t *testing.T) { // TestChannelNextTxData checks the nextTxData function. func TestChannelNextTxData(t *testing.T) { log := testlog.Logger(t, log.LvlCrit) - m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{}) + m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{}, &rollup.Config{}) + m.Clear(ð.L2BlockRef{}) // Nil pending channel should return EOF returnedTxData, err := m.nextTxData(nil) @@ -109,7 +112,8 @@ func TestChannelTxConfirmed(t *testing.T) { // channels on confirmation. This would result in [TxConfirmed] // clearing confirmed transactions, and reseting the pendingChannels map ChannelTimeout: 10, - }) + }, &rollup.Config{}) + m.Clear(ð.L2BlockRef{}) // Let's add a valid pending transaction to the channel manager // So we can demonstrate that TxConfirmed's correctness @@ -157,7 +161,8 @@ func TestChannelTxConfirmed(t *testing.T) { func TestChannelTxFailed(t *testing.T) { // Create a channel manager log := testlog.Logger(t, log.LvlCrit) - m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{}) + m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{}, &rollup.Config{}) + m.Clear(ð.L2BlockRef{}) // Let's add a valid pending transaction to the channel // manager so we can demonstrate correctness diff --git a/op-batcher/batcher/config.go b/op-batcher/batcher/config.go index ad7b611c9a68..d4f34461f02d 100644 --- a/op-batcher/batcher/config.go +++ b/op-batcher/batcher/config.go @@ -52,6 +52,8 @@ type CLIConfig struct { Stopped bool + BatchType uint + TxMgrConfig txmgr.CLIConfig LogConfig oplog.CLIConfig MetricsConfig opmetrics.CLIConfig @@ -93,6 +95,7 @@ func NewConfig(ctx *cli.Context) *CLIConfig { MaxChannelDuration: ctx.Uint64(flags.MaxChannelDurationFlag.Name), MaxL1TxSize: ctx.Uint64(flags.MaxL1TxSizeBytesFlag.Name), Stopped: ctx.Bool(flags.StoppedFlag.Name), + BatchType: ctx.Uint(flags.BatchTypeFlag.Name), TxMgrConfig: txmgr.ReadCLIConfig(ctx), LogConfig: oplog.ReadCLIConfig(ctx), MetricsConfig: opmetrics.ReadCLIConfig(ctx), diff --git a/op-batcher/batcher/driver.go b/op-batcher/batcher/driver.go index bcffef6a9edf..d45ae3153780 100644 --- a/op-batcher/batcher/driver.go +++ b/op-batcher/batcher/driver.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "io" "math/big" _ "net/http/pprof" @@ -16,7 +17,6 @@ import ( "github.com/ethereum-optimism/optimism/op-batcher/metrics" "github.com/ethereum-optimism/optimism/op-node/rollup" - "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) @@ -74,7 +74,7 @@ type BatchSubmitter struct { func NewBatchSubmitter(setup DriverSetup) *BatchSubmitter { return &BatchSubmitter{ DriverSetup: setup, - state: NewChannelManager(setup.Log, setup.Metr, setup.Channel), + state: NewChannelManager(setup.Log, setup.Metr, setup.Channel, setup.RollupCfg), } } @@ -91,7 +91,11 @@ func (l *BatchSubmitter) StartBatchSubmitting() error { l.shutdownCtx, l.cancelShutdownCtx = context.WithCancel(context.Background()) l.killCtx, l.cancelKillCtx = context.WithCancel(context.Background()) - l.state.Clear() + syncStatus, err := fetchSyncStatus(l.shutdownCtx, l.RollupClient, l.Cfg.NetworkTimeout) + if err != nil { + return err + } + l.state.Clear(&syncStatus.SafeL2) l.lastStoredBlock = eth.BlockID{} l.wg.Add(1) @@ -201,15 +205,9 @@ func (l *BatchSubmitter) loadBlockIntoState(ctx context.Context, blockNumber uin // calculateL2BlockRangeToStore determines the range (start,end] that should be loaded into the local state. // It also takes care of initializing some local state (i.e. will modify l.lastStoredBlock in certain conditions) func (l *BatchSubmitter) calculateL2BlockRangeToStore(ctx context.Context) (eth.BlockID, eth.BlockID, error) { - ctx, cancel := context.WithTimeout(ctx, l.Cfg.NetworkTimeout) - defer cancel() - syncStatus, err := l.RollupClient.SyncStatus(ctx) - // Ensure that we have the sync status + syncStatus, err := fetchSyncStatus(ctx, l.RollupClient, l.Cfg.NetworkTimeout) if err != nil { - return eth.BlockID{}, eth.BlockID{}, fmt.Errorf("failed to get sync status: %w", err) - } - if syncStatus.HeadL1 == (eth.L1BlockRef{}) { - return eth.BlockID{}, eth.BlockID{}, errors.New("empty sync status") + return eth.BlockID{}, eth.BlockID{}, err } // Check last stored to see if it needs to be set on startup OR set if is lagged behind. @@ -259,7 +257,12 @@ func (l *BatchSubmitter) loop() { l.Log.Error("error closing the channel manager to handle a L2 reorg", "err", err) } l.publishStateToL1(queue, receiptsCh, true) - l.state.Clear() + if syncStatus, err := fetchSyncStatus(l.shutdownCtx, l.RollupClient, l.Cfg.NetworkTimeout); err == nil { + l.state.Clear(&syncStatus.SafeL2) + } else { + // if fetchSyncStatus failed, ErrReorg will be returned again + l.Log.Error("error fetching sync status from L2 node", "err", err) + } continue } l.publishStateToL1(queue, receiptsCh, false) @@ -395,3 +398,17 @@ func (l *BatchSubmitter) l1Tip(ctx context.Context) (eth.L1BlockRef, error) { } return eth.InfoToL1BlockRef(eth.HeaderBlockInfo(head)), nil } + +func fetchSyncStatus(ctx context.Context, rollupNode RollupClient, timeout time.Duration) (*eth.SyncStatus, error) { + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + syncStatus, err := rollupNode.SyncStatus(ctx) + // Ensure that we have the sync status + if err != nil { + return ð.SyncStatus{}, fmt.Errorf("failed to get sync status: %w", err) + } + if syncStatus.SafeL2 == (eth.L2BlockRef{}) { + return ð.SyncStatus{}, errors.New("empty sync status") + } + return syncStatus, nil +} diff --git a/op-batcher/batcher/service.go b/op-batcher/batcher/service.go index 22e8dd0e2fb8..1c9a493d0c7e 100644 --- a/op-batcher/batcher/service.go +++ b/op-batcher/batcher/service.go @@ -173,6 +173,7 @@ func (bs *BatcherService) initChannelConfig(cfg *CLIConfig) error { SubSafetyMargin: cfg.SubSafetyMargin, MaxFrameSize: cfg.MaxL1TxSize - 1, // subtract 1 byte for version CompressorConfig: cfg.CompressorConfig.Config(), + BatchType: cfg.BatchType, } if err := bs.Channel.Check(); err != nil { return fmt.Errorf("invalid channel configuration: %w", err) diff --git a/op-batcher/flags/flags.go b/op-batcher/flags/flags.go index 9b854f8d6bbb..5e752d9d2748 100644 --- a/op-batcher/flags/flags.go +++ b/op-batcher/flags/flags.go @@ -76,6 +76,12 @@ var ( Usage: "Initialize the batcher in a stopped state. The batcher can be started using the admin_startBatcher RPC", EnvVars: prefixEnvVars("STOPPED"), } + BatchTypeFlag = &cli.UintFlag{ + Name: "batch-type", + Usage: "The batch type. 0 for SingularBatch and 1 for SpanBatch.", + Value: 0, + EnvVars: prefixEnvVars("BATCH_TYPE"), + } // Legacy Flags SequencerHDPathFlag = txmgr.SequencerHDPathFlag ) @@ -94,6 +100,7 @@ var optionalFlags = []cli.Flag{ MaxL1TxSizeBytesFlag, StoppedFlag, SequencerHDPathFlag, + BatchTypeFlag, } func init() { diff --git a/op-e2e/actions/l2_batcher.go b/op-e2e/actions/l2_batcher.go index 57d5864571f0..c1b82cbae14a 100644 --- a/op-e2e/actions/l2_batcher.go +++ b/op-e2e/actions/l2_batcher.go @@ -140,7 +140,7 @@ func (s *L2Batcher) Buffer(t Testing) error { ApproxComprRatio: 1, }) require.NoError(t, e, "failed to create compressor") - ch, err = derive.NewChannelOut(c) + ch, err = derive.NewChannelOut(c, derive.SingularBatchType, nil) } require.NoError(t, err, "failed to create channel") s.l2ChannelOut = ch diff --git a/op-e2e/setup.go b/op-e2e/setup.go index fe70a263985e..40db06f94391 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -49,6 +49,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/p2p" "github.com/ethereum-optimism/optimism/op-node/p2p/store" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/driver" proposermetrics "github.com/ethereum-optimism/optimism/op-proposer/metrics" l2os "github.com/ethereum-optimism/optimism/op-proposer/proposer" @@ -679,6 +680,10 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste return nil, fmt.Errorf("unable to start l2 output submitter: %w", err) } + batchType := derive.SingularBatchType + if os.Getenv("OP_E2E_USE_SPAN_BATCH") == "true" { + batchType = derive.SpanBatchType + } batcherCLIConfig := &bss.CLIConfig{ L1EthRpc: sys.EthInstances["l1"].WSEndpoint(), L2EthRpc: sys.EthInstances["sequencer"].WSEndpoint(), @@ -698,7 +703,8 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste Level: log.LvlInfo, Format: oplog.FormatText, }, - Stopped: sys.cfg.DisableBatcher, // Batch submitter may be enabled later + Stopped: sys.cfg.DisableBatcher, // Batch submitter may be enabled later + BatchType: uint(batchType), } // Batch Submitter batcher, err := bss.BatcherServiceFromCLIConfig(context.Background(), "0.0.1", batcherCLIConfig, sys.cfg.Loggers["batcher"]) diff --git a/op-node/rollup/derive/channel_out.go b/op-node/rollup/derive/channel_out.go index 63e7cc38bc62..b0e36d6091d7 100644 --- a/op-node/rollup/derive/channel_out.go +++ b/op-node/rollup/derive/channel_out.go @@ -48,6 +48,13 @@ type Compressor interface { FullErr() error } +type ChannelOutReader interface { + io.Writer + io.Reader + Reset() + Len() int +} + type ChannelOut struct { id ChannelID // Frame ID of the next frame to emit. Increment after emitting @@ -57,20 +64,35 @@ type ChannelOut struct { // Compressor stage. Write input data to it compress Compressor - + // closed indicates if the channel is closed closed bool + // batchType indicates whether this channel uses SingularBatch or SpanBatch + batchType uint + // spanBatchBuilder contains information requires to build SpanBatch + spanBatchBuilder *SpanBatchBuilder + // reader contains compressed data for making output frames + reader ChannelOutReader } func (co *ChannelOut) ID() ChannelID { return co.id } -func NewChannelOut(compress Compressor) (*ChannelOut, error) { +func NewChannelOut(compress Compressor, batchType uint, spanBatchBuilder *SpanBatchBuilder) (*ChannelOut, error) { + // If the channel uses SingularBatch, use compressor directly as its reader + var reader ChannelOutReader = compress + if batchType == SpanBatchType { + // If the channel uses SpanBatch, create empty buffer for reader + reader = &bytes.Buffer{} + } c := &ChannelOut{ - id: ChannelID{}, // TODO: use GUID here instead of fully random data - frame: 0, - rlpLength: 0, - compress: compress, + id: ChannelID{}, // TODO: use GUID here instead of fully random data + frame: 0, + rlpLength: 0, + compress: compress, + batchType: batchType, + spanBatchBuilder: spanBatchBuilder, + reader: reader, } _, err := rand.Read(c.id[:]) if err != nil { @@ -85,7 +107,11 @@ func (co *ChannelOut) Reset() error { co.frame = 0 co.rlpLength = 0 co.compress.Reset() + co.reader.Reset() co.closed = false + if co.spanBatchBuilder != nil { + co.spanBatchBuilder.Reset() + } _, err := rand.Read(co.id[:]) return err } @@ -99,30 +125,41 @@ func (co *ChannelOut) AddBlock(block *types.Block) (uint64, error) { return 0, errors.New("already closed") } - batch, _, err := BlockToBatch(block) + batch, _, err := BlockToSingularBatch(block) if err != nil { return 0, err } - return co.AddBatch(batch) + return co.AddSingularBatch(batch) } -// AddBatch adds a batch to the channel. It returns the RLP encoded byte size +// AddSingularBatch adds a batch to the channel. It returns the RLP encoded byte size // and an error if there is a problem adding the batch. The only sentinel error // that it returns is ErrTooManyRLPBytes. If this error is returned, the channel // should be closed and a new one should be made. // -// AddBatch should be used together with BlockToBatch if you need to access the +// AddSingularBatch should be used together with BlockToSingularBatch if you need to access the // BatchData before adding a block to the channel. It isn't possible to access // the batch data with AddBlock. -func (co *ChannelOut) AddBatch(batch *BatchData) (uint64, error) { +func (co *ChannelOut) AddSingularBatch(batch *SingularBatch) (uint64, error) { if co.closed { return 0, errors.New("already closed") } + switch co.batchType { + case SingularBatchType: + return co.writeSingularBatch(batch) + case SpanBatchType: + return co.writeSpanBatch(batch) + default: + return 0, fmt.Errorf("unrecognized batch type: %d", co.batchType) + } +} + +func (co *ChannelOut) writeSingularBatch(batch *SingularBatch) (uint64, error) { + var buf bytes.Buffer // We encode to a temporary buffer to determine the encoded length to // ensure that the total size of all RLP elements is less than or equal to MAX_RLP_BYTES_PER_CHANNEL - var buf bytes.Buffer - if err := rlp.Encode(&buf, batch); err != nil { + if err := rlp.Encode(&buf, NewSingularBatchData(*batch)); err != nil { return 0, err } if co.rlpLength+buf.Len() > MaxRLPBytesPerChannel { @@ -136,6 +173,70 @@ func (co *ChannelOut) AddBatch(batch *BatchData) (uint64, error) { return uint64(written), err } +// writeSpanBatch appends a SingularBatch to the channel's SpanBatch. +// A channel can have only one SpanBatch. And compressed results should not be accessible until the channel is closed, since the prefix and payload can be changed. +// So it resets channel contents and rewrites the entire SpanBatch each time, and compressed results are copied to reader after the channel is closed. +// It makes we can only get frames once the channel is full or closed, in the case of SpanBatch. +func (co *ChannelOut) writeSpanBatch(batch *SingularBatch) (uint64, error) { + if co.FullErr() != nil { + // channel is already full + return 0, co.FullErr() + } + var buf bytes.Buffer + // Append Singular batch to its span batch builder + co.spanBatchBuilder.AppendSingularBatch(batch) + // Convert Span batch to RawSpanBatch + rawSpanBatch, err := co.spanBatchBuilder.GetRawSpanBatch() + if err != nil { + return 0, fmt.Errorf("failed to convert SpanBatch into RawSpanBatch: %w", err) + } + // Encode RawSpanBatch into bytes + if err = rlp.Encode(&buf, NewSpanBatchData(*rawSpanBatch)); err != nil { + return 0, fmt.Errorf("failed to encode RawSpanBatch into bytes: %w", err) + } + co.rlpLength = 0 + // Ensure that the total size of all RLP elements is less than or equal to MAX_RLP_BYTES_PER_CHANNEL + if co.rlpLength+buf.Len() > MaxRLPBytesPerChannel { + return 0, fmt.Errorf("could not add %d bytes to channel of %d bytes, max is %d. err: %w", + buf.Len(), co.rlpLength, MaxRLPBytesPerChannel, ErrTooManyRLPBytes) + } + co.rlpLength = buf.Len() + + if co.spanBatchBuilder.GetBlockCount() > 1 { + // Flush compressed data into reader to preserve current result. + // If the channel is full after this block is appended, we should use preserved data. + if err := co.compress.Flush(); err != nil { + return 0, fmt.Errorf("failed to flush compressor: %w", err) + } + _, err = io.Copy(co.reader, co.compress) + if err != nil { + // Must reset reader to avoid partial output + co.reader.Reset() + return 0, fmt.Errorf("failed to copy compressed data to reader: %w", err) + } + } + + // Reset compressor to rewrite the entire span batch + co.compress.Reset() + // Avoid using io.Copy here, because we need all or nothing + written, err := co.compress.Write(buf.Bytes()) + if co.compress.FullErr() != nil { + err = co.compress.FullErr() + if co.spanBatchBuilder.GetBlockCount() == 1 { + // Do not return CompressorFullErr for the first block in the batch + // In this case, reader must be empty. then the contents of compressor will be copied to reader when the channel is closed. + err = nil + } + // If there are more than one blocks in the channel, reader should have data that preserves previous compression result before adding this block. + // So, as a result, this block is not added to the channel and the channel will be closed. + return uint64(written), err + } + + // If compressor is not full yet, reader must be reset to avoid submitting invalid frames + co.reader.Reset() + return uint64(written), err +} + // InputBytes returns the total amount of RLP-encoded input bytes. func (co *ChannelOut) InputBytes() int { return co.rlpLength @@ -145,13 +246,24 @@ func (co *ChannelOut) InputBytes() int { // Use `Flush` or `Close` to move data from the compression buffer into the ready buffer if more bytes // are needed. Add blocks may add to the ready buffer, but it is not guaranteed due to the compression stage. func (co *ChannelOut) ReadyBytes() int { - return co.compress.Len() + return co.reader.Len() } // Flush flushes the internal compression stage to the ready buffer. It enables pulling a larger & more // complete frame. It reduces the compression efficiency. func (co *ChannelOut) Flush() error { - return co.compress.Flush() + if err := co.compress.Flush(); err != nil { + return err + } + if co.batchType == SpanBatchType && co.closed && co.ReadyBytes() == 0 && co.compress.Len() > 0 { + _, err := io.Copy(co.reader, co.compress) + if err != nil { + // Must reset reader to avoid partial output + co.reader.Reset() + return fmt.Errorf("failed to flush compressed data to reader: %w", err) + } + } + return nil } func (co *ChannelOut) FullErr() error { @@ -163,6 +275,11 @@ func (co *ChannelOut) Close() error { return errors.New("already closed") } co.closed = true + if co.batchType == SpanBatchType { + if err := co.Flush(); err != nil { + return err + } + } return co.compress.Close() } @@ -186,8 +303,8 @@ func (co *ChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) (uint16, erro // Copy data from the local buffer into the frame data buffer maxDataSize := maxSize - FrameV0OverHeadSize - if maxDataSize > uint64(co.compress.Len()) { - maxDataSize = uint64(co.compress.Len()) + if maxDataSize > uint64(co.ReadyBytes()) { + maxDataSize = uint64(co.ReadyBytes()) // If we are closed & will not spill past the current frame // mark it is the final frame of the channel. if co.closed { @@ -196,7 +313,7 @@ func (co *ChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) (uint16, erro } f.Data = make([]byte, maxDataSize) - if _, err := io.ReadFull(co.compress, f.Data); err != nil { + if _, err := io.ReadFull(co.reader, f.Data); err != nil { return 0, err } @@ -213,8 +330,8 @@ func (co *ChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) (uint16, erro } } -// BlockToBatch transforms a block into a batch object that can easily be RLP encoded. -func BlockToBatch(block *types.Block) (*BatchData, L1BlockInfo, error) { +// BlockToSingularBatch transforms a block into a batch object that can easily be RLP encoded. +func BlockToSingularBatch(block *types.Block) (*SingularBatch, L1BlockInfo, error) { opaqueTxs := make([]hexutil.Bytes, 0, len(block.Transactions())) for i, tx := range block.Transactions() { if tx.Type() == types.DepositTxType { @@ -238,15 +355,13 @@ func BlockToBatch(block *types.Block) (*BatchData, L1BlockInfo, error) { return nil, l1Info, fmt.Errorf("could not parse the L1 Info deposit: %w", err) } - return NewSingularBatchData( - SingularBatch{ - ParentHash: block.ParentHash(), - EpochNum: rollup.Epoch(l1Info.Number), - EpochHash: l1Info.BlockHash, - Timestamp: block.Time(), - Transactions: opaqueTxs, - }, - ), l1Info, nil + return &SingularBatch{ + ParentHash: block.ParentHash(), + EpochNum: rollup.Epoch(l1Info.Number), + EpochHash: l1Info.BlockHash, + Timestamp: block.Time(), + Transactions: opaqueTxs, + }, l1Info, nil } // ForceCloseTxData generates the transaction data for a transaction which will force close diff --git a/op-node/rollup/derive/channel_out_test.go b/op-node/rollup/derive/channel_out_test.go index 73f07d762884..0a01da76d0a3 100644 --- a/op-node/rollup/derive/channel_out_test.go +++ b/op-node/rollup/derive/channel_out_test.go @@ -29,7 +29,7 @@ func (s *nonCompressor) FullErr() error { } func TestChannelOutAddBlock(t *testing.T) { - cout, err := NewChannelOut(&nonCompressor{}) + cout, err := NewChannelOut(&nonCompressor{}, SingularBatchType, nil) require.NoError(t, err) t.Run("returns err if first tx is not an l1info tx", func(t *testing.T) { @@ -50,7 +50,7 @@ func TestChannelOutAddBlock(t *testing.T) { // max size that is below the fixed frame size overhead of 23, will return // an error. func TestOutputFrameSmallMaxSize(t *testing.T) { - cout, err := NewChannelOut(&nonCompressor{}) + cout, err := NewChannelOut(&nonCompressor{}, SingularBatchType, nil) require.NoError(t, err) // Call OutputFrame with the range of small max size values that err @@ -97,42 +97,42 @@ func TestForceCloseTxData(t *testing.T) { output: "", }, { - frames: []Frame{Frame{FrameNumber: 0, IsLast: false}, Frame{ID: id, FrameNumber: 1, IsLast: true}}, + frames: []Frame{{FrameNumber: 0, IsLast: false}, {ID: id, FrameNumber: 1, IsLast: true}}, errors: true, output: "", }, { - frames: []Frame{Frame{ID: id, FrameNumber: 0, IsLast: false}}, + frames: []Frame{{ID: id, FrameNumber: 0, IsLast: false}}, errors: false, output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000001", }, { - frames: []Frame{Frame{ID: id, FrameNumber: 0, IsLast: true}}, + frames: []Frame{{ID: id, FrameNumber: 0, IsLast: true}}, errors: false, output: "00", }, { - frames: []Frame{Frame{ID: id, FrameNumber: 1, IsLast: false}}, + frames: []Frame{{ID: id, FrameNumber: 1, IsLast: false}}, errors: false, output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000001", }, { - frames: []Frame{Frame{ID: id, FrameNumber: 1, IsLast: true}}, + frames: []Frame{{ID: id, FrameNumber: 1, IsLast: true}}, errors: false, output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000000", }, { - frames: []Frame{Frame{ID: id, FrameNumber: 2, IsLast: true}}, + frames: []Frame{{ID: id, FrameNumber: 2, IsLast: true}}, errors: false, output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000000deadbeefdeadbeefdeadbeefdeadbeef00010000000000", }, { - frames: []Frame{Frame{ID: id, FrameNumber: 1, IsLast: false}, Frame{ID: id, FrameNumber: 3, IsLast: true}}, + frames: []Frame{{ID: id, FrameNumber: 1, IsLast: false}, {ID: id, FrameNumber: 3, IsLast: true}}, errors: false, output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000000deadbeefdeadbeefdeadbeefdeadbeef00020000000000", }, { - frames: []Frame{Frame{ID: id, FrameNumber: 1, IsLast: false}, Frame{ID: id, FrameNumber: 3, IsLast: true}, Frame{ID: id, FrameNumber: 5, IsLast: true}}, + frames: []Frame{{ID: id, FrameNumber: 1, IsLast: false}, {ID: id, FrameNumber: 3, IsLast: true}, {ID: id, FrameNumber: 5, IsLast: true}}, errors: false, output: "00deadbeefdeadbeefdeadbeefdeadbeef00000000000000deadbeefdeadbeefdeadbeefdeadbeef00020000000000", }, @@ -152,6 +152,6 @@ func TestForceCloseTxData(t *testing.T) { func TestBlockToBatchValidity(t *testing.T) { block := new(types.Block) - _, _, err := BlockToBatch(block) + _, _, err := BlockToSingularBatch(block) require.ErrorContains(t, err, "has no transactions") } diff --git a/ops-bedrock/docker-compose.yml b/ops-bedrock/docker-compose.yml index 73d3a54a827f..4819d90aac2a 100644 --- a/ops-bedrock/docker-compose.yml +++ b/ops-bedrock/docker-compose.yml @@ -155,6 +155,7 @@ services: OP_BATCHER_PPROF_ENABLED: "true" OP_BATCHER_METRICS_ENABLED: "true" OP_BATCHER_RPC_ENABLE_ADMIN: "true" + OP_BATCHER_BATCH_TYPE: 0 artifact-server: depends_on: From 6191eea720aed8223e733721fe2fadd0bcf51bde Mon Sep 17 00:00:00 2001 From: Tei Im Date: Thu, 12 Oct 2023 18:50:34 +0900 Subject: [PATCH 016/374] Split ChannelOut to singular and span channel out --- op-batcher/batcher/channel_builder.go | 4 +- op-batcher/batcher/channel_builder_test.go | 2 +- op-e2e/actions/garbage_channel_out.go | 7 +- op-e2e/actions/l2_batcher.go | 2 +- op-node/rollup/derive/channel_out.go | 223 ++++++-------------- op-node/rollup/derive/channel_out_test.go | 4 +- op-node/rollup/derive/span_channel_out.go | 229 +++++++++++++++++++++ 7 files changed, 308 insertions(+), 163 deletions(-) create mode 100644 op-node/rollup/derive/span_channel_out.go diff --git a/op-batcher/batcher/channel_builder.go b/op-batcher/batcher/channel_builder.go index 33e236c2dd93..81bce734b522 100644 --- a/op-batcher/batcher/channel_builder.go +++ b/op-batcher/batcher/channel_builder.go @@ -121,7 +121,7 @@ type channelBuilder struct { // guaranteed to be a ChannelFullError wrapping the specific reason. fullErr error // current channel - co *derive.ChannelOut + co derive.ChannelOut // list of blocks in the channel. Saved in case the channel must be rebuilt blocks []*types.Block // frames data queue, to be send as txs @@ -139,7 +139,7 @@ func newChannelBuilder(cfg ChannelConfig, spanBatchBuilder *derive.SpanBatchBuil if err != nil { return nil, err } - co, err := derive.NewChannelOut(c, cfg.BatchType, spanBatchBuilder) + co, err := derive.NewChannelOut(cfg.BatchType, c, spanBatchBuilder) if err != nil { return nil, err } diff --git a/op-batcher/batcher/channel_builder_test.go b/op-batcher/batcher/channel_builder_test.go index 51c3d76af380..fa8512039d8a 100644 --- a/op-batcher/batcher/channel_builder_test.go +++ b/op-batcher/batcher/channel_builder_test.go @@ -449,7 +449,7 @@ func TestChannelBuilder_OutputWrongFramePanic(t *testing.T) { // to construct a single frame c, err := channelConfig.CompressorConfig.NewCompressor() require.NoError(t, err) - co, err := derive.NewChannelOut(c, derive.SingularBatchType, nil) + co, err := derive.NewChannelOut(derive.SingularBatchType, c, nil) require.NoError(t, err) var buf bytes.Buffer fn, err := co.OutputFrame(&buf, channelConfig.MaxFrameSize) diff --git a/op-e2e/actions/garbage_channel_out.go b/op-e2e/actions/garbage_channel_out.go index a2e5535b1074..d412f80d5566 100644 --- a/op-e2e/actions/garbage_channel_out.go +++ b/op-e2e/actions/garbage_channel_out.go @@ -61,8 +61,11 @@ type ChannelOutIface interface { OutputFrame(w *bytes.Buffer, maxSize uint64) (uint16, error) } -// Compile-time check for ChannelOutIface interface implementation for the ChannelOut type. -var _ ChannelOutIface = (*derive.ChannelOut)(nil) +// Compile-time check for ChannelOutIface interface implementation for the SingularChannelOut type. +var _ ChannelOutIface = (*derive.SingularChannelOut)(nil) + +// Compile-time check for ChannelOutIface interface implementation for the SpanChannelOut type. +var _ ChannelOutIface = (*derive.SpanChannelOut)(nil) // Compile-time check for ChannelOutIface interface implementation for the GarbageChannelOut type. var _ ChannelOutIface = (*GarbageChannelOut)(nil) diff --git a/op-e2e/actions/l2_batcher.go b/op-e2e/actions/l2_batcher.go index c1b82cbae14a..7431e7985bda 100644 --- a/op-e2e/actions/l2_batcher.go +++ b/op-e2e/actions/l2_batcher.go @@ -140,7 +140,7 @@ func (s *L2Batcher) Buffer(t Testing) error { ApproxComprRatio: 1, }) require.NoError(t, e, "failed to create compressor") - ch, err = derive.NewChannelOut(c, derive.SingularBatchType, nil) + ch, err = derive.NewChannelOut(derive.SingularBatchType, c, nil) } require.NoError(t, err, "failed to create channel") s.l2ChannelOut = ch diff --git a/op-node/rollup/derive/channel_out.go b/op-node/rollup/derive/channel_out.go index b0e36d6091d7..d2af4be76e28 100644 --- a/op-node/rollup/derive/channel_out.go +++ b/op-node/rollup/derive/channel_out.go @@ -48,14 +48,31 @@ type Compressor interface { FullErr() error } -type ChannelOutReader interface { - io.Writer - io.Reader - Reset() - Len() int +type ChannelOut interface { + ID() ChannelID + Reset() error + AddBlock(*types.Block) (uint64, error) + AddSingularBatch(*SingularBatch) (uint64, error) + InputBytes() int + ReadyBytes() int + Flush() error + FullErr() error + Close() error + OutputFrame(*bytes.Buffer, uint64) (uint16, error) +} + +func NewChannelOut(batchType uint, compress Compressor, spanBatchBuilder *SpanBatchBuilder) (ChannelOut, error) { + switch batchType { + case SingularBatchType: + return NewSingularChannelOut(compress) + case SpanBatchType: + return NewSpanChannelOut(compress, spanBatchBuilder) + default: + return nil, fmt.Errorf("unrecognized batch type: %d", batchType) + } } -type ChannelOut struct { +type SingularChannelOut struct { id ChannelID // Frame ID of the next frame to emit. Increment after emitting frame uint64 @@ -64,35 +81,20 @@ type ChannelOut struct { // Compressor stage. Write input data to it compress Compressor - // closed indicates if the channel is closed + closed bool - // batchType indicates whether this channel uses SingularBatch or SpanBatch - batchType uint - // spanBatchBuilder contains information requires to build SpanBatch - spanBatchBuilder *SpanBatchBuilder - // reader contains compressed data for making output frames - reader ChannelOutReader } -func (co *ChannelOut) ID() ChannelID { +func (co *SingularChannelOut) ID() ChannelID { return co.id } -func NewChannelOut(compress Compressor, batchType uint, spanBatchBuilder *SpanBatchBuilder) (*ChannelOut, error) { - // If the channel uses SingularBatch, use compressor directly as its reader - var reader ChannelOutReader = compress - if batchType == SpanBatchType { - // If the channel uses SpanBatch, create empty buffer for reader - reader = &bytes.Buffer{} - } - c := &ChannelOut{ - id: ChannelID{}, // TODO: use GUID here instead of fully random data - frame: 0, - rlpLength: 0, - compress: compress, - batchType: batchType, - spanBatchBuilder: spanBatchBuilder, - reader: reader, +func NewSingularChannelOut(compress Compressor) (*SingularChannelOut, error) { + c := &SingularChannelOut{ + id: ChannelID{}, // TODO: use GUID here instead of fully random data + frame: 0, + rlpLength: 0, + compress: compress, } _, err := rand.Read(c.id[:]) if err != nil { @@ -102,16 +104,12 @@ func NewChannelOut(compress Compressor, batchType uint, spanBatchBuilder *SpanBa return c, nil } -// TODO: reuse ChannelOut for performance -func (co *ChannelOut) Reset() error { +// TODO: reuse SingularChannelOut for performance +func (co *SingularChannelOut) Reset() error { co.frame = 0 co.rlpLength = 0 co.compress.Reset() - co.reader.Reset() co.closed = false - if co.spanBatchBuilder != nil { - co.spanBatchBuilder.Reset() - } _, err := rand.Read(co.id[:]) return err } @@ -120,7 +118,7 @@ func (co *ChannelOut) Reset() error { // and an error if there is a problem adding the block. The only sentinel error // that it returns is ErrTooManyRLPBytes. If this error is returned, the channel // should be closed and a new one should be made. -func (co *ChannelOut) AddBlock(block *types.Block) (uint64, error) { +func (co *SingularChannelOut) AddBlock(block *types.Block) (uint64, error) { if co.closed { return 0, errors.New("already closed") } @@ -137,28 +135,17 @@ func (co *ChannelOut) AddBlock(block *types.Block) (uint64, error) { // that it returns is ErrTooManyRLPBytes. If this error is returned, the channel // should be closed and a new one should be made. // -// AddSingularBatch should be used together with BlockToSingularBatch if you need to access the +// AddSingularBatch should be used together with BlockToBatch if you need to access the // BatchData before adding a block to the channel. It isn't possible to access // the batch data with AddBlock. -func (co *ChannelOut) AddSingularBatch(batch *SingularBatch) (uint64, error) { +func (co *SingularChannelOut) AddSingularBatch(batch *SingularBatch) (uint64, error) { if co.closed { return 0, errors.New("already closed") } - switch co.batchType { - case SingularBatchType: - return co.writeSingularBatch(batch) - case SpanBatchType: - return co.writeSpanBatch(batch) - default: - return 0, fmt.Errorf("unrecognized batch type: %d", co.batchType) - } -} - -func (co *ChannelOut) writeSingularBatch(batch *SingularBatch) (uint64, error) { - var buf bytes.Buffer // We encode to a temporary buffer to determine the encoded length to // ensure that the total size of all RLP elements is less than or equal to MAX_RLP_BYTES_PER_CHANNEL + var buf bytes.Buffer if err := rlp.Encode(&buf, NewSingularBatchData(*batch)); err != nil { return 0, err } @@ -173,113 +160,33 @@ func (co *ChannelOut) writeSingularBatch(batch *SingularBatch) (uint64, error) { return uint64(written), err } -// writeSpanBatch appends a SingularBatch to the channel's SpanBatch. -// A channel can have only one SpanBatch. And compressed results should not be accessible until the channel is closed, since the prefix and payload can be changed. -// So it resets channel contents and rewrites the entire SpanBatch each time, and compressed results are copied to reader after the channel is closed. -// It makes we can only get frames once the channel is full or closed, in the case of SpanBatch. -func (co *ChannelOut) writeSpanBatch(batch *SingularBatch) (uint64, error) { - if co.FullErr() != nil { - // channel is already full - return 0, co.FullErr() - } - var buf bytes.Buffer - // Append Singular batch to its span batch builder - co.spanBatchBuilder.AppendSingularBatch(batch) - // Convert Span batch to RawSpanBatch - rawSpanBatch, err := co.spanBatchBuilder.GetRawSpanBatch() - if err != nil { - return 0, fmt.Errorf("failed to convert SpanBatch into RawSpanBatch: %w", err) - } - // Encode RawSpanBatch into bytes - if err = rlp.Encode(&buf, NewSpanBatchData(*rawSpanBatch)); err != nil { - return 0, fmt.Errorf("failed to encode RawSpanBatch into bytes: %w", err) - } - co.rlpLength = 0 - // Ensure that the total size of all RLP elements is less than or equal to MAX_RLP_BYTES_PER_CHANNEL - if co.rlpLength+buf.Len() > MaxRLPBytesPerChannel { - return 0, fmt.Errorf("could not add %d bytes to channel of %d bytes, max is %d. err: %w", - buf.Len(), co.rlpLength, MaxRLPBytesPerChannel, ErrTooManyRLPBytes) - } - co.rlpLength = buf.Len() - - if co.spanBatchBuilder.GetBlockCount() > 1 { - // Flush compressed data into reader to preserve current result. - // If the channel is full after this block is appended, we should use preserved data. - if err := co.compress.Flush(); err != nil { - return 0, fmt.Errorf("failed to flush compressor: %w", err) - } - _, err = io.Copy(co.reader, co.compress) - if err != nil { - // Must reset reader to avoid partial output - co.reader.Reset() - return 0, fmt.Errorf("failed to copy compressed data to reader: %w", err) - } - } - - // Reset compressor to rewrite the entire span batch - co.compress.Reset() - // Avoid using io.Copy here, because we need all or nothing - written, err := co.compress.Write(buf.Bytes()) - if co.compress.FullErr() != nil { - err = co.compress.FullErr() - if co.spanBatchBuilder.GetBlockCount() == 1 { - // Do not return CompressorFullErr for the first block in the batch - // In this case, reader must be empty. then the contents of compressor will be copied to reader when the channel is closed. - err = nil - } - // If there are more than one blocks in the channel, reader should have data that preserves previous compression result before adding this block. - // So, as a result, this block is not added to the channel and the channel will be closed. - return uint64(written), err - } - - // If compressor is not full yet, reader must be reset to avoid submitting invalid frames - co.reader.Reset() - return uint64(written), err -} - // InputBytes returns the total amount of RLP-encoded input bytes. -func (co *ChannelOut) InputBytes() int { +func (co *SingularChannelOut) InputBytes() int { return co.rlpLength } // ReadyBytes returns the number of bytes that the channel out can immediately output into a frame. // Use `Flush` or `Close` to move data from the compression buffer into the ready buffer if more bytes // are needed. Add blocks may add to the ready buffer, but it is not guaranteed due to the compression stage. -func (co *ChannelOut) ReadyBytes() int { - return co.reader.Len() +func (co *SingularChannelOut) ReadyBytes() int { + return co.compress.Len() } // Flush flushes the internal compression stage to the ready buffer. It enables pulling a larger & more // complete frame. It reduces the compression efficiency. -func (co *ChannelOut) Flush() error { - if err := co.compress.Flush(); err != nil { - return err - } - if co.batchType == SpanBatchType && co.closed && co.ReadyBytes() == 0 && co.compress.Len() > 0 { - _, err := io.Copy(co.reader, co.compress) - if err != nil { - // Must reset reader to avoid partial output - co.reader.Reset() - return fmt.Errorf("failed to flush compressed data to reader: %w", err) - } - } - return nil +func (co *SingularChannelOut) Flush() error { + return co.compress.Flush() } -func (co *ChannelOut) FullErr() error { +func (co *SingularChannelOut) FullErr() error { return co.compress.FullErr() } -func (co *ChannelOut) Close() error { +func (co *SingularChannelOut) Close() error { if co.closed { return errors.New("already closed") } co.closed = true - if co.batchType == SpanBatchType { - if err := co.Flush(); err != nil { - return err - } - } return co.compress.Close() } @@ -290,30 +197,15 @@ func (co *ChannelOut) Close() error { // Returns io.EOF when the channel is closed & there are no more frames. // Returns nil if there is still more buffered data. // Returns an error if it ran into an error during processing. -func (co *ChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) (uint16, error) { - f := Frame{ - ID: co.id, - FrameNumber: uint16(co.frame), - } - +func (co *SingularChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) (uint16, error) { // Check that the maxSize is large enough for the frame overhead size. if maxSize < FrameV0OverHeadSize { return 0, ErrMaxFrameSizeTooSmall } - // Copy data from the local buffer into the frame data buffer - maxDataSize := maxSize - FrameV0OverHeadSize - if maxDataSize > uint64(co.ReadyBytes()) { - maxDataSize = uint64(co.ReadyBytes()) - // If we are closed & will not spill past the current frame - // mark it is the final frame of the channel. - if co.closed { - f.IsLast = true - } - } - f.Data = make([]byte, maxDataSize) + f := createEmptyFrame(co.id, co.frame, co.ReadyBytes(), co.closed, maxSize) - if _, err := io.ReadFull(co.reader, f.Data); err != nil { + if _, err := io.ReadFull(co.compress, f.Data); err != nil { return 0, err } @@ -418,3 +310,24 @@ func ForceCloseTxData(frames []Frame) ([]byte, error) { return out.Bytes(), nil } + +// createEmptyFrame creates new empty Frame with given information. Frame data must be copied from ChannelOut. +func createEmptyFrame(id ChannelID, frame uint64, readyBytes int, closed bool, maxSize uint64) *Frame { + f := Frame{ + ID: id, + FrameNumber: uint16(frame), + } + + // Copy data from the local buffer into the frame data buffer + maxDataSize := maxSize - FrameV0OverHeadSize + if maxDataSize > uint64(readyBytes) { + maxDataSize = uint64(readyBytes) + // If we are closed & will not spill past the current frame + // mark it is the final frame of the channel. + if closed { + f.IsLast = true + } + } + f.Data = make([]byte, maxDataSize) + return &f +} diff --git a/op-node/rollup/derive/channel_out_test.go b/op-node/rollup/derive/channel_out_test.go index 0a01da76d0a3..0eef4a241c1b 100644 --- a/op-node/rollup/derive/channel_out_test.go +++ b/op-node/rollup/derive/channel_out_test.go @@ -29,7 +29,7 @@ func (s *nonCompressor) FullErr() error { } func TestChannelOutAddBlock(t *testing.T) { - cout, err := NewChannelOut(&nonCompressor{}, SingularBatchType, nil) + cout, err := NewChannelOut(SingularBatchType, &nonCompressor{}, nil) require.NoError(t, err) t.Run("returns err if first tx is not an l1info tx", func(t *testing.T) { @@ -50,7 +50,7 @@ func TestChannelOutAddBlock(t *testing.T) { // max size that is below the fixed frame size overhead of 23, will return // an error. func TestOutputFrameSmallMaxSize(t *testing.T) { - cout, err := NewChannelOut(&nonCompressor{}, SingularBatchType, nil) + cout, err := NewChannelOut(SingularBatchType, &nonCompressor{}, nil) require.NoError(t, err) // Call OutputFrame with the range of small max size values that err diff --git a/op-node/rollup/derive/span_channel_out.go b/op-node/rollup/derive/span_channel_out.go new file mode 100644 index 000000000000..d074a19c29ef --- /dev/null +++ b/op-node/rollup/derive/span_channel_out.go @@ -0,0 +1,229 @@ +package derive + +import ( + "bytes" + "crypto/rand" + "errors" + "fmt" + "io" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +type SpanChannelOut struct { + id ChannelID + // Frame ID of the next frame to emit. Increment after emitting + frame uint64 + // rlpLength is the uncompressed size of the channel. Must be less than MAX_RLP_BYTES_PER_CHANNEL + rlpLength int + + // Compressor stage. Write input data to it + compress Compressor + // closed indicates if the channel is closed + closed bool + // spanBatchBuilder contains information requires to build SpanBatch + spanBatchBuilder *SpanBatchBuilder + // reader contains compressed data for making output frames + reader *bytes.Buffer +} + +func (co *SpanChannelOut) ID() ChannelID { + return co.id +} + +func NewSpanChannelOut(compress Compressor, spanBatchBuilder *SpanBatchBuilder) (*SpanChannelOut, error) { + c := &SpanChannelOut{ + id: ChannelID{}, // TODO: use GUID here instead of fully random data + frame: 0, + rlpLength: 0, + compress: compress, + spanBatchBuilder: spanBatchBuilder, + reader: &bytes.Buffer{}, + } + _, err := rand.Read(c.id[:]) + if err != nil { + return nil, err + } + + return c, nil +} + +// TODO: reuse ChannelOut for performance +func (co *SpanChannelOut) Reset() error { + co.frame = 0 + co.rlpLength = 0 + co.compress.Reset() + co.reader.Reset() + co.closed = false + co.spanBatchBuilder.Reset() + _, err := rand.Read(co.id[:]) + return err +} + +// AddBlock adds a block to the channel. It returns the RLP encoded byte size +// and an error if there is a problem adding the block. The only sentinel error +// that it returns is ErrTooManyRLPBytes. If this error is returned, the channel +// should be closed and a new one should be made. +func (co *SpanChannelOut) AddBlock(block *types.Block) (uint64, error) { + if co.closed { + return 0, errors.New("already closed") + } + + batch, _, err := BlockToSingularBatch(block) + if err != nil { + return 0, err + } + return co.AddSingularBatch(batch) +} + +// AddSingularBatch adds a batch to the channel. It returns the RLP encoded byte size +// and an error if there is a problem adding the batch. The only sentinel error +// that it returns is ErrTooManyRLPBytes. If this error is returned, the channel +// should be closed and a new one should be made. +// +// AddSingularBatch should be used together with BlockToSingularBatch if you need to access the +// BatchData before adding a block to the channel. It isn't possible to access +// the batch data with AddBlock. +// +// SingularBatch is appended to the channel's SpanBatch. +// A channel can have only one SpanBatch. And compressed results should not be accessible until the channel is closed, since the prefix and payload can be changed. +// So it resets channel contents and rewrites the entire SpanBatch each time, and compressed results are copied to reader after the channel is closed. +// It makes we can only get frames once the channel is full or closed, in the case of SpanBatch. +func (co *SpanChannelOut) AddSingularBatch(batch *SingularBatch) (uint64, error) { + if co.closed { + return 0, errors.New("already closed") + } + if co.FullErr() != nil { + // channel is already full + return 0, co.FullErr() + } + var buf bytes.Buffer + // Append Singular batch to its span batch builder + co.spanBatchBuilder.AppendSingularBatch(batch) + // Convert Span batch to RawSpanBatch + rawSpanBatch, err := co.spanBatchBuilder.GetRawSpanBatch() + if err != nil { + return 0, fmt.Errorf("failed to convert SpanBatch into RawSpanBatch: %w", err) + } + // Encode RawSpanBatch into bytes + if err = rlp.Encode(&buf, NewSpanBatchData(*rawSpanBatch)); err != nil { + return 0, fmt.Errorf("failed to encode RawSpanBatch into bytes: %w", err) + } + // Ensure that the total size of all RLP elements is less than or equal to MAX_RLP_BYTES_PER_CHANNEL + if buf.Len() > MaxRLPBytesPerChannel { + return 0, fmt.Errorf("could not add %d bytes to channel of %d bytes, max is %d. err: %w", + buf.Len(), co.rlpLength, MaxRLPBytesPerChannel, ErrTooManyRLPBytes) + } + co.rlpLength = buf.Len() + + if co.spanBatchBuilder.GetBlockCount() > 1 { + // Flush compressed data into reader to preserve current result. + // If the channel is full after this block is appended, we should use preserved data. + if err := co.compress.Flush(); err != nil { + return 0, fmt.Errorf("failed to flush compressor: %w", err) + } + _, err = io.Copy(co.reader, co.compress) + if err != nil { + // Must reset reader to avoid partial output + co.reader.Reset() + return 0, fmt.Errorf("failed to copy compressed data to reader: %w", err) + } + } + + // Reset compressor to rewrite the entire span batch + co.compress.Reset() + // Avoid using io.Copy here, because we need all or nothing + written, err := co.compress.Write(buf.Bytes()) + if co.compress.FullErr() != nil { + err = co.compress.FullErr() + if co.spanBatchBuilder.GetBlockCount() == 1 { + // Do not return CompressorFullErr for the first block in the batch + // In this case, reader must be empty. then the contents of compressor will be copied to reader when the channel is closed. + err = nil + } + // If there are more than one blocks in the channel, reader should have data that preserves previous compression result before adding this block. + // So, as a result, this block is not added to the channel and the channel will be closed. + return uint64(written), err + } + + // If compressor is not full yet, reader must be reset to avoid submitting invalid frames + co.reader.Reset() + return uint64(written), err +} + +// InputBytes returns the total amount of RLP-encoded input bytes. +func (co *SpanChannelOut) InputBytes() int { + return co.rlpLength +} + +// ReadyBytes returns the number of bytes that the channel out can immediately output into a frame. +// Use `Flush` or `Close` to move data from the compression buffer into the ready buffer if more bytes +// are needed. Add blocks may add to the ready buffer, but it is not guaranteed due to the compression stage. +func (co *SpanChannelOut) ReadyBytes() int { + return co.reader.Len() +} + +// Flush flushes the internal compression stage to the ready buffer. It enables pulling a larger & more +// complete frame. It reduces the compression efficiency. +func (co *SpanChannelOut) Flush() error { + if err := co.compress.Flush(); err != nil { + return err + } + if co.closed && co.ReadyBytes() == 0 && co.compress.Len() > 0 { + _, err := io.Copy(co.reader, co.compress) + if err != nil { + // Must reset reader to avoid partial output + co.reader.Reset() + return fmt.Errorf("failed to flush compressed data to reader: %w", err) + } + } + return nil +} + +func (co *SpanChannelOut) FullErr() error { + return co.compress.FullErr() +} + +func (co *SpanChannelOut) Close() error { + if co.closed { + return errors.New("already closed") + } + co.closed = true + if err := co.Flush(); err != nil { + return err + } + return co.compress.Close() +} + +// OutputFrame writes a frame to w with a given max size and returns the frame +// number. +// Use `ReadyBytes`, `Flush`, and `Close` to modify the ready buffer. +// Returns an error if the `maxSize` < FrameV0OverHeadSize. +// Returns io.EOF when the channel is closed & there are no more frames. +// Returns nil if there is still more buffered data. +// Returns an error if it ran into an error during processing. +func (co *SpanChannelOut) OutputFrame(w *bytes.Buffer, maxSize uint64) (uint16, error) { + // Check that the maxSize is large enough for the frame overhead size. + if maxSize < FrameV0OverHeadSize { + return 0, ErrMaxFrameSizeTooSmall + } + + f := createEmptyFrame(co.id, co.frame, co.ReadyBytes(), co.closed, maxSize) + + if _, err := io.ReadFull(co.reader, f.Data); err != nil { + return 0, err + } + + if err := f.MarshalBinary(w); err != nil { + return 0, err + } + + co.frame += 1 + fn := f.FrameNumber + if f.IsLast { + return fn, io.EOF + } else { + return fn, nil + } +} From 33983267003e8c7d33d22495fe78c4f14e2ea1c7 Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 25 Oct 2023 03:15:00 +0200 Subject: [PATCH 017/374] op-batcher: fix lint --- op-batcher/batcher/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-batcher/batcher/driver.go b/op-batcher/batcher/driver.go index d45ae3153780..d61de4b2b3aa 100644 --- a/op-batcher/batcher/driver.go +++ b/op-batcher/batcher/driver.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "io" "math/big" _ "net/http/pprof" @@ -17,6 +16,7 @@ import ( "github.com/ethereum-optimism/optimism/op-batcher/metrics" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) From 5f5db7775660d1d5a00f396b48ebd11e16cfe0ba Mon Sep 17 00:00:00 2001 From: Tei Im Date: Wed, 25 Oct 2023 15:01:24 +0900 Subject: [PATCH 018/374] Use sequencer number to calculate origin bit of span batch Remove lastProcessedBlock from ChannelManager Add seqNum arg to ChannelOut AddSingularBatch interface --- op-batcher/batcher/channel.go | 5 +- op-batcher/batcher/channel_builder.go | 9 +++- op-batcher/batcher/channel_builder_test.go | 45 ++++++++-------- op-batcher/batcher/channel_manager.go | 32 +++-------- op-batcher/batcher/channel_manager_test.go | 63 +++++++++++----------- op-batcher/batcher/channel_test.go | 8 +-- op-batcher/batcher/driver.go | 37 ++++--------- op-node/rollup/derive/channel_out.go | 8 +-- op-node/rollup/derive/span_batch.go | 19 +++---- op-node/rollup/derive/span_batch_test.go | 8 +-- op-node/rollup/derive/span_channel_out.go | 8 +-- op-node/rollup/derive/test/random.go | 11 ++++ 12 files changed, 117 insertions(+), 136 deletions(-) diff --git a/op-batcher/batcher/channel.go b/op-batcher/batcher/channel.go index cd44f31a9c46..1d1eb2d5f568 100644 --- a/op-batcher/batcher/channel.go +++ b/op-batcher/batcher/channel.go @@ -5,6 +5,7 @@ import ( "math" "github.com/ethereum-optimism/optimism/op-batcher/metrics" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/core/types" @@ -26,8 +27,8 @@ type channel struct { confirmedTransactions map[txID]eth.BlockID } -func newChannel(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, spanBatchBuilder *derive.SpanBatchBuilder) (*channel, error) { - cb, err := newChannelBuilder(cfg, spanBatchBuilder) +func newChannel(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, rcfg *rollup.Config) (*channel, error) { + cb, err := newChannelBuilder(cfg, rcfg) if err != nil { return nil, fmt.Errorf("creating new channel: %w", err) } diff --git a/op-batcher/batcher/channel_builder.go b/op-batcher/batcher/channel_builder.go index 81bce734b522..e336c90ad3d5 100644 --- a/op-batcher/batcher/channel_builder.go +++ b/op-batcher/batcher/channel_builder.go @@ -8,6 +8,7 @@ import ( "math" "github.com/ethereum-optimism/optimism/op-batcher/compressor" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum/go-ethereum/core/types" ) @@ -134,11 +135,15 @@ type channelBuilder struct { // newChannelBuilder creates a new channel builder or returns an error if the // channel out could not be created. -func newChannelBuilder(cfg ChannelConfig, spanBatchBuilder *derive.SpanBatchBuilder) (*channelBuilder, error) { +func newChannelBuilder(cfg ChannelConfig, rcfg *rollup.Config) (*channelBuilder, error) { c, err := cfg.CompressorConfig.NewCompressor() if err != nil { return nil, err } + var spanBatchBuilder *derive.SpanBatchBuilder + if cfg.BatchType == derive.SpanBatchType { + spanBatchBuilder = derive.NewSpanBatchBuilder(rcfg.Genesis.L2Time, rcfg.L2ChainID) + } co, err := derive.NewChannelOut(cfg.BatchType, c, spanBatchBuilder) if err != nil { return nil, err @@ -206,7 +211,7 @@ func (c *channelBuilder) AddBlock(block *types.Block) (derive.L1BlockInfo, error return l1info, fmt.Errorf("converting block to batch: %w", err) } - if _, err = c.co.AddSingularBatch(batch); errors.Is(err, derive.ErrTooManyRLPBytes) || errors.Is(err, derive.CompressorFullErr) { + if _, err = c.co.AddSingularBatch(batch, l1info.SequenceNumber); errors.Is(err, derive.ErrTooManyRLPBytes) || errors.Is(err, derive.CompressorFullErr) { c.setFullErr(err) return l1info, c.FullErr() } else if err != nil { diff --git a/op-batcher/batcher/channel_builder_test.go b/op-batcher/batcher/channel_builder_test.go index fa8512039d8a..db8e74e2e932 100644 --- a/op-batcher/batcher/channel_builder_test.go +++ b/op-batcher/batcher/channel_builder_test.go @@ -35,12 +35,9 @@ var defaultTestChannelConfig = ChannelConfig{ BatchType: derive.SingularBatchType, } -func getSpanBatchBuilder(batchType uint) *derive.SpanBatchBuilder { - if batchType == derive.SpanBatchType { - chainId := big.NewInt(1234) - return derive.NewSpanBatchBuilder(uint64(0), uint64(0), chainId) - } - return nil +var defaultTestRollupConfig = rollup.Config{ + Genesis: rollup.Genesis{L2: eth.BlockID{Number: 0}}, + L2ChainID: big.NewInt(1234), } // TestChannelConfig_Check tests the [ChannelConfig] [Check] function. @@ -169,7 +166,7 @@ func newMiniL2BlockWithNumberParent(numTx int, number *big.Int, parent common.Ha func addTooManyBlocks(cb *channelBuilder) error { rng := rand.New(rand.NewSource(1234)) for i := 0; i < 10_000; i++ { - block, _ := dtest.RandomL2Block(rng, 1000) + block := dtest.RandomL2BlockWithChainId(rng, 1000, defaultTestRollupConfig.L2ChainID) _, err := cb.AddBlock(block) if err != nil { return err @@ -518,7 +515,7 @@ func TestChannelBuilder_OutputFramesWorks_SpanBatch(t *testing.T) { channelConfig.BatchType = derive.SpanBatchType // Construct the channel builder - cb, err := newChannelBuilder(channelConfig, getSpanBatchBuilder(derive.SpanBatchType)) + cb, err := newChannelBuilder(channelConfig, &defaultTestRollupConfig) require.NoError(t, err) require.False(t, cb.IsFull()) require.Equal(t, 0, cb.PendingFrames()) @@ -571,7 +568,7 @@ func ChannelBuilder_MaxRLPBytesPerChannel(t *testing.T, batchType uint) { channelConfig.BatchType = batchType // Construct the channel builder - cb, err := newChannelBuilder(channelConfig, getSpanBatchBuilder(batchType)) + cb, err := newChannelBuilder(channelConfig, &defaultTestRollupConfig) require.NoError(t, err) // Add a block that overflows the [ChannelOut] @@ -594,12 +591,12 @@ func ChannelBuilder_OutputFramesMaxFrameIndex(t *testing.T, batchType uint) { // Continuously add blocks until the max frame index is reached // This should cause the [channelBuilder.OutputFrames] function // to error - cb, err := newChannelBuilder(channelConfig, getSpanBatchBuilder(batchType)) + cb, err := newChannelBuilder(channelConfig, &defaultTestRollupConfig) require.NoError(t, err) require.False(t, cb.IsFull()) require.Equal(t, 0, cb.PendingFrames()) for { - a, _ := dtest.RandomL2Block(rng, 1) + a := dtest.RandomL2BlockWithChainId(rng, 1, defaultTestRollupConfig.L2ChainID) _, err = cb.AddBlock(a) if cb.IsFull() { fullErr := cb.FullErr() @@ -627,7 +624,7 @@ func ChannelBuilder_AddBlock(t *testing.T, batchType uint) { channelConfig.CompressorConfig.ApproxComprRatio = 1 // Construct the channel builder - cb, err := newChannelBuilder(channelConfig, getSpanBatchBuilder(batchType)) + cb, err := newChannelBuilder(channelConfig, &defaultTestRollupConfig) require.NoError(t, err) // Add a nonsense block to the channel builder @@ -660,7 +657,7 @@ func ChannelBuilder_Reset(t *testing.T, batchType uint) { channelConfig.CompressorConfig.TargetFrameSize = 24 channelConfig.CompressorConfig.ApproxComprRatio = 1 - cb, err := newChannelBuilder(channelConfig, getSpanBatchBuilder(batchType)) + cb, err := newChannelBuilder(channelConfig, &defaultTestRollupConfig) require.NoError(t, err) // Add a nonsense block to the channel builder @@ -771,7 +768,7 @@ func ChannelBuilder_PendingFrames_TotalFrames(t *testing.T, batchType uint) { cfg.CompressorConfig.TargetNumFrames = tnf cfg.CompressorConfig.Kind = "shadow" cfg.BatchType = batchType - cb, err := newChannelBuilder(cfg, getSpanBatchBuilder(batchType)) + cb, err := newChannelBuilder(cfg, &defaultTestRollupConfig) require.NoError(err) // initial builder should be empty @@ -780,7 +777,7 @@ func ChannelBuilder_PendingFrames_TotalFrames(t *testing.T, batchType uint) { // fill up for { - block, _ := dtest.RandomL2Block(rng, 4) + block := dtest.RandomL2BlockWithChainId(rng, 4, defaultTestRollupConfig.L2ChainID) _, err := cb.AddBlock(block) if cb.IsFull() { break @@ -810,21 +807,25 @@ func ChannelBuilder_InputBytes(t *testing.T, batchType uint) { rng := rand.New(rand.NewSource(4982432)) cfg := defaultTestChannelConfig cfg.BatchType = batchType - spanBatchBuilder := getSpanBatchBuilder(batchType) - cb, err := newChannelBuilder(cfg, getSpanBatchBuilder(batchType)) + var spanBatchBuilder *derive.SpanBatchBuilder + if batchType == derive.SpanBatchType { + chainId := big.NewInt(1234) + spanBatchBuilder = derive.NewSpanBatchBuilder(uint64(0), chainId) + } + cb, err := newChannelBuilder(cfg, &defaultTestRollupConfig) require.NoError(err) require.Zero(cb.InputBytes()) var l int for i := 0; i < 5; i++ { - block := newMiniL2Block(rng.Intn(32)) + block := dtest.RandomL2BlockWithChainId(rng, rng.Intn(32), defaultTestRollupConfig.L2ChainID) if batchType == derive.SingularBatchType { l += blockBatchRlpSize(t, block) } else { - singularBatch, _, err := derive.BlockToSingularBatch(block) + singularBatch, l1Info, err := derive.BlockToSingularBatch(block) require.NoError(err) - spanBatchBuilder.AppendSingularBatch(singularBatch) + spanBatchBuilder.AppendSingularBatch(singularBatch, l1Info.SequenceNumber) rawSpanBatch, err := spanBatchBuilder.GetRawSpanBatch() require.NoError(err) batch := derive.NewSpanBatchData(*rawSpanBatch) @@ -847,13 +848,13 @@ func ChannelBuilder_OutputBytes(t *testing.T, batchType uint) { cfg.CompressorConfig.TargetNumFrames = 16 cfg.CompressorConfig.ApproxComprRatio = 1.0 cfg.BatchType = batchType - cb, err := newChannelBuilder(cfg, getSpanBatchBuilder(batchType)) + cb, err := newChannelBuilder(cfg, &defaultTestRollupConfig) require.NoError(err, "newChannelBuilder") require.Zero(cb.OutputBytes()) for { - block, _ := dtest.RandomL2Block(rng, rng.Intn(32)) + block := dtest.RandomL2BlockWithChainId(rng, rng.Intn(32), defaultTestRollupConfig.L2ChainID) _, err := cb.AddBlock(block) if errors.Is(err, derive.CompressorFullErr) { break diff --git a/op-batcher/batcher/channel_manager.go b/op-batcher/batcher/channel_manager.go index dc00fab364e9..5829e3dc448b 100644 --- a/op-batcher/batcher/channel_manager.go +++ b/op-batcher/batcher/channel_manager.go @@ -36,9 +36,6 @@ type channelManager struct { // last block hash - for reorg detection tip common.Hash - // last block added to channel. nil at first. - lastProcessedBlock *eth.L2BlockRef - // channel to write new block data to currentChannel *channel // channels to read frame data from, for writing batches onchain @@ -52,19 +49,18 @@ type channelManager struct { func NewChannelManager(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, rcfg *rollup.Config) *channelManager { return &channelManager{ - log: log, - metr: metr, - cfg: cfg, - rcfg: rcfg, - txChannels: make(map[txID]*channel), - lastProcessedBlock: nil, + log: log, + metr: metr, + cfg: cfg, + rcfg: rcfg, + txChannels: make(map[txID]*channel), } } // Clear clears the entire state of the channel manager. // It is intended to be used before launching op-batcher and after an L2 reorg. // Must set lastProcessedBlock as current L2 safe head fetched from L2 node. -func (s *channelManager) Clear(safeHead *eth.L2BlockRef) { +func (s *channelManager) Clear() { s.mu.Lock() defer s.mu.Unlock() s.log.Trace("clearing channel manager state") @@ -74,7 +70,6 @@ func (s *channelManager) Clear(safeHead *eth.L2BlockRef) { s.currentChannel = nil s.channelQueue = nil s.txChannels = make(map[txID]*channel) - s.lastProcessedBlock = safeHead } // TxFailed records a transaction as failed. It will attempt to resubmit the data @@ -204,19 +199,7 @@ func (s *channelManager) ensureChannelWithSpace(l1Head eth.BlockID) error { return nil } - var spanBatchBuilder *derive.SpanBatchBuilder - if s.cfg.BatchType == derive.SpanBatchType { - if s.lastProcessedBlock == nil { - // TODO: we can remove "lastProcessedBlock" if we change the data-builder - // to append a singular-batch *with* the L2 metadata such as the L1-block-info seq-number; - // this helps determine whether or not the L1 origin changed in the first block of the span, - // without having to remember the last block from before the span. - return errors.New("last block is not initialized") - } - // Pass the current lastProcessedBlock as the parent - spanBatchBuilder = derive.NewSpanBatchBuilder(s.lastProcessedBlock.L1Origin.Number, s.rcfg.Genesis.L2Time, s.rcfg.L2ChainID) - } - pc, err := newChannel(s.log, s.metr, s.cfg, spanBatchBuilder) + pc, err := newChannel(s.log, s.metr, s.cfg, s.rcfg) if err != nil { return fmt.Errorf("creating new channel: %w", err) } @@ -262,7 +245,6 @@ func (s *channelManager) processBlocks() error { blocksAdded += 1 latestL2ref = l2BlockRefFromBlockAndL1Info(block, l1info) s.metr.RecordL2BlockInChannel(block) - s.lastProcessedBlock = &latestL2ref // current block got added but channel is now full if s.currentChannel.IsFull() { break diff --git a/op-batcher/batcher/channel_manager_test.go b/op-batcher/batcher/channel_manager_test.go index b68d13e4cc8b..eac3cff44d11 100644 --- a/op-batcher/batcher/channel_manager_test.go +++ b/op-batcher/batcher/channel_manager_test.go @@ -14,7 +14,6 @@ import ( derivetest "github.com/ethereum-optimism/optimism/op-node/rollup/derive/test" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/ethereum-optimism/optimism/op-service/testutils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" @@ -55,7 +54,7 @@ func TestChannelManagerBatchType(t *testing.T) { func ChannelManagerReturnsErrReorg(t *testing.T, batchType uint) { log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{BatchType: batchType}, &rollup.Config{}) - m.Clear(ð.L2BlockRef{}) + m.Clear() a := types.NewBlock(&types.Header{ Number: big.NewInt(0), @@ -97,7 +96,7 @@ func ChannelManagerReturnsErrReorgWhenDrained(t *testing.T, batchType uint) { }, &rollup.Config{}, ) - m.Clear(ð.L2BlockRef{}) + m.Clear() a := newMiniL2Block(0) x := newMiniL2BlockWithNumberParent(0, big.NewInt(1), common.Hash{0xff}) @@ -134,7 +133,7 @@ func ChannelManager_Clear(t *testing.T, batchType uint) { }, BatchType: batchType, }, - &rollup.Config{}, + &defaultTestRollupConfig, ) // Channel Manager state should be empty by default @@ -143,12 +142,11 @@ func ChannelManager_Clear(t *testing.T, batchType uint) { require.Nil(m.currentChannel) require.Empty(m.channelQueue) require.Empty(m.txChannels) - require.Nil(m.lastProcessedBlock) // Set the last block - m.Clear(ð.L2BlockRef{}) + m.Clear() // Add a block to the channel manager - a, _ := derivetest.RandomL2Block(rng, 4) + a := derivetest.RandomL2BlockWithChainId(rng, 4, defaultTestRollupConfig.L2ChainID) newL1Tip := a.Hash() l1BlockID := eth.BlockID{ Hash: a.Hash(), @@ -185,8 +183,7 @@ func ChannelManager_Clear(t *testing.T, batchType uint) { require.Equal(b.Hash(), m.tip) // Clear the channel manager - safeHead := testutils.RandomL2BlockRef(rng) - m.Clear(&safeHead) + m.Clear() // Check that the entire channel manager state cleared require.Empty(m.blocks) @@ -194,7 +191,6 @@ func ChannelManager_Clear(t *testing.T, batchType uint) { require.Nil(m.currentChannel) require.Empty(m.channelQueue) require.Empty(m.txChannels) - require.Equal(m.lastProcessedBlock, &safeHead) } func ChannelManager_TxResend(t *testing.T, batchType uint) { @@ -211,11 +207,11 @@ func ChannelManager_TxResend(t *testing.T, batchType uint) { }, BatchType: batchType, }, - &rollup.Config{}, + &defaultTestRollupConfig, ) - m.Clear(ð.L2BlockRef{}) + m.Clear() - a, _ := derivetest.RandomL2Block(rng, 4) + a := derivetest.RandomL2BlockWithChainId(rng, 4, defaultTestRollupConfig.L2ChainID) require.NoError(m.AddL2Block(a)) @@ -259,11 +255,11 @@ func ChannelManagerCloseBeforeFirstUse(t *testing.T, batchType uint) { }, BatchType: batchType, }, - &rollup.Config{}, + &defaultTestRollupConfig, ) - m.Clear(ð.L2BlockRef{}) + m.Clear() - a, _ := derivetest.RandomL2Block(rng, 4) + a := derivetest.RandomL2BlockWithChainId(rng, 4, defaultTestRollupConfig.L2ChainID) m.Close() @@ -291,9 +287,9 @@ func ChannelManagerCloseNoPendingChannel(t *testing.T, batchType uint) { }, BatchType: batchType, }, - &rollup.Config{}, + &defaultTestRollupConfig, ) - m.Clear(ð.L2BlockRef{}) + m.Clear() a := newMiniL2Block(0) b := newMiniL2BlockWithNumberParent(0, big.NewInt(1), a.Hash()) @@ -322,30 +318,30 @@ func ChannelManagerCloseNoPendingChannel(t *testing.T, batchType uint) { // new channel frames after this point. func ChannelManagerClosePendingChannel(t *testing.T, batchType uint) { require := require.New(t) + rng := rand.New(rand.NewSource(time.Now().UnixNano())) log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{ - MaxFrameSize: 1000, + MaxFrameSize: 10000, ChannelTimeout: 1000, CompressorConfig: compressor.Config{ TargetNumFrames: 1, - TargetFrameSize: 1000, + TargetFrameSize: 10000, ApproxComprRatio: 1.0, }, BatchType: batchType, }, - &rollup.Config{}, + &defaultTestRollupConfig, ) - m.Clear(ð.L2BlockRef{}) + m.Clear() - numTx := 50000 - if batchType == derive.SpanBatchType { - // Adjust number of txs to make 2 frames - // Encoding empty txs as span batch requires more data size because span batch encodes tx signature to fixed length - numTx = 20000 - } - a := newMiniL2Block(numTx) - b := newMiniL2BlockWithNumberParent(10, big.NewInt(1), a.Hash()) + numTx := 20 // Adjust number of txs to make 2 frames + a := derivetest.RandomL2BlockWithChainId(rng, numTx, defaultTestRollupConfig.L2ChainID) + b := derivetest.RandomL2BlockWithChainId(rng, 10, defaultTestRollupConfig.L2ChainID) + bHeader := b.Header() + bHeader.Number = new(big.Int).Add(a.Number(), big.NewInt(1)) + bHeader.ParentHash = a.Hash() + b = b.WithSeal(bHeader) err := m.AddL2Block(a) require.NoError(err, "Failed to add L2 block") @@ -377,6 +373,7 @@ func ChannelManagerClosePendingChannel(t *testing.T, batchType uint) { // have successfully landed on chain. func ChannelManagerCloseAllTxsFailed(t *testing.T, batchType uint) { require := require.New(t) + rng := rand.New(rand.NewSource(time.Now().UnixNano())) log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{ @@ -388,11 +385,11 @@ func ChannelManagerCloseAllTxsFailed(t *testing.T, batchType uint) { ApproxComprRatio: 1.0, }, BatchType: batchType, - }, &rollup.Config{}, + }, &defaultTestRollupConfig, ) - m.Clear(ð.L2BlockRef{}) + m.Clear() - a := newMiniL2Block(50_000) + a := derivetest.RandomL2BlockWithChainId(rng, 50000, defaultTestRollupConfig.L2ChainID) err := m.AddL2Block(a) require.NoError(err, "Failed to add L2 block") diff --git a/op-batcher/batcher/channel_test.go b/op-batcher/batcher/channel_test.go index 26f64204bc73..138416069767 100644 --- a/op-batcher/batcher/channel_test.go +++ b/op-batcher/batcher/channel_test.go @@ -22,7 +22,7 @@ func TestChannelTimeout(t *testing.T) { m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{ ChannelTimeout: 100, }, &rollup.Config{}) - m.Clear(ð.L2BlockRef{}) + m.Clear() // Pending channel is nil so is cannot be timed out require.Nil(t, m.currentChannel) @@ -64,7 +64,7 @@ func TestChannelTimeout(t *testing.T) { func TestChannelNextTxData(t *testing.T) { log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{}, &rollup.Config{}) - m.Clear(ð.L2BlockRef{}) + m.Clear() // Nil pending channel should return EOF returnedTxData, err := m.nextTxData(nil) @@ -113,7 +113,7 @@ func TestChannelTxConfirmed(t *testing.T) { // clearing confirmed transactions, and reseting the pendingChannels map ChannelTimeout: 10, }, &rollup.Config{}) - m.Clear(ð.L2BlockRef{}) + m.Clear() // Let's add a valid pending transaction to the channel manager // So we can demonstrate that TxConfirmed's correctness @@ -162,7 +162,7 @@ func TestChannelTxFailed(t *testing.T) { // Create a channel manager log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{}, &rollup.Config{}) - m.Clear(ð.L2BlockRef{}) + m.Clear() // Let's add a valid pending transaction to the channel // manager so we can demonstrate correctness diff --git a/op-batcher/batcher/driver.go b/op-batcher/batcher/driver.go index d61de4b2b3aa..54633060dac4 100644 --- a/op-batcher/batcher/driver.go +++ b/op-batcher/batcher/driver.go @@ -91,11 +91,7 @@ func (l *BatchSubmitter) StartBatchSubmitting() error { l.shutdownCtx, l.cancelShutdownCtx = context.WithCancel(context.Background()) l.killCtx, l.cancelKillCtx = context.WithCancel(context.Background()) - syncStatus, err := fetchSyncStatus(l.shutdownCtx, l.RollupClient, l.Cfg.NetworkTimeout) - if err != nil { - return err - } - l.state.Clear(&syncStatus.SafeL2) + l.state.Clear() l.lastStoredBlock = eth.BlockID{} l.wg.Add(1) @@ -205,9 +201,15 @@ func (l *BatchSubmitter) loadBlockIntoState(ctx context.Context, blockNumber uin // calculateL2BlockRangeToStore determines the range (start,end] that should be loaded into the local state. // It also takes care of initializing some local state (i.e. will modify l.lastStoredBlock in certain conditions) func (l *BatchSubmitter) calculateL2BlockRangeToStore(ctx context.Context) (eth.BlockID, eth.BlockID, error) { - syncStatus, err := fetchSyncStatus(ctx, l.RollupClient, l.Cfg.NetworkTimeout) + ctx, cancel := context.WithTimeout(ctx, l.Cfg.NetworkTimeout) + defer cancel() + syncStatus, err := l.RollupClient.SyncStatus(ctx) + // Ensure that we have the sync status if err != nil { - return eth.BlockID{}, eth.BlockID{}, err + return eth.BlockID{}, eth.BlockID{}, fmt.Errorf("failed to get sync status: %w", err) + } + if syncStatus.HeadL1 == (eth.L1BlockRef{}) { + return eth.BlockID{}, eth.BlockID{}, errors.New("empty sync status") } // Check last stored to see if it needs to be set on startup OR set if is lagged behind. @@ -257,12 +259,7 @@ func (l *BatchSubmitter) loop() { l.Log.Error("error closing the channel manager to handle a L2 reorg", "err", err) } l.publishStateToL1(queue, receiptsCh, true) - if syncStatus, err := fetchSyncStatus(l.shutdownCtx, l.RollupClient, l.Cfg.NetworkTimeout); err == nil { - l.state.Clear(&syncStatus.SafeL2) - } else { - // if fetchSyncStatus failed, ErrReorg will be returned again - l.Log.Error("error fetching sync status from L2 node", "err", err) - } + l.state.Clear() continue } l.publishStateToL1(queue, receiptsCh, false) @@ -398,17 +395,3 @@ func (l *BatchSubmitter) l1Tip(ctx context.Context) (eth.L1BlockRef, error) { } return eth.InfoToL1BlockRef(eth.HeaderBlockInfo(head)), nil } - -func fetchSyncStatus(ctx context.Context, rollupNode RollupClient, timeout time.Duration) (*eth.SyncStatus, error) { - ctx, cancel := context.WithTimeout(ctx, timeout) - defer cancel() - syncStatus, err := rollupNode.SyncStatus(ctx) - // Ensure that we have the sync status - if err != nil { - return ð.SyncStatus{}, fmt.Errorf("failed to get sync status: %w", err) - } - if syncStatus.SafeL2 == (eth.L2BlockRef{}) { - return ð.SyncStatus{}, errors.New("empty sync status") - } - return syncStatus, nil -} diff --git a/op-node/rollup/derive/channel_out.go b/op-node/rollup/derive/channel_out.go index d2af4be76e28..642c32ac06aa 100644 --- a/op-node/rollup/derive/channel_out.go +++ b/op-node/rollup/derive/channel_out.go @@ -52,7 +52,7 @@ type ChannelOut interface { ID() ChannelID Reset() error AddBlock(*types.Block) (uint64, error) - AddSingularBatch(*SingularBatch) (uint64, error) + AddSingularBatch(*SingularBatch, uint64) (uint64, error) InputBytes() int ReadyBytes() int Flush() error @@ -123,11 +123,11 @@ func (co *SingularChannelOut) AddBlock(block *types.Block) (uint64, error) { return 0, errors.New("already closed") } - batch, _, err := BlockToSingularBatch(block) + batch, l1Info, err := BlockToSingularBatch(block) if err != nil { return 0, err } - return co.AddSingularBatch(batch) + return co.AddSingularBatch(batch, l1Info.SequenceNumber) } // AddSingularBatch adds a batch to the channel. It returns the RLP encoded byte size @@ -138,7 +138,7 @@ func (co *SingularChannelOut) AddBlock(block *types.Block) (uint64, error) { // AddSingularBatch should be used together with BlockToBatch if you need to access the // BatchData before adding a block to the channel. It isn't possible to access // the batch data with AddBlock. -func (co *SingularChannelOut) AddSingularBatch(batch *SingularBatch) (uint64, error) { +func (co *SingularChannelOut) AddSingularBatch(batch *SingularBatch, _ uint64) (uint64, error) { if co.closed { return 0, errors.New("already closed") } diff --git a/op-node/rollup/derive/span_batch.go b/op-node/rollup/derive/span_batch.go index d68d542ff957..770eb58b7008 100644 --- a/op-node/rollup/derive/span_batch.go +++ b/op-node/rollup/derive/span_batch.go @@ -597,31 +597,32 @@ func NewSpanBatch(singularBatches []*SingularBatch) *SpanBatch { // SpanBatchBuilder is a utility type to build a SpanBatch by adding a SingularBatch one by one. // makes easier to stack SingularBatches and convert to RawSpanBatch for encoding. type SpanBatchBuilder struct { - parentEpoch uint64 genesisTimestamp uint64 chainID *big.Int spanBatch *SpanBatch + originChangedBit uint } -func NewSpanBatchBuilder(parentEpoch uint64, genesisTimestamp uint64, chainID *big.Int) *SpanBatchBuilder { +func NewSpanBatchBuilder(genesisTimestamp uint64, chainID *big.Int) *SpanBatchBuilder { return &SpanBatchBuilder{ - parentEpoch: parentEpoch, genesisTimestamp: genesisTimestamp, chainID: chainID, spanBatch: &SpanBatch{}, } } -func (b *SpanBatchBuilder) AppendSingularBatch(singularBatch *SingularBatch) { +func (b *SpanBatchBuilder) AppendSingularBatch(singularBatch *SingularBatch, seqNum uint64) { + if b.GetBlockCount() == 0 { + b.originChangedBit = 0 + if seqNum == 0 { + b.originChangedBit = 1 + } + } b.spanBatch.AppendSingularBatch(singularBatch) } func (b *SpanBatchBuilder) GetRawSpanBatch() (*RawSpanBatch, error) { - originChangedBit := 0 - if uint64(b.spanBatch.GetStartEpochNum()) != b.parentEpoch { - originChangedBit = 1 - } - raw, err := b.spanBatch.ToRawSpanBatch(uint(originChangedBit), b.genesisTimestamp, b.chainID) + raw, err := b.spanBatch.ToRawSpanBatch(b.originChangedBit, b.genesisTimestamp, b.chainID) if err != nil { return nil, err } diff --git a/op-node/rollup/derive/span_batch_test.go b/op-node/rollup/derive/span_batch_test.go index d2a0ac3f8d54..a4929467ac35 100644 --- a/op-node/rollup/derive/span_batch_test.go +++ b/op-node/rollup/derive/span_batch_test.go @@ -493,16 +493,16 @@ func TestSpanBatchBuilder(t *testing.T) { } genesisTimeStamp := 1 + singularBatches[0].Timestamp - 128 - parentEpoch := uint64(singularBatches[0].EpochNum) + var seqNum uint64 = 1 if originChangedBit == 1 { - parentEpoch -= 1 + seqNum = 0 } - spanBatchBuilder := NewSpanBatchBuilder(parentEpoch, genesisTimeStamp, chainID) + spanBatchBuilder := NewSpanBatchBuilder(genesisTimeStamp, chainID) assert.Equal(t, 0, spanBatchBuilder.GetBlockCount()) for i := 0; i < len(singularBatches); i++ { - spanBatchBuilder.AppendSingularBatch(singularBatches[i]) + spanBatchBuilder.AppendSingularBatch(singularBatches[i], seqNum) assert.Equal(t, i+1, spanBatchBuilder.GetBlockCount()) assert.Equal(t, singularBatches[0].ParentHash.Bytes()[:20], spanBatchBuilder.spanBatch.parentCheck) assert.Equal(t, singularBatches[i].EpochHash.Bytes()[:20], spanBatchBuilder.spanBatch.l1OriginCheck) diff --git a/op-node/rollup/derive/span_channel_out.go b/op-node/rollup/derive/span_channel_out.go index d074a19c29ef..608257b7bbb3 100644 --- a/op-node/rollup/derive/span_channel_out.go +++ b/op-node/rollup/derive/span_channel_out.go @@ -70,11 +70,11 @@ func (co *SpanChannelOut) AddBlock(block *types.Block) (uint64, error) { return 0, errors.New("already closed") } - batch, _, err := BlockToSingularBatch(block) + batch, l1Info, err := BlockToSingularBatch(block) if err != nil { return 0, err } - return co.AddSingularBatch(batch) + return co.AddSingularBatch(batch, l1Info.SequenceNumber) } // AddSingularBatch adds a batch to the channel. It returns the RLP encoded byte size @@ -90,7 +90,7 @@ func (co *SpanChannelOut) AddBlock(block *types.Block) (uint64, error) { // A channel can have only one SpanBatch. And compressed results should not be accessible until the channel is closed, since the prefix and payload can be changed. // So it resets channel contents and rewrites the entire SpanBatch each time, and compressed results are copied to reader after the channel is closed. // It makes we can only get frames once the channel is full or closed, in the case of SpanBatch. -func (co *SpanChannelOut) AddSingularBatch(batch *SingularBatch) (uint64, error) { +func (co *SpanChannelOut) AddSingularBatch(batch *SingularBatch, seqNum uint64) (uint64, error) { if co.closed { return 0, errors.New("already closed") } @@ -100,7 +100,7 @@ func (co *SpanChannelOut) AddSingularBatch(batch *SingularBatch) (uint64, error) } var buf bytes.Buffer // Append Singular batch to its span batch builder - co.spanBatchBuilder.AppendSingularBatch(batch) + co.spanBatchBuilder.AppendSingularBatch(batch, seqNum) // Convert Span batch to RawSpanBatch rawSpanBatch, err := co.spanBatchBuilder.GetRawSpanBatch() if err != nil { diff --git a/op-node/rollup/derive/test/random.go b/op-node/rollup/derive/test/random.go index 83ab5835808f..5724fd023f31 100644 --- a/op-node/rollup/derive/test/random.go +++ b/op-node/rollup/derive/test/random.go @@ -1,6 +1,7 @@ package test import ( + "math/big" "math/rand" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" @@ -21,3 +22,13 @@ func RandomL2Block(rng *rand.Rand, txCount int) (*types.Block, []*types.Receipt) } return testutils.RandomBlockPrependTxs(rng, txCount, types.NewTx(l1InfoTx)) } + +func RandomL2BlockWithChainId(rng *rand.Rand, txCount int, chainId *big.Int) *types.Block { + signer := types.NewLondonSigner(chainId) + block, _ := RandomL2Block(rng, 0) + txs := []*types.Transaction{block.Transactions()[0]} // L1 info deposit TX + for i := 0; i < txCount; i++ { + txs = append(txs, testutils.RandomTx(rng, big.NewInt(int64(rng.Uint32())), signer)) + } + return block.WithBody(txs, nil) +} From d2ad25efde8b5ffe310e16baaff4e97dc4a4ae53 Mon Sep 17 00:00:00 2001 From: Luis Marcano Date: Wed, 25 Oct 2023 12:04:19 -0400 Subject: [PATCH 019/374] fix race condition fix: import formatting; LastUpdate as atomic.Int64 fix ci/cd --- op-node/p2p/store/scorebook.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/op-node/p2p/store/scorebook.go b/op-node/p2p/store/scorebook.go index 81def53685fc..68043ef8a9e1 100644 --- a/op-node/p2p/store/scorebook.go +++ b/op-node/p2p/store/scorebook.go @@ -2,6 +2,7 @@ package store import ( "context" + "sync/atomic" "time" "github.com/ethereum-optimism/optimism/op-service/clock" @@ -17,17 +18,18 @@ const ( var scoresBase = ds.NewKey("/peers/scores") +// LastUpdate requires atomic update operations. Use the helper functions SetLastUpdated and LastUpdated to modify and access this field. type scoreRecord struct { - PeerScores PeerScores `json:"peerScores"` LastUpdate int64 `json:"lastUpdate"` // unix timestamp in seconds + PeerScores PeerScores `json:"peerScores"` } func (s *scoreRecord) SetLastUpdated(t time.Time) { - s.LastUpdate = t.Unix() + atomic.StoreInt64(&s.LastUpdate, t.Unix()) } func (s *scoreRecord) LastUpdated() time.Time { - return time.Unix(s.LastUpdate, 0) + return time.Unix(atomic.LoadInt64(&s.LastUpdate), 0) } func (s *scoreRecord) MarshalBinary() (data []byte, err error) { From 50b4767162bbebb5a7decceeebb7d1cf57db4317 Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 25 Oct 2023 23:10:58 +0200 Subject: [PATCH 020/374] op-node: span-batch logging stye fixes Co-authored-by: Adrian Sutton --- op-node/rollup/derive/batch_queue.go | 2 +- op-node/rollup/derive/batches.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index a340bc171bff..b12f08c54fbd 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -247,7 +247,7 @@ batchLoop: remaining = append(remaining, batch) continue case BatchDrop: - batch.Batch.LogContext(bq.log).Warn("dropping batch", + batch.Batch.LogContext(bq.log).Warn("Dropping batch", "l2_safe_head", l2SafeHead.ID(), "l2_safe_head_time", l2SafeHead.Time, ) diff --git a/op-node/rollup/derive/batches.go b/op-node/rollup/derive/batches.go index 73020fa4079f..e618fcc7433a 100644 --- a/op-node/rollup/derive/batches.go +++ b/op-node/rollup/derive/batches.go @@ -53,7 +53,7 @@ func CheckBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1Block } return checkSpanBatch(ctx, cfg, log, l1Blocks, l2SafeHead, spanBatch, batch.L1InclusionBlock, l2Fetcher) default: - log.Warn("unrecognized batch type: %d", batch.Batch.GetBatchType()) + log.Warn("Unrecognized batch type: %d", batch.Batch.GetBatchType()) return BatchDrop } } From a172c7d962f3fd632c73c4ea0d84999d6a53a1e5 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 25 Oct 2023 14:54:14 -0600 Subject: [PATCH 021/374] contracts-bedrock: scripts absolute import Import the scripts files using relative absolute imports from the project root. This makes the file much more portable and follows the conventions that the rest of the repo uses. --- packages/contracts-bedrock/scripts/Deploy.s.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/contracts-bedrock/scripts/Deploy.s.sol b/packages/contracts-bedrock/scripts/Deploy.s.sol index ca494ccb8a9b..c293825a359d 100644 --- a/packages/contracts-bedrock/scripts/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/Deploy.s.sol @@ -10,8 +10,8 @@ import { Safe } from "safe-contracts/Safe.sol"; import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; import { Enum as SafeOps } from "safe-contracts/common/Enum.sol"; -import { Deployer } from "./Deployer.sol"; -import { DeployConfig } from "./DeployConfig.s.sol"; +import { Deployer } from "scripts/Deployer.sol"; +import { DeployConfig } from "scripts/DeployConfig.s.sol"; import { Safe } from "safe-contracts/Safe.sol"; import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; @@ -37,7 +37,7 @@ import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; import { StorageSetter } from "src/universal/StorageSetter.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; -import { Chains } from "./Chains.sol"; +import { Chains } from "scripts/Chains.sol"; import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; From 5cbccfd162ccf7734362fc6a0eff81d978719d10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Oct 2023 23:23:09 +0000 Subject: [PATCH 022/374] build(deps-dev): bump @types/node from 20.8.8 to 20.8.9 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.8 to 20.8.9. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- packages/core-utils/package.json | 2 +- packages/sdk/package.json | 2 +- pnpm-lock.yaml | 130 ++++++++++++++++--------------- 4 files changed, 70 insertions(+), 66 deletions(-) diff --git a/package.json b/package.json index c30e072afdc5..9a94eb9d18ff 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@types/chai": "^4.3.8", "@types/chai-as-promised": "^7.1.4", "@types/mocha": "^10.0.3", - "@types/node": "^20.8.8", + "@types/node": "^20.8.9", "@typescript-eslint/eslint-plugin": "^6.9.0", "@typescript-eslint/parser": "^6.9.0", "chai": "^4.3.10", diff --git a/packages/core-utils/package.json b/packages/core-utils/package.json index 44194a74da0c..ec7ad4020352 100644 --- a/packages/core-utils/package.json +++ b/packages/core-utils/package.json @@ -49,7 +49,7 @@ "node-fetch": "^2.6.7" }, "devDependencies": { - "@types/node": "^20.8.8", + "@types/node": "^20.8.9", "mocha": "^10.2.0" } } diff --git a/packages/sdk/package.json b/packages/sdk/package.json index cbf651cfd58f..be729bed2af0 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -44,7 +44,7 @@ "@types/chai": "^4.3.8", "@types/chai-as-promised": "^7.1.5", "@types/mocha": "^10.0.3", - "@types/node": "^20.8.8", + "@types/node": "^20.8.9", "chai-as-promised": "^7.1.1", "ethereum-waffle": "^4.0.10", "ethers": "^5.7.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a511fe527501..3b54280963db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,8 +31,8 @@ importers: specifier: ^10.0.3 version: 10.0.3 '@types/node': - specifier: ^20.8.8 - version: 20.8.8 + specifier: ^20.8.9 + version: 20.8.9 '@typescript-eslint/eslint-plugin': specifier: ^6.9.0 version: 6.9.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2) @@ -184,7 +184,7 @@ importers: version: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) ts-node: specifier: ^10.9.1 - version: 10.9.1(@types/node@20.8.8)(typescript@5.2.2) + version: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) tsx: specifier: ^3.14.0 version: 3.14.0 @@ -348,7 +348,7 @@ importers: version: 5.2.2 vite: specifier: ^4.5.0 - version: 4.5.0(@types/node@20.8.8) + version: 4.5.0(@types/node@20.8.9) vitest: specifier: ^0.34.2 version: 0.34.2(jsdom@22.1.0) @@ -399,8 +399,8 @@ importers: version: 2.6.7 devDependencies: '@types/node': - specifier: ^20.8.8 - version: 20.8.8 + specifier: ^20.8.9 + version: 20.8.9 mocha: specifier: ^10.2.0 version: 10.2.0 @@ -442,7 +442,7 @@ importers: version: 1.16.6(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 - version: 4.5.0(@types/node@20.8.8) + version: 4.5.0(@types/node@20.8.9) vitest: specifier: ^0.34.2 version: 0.34.2(jsdom@22.1.0) @@ -493,8 +493,8 @@ importers: specifier: ^10.0.3 version: 10.0.3 '@types/node': - specifier: ^20.8.8 - version: 20.8.8 + specifier: ^20.8.9 + version: 20.8.9 chai-as-promised: specifier: ^7.1.1 version: 7.1.1(chai@4.3.10) @@ -521,7 +521,7 @@ importers: version: 15.1.0 ts-node: specifier: ^10.9.1 - version: 10.9.1(@types/node@20.8.8)(typescript@5.2.2) + version: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) typedoc: specifier: ^0.25.2 version: 0.25.2(typescript@5.2.2) @@ -573,7 +573,7 @@ importers: version: 1.16.6(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 - version: 4.5.0(@types/node@20.8.8) + version: 4.5.0(@types/node@20.8.9) vitest: specifier: ^0.34.1 version: 0.34.1 @@ -3882,20 +3882,20 @@ packages: /@types/bn.js@4.11.6: resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: true /@types/bn.js@5.1.0: resolution: {integrity: sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: true /@types/body-parser@1.19.1: resolution: {integrity: sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==} dependencies: '@types/connect': 3.4.35 - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: true /@types/chai-as-promised@7.1.5: @@ -3928,7 +3928,7 @@ packages: /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 /@types/dateformat@5.0.0: resolution: {integrity: sha512-SZg4JdHIWHQGEokbYGZSDvo5wA4TLYPXaqhigs/wH+REDOejcJzgH+qyY+HtEUtWOZxEUkbhbdYPqQDiEgrXeA==} @@ -3942,7 +3942,7 @@ packages: /@types/express-serve-static-core@4.17.35: resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 '@types/send': 0.17.1 @@ -3961,7 +3961,7 @@ packages: resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.8.6 + '@types/node': 20.8.8 dev: true /@types/is-ci@3.0.0: @@ -3988,7 +3988,7 @@ packages: dependencies: '@types/abstract-leveldown': 5.0.2 '@types/level-errors': 3.0.0 - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: true /@types/lru-cache@5.1.1: @@ -4020,7 +4020,7 @@ packages: /@types/mkdirp@0.5.2: resolution: {integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: true /@types/mocha@10.0.3: @@ -4039,7 +4039,7 @@ packages: /@types/node-fetch@2.6.4: resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 form-data: 3.0.1 dev: true @@ -4050,16 +4050,16 @@ packages: /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - /@types/node@20.8.6: - resolution: {integrity: sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==} + /@types/node@20.8.8: + resolution: {integrity: sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==} dependencies: undici-types: 5.25.3 dev: true - /@types/node@20.8.8: - resolution: {integrity: sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==} + /@types/node@20.8.9: + resolution: {integrity: sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==} dependencies: - undici-types: 5.25.3 + undici-types: 5.26.5 /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -4071,7 +4071,7 @@ packages: /@types/pbkdf2@3.1.0: resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: true /@types/pino-multi-stream@5.1.5: @@ -4089,13 +4089,13 @@ packages: /@types/pino-std-serializers@2.4.1: resolution: {integrity: sha512-17XcksO47M24IVTVKPeAByWUd3Oez7EbIjXpSbzMPhXVzgjGtrOa49gKBwxH9hb8dKv58OelsWQ+A1G1l9S3wQ==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: true /@types/pino@6.3.11: resolution: {integrity: sha512-S7+fLONqSpHeW9d7TApUqO6VN47KYgOXhCNKwGBVLHObq8HhaAYlVqUNdfnvoXjCMiwE5xcPm/5R2ZUh8bgaXQ==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 '@types/pino-pretty': 4.7.1 '@types/pino-std-serializers': 2.4.1 sonic-boom: 2.8.0 @@ -4141,7 +4141,7 @@ packages: /@types/readable-stream@2.3.15: resolution: {integrity: sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 safe-buffer: 5.1.2 dev: true @@ -4152,7 +4152,7 @@ packages: /@types/secp256k1@4.0.3: resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: true /@types/seedrandom@3.0.1: @@ -4171,14 +4171,14 @@ packages: resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} dependencies: '@types/mime': 1.3.2 - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: true /@types/serve-static@1.13.10: resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} dependencies: '@types/mime': 1.3.2 - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: true /@types/sinon-chai@3.2.5: @@ -4215,12 +4215,12 @@ packages: /@types/ws@7.4.7: resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 /@types/ws@8.5.3: resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 dev: false /@typescript-eslint/eslint-plugin@6.9.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2): @@ -8985,7 +8985,7 @@ packages: solc: 0.7.3(debug@4.3.4) source-map-support: 0.5.21 stacktrace-parser: 0.1.10 - ts-node: 10.9.1(@types/node@20.8.8)(typescript@5.2.2) + ts-node: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) tsort: 0.0.1 typescript: 5.2.2 undici: 5.24.0 @@ -13739,7 +13739,7 @@ packages: tsconfig-paths: 3.14.2 dev: true - /ts-node@10.9.1(@types/node@20.8.8)(typescript@5.2.2): + /ts-node@10.9.1(@types/node@20.8.9)(typescript@5.2.2): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -13758,7 +13758,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.8.8 + '@types/node': 20.8.9 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 @@ -14081,6 +14081,10 @@ packages: /undici-types@5.25.3: resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==} + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} /undici@5.24.0: resolution: {integrity: sha512-OKlckxBjFl0oXxcj9FU6oB8fDAaiRUq+D8jrFWGmOfI/gIyjk/IeS75LMzgYKUaeHzLUcYvf9bbJGSrUwTfwwQ==} @@ -14359,7 +14363,7 @@ packages: - utf-8-validate - zod - /vite-node@0.34.1(@types/node@20.8.8): + /vite-node@0.34.1(@types/node@20.8.9): resolution: {integrity: sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==} engines: {node: '>=v14.18.0'} hasBin: true @@ -14369,7 +14373,7 @@ packages: mlly: 1.4.0 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.8.8) + vite: 4.5.0(@types/node@20.8.9) transitivePeerDependencies: - '@types/node' - less @@ -14381,7 +14385,7 @@ packages: - terser dev: true - /vite-node@0.34.2(@types/node@20.8.6): + /vite-node@0.34.2(@types/node@20.8.8): resolution: {integrity: sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA==} engines: {node: '>=v14.18.0'} hasBin: true @@ -14391,7 +14395,7 @@ packages: mlly: 1.4.0 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.8.6) + vite: 4.5.0(@types/node@20.8.8) transitivePeerDependencies: - '@types/node' - less @@ -14403,7 +14407,7 @@ packages: - terser dev: true - /vite-node@0.34.2(@types/node@20.8.8): + /vite-node@0.34.2(@types/node@20.8.9): resolution: {integrity: sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA==} engines: {node: '>=v14.18.0'} hasBin: true @@ -14413,7 +14417,7 @@ packages: mlly: 1.4.0 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.8.8) + vite: 4.5.0(@types/node@20.8.9) transitivePeerDependencies: - '@types/node' - less @@ -14425,7 +14429,7 @@ packages: - terser dev: true - /vite-node@0.34.4(@types/node@20.8.6): + /vite-node@0.34.4(@types/node@20.8.8): resolution: {integrity: sha512-ho8HtiLc+nsmbwZMw8SlghESEE3KxJNp04F/jPUCLVvaURwt0d+r9LxEqCX5hvrrOQ0GSyxbYr5ZfRYhQ0yVKQ==} engines: {node: '>=v14.18.0'} hasBin: true @@ -14435,7 +14439,7 @@ packages: mlly: 1.4.0 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.8.6) + vite: 4.5.0(@types/node@20.8.8) transitivePeerDependencies: - '@types/node' - less @@ -14447,7 +14451,7 @@ packages: - terser dev: true - /vite@4.4.10(@types/node@20.8.6): + /vite@4.4.10(@types/node@20.8.8): resolution: {integrity: sha512-TzIjiqx9BEXF8yzYdF2NTf1kFFbjMjUSV0LFZ3HyHoI3SGSPLnnFUKiIQtL3gl2AjHvMrprOvQ3amzaHgQlAxw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -14475,7 +14479,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.8.6 + '@types/node': 20.8.8 esbuild: 0.18.20 postcss: 8.4.27 rollup: 3.28.0 @@ -14483,7 +14487,7 @@ packages: fsevents: 2.3.3 dev: true - /vite@4.5.0(@types/node@20.8.6): + /vite@4.5.0(@types/node@20.8.8): resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -14511,7 +14515,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.8.6 + '@types/node': 20.8.8 esbuild: 0.18.20 postcss: 8.4.27 rollup: 3.28.0 @@ -14519,7 +14523,7 @@ packages: fsevents: 2.3.3 dev: true - /vite@4.5.0(@types/node@20.8.8): + /vite@4.5.0(@types/node@20.8.9): resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -14547,7 +14551,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.8.8 + '@types/node': 20.8.9 esbuild: 0.18.20 postcss: 8.4.27 rollup: 3.28.0 @@ -14588,7 +14592,7 @@ packages: dependencies: '@types/chai': 4.3.8 '@types/chai-subset': 1.3.3 - '@types/node': 20.8.8 + '@types/node': 20.8.9 '@vitest/expect': 0.34.1 '@vitest/runner': 0.34.1 '@vitest/snapshot': 0.34.1 @@ -14607,8 +14611,8 @@ packages: strip-literal: 1.0.1 tinybench: 2.5.0 tinypool: 0.7.0 - vite: 4.5.0(@types/node@20.8.8) - vite-node: 0.34.1(@types/node@20.8.8) + vite: 4.5.0(@types/node@20.8.9) + vite-node: 0.34.1(@types/node@20.8.9) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -14653,7 +14657,7 @@ packages: dependencies: '@types/chai': 4.3.8 '@types/chai-subset': 1.3.3 - '@types/node': 20.8.8 + '@types/node': 20.8.9 '@vitest/expect': 0.34.2 '@vitest/runner': 0.34.2 '@vitest/snapshot': 0.34.2 @@ -14672,8 +14676,8 @@ packages: strip-literal: 1.0.1 tinybench: 2.5.0 tinypool: 0.7.0 - vite: 4.5.0(@types/node@20.8.8) - vite-node: 0.34.2(@types/node@20.8.8) + vite: 4.5.0(@types/node@20.8.9) + vite-node: 0.34.2(@types/node@20.8.9) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -14718,7 +14722,7 @@ packages: dependencies: '@types/chai': 4.3.7 '@types/chai-subset': 1.3.3 - '@types/node': 20.8.6 + '@types/node': 20.8.8 '@vitest/expect': 0.34.2 '@vitest/runner': 0.34.2 '@vitest/snapshot': 0.34.2 @@ -14738,8 +14742,8 @@ packages: strip-literal: 1.0.1 tinybench: 2.5.0 tinypool: 0.7.0 - vite: 4.5.0(@types/node@20.8.6) - vite-node: 0.34.2(@types/node@20.8.6) + vite: 4.5.0(@types/node@20.8.8) + vite-node: 0.34.2(@types/node@20.8.8) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -14784,7 +14788,7 @@ packages: dependencies: '@types/chai': 4.3.7 '@types/chai-subset': 1.3.3 - '@types/node': 20.8.6 + '@types/node': 20.8.8 '@vitest/expect': 0.34.4 '@vitest/runner': 0.34.4 '@vitest/snapshot': 0.34.4 @@ -14803,8 +14807,8 @@ packages: strip-literal: 1.0.1 tinybench: 2.5.0 tinypool: 0.7.0 - vite: 4.4.10(@types/node@20.8.6) - vite-node: 0.34.4(@types/node@20.8.6) + vite: 4.4.10(@types/node@20.8.8) + vite-node: 0.34.4(@types/node@20.8.8) why-is-node-running: 2.2.2 transitivePeerDependencies: - less From d7ee471bfa8b1b186a004f0148805a6fa5b0fddd Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Wed, 25 Oct 2023 19:56:49 -0400 Subject: [PATCH 023/374] indexer.metric.prefix --- indexer/etl/metrics.go | 2 +- indexer/node/metrics.go | 2 +- indexer/processors/bridge.go | 11 +++++++++++ indexer/processors/bridge/metrics.go | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/indexer/etl/metrics.go b/indexer/etl/metrics.go index 5cc75ff0ecb8..32099ba5eef6 100644 --- a/indexer/etl/metrics.go +++ b/indexer/etl/metrics.go @@ -9,7 +9,7 @@ import ( ) var ( - MetricsNamespace string = "etl" + MetricsNamespace string = "op_indexer_etl" ) type Metricer interface { diff --git a/indexer/node/metrics.go b/indexer/node/metrics.go index 2304bc18d56a..55da6a127e55 100644 --- a/indexer/node/metrics.go +++ b/indexer/node/metrics.go @@ -12,7 +12,7 @@ import ( ) var ( - MetricsNamespace = "rpc" + MetricsNamespace = "op_indexer_rpc" batchMethod = "" ) diff --git a/indexer/processors/bridge.go b/indexer/processors/bridge.go index 3471b550a961..54878f4ba7ab 100644 --- a/indexer/processors/bridge.go +++ b/indexer/processors/bridge.go @@ -109,6 +109,17 @@ func (b *BridgeProcessor) run() error { b.log.Error("bridge events indexed, but no observed epoch returned", "latest_bridge_l1_block_number", b.LatestL1Header.Number) return errors.New("bridge events indexed, but no observed epoch returned") } + + latestL1Header, err := b.db.Blocks.L1LatestBlockHeader() + if err != nil { + } + + latestL2Header, err := b.db.Blocks.L2LatestBlockHeader() + if err != nil { + } + + b.LatestL1Header = latestL1Header.RLPHeader.Header() + b.LatestL2Header = latestL2Header.RLPHeader.Header() b.log.Warn("no observed epochs available. waiting...") return nil } diff --git a/indexer/processors/bridge/metrics.go b/indexer/processors/bridge/metrics.go index 38b4f8bcb956..5808921f63e8 100644 --- a/indexer/processors/bridge/metrics.go +++ b/indexer/processors/bridge/metrics.go @@ -10,7 +10,7 @@ import ( ) var ( - MetricsNamespace string = "bridge" + MetricsNamespace string = "op_indexer_bridge" ) type L1Metricer interface { From ec1deb61851868e73594ef1acee6b5d81e680131 Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Wed, 25 Oct 2023 20:03:17 -0400 Subject: [PATCH 024/374] remove unnecessary changes --- indexer/processors/bridge.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/indexer/processors/bridge.go b/indexer/processors/bridge.go index 54878f4ba7ab..3471b550a961 100644 --- a/indexer/processors/bridge.go +++ b/indexer/processors/bridge.go @@ -109,17 +109,6 @@ func (b *BridgeProcessor) run() error { b.log.Error("bridge events indexed, but no observed epoch returned", "latest_bridge_l1_block_number", b.LatestL1Header.Number) return errors.New("bridge events indexed, but no observed epoch returned") } - - latestL1Header, err := b.db.Blocks.L1LatestBlockHeader() - if err != nil { - } - - latestL2Header, err := b.db.Blocks.L2LatestBlockHeader() - if err != nil { - } - - b.LatestL1Header = latestL1Header.RLPHeader.Header() - b.LatestL2Header = latestL2Header.RLPHeader.Header() b.log.Warn("no observed epochs available. waiting...") return nil } From 7a6ae801a6a841bb60b5a7abbc7f192f1b50d05f Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 25 Oct 2023 19:14:55 -0600 Subject: [PATCH 025/374] contracts-bedrock: modern import style in tests Migrate to the modern import style in the tests where the path relative from the project root is used. This makes the code much more portable and easier to modify without the dot dot syntax. There should be very little old relative style imports left in the codebase if any. There are no functional changes with this commit. --- .../test/AddressAliasHelper.t.sol | 2 +- .../test/AdminFaucetAuthModule.t.sol | 6 +++--- .../contracts-bedrock/test/AssetReceiver.t.sol | 6 +++--- .../test/AttestationStation.t.sol | 2 +- .../contracts-bedrock/test/BenchmarkTest.t.sol | 6 +++--- packages/contracts-bedrock/test/Bytes.t.sol | 2 +- .../test/CheckBalanceHigh.t.sol | 2 +- .../test/CheckBalanceLow.t.sol | 2 +- .../test/CheckGelatoLow.t.sol | 2 +- .../contracts-bedrock/test/CheckTrue.t.sol | 2 +- packages/contracts-bedrock/test/Clones.t.sol | 2 +- .../test/CrossDomainMessenger.t.sol | 4 ++-- .../test/CrossDomainOwnable.t.sol | 2 +- .../test/CrossDomainOwnable2.t.sol | 6 +++--- .../test/CrossDomainOwnable3.t.sol | 10 +++++----- .../test/DelayedVetoable.t.sol | 2 +- .../test/DeployerWhitelist.t.sol | 4 ++-- .../test/DisputeGameFactory.t.sol | 12 ++++++------ packages/contracts-bedrock/test/Drippie.t.sol | 8 ++++---- packages/contracts-bedrock/test/Encoding.t.sol | 8 ++++---- packages/contracts-bedrock/test/Faucet.t.sol | 6 +++--- .../test/FaultDisputeGame.t.sol | 2 +- packages/contracts-bedrock/test/FeeVault.t.sol | 12 ++++++------ .../test/GasPriceOracle.t.sol | 8 ++++---- .../test/GovernanceToken.t.sol | 4 ++-- packages/contracts-bedrock/test/Hashing.t.sol | 10 +++++----- packages/contracts-bedrock/test/Helpers.sol | 4 ++-- packages/contracts-bedrock/test/L1Block.t.sol | 4 ++-- .../contracts-bedrock/test/L1BlockNumber.t.sol | 6 +++--- .../test/L1CrossDomainMessenger.t.sol | 18 +++++++++--------- .../test/L1ERC721Bridge.t.sol | 8 ++++---- .../test/L1StandardBridge.t.sol | 2 +- .../test/L2CrossDomainMessenger.t.sol | 16 ++++++++-------- .../test/L2ERC721Bridge.t.sol | 8 ++++---- .../test/L2OutputOracle.t.sol | 2 +- .../test/L2StandardBridge.t.sol | 16 ++++++++-------- .../test/L2ToL1MessagePasser.t.sol | 8 ++++---- .../test/LegacyERC20ETH.t.sol | 6 +++--- .../test/LegacyMessagePasser.t.sol | 6 +++--- packages/contracts-bedrock/test/LibClock.t.sol | 2 +- .../contracts-bedrock/test/LibPosition.t.sol | 2 +- .../contracts-bedrock/test/MerkleTrie.t.sol | 4 ++-- .../contracts-bedrock/test/MintManager.t.sol | 6 +++--- .../test/OptimismMintableERC20.t.sol | 4 ++-- .../test/OptimismMintableERC20Factory.t.sol | 4 ++-- .../test/OptimismMintableERC721.t.sol | 4 ++-- .../test/OptimismMintableERC721Factory.t.sol | 6 +++--- .../test/OptimismPortal.t.sol | 2 +- packages/contracts-bedrock/test/Optimist.t.sol | 10 +++++----- .../test/OptimistAllowlist.t.sol | 10 +++++----- .../test/OptimistInviter.t.sol | 12 ++++++------ .../test/ProtocolVersions.t.sol | 2 +- packages/contracts-bedrock/test/Proxy.t.sol | 2 +- .../contracts-bedrock/test/ProxyAdmin.t.sol | 12 ++++++------ .../contracts-bedrock/test/RLPReader.t.sol | 4 ++-- .../contracts-bedrock/test/RLPWriter.t.sol | 4 ++-- .../test/ResolvedDelegateProxy.t.sol | 4 ++-- .../test/ResourceMetering.t.sol | 6 +++--- packages/contracts-bedrock/test/SafeCall.t.sol | 4 ++-- packages/contracts-bedrock/test/Semver.t.sol | 6 +++--- .../test/SequencerFeeVault.t.sol | 10 +++++----- .../test/StandardBridge.t.sol | 6 +++--- .../contracts-bedrock/test/SystemConfig.t.sol | 10 +++++----- .../contracts-bedrock/test/Transactor.t.sol | 6 +++--- .../contracts-bedrock/test/TransferOnion.t.sol | 2 +- .../test/invariants/AddressAliasHelper.t.sol | 2 +- .../test/invariants/Burn.Eth.t.sol | 2 +- .../test/invariants/Burn.Gas.t.sol | 2 +- .../test/invariants/CrossDomainMessenger.t.sol | 16 ++++++++-------- .../test/invariants/Encoding.t.sol | 2 +- .../test/invariants/Hashing.t.sol | 4 ++-- .../test/invariants/L2OutputOracle.t.sol | 4 ++-- .../test/invariants/OptimismPortal.t.sol | 18 +++++++++--------- .../test/invariants/ResourceMetering.t.sol | 8 ++++---- .../test/invariants/SafeCall.t.sol | 2 +- .../test/invariants/SystemConfig.t.sol | 8 ++++---- 76 files changed, 224 insertions(+), 224 deletions(-) diff --git a/packages/contracts-bedrock/test/AddressAliasHelper.t.sol b/packages/contracts-bedrock/test/AddressAliasHelper.t.sol index d0c5440a5511..45211879c17f 100644 --- a/packages/contracts-bedrock/test/AddressAliasHelper.t.sol +++ b/packages/contracts-bedrock/test/AddressAliasHelper.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { AddressAliasHelper } from "../src/vendor/AddressAliasHelper.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; contract AddressAliasHelper_applyAndUndo_Test is Test { /// @notice Tests that applying and then undoing an alias results in the original address. diff --git a/packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol b/packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol index 3a59ba7e70a4..340bbfe4aa83 100644 --- a/packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol +++ b/packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { AdminFaucetAuthModule } from "../src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; -import { Faucet } from "../src/periphery/faucet/Faucet.sol"; -import { FaucetHelper } from "./Helpers.sol"; +import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; +import { Faucet } from "src/periphery/faucet/Faucet.sol"; +import { FaucetHelper } from "test/Helpers.sol"; /// @title AdminFaucetAuthModuleTest /// @notice Tests the AdminFaucetAuthModule contract. diff --git a/packages/contracts-bedrock/test/AssetReceiver.t.sol b/packages/contracts-bedrock/test/AssetReceiver.t.sol index a7f3693423c7..87c14e2608dd 100644 --- a/packages/contracts-bedrock/test/AssetReceiver.t.sol +++ b/packages/contracts-bedrock/test/AssetReceiver.t.sol @@ -3,9 +3,9 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { TestERC20 } from "./Helpers.sol"; -import { TestERC721 } from "./Helpers.sol"; -import { AssetReceiver } from "../src/periphery/AssetReceiver.sol"; +import { TestERC20 } from "test/Helpers.sol"; +import { TestERC721 } from "test/Helpers.sol"; +import { AssetReceiver } from "src/periphery/AssetReceiver.sol"; contract AssetReceiver_Initializer is Test { address alice = address(128); diff --git a/packages/contracts-bedrock/test/AttestationStation.t.sol b/packages/contracts-bedrock/test/AttestationStation.t.sol index 5d17fcd0e14f..4c9b72254d34 100644 --- a/packages/contracts-bedrock/test/AttestationStation.t.sol +++ b/packages/contracts-bedrock/test/AttestationStation.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; /* Testing utilities */ import { Test } from "forge-std/Test.sol"; -import { AttestationStation } from "../src/periphery/op-nft/AttestationStation.sol"; +import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; contract AttestationStation_Initializer is Test { address alice_attestor = address(128); diff --git a/packages/contracts-bedrock/test/BenchmarkTest.t.sol b/packages/contracts-bedrock/test/BenchmarkTest.t.sol index 64b9d982cf7d..780162b66b0d 100644 --- a/packages/contracts-bedrock/test/BenchmarkTest.t.sol +++ b/packages/contracts-bedrock/test/BenchmarkTest.t.sol @@ -4,9 +4,9 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; -import "./CommonTest.t.sol"; -import { CrossDomainMessenger } from "../src/universal/CrossDomainMessenger.sol"; -import { ResourceMetering } from "../src/L1/ResourceMetering.sol"; +import "test/CommonTest.t.sol"; +import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; // Free function for setting the prevBaseFee param in the OptimismPortal. function setPrevBaseFee(Vm _vm, address _op, uint128 _prevBaseFee) { diff --git a/packages/contracts-bedrock/test/Bytes.t.sol b/packages/contracts-bedrock/test/Bytes.t.sol index 79174d029667..766cf7e01f5b 100644 --- a/packages/contracts-bedrock/test/Bytes.t.sol +++ b/packages/contracts-bedrock/test/Bytes.t.sol @@ -5,7 +5,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; // Target contract -import { Bytes } from "../src/libraries/Bytes.sol"; +import { Bytes } from "src/libraries/Bytes.sol"; contract Bytes_slice_Test is Test { /// @notice Tests that the `slice` function works as expected when starting from index 0. diff --git a/packages/contracts-bedrock/test/CheckBalanceHigh.t.sol b/packages/contracts-bedrock/test/CheckBalanceHigh.t.sol index 07505b85f9e5..3102f560f3c8 100644 --- a/packages/contracts-bedrock/test/CheckBalanceHigh.t.sol +++ b/packages/contracts-bedrock/test/CheckBalanceHigh.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { CheckBalanceHigh } from "../src/periphery/drippie/dripchecks/CheckBalanceHigh.sol"; +import { CheckBalanceHigh } from "src/periphery/drippie/dripchecks/CheckBalanceHigh.sol"; /// @title CheckBalanceHighTest /// @notice Tests the CheckBalanceHigh contract via fuzzing both the success case diff --git a/packages/contracts-bedrock/test/CheckBalanceLow.t.sol b/packages/contracts-bedrock/test/CheckBalanceLow.t.sol index 71bcf199ff71..0345fa248a8a 100644 --- a/packages/contracts-bedrock/test/CheckBalanceLow.t.sol +++ b/packages/contracts-bedrock/test/CheckBalanceLow.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { CheckBalanceLow } from "../src/periphery/drippie/dripchecks/CheckBalanceLow.sol"; +import { CheckBalanceLow } from "src/periphery/drippie/dripchecks/CheckBalanceLow.sol"; /// @title CheckBalanceLowTest /// @notice Tests the CheckBalanceLow contract via fuzzing both the success case diff --git a/packages/contracts-bedrock/test/CheckGelatoLow.t.sol b/packages/contracts-bedrock/test/CheckGelatoLow.t.sol index a89f49251f68..fb213742c917 100644 --- a/packages/contracts-bedrock/test/CheckGelatoLow.t.sol +++ b/packages/contracts-bedrock/test/CheckGelatoLow.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { CheckGelatoLow, IGelatoTreasury } from "../src/periphery/drippie/dripchecks/CheckGelatoLow.sol"; +import { CheckGelatoLow, IGelatoTreasury } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol"; /// @title MockGelatoTreasury /// @notice Mocks the Gelato treasury for testing purposes. Allows arbitrary diff --git a/packages/contracts-bedrock/test/CheckTrue.t.sol b/packages/contracts-bedrock/test/CheckTrue.t.sol index c0b1016fa842..2c7e4be070a2 100644 --- a/packages/contracts-bedrock/test/CheckTrue.t.sol +++ b/packages/contracts-bedrock/test/CheckTrue.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { CheckTrue } from "../src/periphery/drippie/dripchecks/CheckTrue.sol"; +import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol"; /// @title CheckTrueTest /// @notice Ensures that the CheckTrue DripCheck contract always returns true. diff --git a/packages/contracts-bedrock/test/Clones.t.sol b/packages/contracts-bedrock/test/Clones.t.sol index e207b246ad67..4b8802c287e5 100644 --- a/packages/contracts-bedrock/test/Clones.t.sol +++ b/packages/contracts-bedrock/test/Clones.t.sol @@ -5,7 +5,7 @@ import "forge-std/Test.sol"; import { ClonesWithImmutableArgs } from "@cwia/ClonesWithImmutableArgs.sol"; -import { Clone } from "../src/libraries/Clone.sol"; +import { Clone } from "src/libraries/Clone.sol"; contract ExampleClone is Clone { uint256 argOffset; diff --git a/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol index 712fa6da5e3c..f525adc21c1a 100644 --- a/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.15; // Testing utilities -import { Messenger_Initializer, Reverter, CallerCaller, CommonTest } from "./CommonTest.t.sol"; -import { L1CrossDomainMessenger } from "../src/L1/L1CrossDomainMessenger.sol"; +import { Messenger_Initializer, Reverter, CallerCaller, CommonTest } from "test/CommonTest.t.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; // Libraries import { Predeploys } from "../src/libraries/Predeploys.sol"; diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol index 51394e369592..27c8757066f7 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { Vm, VmSafe } from "forge-std/Vm.sol"; -import { CommonTest, Portal_Initializer } from "./CommonTest.t.sol"; +import { CommonTest, Portal_Initializer } from "test/CommonTest.t.sol"; // Libraries import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol index 2eb3082d9dfe..c059872c784a 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol @@ -2,11 +2,11 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest, Messenger_Initializer } from "./CommonTest.t.sol"; +import { CommonTest, Messenger_Initializer } from "test/CommonTest.t.sol"; // Libraries -import { Hashing } from "../src/libraries/Hashing.sol"; -import { Encoding } from "../src/libraries/Encoding.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; // Target contract dependencies diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol index b2a7ff522c17..dbe2c9af3b4c 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol @@ -2,18 +2,18 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest, Messenger_Initializer } from "./CommonTest.t.sol"; +import { CommonTest, Messenger_Initializer } from "test/CommonTest.t.sol"; // Libraries -import { Hashing } from "../src/libraries/Hashing.sol"; -import { Encoding } from "../src/libraries/Encoding.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; // Target contract dependencies -import { AddressAliasHelper } from "../src/vendor/AddressAliasHelper.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; // Target contract -import { CrossDomainOwnable3 } from "../src/L2/CrossDomainOwnable3.sol"; +import { CrossDomainOwnable3 } from "src/L2/CrossDomainOwnable3.sol"; contract XDomainSetter3 is CrossDomainOwnable3 { uint256 public value; diff --git a/packages/contracts-bedrock/test/DelayedVetoable.t.sol b/packages/contracts-bedrock/test/DelayedVetoable.t.sol index cf891069da2b..27d0670a5875 100644 --- a/packages/contracts-bedrock/test/DelayedVetoable.t.sol +++ b/packages/contracts-bedrock/test/DelayedVetoable.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; import { DelayedVetoable } from "src/L1/DelayedVetoable.sol"; contract DelayedVetoable_Init is CommonTest { diff --git a/packages/contracts-bedrock/test/DeployerWhitelist.t.sol b/packages/contracts-bedrock/test/DeployerWhitelist.t.sol index 0d8eda5dcd49..a3096fd373f8 100644 --- a/packages/contracts-bedrock/test/DeployerWhitelist.t.sol +++ b/packages/contracts-bedrock/test/DeployerWhitelist.t.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Target contract -import { DeployerWhitelist } from "../src/legacy/DeployerWhitelist.sol"; +import { DeployerWhitelist } from "src/legacy/DeployerWhitelist.sol"; contract DeployerWhitelist_Test is CommonTest { DeployerWhitelist list; diff --git a/packages/contracts-bedrock/test/DisputeGameFactory.t.sol b/packages/contracts-bedrock/test/DisputeGameFactory.t.sol index 1f81c8b58b3d..a745b73fb04c 100644 --- a/packages/contracts-bedrock/test/DisputeGameFactory.t.sol +++ b/packages/contracts-bedrock/test/DisputeGameFactory.t.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; -import "../src/libraries/DisputeTypes.sol"; -import "../src/libraries/DisputeErrors.sol"; +import "src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeErrors.sol"; import { Test } from "forge-std/Test.sol"; -import { DisputeGameFactory } from "../src/dispute/DisputeGameFactory.sol"; -import { IDisputeGame } from "../src/dispute/interfaces/IDisputeGame.sol"; -import { Proxy } from "../src/universal/Proxy.sol"; -import { L2OutputOracle_Initializer } from "./CommonTest.t.sol"; +import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; +import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; contract DisputeGameFactory_Init is L2OutputOracle_Initializer { DisputeGameFactory factory; diff --git a/packages/contracts-bedrock/test/Drippie.t.sol b/packages/contracts-bedrock/test/Drippie.t.sol index 33a69d861111..758011448608 100644 --- a/packages/contracts-bedrock/test/Drippie.t.sol +++ b/packages/contracts-bedrock/test/Drippie.t.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { Drippie } from "../src/periphery/drippie/Drippie.sol"; -import { IDripCheck } from "../src/periphery/drippie/IDripCheck.sol"; -import { CheckTrue } from "../src/periphery/drippie/dripchecks/CheckTrue.sol"; -import { SimpleStorage } from "./Helpers.sol"; +import { Drippie } from "src/periphery/drippie/Drippie.sol"; +import { IDripCheck } from "src/periphery/drippie/IDripCheck.sol"; +import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol"; +import { SimpleStorage } from "test/Helpers.sol"; /// @title TestDrippie /// @notice This is a wrapper contract around Drippie used for testing. diff --git a/packages/contracts-bedrock/test/Encoding.t.sol b/packages/contracts-bedrock/test/Encoding.t.sol index f2261801bb25..14ac3c81a0f7 100644 --- a/packages/contracts-bedrock/test/Encoding.t.sol +++ b/packages/contracts-bedrock/test/Encoding.t.sol @@ -2,14 +2,14 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Libraries -import { Types } from "../src/libraries/Types.sol"; -import { LegacyCrossDomainUtils } from "../src/libraries/LegacyCrossDomainUtils.sol"; +import { Types } from "src/libraries/Types.sol"; +import { LegacyCrossDomainUtils } from "src/libraries/LegacyCrossDomainUtils.sol"; // Target contract -import { Encoding } from "../src/libraries/Encoding.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; contract Encoding_Test is CommonTest { /// @dev Tests encoding and decoding a nonce and version. diff --git a/packages/contracts-bedrock/test/Faucet.t.sol b/packages/contracts-bedrock/test/Faucet.t.sol index 3f3ca41a8963..3c4da9c98798 100644 --- a/packages/contracts-bedrock/test/Faucet.t.sol +++ b/packages/contracts-bedrock/test/Faucet.t.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { Faucet } from "../src/periphery/faucet/Faucet.sol"; -import { AdminFaucetAuthModule } from "../src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; -import { FaucetHelper } from "./Helpers.sol"; +import { Faucet } from "src/periphery/faucet/Faucet.sol"; +import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; +import { FaucetHelper } from "test/Helpers.sol"; contract Faucet_Initializer is Test { event Drip(string indexed authModule, bytes32 indexed userId, uint256 amount, address indexed recipient); diff --git a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol index e56665e1e784..40297b6cc8c0 100644 --- a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.15; import { Test } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; -import { DisputeGameFactory_Init } from "./DisputeGameFactory.t.sol"; +import { DisputeGameFactory_Init } from "test/DisputeGameFactory.t.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; diff --git a/packages/contracts-bedrock/test/FeeVault.t.sol b/packages/contracts-bedrock/test/FeeVault.t.sol index dede09e762f6..3b877840935c 100644 --- a/packages/contracts-bedrock/test/FeeVault.t.sol +++ b/packages/contracts-bedrock/test/FeeVault.t.sol @@ -2,18 +2,18 @@ pragma solidity 0.8.15; // Testing utilities -import { Bridge_Initializer } from "./CommonTest.t.sol"; -import { BaseFeeVault } from "../src/L2/BaseFeeVault.sol"; -import { StandardBridge } from "../src/universal/StandardBridge.sol"; +import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; // Libraries -import { Predeploys } from "../src/libraries/Predeploys.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; // Target contract dependencies -import { FeeVault } from "../src/universal/FeeVault.sol"; +import { FeeVault } from "src/universal/FeeVault.sol"; // Target contract -import { L1FeeVault } from "../src/L2/L1FeeVault.sol"; +import { L1FeeVault } from "src/L2/L1FeeVault.sol"; // Test the implementations of the FeeVault contract FeeVault_Test is Bridge_Initializer { diff --git a/packages/contracts-bedrock/test/GasPriceOracle.t.sol b/packages/contracts-bedrock/test/GasPriceOracle.t.sol index 7a69ed1bf806..26e571ecb550 100644 --- a/packages/contracts-bedrock/test/GasPriceOracle.t.sol +++ b/packages/contracts-bedrock/test/GasPriceOracle.t.sol @@ -2,14 +2,14 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Target contract dependencies -import { L1Block } from "../src/L2/L1Block.sol"; -import { Predeploys } from "../src/libraries/Predeploys.sol"; +import { L1Block } from "src/L2/L1Block.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; // Target contract -import { GasPriceOracle } from "../src/L2/GasPriceOracle.sol"; +import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; contract GasPriceOracle_Test is CommonTest { event OverheadUpdated(uint256); diff --git a/packages/contracts-bedrock/test/GovernanceToken.t.sol b/packages/contracts-bedrock/test/GovernanceToken.t.sol index c1b4b9595424..ec3c7902af7e 100644 --- a/packages/contracts-bedrock/test/GovernanceToken.t.sol +++ b/packages/contracts-bedrock/test/GovernanceToken.t.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Target contract -import { GovernanceToken } from "../src/governance/GovernanceToken.sol"; +import { GovernanceToken } from "src/governance/GovernanceToken.sol"; contract GovernanceToken_Test is CommonTest { address constant owner = address(0x1234); diff --git a/packages/contracts-bedrock/test/Hashing.t.sol b/packages/contracts-bedrock/test/Hashing.t.sol index 33b8a10c5f41..fc79c24422bd 100644 --- a/packages/contracts-bedrock/test/Hashing.t.sol +++ b/packages/contracts-bedrock/test/Hashing.t.sol @@ -2,15 +2,15 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Libraries -import { Types } from "../src/libraries/Types.sol"; -import { Encoding } from "../src/libraries/Encoding.sol"; -import { LegacyCrossDomainUtils } from "../src/libraries/LegacyCrossDomainUtils.sol"; +import { Types } from "src/libraries/Types.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; +import { LegacyCrossDomainUtils } from "src/libraries/LegacyCrossDomainUtils.sol"; // Target contract -import { Hashing } from "../src/libraries/Hashing.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; contract Hashing_hashDepositSource_Test is CommonTest { /// @notice Tests that hashDepositSource returns the correct hash in a simple case. diff --git a/packages/contracts-bedrock/test/Helpers.sol b/packages/contracts-bedrock/test/Helpers.sol index 13a16e7af9f1..a27da6e2b2fb 100644 --- a/packages/contracts-bedrock/test/Helpers.sol +++ b/packages/contracts-bedrock/test/Helpers.sol @@ -4,11 +4,11 @@ pragma solidity ^0.8.0; import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol"; import { ERC721 } from "@rari-capital/solmate/src/tokens/ERC721.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { OptimistInviter } from "../src/periphery/op-nft/OptimistInviter.sol"; +import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { ECDSAUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol"; -import { AdminFaucetAuthModule } from "../src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; +import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; contract TestERC20 is ERC20 { constructor() ERC20("TEST", "TST", 18) { } diff --git a/packages/contracts-bedrock/test/L1Block.t.sol b/packages/contracts-bedrock/test/L1Block.t.sol index 940db8494001..f44f606a6270 100644 --- a/packages/contracts-bedrock/test/L1Block.t.sol +++ b/packages/contracts-bedrock/test/L1Block.t.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Target contract -import { L1Block } from "../src/L2/L1Block.sol"; +import { L1Block } from "src/L2/L1Block.sol"; contract L1BlockTest is CommonTest { L1Block lb; diff --git a/packages/contracts-bedrock/test/L1BlockNumber.t.sol b/packages/contracts-bedrock/test/L1BlockNumber.t.sol index b80965feea23..8ac6ab140d6b 100644 --- a/packages/contracts-bedrock/test/L1BlockNumber.t.sol +++ b/packages/contracts-bedrock/test/L1BlockNumber.t.sol @@ -5,11 +5,11 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; // Target contract dependencies -import { L1Block } from "../src/L2/L1Block.sol"; -import { Predeploys } from "../src/libraries/Predeploys.sol"; +import { L1Block } from "src/L2/L1Block.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; // Target contract -import { L1BlockNumber } from "../src/legacy/L1BlockNumber.sol"; +import { L1BlockNumber } from "src/legacy/L1BlockNumber.sol"; contract L1BlockNumberTest is Test { L1Block lb; diff --git a/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol index 5090cebb8156..77f966f310d6 100644 --- a/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol @@ -2,21 +2,21 @@ pragma solidity 0.8.15; // Testing utilities -import { Messenger_Initializer, Reverter, ConfigurableCaller } from "./CommonTest.t.sol"; -import { L2OutputOracle_Initializer } from "./L2OutputOracle.t.sol"; +import { Messenger_Initializer, Reverter, ConfigurableCaller } from "test/CommonTest.t.sol"; +import { L2OutputOracle_Initializer } from "test/L2OutputOracle.t.sol"; // Libraries -import { AddressAliasHelper } from "../src/vendor/AddressAliasHelper.sol"; -import { Predeploys } from "../src/libraries/Predeploys.sol"; -import { Hashing } from "../src/libraries/Hashing.sol"; -import { Encoding } from "../src/libraries/Encoding.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; // Target contract dependencies -import { L2OutputOracle } from "../src/L1/L2OutputOracle.sol"; -import { OptimismPortal } from "../src/L1/OptimismPortal.sol"; +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; // Target contract -import { L1CrossDomainMessenger } from "../src/L1/L1CrossDomainMessenger.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; contract L1CrossDomainMessenger_Test is Messenger_Initializer { /// @dev The receiver address diff --git a/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol index 658237ad4ec0..b57c8b7ef70d 100644 --- a/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol @@ -2,15 +2,15 @@ pragma solidity 0.8.15; // Testing utilities -import { ERC721Bridge_Initializer } from "./CommonTest.t.sol"; +import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; // Target contract dependencies -import { L2ERC721Bridge } from "../src/L2/L2ERC721Bridge.sol"; -import { Predeploys } from "../src/libraries/Predeploys.sol"; +import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; // Target contract -import { L1ERC721Bridge } from "../src/L1/L1ERC721Bridge.sol"; +import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; /// @dev Test ERC721 contract. contract TestERC721 is ERC721 { diff --git a/packages/contracts-bedrock/test/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1StandardBridge.t.sol index 18dc292946d7..c8966dd8b62f 100644 --- a/packages/contracts-bedrock/test/L1StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L1StandardBridge.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; // Testing utilities import { stdStorage, StdStorage } from "forge-std/Test.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { Bridge_Initializer } from "./CommonTest.t.sol"; +import { Bridge_Initializer } from "test/CommonTest.t.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; diff --git a/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol index b84d10ff8631..ead28756af6d 100644 --- a/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol @@ -2,20 +2,20 @@ pragma solidity 0.8.15; // Testing utilities -import { Messenger_Initializer, Reverter, ConfigurableCaller } from "./CommonTest.t.sol"; +import { Messenger_Initializer, Reverter, ConfigurableCaller } from "test/CommonTest.t.sol"; // Libraries -import { Hashing } from "../src/libraries/Hashing.sol"; -import { Encoding } from "../src/libraries/Encoding.sol"; -import { Types } from "../src/libraries/Types.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; +import { Types } from "src/libraries/Types.sol"; // Target contract dependencies -import { L2ToL1MessagePasser } from "../src/L2/L2ToL1MessagePasser.sol"; -import { AddressAliasHelper } from "../src/vendor/AddressAliasHelper.sol"; -import { L1CrossDomainMessenger } from "../src/L1/L1CrossDomainMessenger.sol"; +import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; // Target contract -import { L2CrossDomainMessenger } from "../src/L2/L2CrossDomainMessenger.sol"; +import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; contract L2CrossDomainMessenger_Test is Messenger_Initializer { /// @dev Receiver address for testing diff --git a/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol index 7c91f9e57744..03567f3beae1 100644 --- a/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol @@ -2,15 +2,15 @@ pragma solidity 0.8.15; // Testing utilities -import { ERC721Bridge_Initializer } from "./CommonTest.t.sol"; +import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; // Target contract dependencies import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { L1ERC721Bridge } from "../src/L1/L1ERC721Bridge.sol"; -import { OptimismMintableERC721 } from "../src/universal/OptimismMintableERC721.sol"; +import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; // Target contract -import { L2ERC721Bridge } from "../src/L2/L2ERC721Bridge.sol"; +import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; contract TestERC721 is ERC721 { constructor() ERC721("Test", "TST") { } diff --git a/packages/contracts-bedrock/test/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/L2OutputOracle.t.sol index f6c521f11ce6..623fc7aa224c 100644 --- a/packages/contracts-bedrock/test/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/L2OutputOracle.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { stdError } from "forge-std/Test.sol"; -import { L2OutputOracle_Initializer, NextImpl } from "./CommonTest.t.sol"; +import { L2OutputOracle_Initializer, NextImpl } from "test/CommonTest.t.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; diff --git a/packages/contracts-bedrock/test/L2StandardBridge.t.sol b/packages/contracts-bedrock/test/L2StandardBridge.t.sol index b9f31b3abcd7..be7dd6ff639c 100644 --- a/packages/contracts-bedrock/test/L2StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L2StandardBridge.t.sol @@ -3,20 +3,20 @@ pragma solidity 0.8.15; // Testing utilities // Target contract is imported by the `Bridge_Initializer` -import { Bridge_Initializer } from "./CommonTest.t.sol"; +import { Bridge_Initializer } from "test/CommonTest.t.sol"; import { stdStorage, StdStorage } from "forge-std/Test.sol"; -import { CrossDomainMessenger } from "../src/universal/CrossDomainMessenger.sol"; -import { L2ToL1MessagePasser } from "../src/L2/L2ToL1MessagePasser.sol"; +import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; // Libraries -import { Hashing } from "../src/libraries/Hashing.sol"; -import { Types } from "../src/libraries/Types.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { Types } from "src/libraries/Types.sol"; // Target contract dependencies -import { Predeploys } from "../src/libraries/Predeploys.sol"; -import { StandardBridge } from "../src/universal/StandardBridge.sol"; -import { OptimismMintableERC20 } from "../src/universal/OptimismMintableERC20.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; +import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; contract L2StandardBridge_Test is Bridge_Initializer { using stdStorage for StdStorage; diff --git a/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol b/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol index 01ebac687c1c..9e62c74944b4 100644 --- a/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol +++ b/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol @@ -2,14 +2,14 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Libraries -import { Types } from "../src/libraries/Types.sol"; -import { Hashing } from "../src/libraries/Hashing.sol"; +import { Types } from "src/libraries/Types.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; // Target contract -import { L2ToL1MessagePasser } from "../src/L2/L2ToL1MessagePasser.sol"; +import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; contract L2ToL1MessagePasserTest is CommonTest { L2ToL1MessagePasser messagePasser; diff --git a/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol b/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol index 22c801de4ab2..126fdfe661e2 100644 --- a/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol +++ b/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol @@ -2,13 +2,13 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Target contract dependencies -import { Predeploys } from "../src/libraries/Predeploys.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; // Target contract -import { LegacyERC20ETH } from "../src/legacy/LegacyERC20ETH.sol"; +import { LegacyERC20ETH } from "src/legacy/LegacyERC20ETH.sol"; contract LegacyERC20ETH_Test is CommonTest { LegacyERC20ETH eth; diff --git a/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol b/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol index a5914779034d..abf841e3e79e 100644 --- a/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol +++ b/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol @@ -2,13 +2,13 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Testing contract dependencies -import { Predeploys } from "../src/libraries/Predeploys.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; // Target contract -import { LegacyMessagePasser } from "../src/legacy/LegacyMessagePasser.sol"; +import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; contract LegacyMessagePasser_Test is CommonTest { LegacyMessagePasser messagePasser; diff --git a/packages/contracts-bedrock/test/LibClock.t.sol b/packages/contracts-bedrock/test/LibClock.t.sol index cc8fc6606902..41b5ae184976 100644 --- a/packages/contracts-bedrock/test/LibClock.t.sol +++ b/packages/contracts-bedrock/test/LibClock.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.15; import { Test } from "forge-std/Test.sol"; import { LibClock } from "../src/dispute/lib/LibClock.sol"; -import "../src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeTypes.sol"; /// @notice Tests for `LibClock` contract LibClock_Test is Test { diff --git a/packages/contracts-bedrock/test/LibPosition.t.sol b/packages/contracts-bedrock/test/LibPosition.t.sol index 4aa2dc010267..a60f5e2bafca 100644 --- a/packages/contracts-bedrock/test/LibPosition.t.sol +++ b/packages/contracts-bedrock/test/LibPosition.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.15; import { Test } from "forge-std/Test.sol"; import { LibPosition } from "../src/dispute/lib/LibPosition.sol"; -import "../src/libraries/DisputeTypes.sol"; +import "src/libraries/DisputeTypes.sol"; /// @notice Tests for `LibPosition` contract LibPosition_Test is Test { diff --git a/packages/contracts-bedrock/test/MerkleTrie.t.sol b/packages/contracts-bedrock/test/MerkleTrie.t.sol index f6c559bc4644..59673f06e2ae 100644 --- a/packages/contracts-bedrock/test/MerkleTrie.t.sol +++ b/packages/contracts-bedrock/test/MerkleTrie.t.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { CommonTest } from "./CommonTest.t.sol"; -import { MerkleTrie } from "../src/libraries/trie/MerkleTrie.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; +import { MerkleTrie } from "src/libraries/trie/MerkleTrie.sol"; contract MerkleTrie_get_Test is CommonTest { function test_get_validProof1_succeeds() external { diff --git a/packages/contracts-bedrock/test/MintManager.t.sol b/packages/contracts-bedrock/test/MintManager.t.sol index 66578642294f..92fceec0ae1a 100644 --- a/packages/contracts-bedrock/test/MintManager.t.sol +++ b/packages/contracts-bedrock/test/MintManager.t.sol @@ -2,13 +2,13 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Target contract dependencies -import { GovernanceToken } from "../src/governance/GovernanceToken.sol"; +import { GovernanceToken } from "src/governance/GovernanceToken.sol"; // Target contract -import { MintManager } from "../src/governance/MintManager.sol"; +import { MintManager } from "src/governance/MintManager.sol"; contract MintManager_Initializer is CommonTest { address constant owner = address(0x1234); diff --git a/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol index ef6c5468b703..40233eded0f8 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Bridge_Initializer } from "./CommonTest.t.sol"; -import { ILegacyMintableERC20, IOptimismMintableERC20 } from "../src/universal/IOptimismMintableERC20.sol"; +import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; contract OptimismMintableERC20_Test is Bridge_Initializer { diff --git a/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol index 64b0a7de5b98..a09ea0f94df7 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { OptimismMintableERC20 } from "../src/universal/OptimismMintableERC20.sol"; -import { Bridge_Initializer } from "./CommonTest.t.sol"; +import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; +import { Bridge_Initializer } from "test/CommonTest.t.sol"; contract OptimismMintableTokenFactory_Test is Bridge_Initializer { event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); diff --git a/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol index 8935617cd49f..5aac93b2eb4c 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol @@ -5,8 +5,8 @@ import { ERC721, IERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { ERC721Bridge_Initializer } from "./CommonTest.t.sol"; -import { OptimismMintableERC721, IOptimismMintableERC721 } from "../src/universal/OptimismMintableERC721.sol"; +import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; +import { OptimismMintableERC721, IOptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { ERC721 internal L1NFT; diff --git a/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol index 4d8b523706bd..ee70e3ff9f3b 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.15; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { ERC721Bridge_Initializer } from "./CommonTest.t.sol"; -import { OptimismMintableERC721 } from "../src/universal/OptimismMintableERC721.sol"; -import { OptimismMintableERC721Factory } from "../src/universal/OptimismMintableERC721Factory.sol"; +import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; +import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; +import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { OptimismMintableERC721Factory internal factory; diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol index 256e5c6359fc..30f134e6c9b5 100644 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/OptimismPortal.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { stdError } from "forge-std/Test.sol"; -import { Portal_Initializer, CommonTest, NextImpl } from "./CommonTest.t.sol"; +import { Portal_Initializer, CommonTest, NextImpl } from "test/CommonTest.t.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; diff --git a/packages/contracts-bedrock/test/Optimist.t.sol b/packages/contracts-bedrock/test/Optimist.t.sol index f08656bf20da..a7a84e2b9854 100644 --- a/packages/contracts-bedrock/test/Optimist.t.sol +++ b/packages/contracts-bedrock/test/Optimist.t.sol @@ -3,11 +3,11 @@ pragma solidity >=0.6.2 <0.9.0; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { AttestationStation } from "../src/periphery/op-nft/AttestationStation.sol"; -import { Optimist } from "../src/periphery/op-nft/Optimist.sol"; -import { OptimistAllowlist } from "../src/periphery/op-nft/OptimistAllowlist.sol"; -import { OptimistInviter } from "../src/periphery/op-nft/OptimistInviter.sol"; -import { OptimistInviterHelper } from "./Helpers.sol"; +import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; +import { Optimist } from "src/periphery/op-nft/Optimist.sol"; +import { OptimistAllowlist } from "src/periphery/op-nft/OptimistAllowlist.sol"; +import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; +import { OptimistInviterHelper } from "test/Helpers.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; diff --git a/packages/contracts-bedrock/test/OptimistAllowlist.t.sol b/packages/contracts-bedrock/test/OptimistAllowlist.t.sol index 4a3d59db14c5..d7f53ff8c23c 100644 --- a/packages/contracts-bedrock/test/OptimistAllowlist.t.sol +++ b/packages/contracts-bedrock/test/OptimistAllowlist.t.sol @@ -3,11 +3,11 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { AttestationStation } from "../src/periphery/op-nft/AttestationStation.sol"; -import { OptimistAllowlist } from "../src/periphery/op-nft/OptimistAllowlist.sol"; -import { OptimistInviter } from "../src/periphery/op-nft/OptimistInviter.sol"; -import { OptimistInviterHelper } from "./Helpers.sol"; -import { OptimistConstants } from "../src/periphery/op-nft/libraries/OptimistConstants.sol"; +import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; +import { OptimistAllowlist } from "src/periphery/op-nft/OptimistAllowlist.sol"; +import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; +import { OptimistInviterHelper } from "test/Helpers.sol"; +import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; contract OptimistAllowlist_Initializer is Test { event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val); diff --git a/packages/contracts-bedrock/test/OptimistInviter.t.sol b/packages/contracts-bedrock/test/OptimistInviter.t.sol index 6c73f0688925..677dceb7d151 100644 --- a/packages/contracts-bedrock/test/OptimistInviter.t.sol +++ b/packages/contracts-bedrock/test/OptimistInviter.t.sol @@ -3,13 +3,13 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { AttestationStation } from "../src/periphery/op-nft/AttestationStation.sol"; -import { OptimistInviter } from "../src/periphery/op-nft/OptimistInviter.sol"; -import { Optimist } from "../src/periphery/op-nft/Optimist.sol"; +import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; +import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; +import { Optimist } from "src/periphery/op-nft/Optimist.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { TestERC1271Wallet } from "./Helpers.sol"; -import { OptimistInviterHelper } from "./Helpers.sol"; -import { OptimistConstants } from "../src/periphery/op-nft/libraries/OptimistConstants.sol"; +import { TestERC1271Wallet } from "test/Helpers.sol"; +import { OptimistInviterHelper } from "test/Helpers.sol"; +import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; contract OptimistInviter_Initializer is Test { event InviteClaimed(address indexed issuer, address indexed claimer); diff --git a/packages/contracts-bedrock/test/ProtocolVersions.t.sol b/packages/contracts-bedrock/test/ProtocolVersions.t.sol index 5c01bafb5e46..814c36ec9639 100644 --- a/packages/contracts-bedrock/test/ProtocolVersions.t.sol +++ b/packages/contracts-bedrock/test/ProtocolVersions.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; diff --git a/packages/contracts-bedrock/test/Proxy.t.sol b/packages/contracts-bedrock/test/Proxy.t.sol index 8474f50aea77..fa794dd295b2 100644 --- a/packages/contracts-bedrock/test/Proxy.t.sol +++ b/packages/contracts-bedrock/test/Proxy.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { Proxy } from "../src/universal/Proxy.sol"; +import { Proxy } from "src/universal/Proxy.sol"; import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; contract SimpleStorage { diff --git a/packages/contracts-bedrock/test/ProxyAdmin.t.sol b/packages/contracts-bedrock/test/ProxyAdmin.t.sol index 49b290f25bb9..083ba04c2fe5 100644 --- a/packages/contracts-bedrock/test/ProxyAdmin.t.sol +++ b/packages/contracts-bedrock/test/ProxyAdmin.t.sol @@ -2,12 +2,12 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { Proxy } from "../src/universal/Proxy.sol"; -import { ProxyAdmin } from "../src/universal/ProxyAdmin.sol"; -import { SimpleStorage } from "./Proxy.t.sol"; -import { L1ChugSplashProxy } from "../src/legacy/L1ChugSplashProxy.sol"; -import { ResolvedDelegateProxy } from "../src/legacy/ResolvedDelegateProxy.sol"; -import { AddressManager } from "../src/legacy/AddressManager.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; +import { SimpleStorage } from "test/Proxy.t.sol"; +import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; +import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; +import { AddressManager } from "src/legacy/AddressManager.sol"; contract ProxyAdmin_Test is Test { address alice = address(64); diff --git a/packages/contracts-bedrock/test/RLPReader.t.sol b/packages/contracts-bedrock/test/RLPReader.t.sol index 2276370a69d2..17fe69c817c0 100644 --- a/packages/contracts-bedrock/test/RLPReader.t.sol +++ b/packages/contracts-bedrock/test/RLPReader.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.15; import { stdError } from "forge-std/Test.sol"; -import { CommonTest } from "./CommonTest.t.sol"; -import { RLPReader } from "../src/libraries/rlp/RLPReader.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; +import { RLPReader } from "src/libraries/rlp/RLPReader.sol"; contract RLPReader_readBytes_Test is CommonTest { function test_readBytes_bytestring00_succeeds() external { diff --git a/packages/contracts-bedrock/test/RLPWriter.t.sol b/packages/contracts-bedrock/test/RLPWriter.t.sol index 6b3468c81ae9..b1735578ad44 100644 --- a/packages/contracts-bedrock/test/RLPWriter.t.sol +++ b/packages/contracts-bedrock/test/RLPWriter.t.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { RLPWriter } from "../src/libraries/rlp/RLPWriter.sol"; -import { CommonTest } from "./CommonTest.t.sol"; +import { RLPWriter } from "src/libraries/rlp/RLPWriter.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; contract RLPWriter_writeString_Test is CommonTest { function test_writeString_empty_succeeds() external { diff --git a/packages/contracts-bedrock/test/ResolvedDelegateProxy.t.sol b/packages/contracts-bedrock/test/ResolvedDelegateProxy.t.sol index d740bc385964..33a81bc2ca0e 100644 --- a/packages/contracts-bedrock/test/ResolvedDelegateProxy.t.sol +++ b/packages/contracts-bedrock/test/ResolvedDelegateProxy.t.sol @@ -5,10 +5,10 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; // Target contract dependencies -import { AddressManager } from "../src/legacy/AddressManager.sol"; +import { AddressManager } from "src/legacy/AddressManager.sol"; // Target contract -import { ResolvedDelegateProxy } from "../src/legacy/ResolvedDelegateProxy.sol"; +import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; contract ResolvedDelegateProxy_Test is Test { AddressManager internal addressManager; diff --git a/packages/contracts-bedrock/test/ResourceMetering.t.sol b/packages/contracts-bedrock/test/ResourceMetering.t.sol index 2493896b8055..01fcab1c9264 100644 --- a/packages/contracts-bedrock/test/ResourceMetering.t.sol +++ b/packages/contracts-bedrock/test/ResourceMetering.t.sol @@ -5,13 +5,13 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; // Libraries -import { Constants } from "../src/libraries/Constants.sol"; +import { Constants } from "src/libraries/Constants.sol"; // Target contract dependencies -import { Proxy } from "../src/universal/Proxy.sol"; +import { Proxy } from "src/universal/Proxy.sol"; // Target contract -import { ResourceMetering } from "../src/L1/ResourceMetering.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; contract MeterUser is ResourceMetering { ResourceMetering.ResourceConfig public innerConfig; diff --git a/packages/contracts-bedrock/test/SafeCall.t.sol b/packages/contracts-bedrock/test/SafeCall.t.sol index 308344787414..550e7dd982b4 100644 --- a/packages/contracts-bedrock/test/SafeCall.t.sol +++ b/packages/contracts-bedrock/test/SafeCall.t.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Target contract -import { SafeCall } from "../src/libraries/SafeCall.sol"; +import { SafeCall } from "src/libraries/SafeCall.sol"; contract SafeCall_Test is CommonTest { /// @dev Tests that the `send` function succeeds. diff --git a/packages/contracts-bedrock/test/Semver.t.sol b/packages/contracts-bedrock/test/Semver.t.sol index c15044eb3fa2..08d0dae64f06 100644 --- a/packages/contracts-bedrock/test/Semver.t.sol +++ b/packages/contracts-bedrock/test/Semver.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { CommonTest } from "./CommonTest.t.sol"; -import { Semver } from "../src/universal/Semver.sol"; -import { Proxy } from "../src/universal/Proxy.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; +import { Semver } from "src/universal/Semver.sol"; +import { Proxy } from "src/universal/Proxy.sol"; /// @notice Test the Semver contract that is used for semantic versioning /// of various contracts. diff --git a/packages/contracts-bedrock/test/SequencerFeeVault.t.sol b/packages/contracts-bedrock/test/SequencerFeeVault.t.sol index 026b80e21d57..9c6b391a9194 100644 --- a/packages/contracts-bedrock/test/SequencerFeeVault.t.sol +++ b/packages/contracts-bedrock/test/SequencerFeeVault.t.sol @@ -2,17 +2,17 @@ pragma solidity 0.8.15; // Testing utilities -import { FeeVault_Initializer, Reverter } from "./CommonTest.t.sol"; -import { StandardBridge } from "../src/universal/StandardBridge.sol"; +import { FeeVault_Initializer, Reverter } from "test/CommonTest.t.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; // Libraries -import { Predeploys } from "../src/libraries/Predeploys.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; // Target contract dependencies -import { FeeVault } from "../src/universal/FeeVault.sol"; +import { FeeVault } from "src/universal/FeeVault.sol"; // Target contract -import { SequencerFeeVault } from "../src/L2/SequencerFeeVault.sol"; +import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; contract SequencerFeeVault_Test is FeeVault_Initializer { /// @dev Sets up the test suite. diff --git a/packages/contracts-bedrock/test/StandardBridge.t.sol b/packages/contracts-bedrock/test/StandardBridge.t.sol index fd96e09f2c67..000d2334ae34 100644 --- a/packages/contracts-bedrock/test/StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/StandardBridge.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { StandardBridge } from "../src/universal/StandardBridge.sol"; -import { CommonTest } from "./CommonTest.t.sol"; -import { OptimismMintableERC20, ILegacyMintableERC20 } from "../src/universal/OptimismMintableERC20.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; +import { OptimismMintableERC20, ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; /// @title StandardBridgeTester diff --git a/packages/contracts-bedrock/test/SystemConfig.t.sol b/packages/contracts-bedrock/test/SystemConfig.t.sol index bb355fc4146c..b6cb18cf7d7c 100644 --- a/packages/contracts-bedrock/test/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/SystemConfig.t.sol @@ -2,17 +2,17 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/CommonTest.t.sol"; // Libraries -import { Constants } from "../src/libraries/Constants.sol"; +import { Constants } from "src/libraries/Constants.sol"; // Target contract dependencies -import { ResourceMetering } from "../src/L1/ResourceMetering.sol"; -import { Proxy } from "../src/universal/Proxy.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { Proxy } from "src/universal/Proxy.sol"; // Target contract -import { SystemConfig } from "../src/L1/SystemConfig.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; contract SystemConfig_Init is CommonTest { SystemConfig sysConf; diff --git a/packages/contracts-bedrock/test/Transactor.t.sol b/packages/contracts-bedrock/test/Transactor.t.sol index 3eefd78287cc..70c02e53d813 100644 --- a/packages/contracts-bedrock/test/Transactor.t.sol +++ b/packages/contracts-bedrock/test/Transactor.t.sol @@ -3,9 +3,9 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { CallRecorder } from "./Helpers.sol"; -import { Reverter } from "./Helpers.sol"; -import { Transactor } from "../src/periphery/Transactor.sol"; +import { CallRecorder } from "test/Helpers.sol"; +import { Reverter } from "test/Helpers.sol"; +import { Transactor } from "src/periphery/Transactor.sol"; contract Transactor_Initializer is Test { address alice = address(128); diff --git a/packages/contracts-bedrock/test/TransferOnion.t.sol b/packages/contracts-bedrock/test/TransferOnion.t.sol index 88fe1dc60ab4..27947e82c20e 100644 --- a/packages/contracts-bedrock/test/TransferOnion.t.sol +++ b/packages/contracts-bedrock/test/TransferOnion.t.sol @@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; // Target contract -import { TransferOnion } from "../src/periphery/TransferOnion.sol"; +import { TransferOnion } from "src/periphery/TransferOnion.sol"; /// @title TransferOnionTest /// @notice Test coverage of TransferOnion diff --git a/packages/contracts-bedrock/test/invariants/AddressAliasHelper.t.sol b/packages/contracts-bedrock/test/invariants/AddressAliasHelper.t.sol index 9c5d5f205a69..fd5bcc8c7cad 100644 --- a/packages/contracts-bedrock/test/invariants/AddressAliasHelper.t.sol +++ b/packages/contracts-bedrock/test/invariants/AddressAliasHelper.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; -import { AddressAliasHelper } from "../../src/vendor/AddressAliasHelper.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; contract AddressAliasHelper_Converter { bool public failedRoundtrip; diff --git a/packages/contracts-bedrock/test/invariants/Burn.Eth.t.sol b/packages/contracts-bedrock/test/invariants/Burn.Eth.t.sol index 49f2a0249908..0fdfcdbbb194 100644 --- a/packages/contracts-bedrock/test/invariants/Burn.Eth.t.sol +++ b/packages/contracts-bedrock/test/invariants/Burn.Eth.t.sol @@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; -import { Burn } from "../../src/libraries/Burn.sol"; +import { Burn } from "src/libraries/Burn.sol"; contract Burn_EthBurner is StdUtils { Vm internal vm; diff --git a/packages/contracts-bedrock/test/invariants/Burn.Gas.t.sol b/packages/contracts-bedrock/test/invariants/Burn.Gas.t.sol index 8e973245a419..4e9145a08d77 100644 --- a/packages/contracts-bedrock/test/invariants/Burn.Gas.t.sol +++ b/packages/contracts-bedrock/test/invariants/Burn.Gas.t.sol @@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; -import { Burn } from "../../src/libraries/Burn.sol"; +import { Burn } from "src/libraries/Burn.sol"; contract Burn_GasBurner is StdUtils { Vm internal vm; diff --git a/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol index 1fb358e85c03..6eef617f5095 100644 --- a/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol @@ -3,14 +3,14 @@ pragma solidity 0.8.15; import { StdUtils } from "forge-std/StdUtils.sol"; import { Vm } from "forge-std/Vm.sol"; -import { OptimismPortal } from "../../src/L1/OptimismPortal.sol"; -import { L1CrossDomainMessenger } from "../../src/L1/L1CrossDomainMessenger.sol"; -import { Messenger_Initializer } from "../CommonTest.t.sol"; -import { Types } from "../../src/libraries/Types.sol"; -import { Predeploys } from "../../src/libraries/Predeploys.sol"; -import { Constants } from "../../src/libraries/Constants.sol"; -import { Encoding } from "../../src/libraries/Encoding.sol"; -import { Hashing } from "../../src/libraries/Hashing.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { Messenger_Initializer } from "test/CommonTest.t.sol"; +import { Types } from "src/libraries/Types.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Constants } from "src/libraries/Constants.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; contract RelayActor is StdUtils { // Storage slot of the l2Sender diff --git a/packages/contracts-bedrock/test/invariants/Encoding.t.sol b/packages/contracts-bedrock/test/invariants/Encoding.t.sol index 405ac3781515..566c82903e01 100644 --- a/packages/contracts-bedrock/test/invariants/Encoding.t.sol +++ b/packages/contracts-bedrock/test/invariants/Encoding.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; -import { Encoding } from "../../src/libraries/Encoding.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; contract Encoding_Converter { bool public failedRoundtripAToB; diff --git a/packages/contracts-bedrock/test/invariants/Hashing.t.sol b/packages/contracts-bedrock/test/invariants/Hashing.t.sol index 729f177be30a..c972148f12b0 100644 --- a/packages/contracts-bedrock/test/invariants/Hashing.t.sol +++ b/packages/contracts-bedrock/test/invariants/Hashing.t.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; -import { Encoding } from "../../src/libraries/Encoding.sol"; -import { Hashing } from "../../src/libraries/Hashing.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; contract Hash_CrossDomainHasher { bool public failedCrossDomainHashHighVersion; diff --git a/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol index 8423e5a9b547..79d637fca9d6 100644 --- a/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { L2OutputOracle_Initializer } from "../CommonTest.t.sol"; -import { L2OutputOracle } from "../../src/L1/L2OutputOracle.sol"; +import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { Vm } from "forge-std/Vm.sol"; contract L2OutputOracle_Proposer { diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol index 145a3b9e56b2..f0ac1e197843 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol @@ -4,15 +4,15 @@ pragma solidity 0.8.15; import { StdUtils } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; -import { OptimismPortal } from "../../src/L1/OptimismPortal.sol"; -import { L2OutputOracle } from "../../src/L1/L2OutputOracle.sol"; -import { AddressAliasHelper } from "../../src/vendor/AddressAliasHelper.sol"; -import { SystemConfig } from "../../src/L1/SystemConfig.sol"; -import { ResourceMetering } from "../../src/L1/ResourceMetering.sol"; -import { Constants } from "../../src/libraries/Constants.sol"; - -import { Portal_Initializer } from "../CommonTest.t.sol"; -import { Types } from "../../src/libraries/Types.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { Constants } from "src/libraries/Constants.sol"; + +import { Portal_Initializer } from "test/CommonTest.t.sol"; +import { Types } from "src/libraries/Types.sol"; contract OptimismPortal_Depositor is StdUtils, ResourceMetering { Vm internal vm; diff --git a/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol b/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol index 3f2ffce7199d..866861331219 100644 --- a/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol +++ b/packages/contracts-bedrock/test/invariants/ResourceMetering.t.sol @@ -6,10 +6,10 @@ import { Test } from "forge-std/Test.sol"; import { StdUtils } from "forge-std/StdUtils.sol"; import { StdInvariant } from "forge-std/StdInvariant.sol"; -import { Arithmetic } from "../../src/libraries/Arithmetic.sol"; -import { ResourceMetering } from "../../src/L1/ResourceMetering.sol"; -import { Proxy } from "../../src/universal/Proxy.sol"; -import { Constants } from "../../src/libraries/Constants.sol"; +import { Arithmetic } from "src/libraries/Arithmetic.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { Constants } from "src/libraries/Constants.sol"; contract ResourceMetering_User is StdUtils, ResourceMetering { bool public failedMaxGasPerBlock; diff --git a/packages/contracts-bedrock/test/invariants/SafeCall.t.sol b/packages/contracts-bedrock/test/invariants/SafeCall.t.sol index bb2bdc570200..66fbc0be115b 100644 --- a/packages/contracts-bedrock/test/invariants/SafeCall.t.sol +++ b/packages/contracts-bedrock/test/invariants/SafeCall.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { StdUtils } from "forge-std/StdUtils.sol"; import { Vm } from "forge-std/Vm.sol"; -import { SafeCall } from "../../src/libraries/SafeCall.sol"; +import { SafeCall } from "src/libraries/SafeCall.sol"; contract SafeCall_Succeeds_Invariants is Test { SafeCaller_Actor actor; diff --git a/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol b/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol index eb54e0f5ae54..436148cd609c 100644 --- a/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { SystemConfig } from "../../src/L1/SystemConfig.sol"; -import { Proxy } from "../../src/universal/Proxy.sol"; -import { ResourceMetering } from "../../src/L1/ResourceMetering.sol"; -import { Constants } from "../../src/libraries/Constants.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { Constants } from "src/libraries/Constants.sol"; contract SystemConfig_GasLimitLowerBound_Invariant is Test { struct FuzzInterface { From 0ec7e153700b994205a8d7e9bd6267796bf2fd05 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 25 Oct 2023 19:20:52 -0600 Subject: [PATCH 026/374] contracts-bedrock: delete dead rlp code This code is no longer used so we should delete it to reduce compile times slightly. It is a library for computing contract addresses, taken from the solmate issues. It may be in modern versions of solmate if we ever end up needing it again. --- packages/contracts-bedrock/test/RLP.t.sol | 46 ----------------------- 1 file changed, 46 deletions(-) delete mode 100644 packages/contracts-bedrock/test/RLP.t.sol diff --git a/packages/contracts-bedrock/test/RLP.t.sol b/packages/contracts-bedrock/test/RLP.t.sol deleted file mode 100644 index fadd5b21bec1..000000000000 --- a/packages/contracts-bedrock/test/RLP.t.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: Unlicense -pragma solidity ^0.8.0; - -import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; - -/// @title LibRLP -/// @notice Via https://github.com/Rari-Capital/solmate/issues/207. -library LibRLP { - using Bytes32AddressLib for bytes32; - - function computeAddress(address deployer, uint256 nonce) internal pure returns (address) { - // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, - // computed via 0x80 + 0. - // A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix - // that comes before it. - if (nonce == 0x00) { - return keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))).fromLast20Bytes(); - } - if (nonce <= 0x7f) { - return keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))).fromLast20Bytes(); - } - - // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix - // of 0x80 + length. - if (nonce <= type(uint8).max) { - return keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce))) - .fromLast20Bytes(); - } - if (nonce <= type(uint16).max) { - return keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce))) - .fromLast20Bytes(); - } - if (nonce <= type(uint24).max) { - return keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce))) - .fromLast20Bytes(); - } - - // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp - // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce) - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) - // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex) - // We assume nobody can have a nonce large enough to require more than 32 bytes. - return keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))) - .fromLast20Bytes(); - } -} From 37a0c5d8c39be66a0e848ec7fcc1942e636a935d Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 25 Oct 2023 19:25:44 -0600 Subject: [PATCH 027/374] contracts-bedrock: delete dead eas upgrade script All upgraes in the future will go through the `superchain-ops` repo. Delete this script to reduce compile time of the contracts. All new chains will have EAS in their genesis. Chains that do not have EAS already should use the `superchain-ops` repo to create a deploy script. --- .../scripts/upgrades/EASUpgrade.s.sol | 130 ------------------ 1 file changed, 130 deletions(-) delete mode 100644 packages/contracts-bedrock/scripts/upgrades/EASUpgrade.s.sol diff --git a/packages/contracts-bedrock/scripts/upgrades/EASUpgrade.s.sol b/packages/contracts-bedrock/scripts/upgrades/EASUpgrade.s.sol deleted file mode 100644 index 3eb8db286721..000000000000 --- a/packages/contracts-bedrock/scripts/upgrades/EASUpgrade.s.sol +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import { console2 as console } from "forge-std/console2.sol"; -import { SafeBuilder } from "../universal/SafeBuilder.sol"; -import { IGnosisSafe, Enum } from "../interfaces/IGnosisSafe.sol"; -import { IMulticall3 } from "forge-std/interfaces/IMulticall3.sol"; -import { Predeploys } from "../../src/libraries/Predeploys.sol"; -import { ProxyAdmin } from "../../src/universal/ProxyAdmin.sol"; -import { Deployer } from "../Deployer.sol"; - -/// @title EASUpgrader -/// @notice Upgrades the EAS predeploys. -contract EASUpgrader is SafeBuilder, Deployer { - /// @notice The proxy admin predeploy on L2. - ProxyAdmin immutable PROXY_ADMIN = ProxyAdmin(Predeploys.PROXY_ADMIN); - - /// @notice Represents the EAS contracts predeploys - struct ContractSet { - address EAS; - address SchemaRegistry; - } - - /// @notice A mapping of chainid to a ContractSet of implementations. - mapping(uint256 => ContractSet) internal implementations; - - /// @notice A mapping of chainid to ContractSet of proxy addresses. - mapping(uint256 => ContractSet) internal proxies; - - /// @notice The expected versions for the contracts to be upgraded to. - string internal constant EAS_Version = "1.0.0"; - string internal constant SchemaRegistry_Version = "1.0.0"; - - /// @notice Place the contract addresses in storage so they can be used when building calldata. - function setUp() public override { - super.setUp(); - - implementations[OP_GOERLI] = - ContractSet({ EAS: getAddress("EAS"), SchemaRegistry: getAddress("SchemaRegistry") }); - - proxies[OP_GOERLI] = ContractSet({ EAS: Predeploys.EAS, SchemaRegistry: Predeploys.SCHEMA_REGISTRY }); - } - - /// @notice - function name() public pure override returns (string memory) { - return "EASUpgrader"; - } - - /// @notice Follow up assertions to ensure that the script ran to completion. - function _postCheck() internal view override { - ContractSet memory prox = getProxies(); - require(_versionHash(prox.EAS) == keccak256(bytes(EAS_Version)), "EAS"); - require(_versionHash(prox.SchemaRegistry) == keccak256(bytes(SchemaRegistry_Version)), "SchemaRegistry"); - - // Check that the codehashes of all implementations match the proxies set implementations. - ContractSet memory impl = getImplementations(); - require(PROXY_ADMIN.getProxyImplementation(prox.EAS).codehash == impl.EAS.codehash); - require(PROXY_ADMIN.getProxyImplementation(prox.SchemaRegistry).codehash == impl.SchemaRegistry.codehash); - } - - /// @notice Test coverage of the logic. Should only run on goerli but other chains - /// could be added. - function test_script_succeeds() external skipWhenNotForking { - address _safe; - address _proxyAdmin; - - if (block.chainid == OP_GOERLI) { - _safe = 0xE534ccA2753aCFbcDBCeB2291F596fc60495257e; - _proxyAdmin = 0x4200000000000000000000000000000000000018; - } - - require(_safe != address(0) && _proxyAdmin != address(0)); - - 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(); - } - - /// @notice Builds the calldata that the multisig needs to make for the upgrade to happen. - /// A total of 9 calls are made to the proxy admin to upgrade the implementations - /// of the predeploys. - function buildCalldata(address _proxyAdmin) internal view override returns (bytes memory) { - IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](2); - - ContractSet memory impl = getImplementations(); - ContractSet memory prox = getProxies(); - - // Upgrade EAS - calls[0] = IMulticall3.Call3({ - target: _proxyAdmin, - allowFailure: false, - callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.EAS), impl.EAS)) - }); - - // Upgrade SchemaRegistry - calls[1] = IMulticall3.Call3({ - target: _proxyAdmin, - allowFailure: false, - callData: abi.encodeCall(ProxyAdmin.upgrade, (payable(prox.SchemaRegistry), impl.SchemaRegistry)) - }); - - return abi.encodeCall(IMulticall3.aggregate3, (calls)); - } - - /// @notice Returns the ContractSet that represents the implementations for a given network. - function getImplementations() internal view returns (ContractSet memory) { - ContractSet memory set = implementations[block.chainid]; - require(set.EAS != address(0), "no implementations for this network"); - return set; - } - - /// @notice Returns the ContractSet that represents the proxies for a given network. - function getProxies() internal view returns (ContractSet memory) { - ContractSet memory set = proxies[block.chainid]; - require(set.EAS != address(0), "no proxies for this network"); - return set; - } -} From 3d61fe8f2ca02169d7e436553dbe52098e5ee512 Mon Sep 17 00:00:00 2001 From: bendanzhentan <455462586@qq.com> Date: Wed, 25 Oct 2023 14:46:03 +0800 Subject: [PATCH 028/374] fix: string encode error TS2345 --- packages/common-ts/src/base-service/base-service-v2.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/common-ts/src/base-service/base-service-v2.ts b/packages/common-ts/src/base-service/base-service-v2.ts index e6b34a0d44f1..79672e9b41e6 100644 --- a/packages/common-ts/src/base-service/base-service-v2.ts +++ b/packages/common-ts/src/base-service/base-service-v2.ts @@ -336,7 +336,8 @@ export abstract class BaseServiceV2< app.use( bodyParser.json({ verify: (req, res, buf, encoding) => { - ;(req as any).rawBody = buf?.toString(encoding || 'utf8') || '' + ;(req as any).rawBody = + buf?.toString((encoding as BufferEncoding) || 'utf8') || '' }, ...(this.params.bodyParserParams ?? {}), }) From 08c3a506dc967b6b99a81016ec907326af33f8d8 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 25 Oct 2023 19:37:41 -0600 Subject: [PATCH 029/374] op-bindings: regenerate --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index d6c26b36bba1..e7983bf62efd 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:128:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:287;176:23;;;158:42;;146:2;131:18;1710:45:128;;;;;;;;2448:99;;;412:42:287;2534:6:128;400:55:287;382:74;;370:2;355:18;2448:99:128;211:251:287;26025:6379:128;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:287;;;1743:2;1728:18;26025:6379:128;1609:177:287;26025:6379:128;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:128;;-1:-1:-1;28593:7:128;:20::i;:::-;28579:34;-1:-1:-1;28643:10:128;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:128;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:128;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:128;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:128;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:128;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:128:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:128;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:128;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:128:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:287;19164:28:128;;;2164:21:287;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:128;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:128;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:287;14107:30:128;;;2511:21:287;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:128;2327:344:287;14055:97:128;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:128:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:128;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:128;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:128;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:128;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:128;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:128;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:128;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:128;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:128;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:128;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:128;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:128;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:287;37406:29:128;;;2860:21:287;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:128;2676:343:287;37297:157:128;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:128;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:128;;-1:-1:-1;;38164:8:128;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:128;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:128;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:128;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:128;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:128;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:128;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:128;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:128;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:287;20288:41:128;;;3208:21:287;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:128;3024:338:287;20288:41:128;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:128;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:128;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:128:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:128;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:129;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:128;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:287;;;8234:54:128;3601:23:287;;;3581:18;;;3574:51;8203:11:128;;;;8234:19;:6;:19;;;;3513:18:287;;8234:54:128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:128;;-1:-1:-1;;;7642:2553:128;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:128;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:128;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:128;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:128;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:128;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:128;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:128;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:128;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:128;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:128;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:128;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:128;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:128;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:128:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:128;25120:9;25084:343;;;-1:-1:-1;;25526:4:128;25519:18;-1:-1:-1;;;;23913:1654:128:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:287;21415:72:128;;;4259:21:287;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:128;4075:399:287;21415:72:128;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:287:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:287;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:287;-1:-1:-1;1349:2:287;1334:18;;1321:32;;-1:-1:-1;1365:16:287;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:287;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:287:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:287;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:287:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:127:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:286;176:23;;;158:42;;146:2;131:18;1710:45:127;;;;;;;;2448:99;;;412:42:286;2534:6:127;400:55:286;382:74;;370:2;355:18;2448:99:127;211:251:286;26025:6379:127;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:286;;;1743:2;1728:18;26025:6379:127;1609:177:286;26025:6379:127;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:127;;-1:-1:-1;28593:7:127;:20::i;:::-;28579:34;-1:-1:-1;28643:10:127;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:127;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:127;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:127;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:127;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:127;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:127:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:127;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:127;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:127:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:286;19164:28:127;;;2164:21:286;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:127;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:127;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:286;14107:30:127;;;2511:21:286;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:127;2327:344:286;14055:97:127;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:127:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:127;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:127;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:127;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:127;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:127;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:127;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:127;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:127;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:127;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:127;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:127;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:127;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:286;37406:29:127;;;2860:21:286;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:127;2676:343:286;37297:157:127;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:127;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:127;;-1:-1:-1;;38164:8:127;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:127;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:127;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:127;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:127;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:127;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:127;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:127;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:127;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:286;20288:41:127;;;3208:21:286;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:127;3024:338:286;20288:41:127;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:127;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:127;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:127:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:127;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:128;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:127;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:286;;;8234:54:127;3601:23:286;;;3581:18;;;3574:51;8203:11:127;;;;8234:19;:6;:19;;;;3513:18:286;;8234:54:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:127;;-1:-1:-1;;;7642:2553:127;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:127;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:127;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:127;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:127;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:127;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:127;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:127;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:127;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:127;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:127;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:127;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:127;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:127;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:127:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:127;25120:9;25084:343;;;-1:-1:-1;;25526:4:127;25519:18;-1:-1:-1;;;;23913:1654:127:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:286;21415:72:127;;;4259:21:286;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:127;4075:399:286;21415:72:127;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:286:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:286;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:286;-1:-1:-1;1349:2:286;1334:18;;1321:32;;-1:-1:-1;1365:16:286;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:286;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:286:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:286;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:286:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 2c53d11a0d7f..54abd4665e9b 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:130:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:287;;;401:2;386:18;537:68:130;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:287;;607:22;589:41;;577:2;562:18;680:66:130;449:187:287;1367:1211:130;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:287;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:130;1100:248:287;2620:1595:130;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:130;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:130:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:287;906:62:130;;;2890:21:287;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:130;;;;;;;;-1:-1:-1;1099:14:130;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:130;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:130:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:130:o;552:449:129:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:129:o;14:248:287:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:287;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:287:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:287;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:287;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:287;1069:19;1056:33;;-1:-1:-1;641:454:287;-1:-1:-1;641:454:287:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:287;;2017:180;-1:-1:-1;2017:180:287:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:287;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:287;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:129:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:286;;;401:2;386:18;537:68:129;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:286;;607:22;589:41;;577:2;562:18;680:66:129;449:187:286;1367:1211:129;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:286;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:129;1100:248:286;2620:1595:129;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:129;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:129:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:286;906:62:129;;;2890:21:286;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:129;;;;;;;;-1:-1:-1;1099:14:129;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:129;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:129:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:129:o;552:449:128:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:128:o;14:248:286:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:286;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:286:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:286;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:286;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:286;1069:19;1056:33;;-1:-1:-1;641:454:286;-1:-1:-1;641:454:286:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:286;;2017:180;-1:-1:-1;2017:180:286:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:286;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:286;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { From 798f054993dd4e2dde968e3d48dd1fe1f477bb20 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 25 Oct 2023 19:23:16 -0600 Subject: [PATCH 030/374] contracts-bedrock: delete dead delete output code We have migrated to using `superchain-ops` for any sort of safe interactions. This code will likely need to be ported over to the `superchain-ops` repo in the future. It is not necessary for now, so delete it. --- .../scripts/outputs/DeleteOutput.s.sol | 152 ------------------ .../scripts/outputs/README.md | 38 ----- 2 files changed, 190 deletions(-) delete mode 100644 packages/contracts-bedrock/scripts/outputs/DeleteOutput.s.sol delete mode 100644 packages/contracts-bedrock/scripts/outputs/README.md diff --git a/packages/contracts-bedrock/scripts/outputs/DeleteOutput.s.sol b/packages/contracts-bedrock/scripts/outputs/DeleteOutput.s.sol deleted file mode 100644 index 2e79e88000ac..000000000000 --- a/packages/contracts-bedrock/scripts/outputs/DeleteOutput.s.sol +++ /dev/null @@ -1,152 +0,0 @@ -// 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 "../../src/libraries/Types.sol"; -import { FeeVault } from "../../src/universal/FeeVault.sol"; -import { L2OutputOracle } from "../../src/L1/L2OutputOracle.sol"; -import { Predeploys } from "../../src/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() external skipWhenNotForking { - 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) 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(); - } -} diff --git a/packages/contracts-bedrock/scripts/outputs/README.md b/packages/contracts-bedrock/scripts/outputs/README.md deleted file mode 100644 index 24621bc43921..000000000000 --- a/packages/contracts-bedrock/scripts/outputs/README.md +++ /dev/null @@ -1,38 +0,0 @@ -## 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 `` 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 \ - -``` - -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 -`` 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 \ - -``` - - From bd23c0aa618f21b15debc4aaab2dc11a21cd0a16 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 25 Oct 2023 20:20:34 -0600 Subject: [PATCH 031/374] op-bindings: regenerate --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index d6c26b36bba1..e7983bf62efd 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:128:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:287;176:23;;;158:42;;146:2;131:18;1710:45:128;;;;;;;;2448:99;;;412:42:287;2534:6:128;400:55:287;382:74;;370:2;355:18;2448:99:128;211:251:287;26025:6379:128;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:287;;;1743:2;1728:18;26025:6379:128;1609:177:287;26025:6379:128;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:128;;-1:-1:-1;28593:7:128;:20::i;:::-;28579:34;-1:-1:-1;28643:10:128;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:128;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:128;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:128;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:128;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:128;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:128:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:128;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:128;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:128:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:287;19164:28:128;;;2164:21:287;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:128;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:128;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:287;14107:30:128;;;2511:21:287;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:128;2327:344:287;14055:97:128;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:128:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:128;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:128;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:128;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:128;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:128;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:128;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:128;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:128;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:128;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:128;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:128;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:128;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:287;37406:29:128;;;2860:21:287;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:128;2676:343:287;37297:157:128;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:128;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:128;;-1:-1:-1;;38164:8:128;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:128;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:128;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:128;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:128;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:128;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:128;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:128;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:128;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:287;20288:41:128;;;3208:21:287;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:128;3024:338:287;20288:41:128;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:128;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:128;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:128:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:128;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:129;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:128;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:287;;;8234:54:128;3601:23:287;;;3581:18;;;3574:51;8203:11:128;;;;8234:19;:6;:19;;;;3513:18:287;;8234:54:128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:128;;-1:-1:-1;;;7642:2553:128;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:128;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:128;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:128;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:128;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:128;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:128;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:128;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:128;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:128;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:128;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:128;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:128;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:128;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:128:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:128;25120:9;25084:343;;;-1:-1:-1;;25526:4:128;25519:18;-1:-1:-1;;;;23913:1654:128:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:287;21415:72:128;;;4259:21:287;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:128;4075:399:287;21415:72:128;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:287:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:287;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:287;-1:-1:-1;1349:2:287;1334:18;;1321:32;;-1:-1:-1;1365:16:287;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:287;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:287:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:287;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:287:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:127:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:286;176:23;;;158:42;;146:2;131:18;1710:45:127;;;;;;;;2448:99;;;412:42:286;2534:6:127;400:55:286;382:74;;370:2;355:18;2448:99:127;211:251:286;26025:6379:127;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:286;;;1743:2;1728:18;26025:6379:127;1609:177:286;26025:6379:127;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:127;;-1:-1:-1;28593:7:127;:20::i;:::-;28579:34;-1:-1:-1;28643:10:127;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:127;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:127;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:127;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:127;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:127;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:127:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:127;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:127;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:127:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:286;19164:28:127;;;2164:21:286;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:127;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:127;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:286;14107:30:127;;;2511:21:286;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:127;2327:344:286;14055:97:127;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:127:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:127;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:127;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:127;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:127;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:127;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:127;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:127;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:127;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:127;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:127;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:127;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:127;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:286;37406:29:127;;;2860:21:286;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:127;2676:343:286;37297:157:127;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:127;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:127;;-1:-1:-1;;38164:8:127;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:127;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:127;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:127;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:127;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:127;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:127;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:127;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:127;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:286;20288:41:127;;;3208:21:286;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:127;3024:338:286;20288:41:127;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:127;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:127;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:127:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:127;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:128;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:127;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:286;;;8234:54:127;3601:23:286;;;3581:18;;;3574:51;8203:11:127;;;;8234:19;:6;:19;;;;3513:18:286;;8234:54:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:127;;-1:-1:-1;;;7642:2553:127;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:127;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:127;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:127;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:127;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:127;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:127;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:127;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:127;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:127;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:127;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:127;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:127;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:127;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:127:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:127;25120:9;25084:343;;;-1:-1:-1;;25526:4:127;25519:18;-1:-1:-1;;;;23913:1654:127:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:286;21415:72:127;;;4259:21:286;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:127;4075:399:286;21415:72:127;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:286:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:286;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:286;-1:-1:-1;1349:2:286;1334:18;;1321:32;;-1:-1:-1;1365:16:286;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:286;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:286:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:286;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:286:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 2c53d11a0d7f..54abd4665e9b 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:130:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:287;;;401:2;386:18;537:68:130;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:287;;607:22;589:41;;577:2;562:18;680:66:130;449:187:287;1367:1211:130;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:287;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:130;1100:248:287;2620:1595:130;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:130;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:130:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:287;906:62:130;;;2890:21:287;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:130;;;;;;;;-1:-1:-1;1099:14:130;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:130;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:130:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:130:o;552:449:129:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:129:o;14:248:287:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:287;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:287:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:287;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:287;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:287;1069:19;1056:33;;-1:-1:-1;641:454:287;-1:-1:-1;641:454:287:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:287;;2017:180;-1:-1:-1;2017:180:287:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:287;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:287;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:129:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:286;;;401:2;386:18;537:68:129;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:286;;607:22;589:41;;577:2;562:18;680:66:129;449:187:286;1367:1211:129;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:286;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:129;1100:248:286;2620:1595:129;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:129;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:129:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:286;906:62:129;;;2890:21:286;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:129;;;;;;;;-1:-1:-1;1099:14:129;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:129;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:129:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:129:o;552:449:128:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:128:o;14:248:286:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:286;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:286:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:286;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:286;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:286;1069:19;1056:33;;-1:-1:-1;641:454:286;-1:-1:-1;641:454:286:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:286;;2017:180;-1:-1:-1;2017:180:286:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:286;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:286;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { From 329bec4998ac21ffd445c74a717f05d15def6eee Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Thu, 26 Oct 2023 12:22:50 +1000 Subject: [PATCH 032/374] op-e2e: Add waiter to ActL1IncludeTx This mirrors a change to the L2 block builder to wait for the tx pool to have a processable transaction. The txpool does promotion async so a simple check leads to race conditions. Fixes intermittency in TestFinalizeWhileSyncing --- op-e2e/actions/l1_miner.go | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/op-e2e/actions/l1_miner.go b/op-e2e/actions/l1_miner.go index 70c5059a16c0..fecfb1532aaf 100644 --- a/op-e2e/actions/l1_miner.go +++ b/op-e2e/actions/l1_miner.go @@ -1,8 +1,11 @@ package actions import ( + "context" "math/big" + "time" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core" @@ -95,11 +98,19 @@ func (s *L1Miner) ActL1IncludeTx(from common.Address) Action { t.InvalidAction("no tx inclusion when not building l1 block") return } - i := s.pendingIndices[from] - txs, q := s.eth.TxPool().ContentFrom(from) - if uint64(len(txs)) <= i { - t.Fatalf("no pending txs from %s, and have %d unprocessable queued txs from this account", from, len(q)) - } + var i uint64 + var txs []*types.Transaction + var q []*types.Transaction + // Wait for the tx to be in the pending tx queue + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + err := wait.For(ctx, time.Second, func() (bool, error) { + i = s.pendingIndices[from] + txs, q = s.eth.TxPool().ContentFrom(from) + return uint64(len(txs)) > i, nil + }) + require.NoError(t, err, + "no pending txs from %s, and have %d unprocessable queued txs from this account: %w", from, len(q), err) tx := txs[i] s.IncludeTx(t, tx) s.pendingIndices[from] = i + 1 // won't retry the tx From ef3ecc2e585cd372940d3fce64d291abead5a0fb Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Wed, 25 Oct 2023 22:45:52 -0700 Subject: [PATCH 033/374] Enable Canyon in the devnet This does several things to enable Canyon 1. Update to op-geth which has all canyon changes enabled in it 2. Thread the new 1559 config change through the devnet config 3. Fix some EIP-1559 calculations where were use CalcBaseFee 4. Add the PostCanyonDenominator in several deploy configs --- go.mod | 2 +- go.sum | 4 ++-- op-chain-ops/genesis/config.go | 5 +++++ op-chain-ops/genesis/genesis.go | 9 +++++++-- .../genesis/testdata/test-deploy-config-full.json | 1 + op-e2e/actions/l1_miner.go | 2 +- op-program/client/l2/engineapi/block_processor.go | 2 +- .../deploy-config/devnetL1-template.json | 4 +++- .../contracts-bedrock/deploy-config/getting-started.json | 1 + packages/contracts-bedrock/deploy-config/goerli.json | 1 + packages/contracts-bedrock/deploy-config/hardhat.json | 1 + 11 files changed, 24 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 3713a12490c6..370e4dddcd44 100644 --- a/go.mod +++ b/go.mod @@ -209,7 +209,7 @@ require ( rsc.io/tmplfunc v0.0.3 // indirect ) -replace github.com/ethereum/go-ethereum v1.13.1 => github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024150425-5023660bf92d +replace github.com/ethereum/go-ethereum v1.13.1 => github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024175019-29cd9a353f83 //replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain //replace github.com/ethereum/go-ethereum v1.13.1 => ../go-ethereum diff --git a/go.sum b/go.sum index 1627f592ddca..45a78c60555e 100644 --- a/go.sum +++ b/go.sum @@ -151,8 +151,8 @@ github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/ github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= -github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024150425-5023660bf92d h1:5dptu9FNKPcZ3o5h2incAbQWH411Mw4HKlsZ4sF4llY= -github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024150425-5023660bf92d/go.mod h1:hl28ffXoV4maInP7dvhvNgDO79Q5M3MEYrPZZO6u3W8= +github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024175019-29cd9a353f83 h1:RFKnTUJqbYM8+dueFcGPdOY0ycrOhxp0HQJyy2OYzvc= +github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024175019-29cd9a353f83/go.mod h1:hl28ffXoV4maInP7dvhvNgDO79Q5M3MEYrPZZO6u3W8= github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231018202221-fdba3d104171 h1:MjCUj16JSLZRDnQQ6OOUy6Chfb4dKo7ahFceNi0RKZ8= github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231018202221-fdba3d104171/go.mod h1:/70H/KqrtKcvWvNGVj6S3rAcLC+kUPr3t2aDmYIS+Xk= github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg= diff --git a/op-chain-ops/genesis/config.go b/op-chain-ops/genesis/config.go index b706f59dd7cd..0e1e4dcfa581 100644 --- a/op-chain-ops/genesis/config.go +++ b/op-chain-ops/genesis/config.go @@ -185,6 +185,8 @@ type DeployConfig struct { EIP1559Elasticity uint64 `json:"eip1559Elasticity"` // EIP1559Denominator is the denominator of EIP1559 base fee market. EIP1559Denominator uint64 `json:"eip1559Denominator"` + // EIP1559DenominatorCanyon is the denominator of EIP1559 base fee market when Canyon is active. + EIP1559DenominatorCanyon uint64 `json:"eip1559DenominatorCanyon"` // SystemConfigStartBlock represents the block at which the op-node should start syncing // from. It is an override to set this value on legacy networks where it is not set by // default. It can be removed once all networks have this value set in their storage. @@ -318,6 +320,9 @@ func (d *DeployConfig) Check() error { if d.EIP1559Denominator == 0 { return fmt.Errorf("%w: EIP1559Denominator cannot be 0", ErrInvalidDeployConfig) } + if d.L2GenesisCanyonTimeOffset != nil && d.EIP1559DenominatorCanyon == 0 { + return fmt.Errorf("%w: EIP1559DenominatorCanyon cannot be 0 if Canyon is activated", ErrInvalidDeployConfig) + } if d.EIP1559Elasticity == 0 { return fmt.Errorf("%w: EIP1559Elasticity cannot be 0", ErrInvalidDeployConfig) } diff --git a/op-chain-ops/genesis/genesis.go b/op-chain-ops/genesis/genesis.go index adae3c489ce5..7a4df6b1ad49 100644 --- a/op-chain-ops/genesis/genesis.go +++ b/op-chain-ops/genesis/genesis.go @@ -31,6 +31,10 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro if eip1559Denom == 0 { eip1559Denom = 50 } + eip1559DenomCanyon := config.EIP1559DenominatorCanyon + if eip1559DenomCanyon == 0 { + eip1559DenomCanyon = 250 + } eip1559Elasticity := config.EIP1559Elasticity if eip1559Elasticity == 0 { eip1559Elasticity = 10 @@ -61,8 +65,9 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro CanyonTime: config.CanyonTime(block.Time()), ShanghaiTime: config.CanyonTime(block.Time()), Optimism: ¶ms.OptimismConfig{ - EIP1559Denominator: eip1559Denom, - EIP1559Elasticity: eip1559Elasticity, + EIP1559Denominator: eip1559Denom, + EIP1559Elasticity: eip1559Elasticity, + EIP1559DenominatorPostCanyon: eip1559DenomCanyon, }, } diff --git a/op-chain-ops/genesis/testdata/test-deploy-config-full.json b/op-chain-ops/genesis/testdata/test-deploy-config-full.json index e496fce29090..d2f7b980ddae 100644 --- a/op-chain-ops/genesis/testdata/test-deploy-config-full.json +++ b/op-chain-ops/genesis/testdata/test-deploy-config-full.json @@ -62,6 +62,7 @@ "governanceTokenOwner": "0x0000000000000000000000000000000000000333", "deploymentWaitConfirmations": 1, "eip1559Denominator": 8, + "eip1559DenominatorCanyon": 12, "eip1559Elasticity": 2, "fundDevAccounts": true, "faultGameAbsolutePrestate": "0x0000000000000000000000000000000000000000000000000000000000000000", diff --git a/op-e2e/actions/l1_miner.go b/op-e2e/actions/l1_miner.go index 70c5059a16c0..c9d085877bf6 100644 --- a/op-e2e/actions/l1_miner.go +++ b/op-e2e/actions/l1_miner.go @@ -67,7 +67,7 @@ func (s *L1Miner) ActL1StartBlock(timeDelta uint64) Action { MixDigest: common.Hash{}, // TODO: maybe randomize this (prev-randao value) } if s.l1Cfg.Config.IsLondon(header.Number) { - header.BaseFee = eip1559.CalcBaseFee(s.l1Cfg.Config, parent) + header.BaseFee = eip1559.CalcBaseFee(s.l1Cfg.Config, parent, header.Time) // At the transition, double the gas limit so the gas target is equal to the old gas limit. if !s.l1Cfg.Config.IsLondon(parent.Number) { header.GasLimit = parent.GasLimit * s.l1Cfg.Config.ElasticityMultiplier() diff --git a/op-program/client/l2/engineapi/block_processor.go b/op-program/client/l2/engineapi/block_processor.go index 22c6e1441401..c6966e0d94c2 100644 --- a/op-program/client/l2/engineapi/block_processor.go +++ b/op-program/client/l2/engineapi/block_processor.go @@ -68,7 +68,7 @@ func NewBlockProcessorFromHeader(provider BlockDataProvider, h *types.Header) (* return nil, fmt.Errorf("get parent state: %w", err) } header.Number = new(big.Int).Add(parentHeader.Number, common.Big1) - header.BaseFee = eip1559.CalcBaseFee(provider.Config(), parentHeader) + header.BaseFee = eip1559.CalcBaseFee(provider.Config(), parentHeader, header.Time) header.GasUsed = 0 gasPool := new(core.GasPool).AddGas(header.GasLimit) return &BlockProcessor{ diff --git a/packages/contracts-bedrock/deploy-config/devnetL1-template.json b/packages/contracts-bedrock/deploy-config/devnetL1-template.json index 10badc81e0df..c7acc73768f0 100644 --- a/packages/contracts-bedrock/deploy-config/devnetL1-template.json +++ b/packages/contracts-bedrock/deploy-config/devnetL1-template.json @@ -32,7 +32,7 @@ "portalGuardian": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", "finalizationPeriodSeconds": 2, "fundDevAccounts": true, - "l2GenesisBlockBaseFeePerGas": "0x1", + "l2GenesisBlockBaseFeePerGas": "1", "gasPriceOracleOverhead": 2100, "gasPriceOracleScalar": 1000000, "enableGovernance": true, @@ -40,10 +40,12 @@ "governanceTokenName": "Optimism", "governanceTokenOwner": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", "eip1559Denominator": 50, + "eip1559DenominatorCanyon": 250, "eip1559Elasticity": 6, "l1GenesisBlockTimestamp": "0x64c811bf", "l2GenesisRegolithTimeOffset": "0x0", "l2GenesisSpanBatchTimeOffset": "0x0", + "l2GenesisCanyonTimeOffset": "0x40", "faultGameAbsolutePrestate": "0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98", "faultGameMaxDepth": 30, "faultGameMaxDuration": 1200, diff --git a/packages/contracts-bedrock/deploy-config/getting-started.json b/packages/contracts-bedrock/deploy-config/getting-started.json index 1757c3d049fa..7ac03cdc652d 100644 --- a/packages/contracts-bedrock/deploy-config/getting-started.json +++ b/packages/contracts-bedrock/deploy-config/getting-started.json @@ -51,6 +51,7 @@ "l2GenesisRegolithTimeOffset": "0x0", "eip1559Denominator": 50, + "eip1559DenominatorCanyon": 250, "eip1559Elasticity": 10, "systemConfigStartBlock": 0, diff --git a/packages/contracts-bedrock/deploy-config/goerli.json b/packages/contracts-bedrock/deploy-config/goerli.json index 1fa80b8c75ad..5c084b4fd36c 100644 --- a/packages/contracts-bedrock/deploy-config/goerli.json +++ b/packages/contracts-bedrock/deploy-config/goerli.json @@ -37,6 +37,7 @@ "l2GenesisBlockGasLimit": "0x2faf080", "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", "eip1559Denominator": 50, + "eip1559DenominatorCanyon": 250, "eip1559Elasticity": 10, "systemConfigStartBlock": 8300214, "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", diff --git a/packages/contracts-bedrock/deploy-config/hardhat.json b/packages/contracts-bedrock/deploy-config/hardhat.json index ab5279412ef4..3a59eb60ccb8 100644 --- a/packages/contracts-bedrock/deploy-config/hardhat.json +++ b/packages/contracts-bedrock/deploy-config/hardhat.json @@ -37,6 +37,7 @@ "governanceTokenOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", "finalizationPeriodSeconds": 2, "eip1559Denominator": 50, + "eip1559DenominatorCanyon": 250, "eip1559Elasticity": 10, "l2GenesisRegolithTimeOffset": "0x0", "systemConfigStartBlock": 0, From 30871d7fdf746d3917fa79b9feb77eb4172e4762 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 07:28:29 +0000 Subject: [PATCH 034/374] build(deps): bump github.com/onsi/gomega from 1.28.1 to 1.29.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.28.1 to 1.29.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.28.1...v1.29.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3713a12490c6..f9733ad04b61 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/multiformats/go-multiaddr v0.12.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/olekukonko/tablewriter v0.0.5 - github.com/onsi/gomega v1.28.1 + github.com/onsi/gomega v1.29.0 github.com/pkg/errors v0.9.1 github.com/pkg/profile v1.7.0 github.com/prometheus/client_golang v1.17.0 diff --git a/go.sum b/go.sum index 1627f592ddca..ee04405cff83 100644 --- a/go.sum +++ b/go.sum @@ -569,8 +569,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.28.1 h1:MijcGUbfYuznzK/5R4CPNoUP/9Xvuo20sXfEm6XxoTA= -github.com/onsi/gomega v1.28.1/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= From 68e012cd5238d6c9777b319019ee7574442374c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 07:28:34 +0000 Subject: [PATCH 035/374] build(deps): bump gorm.io/driver/postgres from 1.5.3 to 1.5.4 Bumps [gorm.io/driver/postgres](https://github.com/go-gorm/postgres) from 1.5.3 to 1.5.4. - [Commits](https://github.com/go-gorm/postgres/compare/v1.5.3...v1.5.4) --- updated-dependencies: - dependency-name: gorm.io/driver/postgres dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3713a12490c6..99f6d68739de 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( golang.org/x/sync v0.4.0 golang.org/x/term v0.13.0 golang.org/x/time v0.3.0 - gorm.io/driver/postgres v1.5.3 + gorm.io/driver/postgres v1.5.4 gorm.io/gorm v1.25.5 ) diff --git a/go.sum b/go.sum index 1627f592ddca..649bcb92a4de 100644 --- a/go.sum +++ b/go.sum @@ -982,8 +982,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/postgres v1.5.3 h1:qKGY5CPHOuj47K/VxbCXJfFvIUeqMSXXadqdCY+MbBU= -gorm.io/driver/postgres v1.5.3/go.mod h1:F+LtvlFhZT7UBiA81mC9W6Su3D4WUhSboc/36QZU0gk= +gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo= +gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0= gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= From 9c0960cc8944e42620562034aaeea20262d7a6cb Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 26 Oct 2023 15:10:28 +0200 Subject: [PATCH 036/374] ops: handle warm-up output case during docker publish correctly --- .circleci/config.yml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f1e0212e0087..747de52041a4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -229,17 +229,24 @@ jobs: # and naming allows us to use the DLC (docker-layer-cache) docker buildx create --driver=docker-container --name=buildx-build --bootstrap --use - DOCKER_OUTPUT_DESTINATION="--load" - # if we are publishing, change the destination + DOCKER_OUTPUT_DESTINATION="" if [ "<>" == "true" ]; then - DOCKER_OUTPUT_DESTINATION="--push" echo "Building for platforms $PLATFORMS and then publishing to registry" + DOCKER_OUTPUT_DESTINATION="--push" + if [ "<>" != "" ]; then + echo "ERROR: cannot save image to docker when publishing to registry" + exit 1 + fi else - if [[ $PLATFORMS == *,* ]]; then - echo "ERROR: cannot perform multi-arch build while also loading the result into regular docker" + if [ "<>" == "" ]; then + echo "Running $PLATFORMS build without destination (cache warm-up)" + DOCKER_OUTPUT_DESTINATION="" + elif [[ $PLATFORMS == *,* ]]; then + echo "ERROR: cannot perform multi-arch (platforms: $PLATFORMS) build while also loading the result into regular docker" exit 1 else echo "Running single-platform $PLATFORMS build and loading into docker" + DOCKER_OUTPUT_DESTINATION="--load" fi fi From 0fc2b1dc54e62a66b96de48a8bb5d77d1c562907 Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Thu, 26 Oct 2023 07:24:44 -0700 Subject: [PATCH 037/374] Update packages/contracts-bedrock/deploy-config/devnetL1-template.json Co-authored-by: Adrian Sutton --- packages/contracts-bedrock/deploy-config/devnetL1-template.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/deploy-config/devnetL1-template.json b/packages/contracts-bedrock/deploy-config/devnetL1-template.json index c7acc73768f0..f05de9180ea5 100644 --- a/packages/contracts-bedrock/deploy-config/devnetL1-template.json +++ b/packages/contracts-bedrock/deploy-config/devnetL1-template.json @@ -32,7 +32,7 @@ "portalGuardian": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", "finalizationPeriodSeconds": 2, "fundDevAccounts": true, - "l2GenesisBlockBaseFeePerGas": "1", + "l2GenesisBlockBaseFeePerGas": "0x1", "gasPriceOracleOverhead": 2100, "gasPriceOracleScalar": 1000000, "enableGovernance": true, From 4d5375b0f1c34a3015309c7356a8f38e03261c89 Mon Sep 17 00:00:00 2001 From: tre Date: Thu, 26 Oct 2023 08:39:31 -0700 Subject: [PATCH 038/374] periphery deploy configs for op chains --- .../deployments/4460/.chainId | 1 + .../deployments/58008/.chainId | 1 + .../deployments/84532/.chainId | 1 + .../deployments/919/.chainId | 1 + .../deployments/999999999/.chainId | 1 + .../deployments/optimism-sepolia/.chainId | 1 + .../periphery-deploy-config/4460.json | 24 +++++++++++++++++++ .../periphery-deploy-config/58008.json | 24 +++++++++++++++++++ .../periphery-deploy-config/84532.json | 24 +++++++++++++++++++ .../periphery-deploy-config/901.json | 24 +++++++++++++++++++ .../periphery-deploy-config/919.json | 24 +++++++++++++++++++ .../periphery-deploy-config/999999999.json | 24 +++++++++++++++++++ .../optimism-sepolia.json | 24 +++++++++++++++++++ 13 files changed, 174 insertions(+) create mode 100644 packages/contracts-bedrock/deployments/4460/.chainId create mode 100644 packages/contracts-bedrock/deployments/58008/.chainId create mode 100644 packages/contracts-bedrock/deployments/84532/.chainId create mode 100644 packages/contracts-bedrock/deployments/919/.chainId create mode 100644 packages/contracts-bedrock/deployments/999999999/.chainId create mode 100644 packages/contracts-bedrock/deployments/optimism-sepolia/.chainId create mode 100644 packages/contracts-bedrock/periphery-deploy-config/4460.json create mode 100644 packages/contracts-bedrock/periphery-deploy-config/58008.json create mode 100644 packages/contracts-bedrock/periphery-deploy-config/84532.json create mode 100644 packages/contracts-bedrock/periphery-deploy-config/901.json create mode 100644 packages/contracts-bedrock/periphery-deploy-config/919.json create mode 100644 packages/contracts-bedrock/periphery-deploy-config/999999999.json create mode 100644 packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json diff --git a/packages/contracts-bedrock/deployments/4460/.chainId b/packages/contracts-bedrock/deployments/4460/.chainId new file mode 100644 index 000000000000..361dd3a2f486 --- /dev/null +++ b/packages/contracts-bedrock/deployments/4460/.chainId @@ -0,0 +1 @@ +4460 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/58008/.chainId b/packages/contracts-bedrock/deployments/58008/.chainId new file mode 100644 index 000000000000..df498f3fb9d4 --- /dev/null +++ b/packages/contracts-bedrock/deployments/58008/.chainId @@ -0,0 +1 @@ +58008 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/84532/.chainId b/packages/contracts-bedrock/deployments/84532/.chainId new file mode 100644 index 000000000000..667f99daf6e6 --- /dev/null +++ b/packages/contracts-bedrock/deployments/84532/.chainId @@ -0,0 +1 @@ +84532 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/919/.chainId b/packages/contracts-bedrock/deployments/919/.chainId new file mode 100644 index 000000000000..8cef75946fe3 --- /dev/null +++ b/packages/contracts-bedrock/deployments/919/.chainId @@ -0,0 +1 @@ +919 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/999999999/.chainId b/packages/contracts-bedrock/deployments/999999999/.chainId new file mode 100644 index 000000000000..d2caa99e0807 --- /dev/null +++ b/packages/contracts-bedrock/deployments/999999999/.chainId @@ -0,0 +1 @@ +999999999 \ No newline at end of file diff --git a/packages/contracts-bedrock/deployments/optimism-sepolia/.chainId b/packages/contracts-bedrock/deployments/optimism-sepolia/.chainId new file mode 100644 index 000000000000..03f37de82513 --- /dev/null +++ b/packages/contracts-bedrock/deployments/optimism-sepolia/.chainId @@ -0,0 +1 @@ +11155420 \ No newline at end of file diff --git a/packages/contracts-bedrock/periphery-deploy-config/4460.json b/packages/contracts-bedrock/periphery-deploy-config/4460.json new file mode 100644 index 000000000000..a429b89f9a69 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/4460.json @@ -0,0 +1,24 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/58008.json b/packages/contracts-bedrock/periphery-deploy-config/58008.json new file mode 100644 index 000000000000..a429b89f9a69 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/58008.json @@ -0,0 +1,24 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/84532.json b/packages/contracts-bedrock/periphery-deploy-config/84532.json new file mode 100644 index 000000000000..a429b89f9a69 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/84532.json @@ -0,0 +1,24 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/901.json b/packages/contracts-bedrock/periphery-deploy-config/901.json new file mode 100644 index 000000000000..a429b89f9a69 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/901.json @@ -0,0 +1,24 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/919.json b/packages/contracts-bedrock/periphery-deploy-config/919.json new file mode 100644 index 000000000000..a429b89f9a69 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/919.json @@ -0,0 +1,24 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/999999999.json b/packages/contracts-bedrock/periphery-deploy-config/999999999.json new file mode 100644 index 000000000000..a429b89f9a69 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/999999999.json @@ -0,0 +1,24 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000 +} diff --git a/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json b/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json new file mode 100644 index 000000000000..a429b89f9a69 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json @@ -0,0 +1,24 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000 +} From 8b964040fba52a310fa4d9f9711ee53b5e02e61a Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 26 Oct 2023 10:38:01 -0600 Subject: [PATCH 039/374] op-bindings: regenerate --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index e7983bf62efd..75570153b367 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:127:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:286;176:23;;;158:42;;146:2;131:18;1710:45:127;;;;;;;;2448:99;;;412:42:286;2534:6:127;400:55:286;382:74;;370:2;355:18;2448:99:127;211:251:286;26025:6379:127;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:286;;;1743:2;1728:18;26025:6379:127;1609:177:286;26025:6379:127;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:127;;-1:-1:-1;28593:7:127;:20::i;:::-;28579:34;-1:-1:-1;28643:10:127;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:127;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:127;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:127;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:127;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:127;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:127:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:127;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:127;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:127:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:286;19164:28:127;;;2164:21:286;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:127;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:127;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:286;14107:30:127;;;2511:21:286;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:127;2327:344:286;14055:97:127;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:127:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:127;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:127;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:127;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:127;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:127;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:127;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:127;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:127;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:127;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:127;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:127;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:127;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:286;37406:29:127;;;2860:21:286;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:127;2676:343:286;37297:157:127;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:127;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:127;;-1:-1:-1;;38164:8:127;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:127;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:127;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:127;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:127;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:127;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:127;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:127;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:127;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:286;20288:41:127;;;3208:21:286;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:127;3024:338:286;20288:41:127;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:127;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:127;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:127:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:127;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:128;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:127;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:286;;;8234:54:127;3601:23:286;;;3581:18;;;3574:51;8203:11:127;;;;8234:19;:6;:19;;;;3513:18:286;;8234:54:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:127;;-1:-1:-1;;;7642:2553:127;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:127;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:127;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:127;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:127;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:127;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:127;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:127;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:127;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:127;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:127;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:127;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:127;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:127;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:127:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:127;25120:9;25084:343;;;-1:-1:-1;;25526:4:127;25519:18;-1:-1:-1;;;;23913:1654:127:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:286;21415:72:127;;;4259:21:286;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:127;4075:399:286;21415:72:127;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:286:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:286;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:286;-1:-1:-1;1349:2:286;1334:18;;1321:32;;-1:-1:-1;1365:16:286;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:286;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:286:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:286;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:286:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:126:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:285;176:23;;;158:42;;146:2;131:18;1710:45:126;;;;;;;;2448:99;;;412:42:285;2534:6:126;400:55:285;382:74;;370:2;355:18;2448:99:126;211:251:285;26025:6379:126;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:285;;;1743:2;1728:18;26025:6379:126;1609:177:285;26025:6379:126;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:126;;-1:-1:-1;28593:7:126;:20::i;:::-;28579:34;-1:-1:-1;28643:10:126;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:126;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:126;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:126;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:126;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:126;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:126:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:126;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:126;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:126:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:285;19164:28:126;;;2164:21:285;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:126;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:126;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:285;14107:30:126;;;2511:21:285;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:126;2327:344:285;14055:97:126;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:126:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:126;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:126;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:126;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:126;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:126;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:126;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:126;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:126;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:126;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:126;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:126;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:126;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:285;37406:29:126;;;2860:21:285;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:126;2676:343:285;37297:157:126;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:126;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:126;;-1:-1:-1;;38164:8:126;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:126;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:126;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:126;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:126;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:126;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:126;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:126;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:126;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:285;20288:41:126;;;3208:21:285;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:126;3024:338:285;20288:41:126;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:126;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:126;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:126:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:126;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:127;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:126;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:285;;;8234:54:126;3601:23:285;;;3581:18;;;3574:51;8203:11:126;;;;8234:19;:6;:19;;;;3513:18:285;;8234:54:126;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:126;;-1:-1:-1;;;7642:2553:126;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:126;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:126;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:126;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:126;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:126;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:126;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:126;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:126;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:126;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:126;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:126;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:126;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:126;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:126:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:126;25120:9;25084:343;;;-1:-1:-1;;25526:4:126;25519:18;-1:-1:-1;;;;23913:1654:126:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:285;21415:72:126;;;4259:21:285;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:126;4075:399:285;21415:72:126;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:285:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:285;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:285;-1:-1:-1;1349:2:285;1334:18;;1321:32;;-1:-1:-1;1365:16:285;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:285;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:285:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:285;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:285:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 54abd4665e9b..87c5194ee3bc 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:129:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:286;;;401:2;386:18;537:68:129;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:286;;607:22;589:41;;577:2;562:18;680:66:129;449:187:286;1367:1211:129;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:286;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:129;1100:248:286;2620:1595:129;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:129;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:129:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:286;906:62:129;;;2890:21:286;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:129;;;;;;;;-1:-1:-1;1099:14:129;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:129;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:129:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:129:o;552:449:128:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:128:o;14:248:286:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:286;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:286:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:286;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:286;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:286;1069:19;1056:33;;-1:-1:-1;641:454:286;-1:-1:-1;641:454:286:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:286;;2017:180;-1:-1:-1;2017:180:286:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:286;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:286;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:128:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:285;;;401:2;386:18;537:68:128;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:285;;607:22;589:41;;577:2;562:18;680:66:128;449:187:285;1367:1211:128;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:285;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:128;1100:248:285;2620:1595:128;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:128;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:128:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:285;906:62:128;;;2890:21:285;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:128;;;;;;;;-1:-1:-1;1099:14:128;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:128;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:128:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:128:o;552:449:127:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:127:o;14:248:285:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:285;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:285:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:285;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:285;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:285;1069:19;1056:33;;-1:-1:-1;641:454:285;-1:-1:-1;641:454:285:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:285;;2017:180;-1:-1:-1;2017:180:285:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:285;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:285;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { From d42577120629dfe167abff9256819a8ec6d2e3e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 16:50:58 +0000 Subject: [PATCH 040/374] build(deps): bump github.com/google/uuid from 1.3.1 to 1.4.0 Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.3.1 to 1.4.0. - [Release notes](https://github.com/google/uuid/releases) - [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) --- updated-dependencies: - dependency-name: github.com/google/uuid dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0c1231d9d041..eb86a741e197 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb github.com/google/go-cmp v0.6.0 github.com/google/gofuzz v1.2.1-0.20220503160820-4a35382e8fc8 - github.com/google/uuid v1.3.1 + github.com/google/uuid v1.4.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru/v2 v2.0.5 github.com/holiman/uint256 v1.2.3 diff --git a/go.sum b/go.sum index bb949ec67bae..84e5b9ca917b 100644 --- a/go.sum +++ b/go.sum @@ -270,8 +270,8 @@ github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0Z github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= From ae67c7ced53630243554b6dbe9515a7eda526d41 Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 11:01:01 -0600 Subject: [PATCH 041/374] Verify Initializer Volues in Contract & Genesis Match - add match check-values-match job that searches using grep - define workflow to verify initializer value matches between contract and genesis --- .circleci/config.yml | 46 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f1e0212e0087..b29b3f3de3e9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1222,6 +1222,46 @@ jobs: name: check-generated-mocks command: make generate-mocks-op-service && git diff --exit-code + check-values-match: + parameters: + pattern_file1: + type: string + default: "uint8 internal constant INITIALIZER =" + pattern_file2: + type: string + default: "const initializedValue =" + file1_path: + type: string + default: "packages/contracts-bedrock/src/libraries/Constants.sol" + file2_path: + type: string + default: "op-chain-ops/genesis/config.go" + + docker: + - image: cimg/base:2020.01 + + steps: + - checkout + - run: + name: Extract value from file1 + command: | + VALUE1=$(grep '<< parameters.pattern_file1 >>' << parameters.file1_path >> | awk -F'=' '{print $2}' | tr -d ' ;') + echo "export VALUE1=$VALUE1" >> $BASH_ENV + - run: + name: Extract value from file2 + command: | + VALUE2=$(grep '<< parameters.pattern_file2 >>' << parameters.file2_path >> | awk -F'=' '{print $2}' | tr -d ' ;') + echo "export VALUE2=$VALUE2" >> $BASH_ENV + - run: + name: Compare values + command: | + if [ "$VALUE1" != "$VALUE2" ]; then + echo "Error: Values from file1 ($VALUE1) and file2 ($VALUE2) don't match." + exit 1 + else + echo "Values match!" + fi + workflows: main: when: @@ -1466,7 +1506,11 @@ workflows: - check-generated-mocks-op-service - cannon-go-lint-and-test - cannon-build-test-vectors - + - check-values-match: + pattern_file1: "uint8 internal constant INITIALIZER =" + pattern_file2: "const initializedValue =" + file1_path: "packages/contracts-bedrock/src/libraries/Constants.sol" + file2_path: "op-chain-ops/genesis/config.go" release: when: not: From 3f41ff95a8b3ed5b25276f85dd46a65f467c415a Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 11:05:06 -0600 Subject: [PATCH 042/374] docker image & fmt --- .circleci/config.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b29b3f3de3e9..09bf97c48270 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1236,10 +1236,8 @@ jobs: file2_path: type: string default: "op-chain-ops/genesis/config.go" - docker: - - image: cimg/base:2020.01 - + - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest steps: - checkout - run: From 93f38e6d3c9435be73726fd2b055595b40914b1c Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 11:08:41 -0600 Subject: [PATCH 043/374] defaults --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 09bf97c48270..0455c533c3d3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1226,16 +1226,16 @@ jobs: parameters: pattern_file1: type: string - default: "uint8 internal constant INITIALIZER =" + default: "" pattern_file2: type: string - default: "const initializedValue =" + default: "" file1_path: type: string - default: "packages/contracts-bedrock/src/libraries/Constants.sol" + default: "" file2_path: type: string - default: "op-chain-ops/genesis/config.go" + default: "" docker: - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest steps: From 03f5fd0c27a410b0b2fc721ea4949a0078b4849b Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 11:41:01 -0600 Subject: [PATCH 044/374] add awk script to ignore single and multi line comments & require only 1 match --- .circleci/config.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0455c533c3d3..2512ef11d3ce 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1240,16 +1240,40 @@ jobs: - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest steps: - checkout + - run: + name: Filter comments and match only 1 script + command: | + SCRIPT=$(cat <<'EOF' + BEGIN { in_comment = 0; matches = 0; } + /^ *\/\*/ { in_comment = 1; } + in_comment && /\*\// { in_comment = 0; next; } + !in_comment && !/^ *\/\// && /PATTERN/ { matches++; matched_line = $0; } + END { + if (matches == 1) { + print matched_line; + } else if (matches > 1) { + print "Multiple matches found. Exiting."; + exit 1; + } else { + print "No matches found. Exiting."; + exit 1; + } + } + EOF + ) + echo "export SCRIPT=$SCRIPT" >> $BASH_ENV - run: name: Extract value from file1 command: | - VALUE1=$(grep '<< parameters.pattern_file1 >>' << parameters.file1_path >> | awk -F'=' '{print $2}' | tr -d ' ;') + VALUE1=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file1 >>' -f- << parameters.file1_path >> | awk -F'=' '{print $2}' | tr -d ' ;') echo "export VALUE1=$VALUE1" >> $BASH_ENV + - run: name: Extract value from file2 command: | - VALUE2=$(grep '<< parameters.pattern_file2 >>' << parameters.file2_path >> | awk -F'=' '{print $2}' | tr -d ' ;') + VALUE2=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file2 >>' -f- << parameters.file2_path >> | awk -F'=' '{print $2}' | tr -d ' ;') echo "export VALUE2=$VALUE2" >> $BASH_ENV + - run: name: Compare values command: | @@ -1260,6 +1284,7 @@ jobs: echo "Values match!" fi + workflows: main: when: From 27009c135f544aeb25b9445df0b4a00d464903b0 Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 11:42:40 -0600 Subject: [PATCH 045/374] indent --- .circleci/config.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2512ef11d3ce..b77c29d41718 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1244,24 +1244,24 @@ jobs: name: Filter comments and match only 1 script command: | SCRIPT=$(cat <<'EOF' - BEGIN { in_comment = 0; matches = 0; } - /^ *\/\*/ { in_comment = 1; } - in_comment && /\*\// { in_comment = 0; next; } - !in_comment && !/^ *\/\// && /PATTERN/ { matches++; matched_line = $0; } - END { - if (matches == 1) { - print matched_line; - } else if (matches > 1) { - print "Multiple matches found. Exiting."; - exit 1; - } else { - print "No matches found. Exiting."; - exit 1; - } - } - EOF - ) - echo "export SCRIPT=$SCRIPT" >> $BASH_ENV + BEGIN { in_comment = 0; matches = 0; } + /^ *\/\*/ { in_comment = 1; } + in_comment && /\*\// { in_comment = 0; next; } + !in_comment && !/^ *\/\// && /PATTERN/ { matches++; matched_line = $0; } + END { + if (matches == 1) { + print matched_line; + } else if (matches > 1) { + print "Multiple matches found. Exiting."; + exit 1; + } else { + print "No matches found. Exiting."; + exit 1; + } + } + EOF + ) + echo "export SCRIPT=$SCRIPT" >> $BASH_ENV - run: name: Extract value from file1 command: | From fb12a4ac4493a4237bdb2102e53e5866d2e97e3e Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 11:48:41 -0600 Subject: [PATCH 046/374] CircleCI didn't like the << in my last script, switching to string literal --- .circleci/config.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b77c29d41718..0b900433ab2d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1243,7 +1243,7 @@ jobs: - run: name: Filter comments and match only 1 script command: | - SCRIPT=$(cat <<'EOF' + AWK_SCRIPT=' BEGIN { in_comment = 0; matches = 0; } /^ *\/\*/ { in_comment = 1; } in_comment && /\*\// { in_comment = 0; next; } @@ -1258,10 +1258,8 @@ jobs: print "No matches found. Exiting."; exit 1; } - } - EOF - ) - echo "export SCRIPT=$SCRIPT" >> $BASH_ENV + }' + echo "export SCRIPT=$AWK_SCRIPT" >> $BASH_ENV - run: name: Extract value from file1 command: | From cd85e3d5a49148cd0217baa89229b154c8a10369 Mon Sep 17 00:00:00 2001 From: Will Cory Date: Wed, 25 Oct 2023 09:40:57 -0700 Subject: [PATCH 047/374] chore: Improve chain-mon docker build --- ops/docker/Dockerfile.packages | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/ops/docker/Dockerfile.packages b/ops/docker/Dockerfile.packages index d84a3726ac35..18bf17ddf270 100644 --- a/ops/docker/Dockerfile.packages +++ b/ops/docker/Dockerfile.packages @@ -79,26 +79,38 @@ RUN git submodule update --init --recursive RUN pnpm build +FROM base as chain-mon +WORKDIR /opt/optimism/packages/chain-mon +ENTRYPOINT ["pnpm", "run"] + +# TODO keeping the rest of these here for now because they are being used +# but we should really delete them we only need one image FROM base as replica-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run", "start:replica-mon"] +ENTRYPOINT ["pnpm", "run"] +CMD ["start:replica-mon"] FROM base as balance-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run", "start:balance-mon"] +ENTRYPOINT ["pnpm", "run"] +CMD ["start:balance-mon"] FROM base as drippie-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run", "start:drippie-mon"] +ENTRYPOINT ["pnpm", "run"] +CMD ["start:drippie-mon"] FROM base as wd-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run", "start:wd-mon"] +ENTRYPOINT ["pnpm", "run"] +CMD ["start:wd-mon"] FROM base as wallet-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run", "start:wallet-mon"] +ENTRYPOINT ["pnpm", "run"] +CMD ["start:wallet-mon"] from base as fault-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run", "start:fault-mon"] +ENTRYPOINT ["pnpm", "run"] +CMD ["start:fault-mon"] From e02becb534145a8c89c5bf5b415aee892044d934 Mon Sep 17 00:00:00 2001 From: Will Cory Date: Thu, 26 Oct 2023 10:49:31 -0700 Subject: [PATCH 048/374] move entrypoint to builder image --- ops/docker/Dockerfile.packages | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ops/docker/Dockerfile.packages b/ops/docker/Dockerfile.packages index 18bf17ddf270..e05febf6081e 100644 --- a/ops/docker/Dockerfile.packages +++ b/ops/docker/Dockerfile.packages @@ -79,38 +79,33 @@ RUN git submodule update --init --recursive RUN pnpm build +ENTRYPOINT ["pnpm", "run"] + FROM base as chain-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run"] # TODO keeping the rest of these here for now because they are being used # but we should really delete them we only need one image FROM base as replica-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run"] CMD ["start:replica-mon"] FROM base as balance-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run"] CMD ["start:balance-mon"] FROM base as drippie-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run"] CMD ["start:drippie-mon"] FROM base as wd-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run"] CMD ["start:wd-mon"] FROM base as wallet-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run"] CMD ["start:wallet-mon"] from base as fault-mon WORKDIR /opt/optimism/packages/chain-mon -ENTRYPOINT ["pnpm", "run"] CMD ["start:fault-mon"] From d64776935f8982cecb87f5e4ec989edf095c8483 Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 11:58:03 -0600 Subject: [PATCH 049/374] quote kind --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0b900433ab2d..225112fc1bb1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1243,7 +1243,7 @@ jobs: - run: name: Filter comments and match only 1 script command: | - AWK_SCRIPT=' + AWK_SCRIPT=" BEGIN { in_comment = 0; matches = 0; } /^ *\/\*/ { in_comment = 1; } in_comment && /\*\// { in_comment = 0; next; } @@ -1258,7 +1258,7 @@ jobs: print "No matches found. Exiting."; exit 1; } - }' + }" echo "export SCRIPT=$AWK_SCRIPT" >> $BASH_ENV - run: name: Extract value from file1 From ef1dfdb00d9a3b494b52aa78102fc5451c560ed7 Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 12:06:10 -0600 Subject: [PATCH 050/374] inline script --- .circleci/config.yml | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 225112fc1bb1..19449a6fe57d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1243,23 +1243,7 @@ jobs: - run: name: Filter comments and match only 1 script command: | - AWK_SCRIPT=" - BEGIN { in_comment = 0; matches = 0; } - /^ *\/\*/ { in_comment = 1; } - in_comment && /\*\// { in_comment = 0; next; } - !in_comment && !/^ *\/\// && /PATTERN/ { matches++; matched_line = $0; } - END { - if (matches == 1) { - print matched_line; - } else if (matches > 1) { - print "Multiple matches found. Exiting."; - exit 1; - } else { - print "No matches found. Exiting."; - exit 1; - } - }" - echo "export SCRIPT=$AWK_SCRIPT" >> $BASH_ENV + SCRIPT='BEGIN { in_comment = 0; matches = 0; } /^ *\/\*/ { in_comment = 1; } in_comment && /\*\// { in_comment = 0; next; } !in_comment && !/^ *\/\// && $0 ~ PATTERN { matches++; matched_line = $0; } END { if (matches == 1) { print matched_line; } else if (matches > 1) { print "Multiple matches found. Exiting."; exit 1; } else { print "No matches found. Exiting."; exit 1; } }' - run: name: Extract value from file1 command: | From b63da6564b344a40060773dad2041ec24b9da369 Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Thu, 26 Oct 2023 11:10:10 -0700 Subject: [PATCH 051/374] op-node: Pull in Canyon Time from superchain registry --- go.mod | 4 ++-- go.sum | 8 ++++---- op-chain-ops/genesis/genesis.go | 6 +++--- op-node/flags/flags.go | 2 +- op-node/rollup/superchain.go | 3 ++- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index eb86a741e197..7b15580851dd 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 - github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231018202221-fdba3d104171 + github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231026175037-2cff0d130e74 github.com/ethereum/go-ethereum v1.13.1 github.com/fsnotify/fsnotify v1.7.0 github.com/go-chi/chi/v5 v5.0.10 @@ -209,7 +209,7 @@ require ( rsc.io/tmplfunc v0.0.3 // indirect ) -replace github.com/ethereum/go-ethereum v1.13.1 => github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024175019-29cd9a353f83 +replace github.com/ethereum/go-ethereum v1.13.1 => github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231026180835-94fbbd04522e //replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain //replace github.com/ethereum/go-ethereum v1.13.1 => ../go-ethereum diff --git a/go.sum b/go.sum index 84e5b9ca917b..87fbcbcfa36f 100644 --- a/go.sum +++ b/go.sum @@ -151,10 +151,10 @@ github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/ github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= -github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024175019-29cd9a353f83 h1:RFKnTUJqbYM8+dueFcGPdOY0ycrOhxp0HQJyy2OYzvc= -github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024175019-29cd9a353f83/go.mod h1:hl28ffXoV4maInP7dvhvNgDO79Q5M3MEYrPZZO6u3W8= -github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231018202221-fdba3d104171 h1:MjCUj16JSLZRDnQQ6OOUy6Chfb4dKo7ahFceNi0RKZ8= -github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231018202221-fdba3d104171/go.mod h1:/70H/KqrtKcvWvNGVj6S3rAcLC+kUPr3t2aDmYIS+Xk= +github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231026180835-94fbbd04522e h1:5ucLyIBCwo07ejZOKFY+6QbCqbLgITHWVqkmLoO6604= +github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231026180835-94fbbd04522e/go.mod h1:m6GrpSyAe1zdFLJlSctgYKSXUdHwj/yfq2WSOc5vs2A= +github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231026175037-2cff0d130e74 h1:02gXBD+Cas7xj9rpkke5wD1+vpfYxyF/+31M5tosP9A= +github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231026175037-2cff0d130e74/go.mod h1:/70H/KqrtKcvWvNGVj6S3rAcLC+kUPr3t2aDmYIS+Xk= github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg= github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= diff --git a/op-chain-ops/genesis/genesis.go b/op-chain-ops/genesis/genesis.go index 7a4df6b1ad49..c4aef7d94317 100644 --- a/op-chain-ops/genesis/genesis.go +++ b/op-chain-ops/genesis/genesis.go @@ -65,9 +65,9 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro CanyonTime: config.CanyonTime(block.Time()), ShanghaiTime: config.CanyonTime(block.Time()), Optimism: ¶ms.OptimismConfig{ - EIP1559Denominator: eip1559Denom, - EIP1559Elasticity: eip1559Elasticity, - EIP1559DenominatorPostCanyon: eip1559DenomCanyon, + EIP1559Denominator: eip1559Denom, + EIP1559Elasticity: eip1559Elasticity, + EIP1559DenominatorCanyon: eip1559DenomCanyon, }, } diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go index 6c5b2fe78f31..8f0247949137 100644 --- a/op-node/flags/flags.go +++ b/op-node/flags/flags.go @@ -256,7 +256,7 @@ var ( CanyonOverrideFlag = &cli.Uint64Flag{ Name: "override.canyon", Usage: "Manually specify the Canyon fork timestamp, overriding the bundled setting", - Hidden: true, + Hidden: false, } ) diff --git a/op-node/rollup/superchain.go b/op-node/rollup/superchain.go index 2235a0051e86..88d802f5cf13 100644 --- a/op-node/rollup/superchain.go +++ b/op-node/rollup/superchain.go @@ -12,7 +12,7 @@ import ( "github.com/ethereum-optimism/superchain-registry/superchain" ) -var OPStackSupport = params.ProtocolVersionV0{Build: [8]byte{}, Major: 3, Minor: 1, Patch: 0, PreRelease: 1}.Encode() +var OPStackSupport = params.ProtocolVersionV0{Build: [8]byte{}, Major: 4, Minor: 0, Patch: 0, PreRelease: 1}.Encode() const ( opMainnet = 10 @@ -98,6 +98,7 @@ func LoadOPStackRollupConfig(chainID uint64) (*Config, error) { L1ChainID: new(big.Int).SetUint64(superChain.Config.L1.ChainID), L2ChainID: new(big.Int).SetUint64(chConfig.ChainID), RegolithTime: ®olithTime, + CanyonTime: superChain.Config.CanyonTime, BatchInboxAddress: common.Address(chConfig.BatchInboxAddr), DepositContractAddress: depositContractAddress, L1SystemConfigAddress: common.Address(chConfig.SystemConfigAddr), From fafcb05e4256d8161b6c7d4f53b9cc7782f825eb Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 12:10:16 -0600 Subject: [PATCH 052/374] export script to bash env --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 19449a6fe57d..c40cafe92761 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1244,6 +1244,7 @@ jobs: name: Filter comments and match only 1 script command: | SCRIPT='BEGIN { in_comment = 0; matches = 0; } /^ *\/\*/ { in_comment = 1; } in_comment && /\*\// { in_comment = 0; next; } !in_comment && !/^ *\/\// && $0 ~ PATTERN { matches++; matched_line = $0; } END { if (matches == 1) { print matched_line; } else if (matches > 1) { print "Multiple matches found. Exiting."; exit 1; } else { print "No matches found. Exiting."; exit 1; } }' + echo "export SCRIPT='$SCRIPT'" >> $BASH_ENV - run: name: Extract value from file1 command: | From b5914297b38121c36eab686f80ab70d302be3c2c Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 12:31:46 -0600 Subject: [PATCH 053/374] handle awk error --- .circleci/config.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c40cafe92761..184a4acf1146 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1248,13 +1248,29 @@ jobs: - run: name: Extract value from file1 command: | - VALUE1=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file1 >>' -f- << parameters.file1_path >> | awk -F'=' '{print $2}' | tr -d ' ;') + VALUE1_MATCH=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file1 >>' -f- "<< parameters.file1_path >>") + + if [ $? -ne 0 ]; then + exit 1 + fi + VALUE1=$(echo "$VALUE1_MATCH" | awk -F'=' '{print $2}' | tr -d ' ;') + echo "Value:" + echo "$VALUE1" echo "export VALUE1=$VALUE1" >> $BASH_ENV - run: name: Extract value from file2 command: | VALUE2=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file2 >>' -f- << parameters.file2_path >> | awk -F'=' '{print $2}' | tr -d ' ;') + VALUE2_MATCH=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file2 >>' -f- "<< parameters.file2_path >>") + + if [ $? -ne 0 ]; then + exit 1 + fi + + VALUE2=$(echo "$VALUE2_MATCH" | awk -F'=' '{print $2}' | tr -d ' ;') + echo "Value:" + echo "$VALUE2" echo "export VALUE2=$VALUE2" >> $BASH_ENV - run: From ed4a4868acaf670a7464083d9d73eedbd5511327 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 05:02:38 +1000 Subject: [PATCH 054/374] ci: Add filters so op-stack-go-docker-build-release builds on tags. --- .circleci/config.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 747de52041a4..72fec84fe746 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1488,6 +1488,11 @@ workflows: ignore: /.*/ - docker-build: # just to warm up the cache (other jobs run in parallel) name: op-stack-go-docker-build-release + filters: + tags: + only: /^(proxyd|indexer|ci-builder|ufm-[a-z0-9\-]*|op-[a-z0-9\-]*)\/v.*/ + branches: + ignore: /.*/ docker_name: op-stack-go docker_tags: <> platforms: "linux/amd64,linux/arm64" From af5ad1d2aa6f1a9aa29b1a8fe93989b1104d0ca8 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 25 Oct 2023 20:15:49 -0600 Subject: [PATCH 055/374] contracts-bedrock: fix test legibility Adds a new helper library called `EIP1967Helper` that can get the admin and impl storage slots from a `Proxy` implementing ERC1967. This is more helpful to use than hardcoded magic values such as `multisig` because it is not clear who the multisig is since its value is assigned in a different file. We want to decouple the value from a magic value and set it to exactly what we want it to be which is the admin. This will work in all cases no matter what the admin is since it dynamically pulls the value from storage for the tests. --- packages/contracts-bedrock/.gas-snapshot | 2 +- packages/contracts-bedrock/test/CommonTest.t.sol | 13 +++++++++++++ .../contracts-bedrock/test/L2OutputOracle.t.sol | 4 ++-- .../test/invariants/OptimismPortal.t.sol | 13 +++++++------ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index ac878dee55d9..5b6747f72e62 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -249,7 +249,7 @@ L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 23902) L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 46800) L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 15216) L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 20216) -L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 191455) +L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 187875) L2OutputOracle_constructor_Test:test_constructor_l2BlockTimeZero_reverts() (gas: 39022) L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 39032) L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 51777) diff --git a/packages/contracts-bedrock/test/CommonTest.t.sol b/packages/contracts-bedrock/test/CommonTest.t.sol index 56c9ded975e2..a3a64b6d9b22 100644 --- a/packages/contracts-bedrock/test/CommonTest.t.sol +++ b/packages/contracts-bedrock/test/CommonTest.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { Test, StdUtils } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; @@ -731,6 +732,18 @@ contract FFIInterface is Test { } } +library EIP1967Helper { + Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + function getAdmin(address _proxy) internal view returns (address) { + return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_OWNER_ADDRESS)))); + } + + function getImplementation(address _proxy) internal view returns (address) { + return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_IMPLEMENTATION_ADDRESS)))); + } +} + // Used for testing a future upgrade beyond the current implementations. // We include some variables so that we can sanity check accessing storage values after an upgrade. contract NextImpl is Initializable { diff --git a/packages/contracts-bedrock/test/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/L2OutputOracle.t.sol index 623fc7aa224c..52b87b450aa8 100644 --- a/packages/contracts-bedrock/test/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/L2OutputOracle.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { stdError } from "forge-std/Test.sol"; -import { L2OutputOracle_Initializer, NextImpl } from "test/CommonTest.t.sol"; +import { L2OutputOracle_Initializer, NextImpl, EIP1967Helper } from "test/CommonTest.t.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; @@ -463,7 +463,7 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { assertEq(bytes32(0), slot21Before); NextImpl nextImpl = new NextImpl(); - vm.startPrank(multisig); + vm.startPrank(EIP1967Helper.getAdmin(address(proxy))); proxy.upgradeToAndCall( address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, Constants.INITIALIZER + 1) ); diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol index f0ac1e197843..af38e6536bb8 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol @@ -12,6 +12,7 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Portal_Initializer } from "test/CommonTest.t.sol"; +import { EIP1967Helper } from "test/CommonTest.t.sol"; import { Types } from "src/libraries/Types.sol"; contract OptimismPortal_Depositor is StdUtils, ResourceMetering { @@ -158,8 +159,8 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness { // Set the target contract to the portal proxy targetContract(address(op)); - // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded - excludeSender(address(multisig)); + // Exclude the proxy admin from the senders so that the proxy cannot be upgraded + excludeSender(EIP1967Helper.getAdmin(address(op))); } /// @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization @@ -188,8 +189,8 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness // Set the target contract to the portal proxy targetContract(address(op)); - // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded - excludeSender(address(multisig)); + // Exclude the proxy admin from the senders so that the proxy cannot be upgraded + excludeSender(EIP1967Helper.getAdmin(address(op))); } /// @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal @@ -215,8 +216,8 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant // Set the target contract to the portal proxy targetContract(address(op)); - // Exclude the proxy multisig from the senders so that the proxy cannot be upgraded - excludeSender(address(multisig)); + // Exclude the proxy admin from the senders so that the proxy cannot be upgraded + excludeSender(EIP1967Helper.getAdmin(address(op))); } /// @custom:invariant A withdrawal should **always** be able to be finalized From 78c6c7f32b5f82dc3131583d6773d84e08b7e91e Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 26 Oct 2023 08:57:21 -0600 Subject: [PATCH 056/374] invariant-docs: regenerate --- .../contracts-bedrock/invariant-docs/OptimismPortal.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md index d9f5bf7d8a97..c13d0212128d 100644 --- a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md +++ b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md @@ -1,21 +1,21 @@ # `OptimismPortal` Invariants ## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. -**Test:** [`OptimismPortal.t.sol#L147`](../test/invariants/OptimismPortal.t.sol#L147) +**Test:** [`OptimismPortal.t.sol#L148`](../test/invariants/OptimismPortal.t.sol#L148) All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. ## `finalizeWithdrawalTransaction` should revert if the finalization period has not elapsed. -**Test:** [`OptimismPortal.t.sol#L170`](../test/invariants/OptimismPortal.t.sol#L170) +**Test:** [`OptimismPortal.t.sol#L171`](../test/invariants/OptimismPortal.t.sol#L171) A withdrawal that has been proven should not be able to be finalized until after the finalization period has elapsed. ## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. -**Test:** [`OptimismPortal.t.sol#L200`](../test/invariants/OptimismPortal.t.sol#L200) +**Test:** [`OptimismPortal.t.sol#L201`](../test/invariants/OptimismPortal.t.sol#L201) Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice. ## A withdrawal should **always** be able to be finalized `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. -**Test:** [`OptimismPortal.t.sol#L229`](../test/invariants/OptimismPortal.t.sol#L229) +**Test:** [`OptimismPortal.t.sol#L230`](../test/invariants/OptimismPortal.t.sol#L230) This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. \ No newline at end of file From 43f9f7ae24ff734a2ab4e0c034129d5df477020e Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 26 Oct 2023 13:52:50 -0600 Subject: [PATCH 057/374] contracts-bedrock: gas snapshot --- packages/contracts-bedrock/.gas-snapshot | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 5b6747f72e62..449fd2dcba8c 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -49,7 +49,6 @@ CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34883) DelayedVetoable_Getters_Test:test_getters() (gas: 24466) DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 36220) DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 21867) -DeleteOutput:test_script_succeeds() (gas: 3100) DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582) DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395) DisputeGameFactory_Owner_Test:test_owner_succeeds() (gas: 12581) @@ -77,7 +76,6 @@ Drippie_Test:test_status_unauthorized_reverts() (gas: 167388) Drippie_Test:test_trigger_oneFunction_succeeds() (gas: 338226) Drippie_Test:test_trigger_twoFunctions_succeeds() (gas: 491907) Drippie_Test:test_twice_inOneInterval_reverts() (gas: 303933) -EASUpgrader:test_script_succeeds() (gas: 3078) FaucetTest:test_authAdmin_drip_succeeds() (gas: 366107) FaucetTest:test_drip_afterTimeout_succeeds() (gas: 447891) FaucetTest:test_drip_beforeTimeout_reverts() (gas: 378884) From 16b0527c6cbaf79e5e7a761a39a6aa91bd31e3fe Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 12:56:43 -0600 Subject: [PATCH 058/374] remove old line --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 184a4acf1146..9288400aa475 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1261,7 +1261,6 @@ jobs: - run: name: Extract value from file2 command: | - VALUE2=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file2 >>' -f- << parameters.file2_path >> | awk -F'=' '{print $2}' | tr -d ' ;') VALUE2_MATCH=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file2 >>' -f- "<< parameters.file2_path >>") if [ $? -ne 0 ]; then From e65c212241e89d9a3a5266df83fdfac40dbbee30 Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 12:57:20 -0600 Subject: [PATCH 059/374] format --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9288400aa475..d87803690962 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1249,10 +1249,10 @@ jobs: name: Extract value from file1 command: | VALUE1_MATCH=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file1 >>' -f- "<< parameters.file1_path >>") - if [ $? -ne 0 ]; then exit 1 fi + VALUE1=$(echo "$VALUE1_MATCH" | awk -F'=' '{print $2}' | tr -d ' ;') echo "Value:" echo "$VALUE1" @@ -1262,7 +1262,6 @@ jobs: name: Extract value from file2 command: | VALUE2_MATCH=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file2 >>' -f- "<< parameters.file2_path >>") - if [ $? -ne 0 ]; then exit 1 fi From 5821f294912ba44b172943e34924f27f171089b2 Mon Sep 17 00:00:00 2001 From: Tushar Shah Date: Thu, 26 Oct 2023 13:31:10 -0600 Subject: [PATCH 060/374] Move value match and check logic to script --- .circleci/config.yml | 42 +-------------- ops/scripts/ci-match-values-between-files.sh | 57 ++++++++++++++++++++ 2 files changed, 59 insertions(+), 40 deletions(-) create mode 100755 ops/scripts/ci-match-values-between-files.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index d87803690962..087a296f38f9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1241,47 +1241,9 @@ jobs: steps: - checkout - run: - name: Filter comments and match only 1 script + name: Verify Values Match command: | - SCRIPT='BEGIN { in_comment = 0; matches = 0; } /^ *\/\*/ { in_comment = 1; } in_comment && /\*\// { in_comment = 0; next; } !in_comment && !/^ *\/\// && $0 ~ PATTERN { matches++; matched_line = $0; } END { if (matches == 1) { print matched_line; } else if (matches > 1) { print "Multiple matches found. Exiting."; exit 1; } else { print "No matches found. Exiting."; exit 1; } }' - echo "export SCRIPT='$SCRIPT'" >> $BASH_ENV - - run: - name: Extract value from file1 - command: | - VALUE1_MATCH=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file1 >>' -f- "<< parameters.file1_path >>") - if [ $? -ne 0 ]; then - exit 1 - fi - - VALUE1=$(echo "$VALUE1_MATCH" | awk -F'=' '{print $2}' | tr -d ' ;') - echo "Value:" - echo "$VALUE1" - echo "export VALUE1=$VALUE1" >> $BASH_ENV - - - run: - name: Extract value from file2 - command: | - VALUE2_MATCH=$(echo "$SCRIPT" | awk -v PATTERN='<< parameters.pattern_file2 >>' -f- "<< parameters.file2_path >>") - if [ $? -ne 0 ]; then - exit 1 - fi - - VALUE2=$(echo "$VALUE2_MATCH" | awk -F'=' '{print $2}' | tr -d ' ;') - echo "Value:" - echo "$VALUE2" - echo "export VALUE2=$VALUE2" >> $BASH_ENV - - - run: - name: Compare values - command: | - if [ "$VALUE1" != "$VALUE2" ]; then - echo "Error: Values from file1 ($VALUE1) and file2 ($VALUE2) don't match." - exit 1 - else - echo "Values match!" - fi - - + ./ops/scripts/ci-match-values-between-files.sh "<< parameters.file1_path >>" "<< parameters.pattern_file1 >>" "<< parameters.file2_path >>" "<< parameters.pattern_file2 >>" workflows: main: when: diff --git a/ops/scripts/ci-match-values-between-files.sh b/ops/scripts/ci-match-values-between-files.sh new file mode 100755 index 000000000000..53d680cd3197 --- /dev/null +++ b/ops/scripts/ci-match-values-between-files.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +set -euo pipefail + +FILE1=$1 +PATTERN1=$2 +FILE2=$3 +PATTERN2=$4 + +# shellcheck disable=SC2016 +SCRIPT=' +BEGIN { + in_comment = 0; + matches = 0; +} + +/^ *\/\*/ { + in_comment = 1; +} + +in_comment && /\*\// { + in_comment = 0; + next; +} + +!in_comment && !/^ *\/\// && $0 ~ PATTERN { + matches++; + matched_line = $0; +} + +END { + if (matches == 1) { + print matched_line; + } else if (matches > 1) { + print "Multiple matches found. Exiting."; + exit 1; + } else { + print "No matches found. Exiting."; + exit 1; + } +}' + +VALUE1_MATCH=$(echo "$SCRIPT" | awk -v PATTERN="$PATTERN1" -f- "$FILE1") +VALUE1=$(echo "$VALUE1_MATCH" | awk -F'=' '{print $2}' | tr -d ' ;') +echo "Value from File 1: $VALUE1" + +VALUE2_MATCH=$(echo "$SCRIPT" | awk -v PATTERN="$PATTERN2" -f- "$FILE2") +VALUE2=$(echo "$VALUE2_MATCH" | awk -F'=' '{print $2}' | tr -d ' ;') +echo "Value from File 2: $VALUE2" + +if [ "$VALUE1" != "$VALUE2" ]; then + echo "Error: Values from file1 ($VALUE1) and file2 ($VALUE2) don't match." + exit 1 +fi + +echo "Values match!" + From 31d1b6f59645f988246b0be06897e1fca4f0ab82 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 06:03:05 +1000 Subject: [PATCH 061/374] ci: Use pipeline.git.tag not pipeline.git.branch when doing releases. --- .circleci/config.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 72fec84fe746..9afdb33a19b9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1506,7 +1506,7 @@ workflows: branches: ignore: /.*/ docker_name: op-heartbeat - docker_tags: <>,<> + docker_tags: <>,<> requires: ['op-stack-go-docker-build-release'] platforms: "linux/amd64,linux/arm64" publish: true @@ -1521,7 +1521,7 @@ workflows: branches: ignore: /.*/ docker_name: op-node - docker_tags: <>,<> + docker_tags: <>,<> requires: ['op-stack-go-docker-build-release'] platforms: "linux/amd64,linux/arm64" publish: true @@ -1536,7 +1536,7 @@ workflows: branches: ignore: /.*/ docker_name: op-batcher - docker_tags: <>,<> + docker_tags: <>,<> requires: ['op-stack-go-docker-build-release'] platforms: "linux/amd64,linux/arm64" publish: true @@ -1551,7 +1551,7 @@ workflows: branches: ignore: /.*/ docker_name: op-proposer - docker_tags: <>,<> + docker_tags: <>,<> requires: ['op-stack-go-docker-build-release'] platforms: "linux/amd64,linux/arm64" publish: true @@ -1566,7 +1566,7 @@ workflows: branches: ignore: /.*/ docker_name: op-challenger - docker_tags: <>,<> + docker_tags: <>,<> requires: ['op-stack-go-docker-build-release'] platforms: "linux/amd64,linux/arm64" publish: true @@ -1581,7 +1581,7 @@ workflows: branches: ignore: /.*/ docker_name: op-ufm - docker_tags: <>,<> + docker_tags: <>,<> publish: true release: true context: @@ -1596,7 +1596,7 @@ workflows: branches: ignore: /.*/ docker_name: proxyd - docker_tags: <>,<> + docker_tags: <>,<> publish: true release: true context: @@ -1611,7 +1611,7 @@ workflows: branches: ignore: /.*/ docker_name: indexer - docker_tags: <>,<> + docker_tags: <>,<> publish: true release: true context: From fdc2193e25791eaf06284f26bb6634c09a4365fc Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 06:55:24 +1000 Subject: [PATCH 062/374] op-e2e: Disable cannon tests when using HTTP instead of WS Fault dispute tests take longer to execute when polling with HTTP so disable the longer running cannon tests on HTTP. Cannon itself is unaffected by the connection type and the challenger is tested with HTTP via the alphabet game tests. --- op-e2e/faultproof_test.go | 14 +++++++------- op-e2e/helper.go | 11 ++++++++++- op-e2e/op_geth.go | 2 +- op-e2e/setup.go | 10 ++++++---- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/op-e2e/faultproof_test.go b/op-e2e/faultproof_test.go index cd38f67af8e3..a191532139d6 100644 --- a/op-e2e/faultproof_test.go +++ b/op-e2e/faultproof_test.go @@ -18,7 +18,7 @@ import ( ) func TestMultipleCannonGames(t *testing.T) { - InitParallel(t) + InitParallel(t, SkipIfHTTP) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -78,7 +78,7 @@ func TestMultipleCannonGames(t *testing.T) { } func TestMultipleGameTypes(t *testing.T) { - InitParallel(t) + InitParallel(t, SkipIfHTTP) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -277,7 +277,7 @@ func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { } func TestCannonDisputeGame(t *testing.T) { - InitParallel(t) + InitParallel(t, SkipIfHTTP) tests := []struct { name string @@ -328,7 +328,7 @@ func TestCannonDisputeGame(t *testing.T) { } func TestCannonDefendStep(t *testing.T) { - InitParallel(t) + InitParallel(t, SkipIfHTTP) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -370,7 +370,7 @@ func TestCannonDefendStep(t *testing.T) { } func TestCannonProposedOutputRootInvalid(t *testing.T) { - InitParallel(t) + InitParallel(t, SkipIfHTTP) // honestStepsFail attempts to perform both an attack and defend step using the correct trace. honestStepsFail := func(ctx context.Context, game *disputegame.CannonGameHelper, correctTrace *disputegame.HonestHelper, parentClaimIdx int64) { // Attack step should fail @@ -448,7 +448,7 @@ func TestCannonProposedOutputRootInvalid(t *testing.T) { } func TestCannonPoisonedPostState(t *testing.T) { - InitParallel(t) + InitParallel(t, SkipIfHTTP) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -558,7 +558,7 @@ func setupDisputeGameForInvalidOutputRoot(t *testing.T, outputRoot common.Hash) } func TestCannonChallengeWithCorrectRoot(t *testing.T) { - InitParallel(t) + InitParallel(t, SkipIfHTTP) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) diff --git a/op-e2e/helper.go b/op-e2e/helper.go index 04f5a4c0feac..eafeeb576e31 100644 --- a/op-e2e/helper.go +++ b/op-e2e/helper.go @@ -7,9 +7,18 @@ import ( var enableParallelTesting bool = os.Getenv("OP_E2E_DISABLE_PARALLEL") != "true" -func InitParallel(t *testing.T) { +func InitParallel(t *testing.T, opts ...func(t *testing.T)) { t.Helper() if enableParallelTesting { t.Parallel() } + for _, opt := range opts { + opt(t) + } +} + +func SkipIfHTTP(t *testing.T) { + if UseHTTP() { + t.Skip("Skipping test because HTTP connection is in use") + } } diff --git a/op-e2e/op_geth.go b/op-e2e/op_geth.go index 8a1bf8bbbe61..6b7eef31b48b 100644 --- a/op-e2e/op_geth.go +++ b/op-e2e/op_geth.go @@ -102,7 +102,7 @@ func NewOpGeth(t *testing.T, ctx context.Context, cfg *SystemConfig) (*OpGeth, e ) require.Nil(t, err) - l2Client, err := ethclient.Dial(node.HTTPEndpoint()) + l2Client, err := ethclient.Dial(selectEndpoint(node)) require.Nil(t, err) genesisPayload, err := eth.BlockAsPayload(l2GenesisBlock, cfg.DeployConfig.CanyonTime(l2GenesisBlock.Time())) diff --git a/op-e2e/setup.go b/op-e2e/setup.go index fe70a263985e..6f65a2b51916 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -758,9 +758,12 @@ func (sys *System) newMockNetPeer() (host.Host, error) { return sys.Mocknet.AddPeerWithPeerstore(p, eps) } +func UseHTTP() bool { + return os.Getenv("OP_E2E_USE_HTTP") == "true" +} + func selectEndpoint(node EthInstance) string { - useHTTP := os.Getenv("OP_E2E_USE_HTTP") == "true" - if useHTTP { + if UseHTTP() { log.Info("using HTTP client") return node.HTTPEndpoint() } @@ -785,9 +788,8 @@ type WSOrHTTPEndpoint interface { } func configureL2(rollupNodeCfg *rollupNode.Config, l2Node WSOrHTTPEndpoint, jwtSecret [32]byte) { - useHTTP := os.Getenv("OP_E2E_USE_HTTP") == "true" l2EndpointConfig := l2Node.WSAuthEndpoint() - if useHTTP { + if UseHTTP() { l2EndpointConfig = l2Node.HTTPAuthEndpoint() } From 8ec6427a3a9c09f3c0a2c90130ebf66c6ff7bef9 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 08:32:06 +1000 Subject: [PATCH 063/374] ci: Configure docker auth before attempting to publish. --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9afdb33a19b9..82bc88eb0f06 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -231,6 +231,7 @@ jobs: DOCKER_OUTPUT_DESTINATION="" if [ "<>" == "true" ]; then + gcloud auth configure-docker <> echo "Building for platforms $PLATFORMS and then publishing to registry" DOCKER_OUTPUT_DESTINATION="--push" if [ "<>" != "" ]; then From ab6d0be9c16c6af2042ee6f75895f960eb00f8b7 Mon Sep 17 00:00:00 2001 From: Kevin Kz Date: Thu, 26 Oct 2023 16:47:05 -0600 Subject: [PATCH 064/374] Specify that the recognized batch submitter account is stored in the System Configuration. --- specs/glossary.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/specs/glossary.md b/specs/glossary.md index cb96c8922e07..fc954bc5534f 100644 --- a/specs/glossary.md +++ b/specs/glossary.md @@ -471,9 +471,8 @@ channels available. These transactions carry one or more full frames, which may channel's frame may be split between multiple batcher transactions. When submitted to Ethereum calldata, the batcher transaction's receiver must be the sequencer inbox address. The -transaction must also be signed by a recognized batch submitter account. - -> **TODO** specify where these recognized batch submitter accounts are stored +transaction must also be signed by a recognized batch submitter account. The recognized batch submitter account +is stored in the [System Configuration][system-config]. ## Channel Timeout From ef2ceff26c5b81d8b325a34fabc4100cf7f1cd5f Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 08:53:17 +1000 Subject: [PATCH 065/374] ci: Allow . and / in docker tags. Remove the publish step because all tags are added by the docker buildx step already. --- .circleci/config.yml | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 82bc88eb0f06..118113b542a3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -218,7 +218,7 @@ jobs: export REGISTRY="<>" export REPOSITORY="<>" - export IMAGE_TAGS="$(echo -ne "<>" | sed "s/[^a-zA-Z0-9\n,]/-/g")" + export IMAGE_TAGS="$(echo -ne "<>" | sed "s/[^a-zA-Z0-9\n,./]/-/g")" export GIT_COMMIT="$(git rev-parse HEAD)" export GIT_DATE="$(git show -s --format='%ct')" export GIT_VERSION="<>" @@ -272,20 +272,6 @@ jobs: root: /tmp/docker_images paths: # only write the one file, to avoid concurrent workspace-file additions - "<>.tar" - - when: - condition: "<>" - steps: - - run: - name: Publish - command: | - gcloud auth configure-docker <> - IMAGE_BASE="<>/<>/<>" - # tags, without the '-t ' here, so we can loop over them - DOCKER_TAGS="$(echo -ne "<>" | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g" | sed -e "s|^|${IMAGE_BASE}:|")" - for docker_image_tag in $DOCKER_TAGS; do - docker image push $docker_image_tag - done - no_output_timeout: 45m - when: condition: "<>" steps: From 6a7360bc6dd3fb86be7c641bc7803212e4ca5b03 Mon Sep 17 00:00:00 2001 From: Zach Howard Date: Thu, 26 Oct 2023 18:55:56 -0400 Subject: [PATCH 066/374] Fixes docker-bake build targets for ci-builder and chain-mon --- docker-bake.hcl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-bake.hcl b/docker-bake.hcl index afdc5996d25c..d808f751b273 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -158,7 +158,7 @@ target "ufm-metamask" { tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/ufm-metamask:${tag}"] } -type "chain-mon" { +target "chain-mon" { dockerfile = "./ops/docker/Dockerfile.packages" context = "." args = { @@ -173,9 +173,9 @@ type "chain-mon" { tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/chain-mon:${tag}"] } -type "ci-builder" { - dockerfile = "Dockerfile" - context = "ops/docker/ci-builder" +target "ci-builder" { + dockerfile = "./ops/docker/ci-builder/Dockerfile" + context = "." platforms = split(",", PLATFORMS) tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/ci-builder:${tag}"] } From 485f9c659164b0c3906f9683d9e2748b646c5ebc Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 08:59:11 +1000 Subject: [PATCH 067/374] ci: Disallow . and / in docker tags again. Remove the git tag from the release tags to add and allow the release script to add it instead. --- .circleci/config.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 118113b542a3..e9b5021d5aa7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -218,7 +218,7 @@ jobs: export REGISTRY="<>" export REPOSITORY="<>" - export IMAGE_TAGS="$(echo -ne "<>" | sed "s/[^a-zA-Z0-9\n,./]/-/g")" + export IMAGE_TAGS="$(echo -ne "<>" | sed "s/[^a-zA-Z0-9\n,]/-/g")" export GIT_COMMIT="$(git rev-parse HEAD)" export GIT_DATE="$(git show -s --format='%ct')" export GIT_VERSION="<>" @@ -1493,7 +1493,7 @@ workflows: branches: ignore: /.*/ docker_name: op-heartbeat - docker_tags: <>,<> + docker_tags: <> requires: ['op-stack-go-docker-build-release'] platforms: "linux/amd64,linux/arm64" publish: true @@ -1508,7 +1508,7 @@ workflows: branches: ignore: /.*/ docker_name: op-node - docker_tags: <>,<> + docker_tags: <> requires: ['op-stack-go-docker-build-release'] platforms: "linux/amd64,linux/arm64" publish: true @@ -1523,7 +1523,7 @@ workflows: branches: ignore: /.*/ docker_name: op-batcher - docker_tags: <>,<> + docker_tags: <> requires: ['op-stack-go-docker-build-release'] platforms: "linux/amd64,linux/arm64" publish: true @@ -1538,7 +1538,7 @@ workflows: branches: ignore: /.*/ docker_name: op-proposer - docker_tags: <>,<> + docker_tags: <> requires: ['op-stack-go-docker-build-release'] platforms: "linux/amd64,linux/arm64" publish: true @@ -1553,7 +1553,7 @@ workflows: branches: ignore: /.*/ docker_name: op-challenger - docker_tags: <>,<> + docker_tags: <> requires: ['op-stack-go-docker-build-release'] platforms: "linux/amd64,linux/arm64" publish: true @@ -1568,7 +1568,7 @@ workflows: branches: ignore: /.*/ docker_name: op-ufm - docker_tags: <>,<> + docker_tags: <> publish: true release: true context: @@ -1583,7 +1583,7 @@ workflows: branches: ignore: /.*/ docker_name: proxyd - docker_tags: <>,<> + docker_tags: <> publish: true release: true context: @@ -1598,7 +1598,7 @@ workflows: branches: ignore: /.*/ docker_name: indexer - docker_tags: <>,<> + docker_tags: <> publish: true release: true context: From b62235a3365968409a0b0b0dbea68a8229948d25 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 09:23:57 +1000 Subject: [PATCH 068/374] op-e2e: Use a short wait for new claim when performing all possible dishonest moves. The timeout is expected to be reached sometimes because the challenger has chosen not to respond, so we don't want the default long timeout. --- op-e2e/e2eutils/disputegame/dishonest_helper.go | 5 ++++- op-e2e/e2eutils/disputegame/game_helper.go | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/op-e2e/e2eutils/disputegame/dishonest_helper.go b/op-e2e/e2eutils/disputegame/dishonest_helper.go index fde8b817843e..6b6f1912c18e 100644 --- a/op-e2e/e2eutils/disputegame/dishonest_helper.go +++ b/op-e2e/e2eutils/disputegame/dishonest_helper.go @@ -3,6 +3,7 @@ package disputegame import ( "context" "errors" + "time" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum/go-ethereum/common" @@ -96,7 +97,9 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context) { var numClaimsSeen int64 for { - newCount, err := d.WaitForNewClaim(ctx, numClaimsSeen) + // Use a short timeout since we don't know the challenger will respond, + // and this is only designed for the alphabet game where the response should be fast. + newCount, err := d.waitForNewClaim(ctx, numClaimsSeen, 30*time.Second) if errors.Is(err, context.DeadlineExceeded) { // we assume that the honest challenger has stopped responding // There's nothing to respond to. diff --git a/op-e2e/e2eutils/disputegame/game_helper.go b/op-e2e/e2eutils/disputegame/game_helper.go index 5563d437fc59..6ce31f2f9c76 100644 --- a/op-e2e/e2eutils/disputegame/game_helper.go +++ b/op-e2e/e2eutils/disputegame/game_helper.go @@ -304,7 +304,10 @@ func (g *FaultGameHelper) ChallengeRootClaim(ctx context.Context, performMove Mo } func (g *FaultGameHelper) WaitForNewClaim(ctx context.Context, checkPoint int64) (int64, error) { - timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) + return g.waitForNewClaim(ctx, checkPoint, defaultTimeout) +} +func (g *FaultGameHelper) waitForNewClaim(ctx context.Context, checkPoint int64, timeout time.Duration) (int64, error) { + timedCtx, cancel := context.WithTimeout(ctx, timeout) defer cancel() var newClaimLen int64 err := wait.For(timedCtx, time.Second, func() (bool, error) { From 40858b5a39819cce8bf9e7962fd510cd76a6d678 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 10:09:04 +1000 Subject: [PATCH 069/374] op-e2e: Fix race condition with removing included tx from the pool The tx pool updates async, so the list of pending transactions may contain transactions included in a block if the tx pool update hasn't completed. Filter any transactions with nonces that are too low to avoid this race condition. --- op-e2e/actions/l1_miner.go | 23 ++++------------- op-e2e/actions/l2_engine.go | 21 ++-------------- op-e2e/actions/tx_helper.go | 49 +++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 37 deletions(-) create mode 100644 op-e2e/actions/tx_helper.go diff --git a/op-e2e/actions/l1_miner.go b/op-e2e/actions/l1_miner.go index 812d35dfb3f9..8ba3ee857b67 100644 --- a/op-e2e/actions/l1_miner.go +++ b/op-e2e/actions/l1_miner.go @@ -1,11 +1,8 @@ package actions import ( - "context" "math/big" - "time" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core" @@ -98,22 +95,12 @@ func (s *L1Miner) ActL1IncludeTx(from common.Address) Action { t.InvalidAction("no tx inclusion when not building l1 block") return } - var i uint64 - var txs []*types.Transaction - var q []*types.Transaction - // Wait for the tx to be in the pending tx queue - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - err := wait.For(ctx, time.Second, func() (bool, error) { - i = s.pendingIndices[from] - txs, q = s.eth.TxPool().ContentFrom(from) - return uint64(len(txs)) > i, nil - }) - require.NoError(t, err, - "no pending txs from %s, and have %d unprocessable queued txs from this account: %w", from, len(q), err) - tx := txs[i] + getPendingIndex := func(from common.Address) uint64 { + return s.pendingIndices[from] + } + tx := firstValidTx(t, from, getPendingIndex, s.eth.TxPool().ContentFrom, s.EthClient().NonceAt) s.IncludeTx(t, tx) - s.pendingIndices[from] = i + 1 // won't retry the tx + s.pendingIndices[from] = s.pendingIndices[from] + 1 // won't retry the tx } } diff --git a/op-e2e/actions/l2_engine.go b/op-e2e/actions/l2_engine.go index 33669ec6afcc..d1230ec8b7c5 100644 --- a/op-e2e/actions/l2_engine.go +++ b/op-e2e/actions/l2_engine.go @@ -1,12 +1,9 @@ package actions import ( - "context" "errors" - "time" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" - "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi" "github.com/stretchr/testify/require" @@ -179,22 +176,8 @@ func (e *L2Engine) ActL2IncludeTx(from common.Address) Action { return } - var i uint64 - var txs []*types.Transaction - var q []*types.Transaction - // Wait for the tx to be in the pending tx queue - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - err := wait.For(ctx, time.Second, func() (bool, error) { - i = e.engineApi.PendingIndices(from) - txs, q = e.eth.TxPool().ContentFrom(from) - return uint64(len(txs)) > i, nil - }) - require.NoError(t, err, - "no pending txs from %s, and have %d unprocessable queued txs from this account: %w", from, len(q), err) - - tx := txs[i] - err = e.engineApi.IncludeTx(tx, from) + tx := firstValidTx(t, from, e.engineApi.PendingIndices, e.eth.TxPool().ContentFrom, e.EthClient().NonceAt) + err := e.engineApi.IncludeTx(tx, from) if errors.Is(err, engineapi.ErrNotBuildingBlock) { t.InvalidAction(err.Error()) } else if errors.Is(err, engineapi.ErrUsesTooMuchGas) { diff --git a/op-e2e/actions/tx_helper.go b/op-e2e/actions/tx_helper.go new file mode 100644 index 000000000000..e63c1a224822 --- /dev/null +++ b/op-e2e/actions/tx_helper.go @@ -0,0 +1,49 @@ +package actions + +import ( + "context" + "math/big" + "time" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" +) + +// firstValidTx finds the first transaction that is valid for inclusion from the specified address. +// It uses a waiter and filtering of already included transactions to avoid race conditions with the async +// updates to the transaction pool. +func firstValidTx( + t Testing, + from common.Address, + pendingIndices func(common.Address) uint64, + contentFrom func(common.Address) ([]*types.Transaction, []*types.Transaction), + nonceAt func(context.Context, common.Address, *big.Int) (uint64, error), +) *types.Transaction { + var i uint64 + var txs []*types.Transaction + var q []*types.Transaction + // Wait for the tx to be in the pending tx queue + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + err := wait.For(ctx, time.Second, func() (bool, error) { + i = pendingIndices(from) + txs, q = contentFrom(from) + // Remove any transactions that have already been included in the head block + // The tx pool only prunes included transactions async so they may still be in the list + nonce, err := nonceAt(ctx, from, nil) + if err != nil { + return false, err + } + for len(txs) > 0 && txs[0].Nonce() < nonce { + t.Logf("Removing already included transaction from list of length %v", len(txs)) + txs = txs[1:] + } + return uint64(len(txs)) > i, nil + }) + require.NoError(t, err, + "no pending txs from %s, and have %d unprocessable queued txs from this account: %w", from, len(q), err) + + return txs[i] +} From 9f388881064bcc4e15635293c7ff1f91d62f1ef1 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 26 Oct 2023 18:54:34 -0600 Subject: [PATCH 070/374] ci-builder: go version env var Makes setting the go version via the env var `GO_VERSION` possible. Previously it hardcoded the version that it was unpacking but used the env var in other locations. Now setting the env var for `GO_VERSION` will allow the user to configure whatever version they want to include in the image. --- ops/docker/ci-builder/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ops/docker/ci-builder/Dockerfile b/ops/docker/ci-builder/Dockerfile index 4f7cf7234978..ab9f0565c258 100644 --- a/ops/docker/ci-builder/Dockerfile +++ b/ops/docker/ci-builder/Dockerfile @@ -39,7 +39,7 @@ ENV GO_VERSION=1.21.1 # Fetch go manually, rather than using a Go base image, so we can copy the installation into the final stage RUN curl -sL https://go.dev/dl/go$GO_VERSION.linux-amd64.tar.gz -o go$GO_VERSION.linux-amd64.tar.gz && \ - tar -C /usr/local/ -xzvf go1.21.1.linux-amd64.tar.gz + tar -C /usr/local/ -xzvf go$GO_VERSION.linux-amd64.tar.gz ENV GOPATH=/go ENV PATH=/usr/local/go/bin:$GOPATH/bin:$PATH From ea77d5a1999aba8e97b95ee06cf9f54023bbbcce Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 11:05:50 +1000 Subject: [PATCH 071/374] ci: Notify slack when semgrep or docker publish fails on develop branch --- .circleci/config.yml | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e9b5021d5aa7..0e4ff1745cef 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -58,6 +58,19 @@ commands: cd ops/check-changed pip3 install -r requirements.txt python3 main.py "<>" + notify-failures-on-develop: + description: "Notify Slack" + parameters: + channel: + type: string + default: C03N11M0BBN + steps: + - slack/notify: + channel: << parameters.channel >> + event: fail + template: basic_fail_1 + branch_pattern: develop + jobs: cannon-go-lint-and-test: docker: @@ -260,6 +273,10 @@ jobs: <> no_output_timeout: 45m + - when: + condition: "<>" + steps: + - notify-failures-on-develop - when: condition: "<>" steps: @@ -585,10 +602,7 @@ jobs: - run: name: Check TODO issues command: ./ops/scripts/todo-checker.sh --verbose - - slack/notify: - channel: C03N11M0BBN - event: fail - template: basic_fail_1 + - notify-failures-on-develop bedrock-markdown: machine: @@ -632,10 +646,8 @@ jobs: name: link lint command: | make bedrock-markdown-links - - slack/notify: + - notify-failures-on-develop: channel: C055R639XT9 #notify-link-check - event: fail - template: basic_fail_1 fuzz-golang: parameters: @@ -1114,6 +1126,7 @@ jobs: - run: name: "Semgrep scan" command: semgrep ci + - notify-failures-on-develop go-mod-download: docker: @@ -1173,10 +1186,7 @@ jobs: command: | make verify-goerli working_directory: op-program - - slack/notify: - channel: C03N11M0BBN - event: fail - template: basic_fail_1 + - notify-failures-on-develop op-program-compat: docker: @@ -1672,6 +1682,7 @@ workflows: platforms: "linux/amd64,linux/arm64" context: - oplabs-gcr + - slack - docker-build: name: op-node-docker-publish docker_name: op-node @@ -1681,6 +1692,7 @@ workflows: publish: true context: - oplabs-gcr + - slack - docker-build: name: op-batcher-docker-publish docker_name: op-batcher @@ -1690,6 +1702,7 @@ workflows: publish: true context: - oplabs-gcr + - slack - docker-build: name: op-program-docker-publish docker_name: op-program @@ -1699,6 +1712,7 @@ workflows: publish: true context: - oplabs-gcr + - slack - docker-build: name: op-proposer-docker-publish docker_name: op-proposer @@ -1708,6 +1722,7 @@ workflows: publish: true context: - oplabs-gcr + - slack - docker-build: name: op-challenger-docker-publish docker_name: op-challenger @@ -1717,6 +1732,7 @@ workflows: publish: true context: - oplabs-gcr + - slack - docker-build: name: op-heartbeat-docker-publish docker_name: op-heartbeat @@ -1726,6 +1742,7 @@ workflows: publish: true context: - oplabs-gcr + - slack - docker-build: name: indexer-docker-publish docker_name: indexer @@ -1733,6 +1750,7 @@ workflows: publish: true context: - oplabs-gcr + - slack platforms: "linux/amd64,linux/arm64" - docker-build: name: chain-mon-docker-publish @@ -1741,6 +1759,7 @@ workflows: publish: true context: - oplabs-gcr + - slack - docker-build: name: ufm-metamask-docker-publish docker_name: ufm-metamask @@ -1748,3 +1767,4 @@ workflows: publish: true context: - oplabs-gcr + - slack From 2ec6f8fc8bec825b72d95ec105a44c6a3ee88818 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 11:22:46 +1000 Subject: [PATCH 072/374] op-e2e: Disable cannon tests for external geth Moves choice of running cannon tests to a separate env var rather so it is possible to run cannon tests with HTTP when desired. --- .circleci/config.yml | 9 ++++++++- op-e2e/faultproof_test.go | 14 +++++++------- op-e2e/helper.go | 6 +++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e9b5021d5aa7..beaffef8fb97 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -772,6 +772,10 @@ jobs: target: description: The make target to execute type: string + cannon_enabled: + description: Whether to include cannon tests + default: true + type: boolean docker: - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest resource_class: xlarge @@ -797,7 +801,8 @@ jobs: command: go tool dist list | grep mips - run: name: run tests - command: + command: | + export OP_E2E_CANNON_ENABLED="<>" # Note: We don't use circle CI test splits because we need to split by test name, not by package. There is an additional # constraint that gotestsum does not currently (nor likely will) accept files from different pacakges when building. JUNIT_FILE=/tmp/test-results/<>_<>.xml make <> @@ -1361,6 +1366,7 @@ workflows: name: op-e2e-HTTP-tests module: op-e2e target: test-http + cannon_enabled: false requires: - op-stack-go-lint - devnet-allocs @@ -1368,6 +1374,7 @@ workflows: name: op-e2e-ext-geth-tests module: op-e2e target: test-external-geth + cannon_enabled: false requires: - op-stack-go-lint - devnet-allocs diff --git a/op-e2e/faultproof_test.go b/op-e2e/faultproof_test.go index a191532139d6..e6b2c755aeba 100644 --- a/op-e2e/faultproof_test.go +++ b/op-e2e/faultproof_test.go @@ -18,7 +18,7 @@ import ( ) func TestMultipleCannonGames(t *testing.T) { - InitParallel(t, SkipIfHTTP) + InitParallel(t, UsesCannon) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -78,7 +78,7 @@ func TestMultipleCannonGames(t *testing.T) { } func TestMultipleGameTypes(t *testing.T) { - InitParallel(t, SkipIfHTTP) + InitParallel(t, UsesCannon) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -277,7 +277,7 @@ func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { } func TestCannonDisputeGame(t *testing.T) { - InitParallel(t, SkipIfHTTP) + InitParallel(t, UsesCannon) tests := []struct { name string @@ -328,7 +328,7 @@ func TestCannonDisputeGame(t *testing.T) { } func TestCannonDefendStep(t *testing.T) { - InitParallel(t, SkipIfHTTP) + InitParallel(t, UsesCannon) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -370,7 +370,7 @@ func TestCannonDefendStep(t *testing.T) { } func TestCannonProposedOutputRootInvalid(t *testing.T) { - InitParallel(t, SkipIfHTTP) + InitParallel(t, UsesCannon) // honestStepsFail attempts to perform both an attack and defend step using the correct trace. honestStepsFail := func(ctx context.Context, game *disputegame.CannonGameHelper, correctTrace *disputegame.HonestHelper, parentClaimIdx int64) { // Attack step should fail @@ -448,7 +448,7 @@ func TestCannonProposedOutputRootInvalid(t *testing.T) { } func TestCannonPoisonedPostState(t *testing.T) { - InitParallel(t, SkipIfHTTP) + InitParallel(t, UsesCannon) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -558,7 +558,7 @@ func setupDisputeGameForInvalidOutputRoot(t *testing.T, outputRoot common.Hash) } func TestCannonChallengeWithCorrectRoot(t *testing.T) { - InitParallel(t, SkipIfHTTP) + InitParallel(t, UsesCannon) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) diff --git a/op-e2e/helper.go b/op-e2e/helper.go index eafeeb576e31..0b36458d4780 100644 --- a/op-e2e/helper.go +++ b/op-e2e/helper.go @@ -17,8 +17,8 @@ func InitParallel(t *testing.T, opts ...func(t *testing.T)) { } } -func SkipIfHTTP(t *testing.T) { - if UseHTTP() { - t.Skip("Skipping test because HTTP connection is in use") +func UsesCannon(t *testing.T) { + if os.Getenv("OP_E2E_CANNON_ENABLED") == "false" { + t.Skip("Skipping cannon test") } } From eb7e94ea27d4616ffdeb3a5272ab930920be8cf6 Mon Sep 17 00:00:00 2001 From: Michael de Hoog Date: Thu, 26 Oct 2023 15:40:45 -1000 Subject: [PATCH 073/374] Missing envvars setting for --override.canyon flag --- op-node/flags/flags.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go index 8f0247949137..c660db759acd 100644 --- a/op-node/flags/flags.go +++ b/op-node/flags/flags.go @@ -254,9 +254,10 @@ var ( EnvVars: prefixEnvVars("ROLLUP_LOAD_PROTOCOL_VERSIONS"), } CanyonOverrideFlag = &cli.Uint64Flag{ - Name: "override.canyon", - Usage: "Manually specify the Canyon fork timestamp, overriding the bundled setting", - Hidden: false, + Name: "override.canyon", + Usage: "Manually specify the Canyon fork timestamp, overriding the bundled setting", + EnvVars: prefixEnvVars("OVERRIDE_CANYON"), + Hidden: false, } ) From d9e44b5694c1c8a943b1195968c3eaeb6340b4a6 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 11:48:15 +1000 Subject: [PATCH 074/374] op-e2e: Wait for external clients to terminate after Kill() Otherwise the client may write to a directory the test tries to delete causing failures. --- op-e2e/external.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/op-e2e/external.go b/op-e2e/external.go index aaeaa4448184..0efdf4deb600 100644 --- a/op-e2e/external.go +++ b/op-e2e/external.go @@ -2,6 +2,7 @@ package op_e2e import ( "encoding/json" + "errors" "math/big" "os" "os/exec" @@ -51,6 +52,11 @@ func (eec *ExternalEthClient) Close() error { select { case <-time.After(5 * time.Second): eec.Session.Kill() + select { + case <-time.After(30 * time.Second): + return errors.New("external client failed to terminate") + case <-eec.Session.Exited: + } case <-eec.Session.Exited: } return nil From ff2b8879f6572b711e5c24df4d2cfd8037a8e219 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 16:35:21 +1000 Subject: [PATCH 075/374] op-e2e: Split e2e tests into two executors --- .circleci/config.yml | 6 +++++ op-e2e/faultproof_test.go | 32 ++++++++++++----------- op-e2e/helper.go | 55 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index beaffef8fb97..57cc16eb6c0c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -779,6 +779,12 @@ jobs: docker: - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest resource_class: xlarge + # Note: Tests are split between runs manually. + # Tests default to run on the first executor but can be moved to the second with: + # InitParallel(t, UseExecutor(1)) + # Any tests assigned to an executor greater than the number available automatically use the last executor. + # Executor indexes start from 0 + parallelism: 2 steps: - checkout - check-changed: diff --git a/op-e2e/faultproof_test.go b/op-e2e/faultproof_test.go index e6b2c755aeba..1998cf6c7516 100644 --- a/op-e2e/faultproof_test.go +++ b/op-e2e/faultproof_test.go @@ -18,7 +18,7 @@ import ( ) func TestMultipleCannonGames(t *testing.T) { - InitParallel(t, UsesCannon) + InitParallel(t, UsesCannon, UseExecutor(1)) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -78,7 +78,7 @@ func TestMultipleCannonGames(t *testing.T) { } func TestMultipleGameTypes(t *testing.T) { - InitParallel(t, UsesCannon) + InitParallel(t, UsesCannon, UseExecutor(1)) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -113,7 +113,7 @@ func TestMultipleGameTypes(t *testing.T) { } func TestChallengerCompleteDisputeGame(t *testing.T) { - InitParallel(t) + InitParallel(t, UseExecutor(1)) tests := []struct { name string @@ -182,7 +182,7 @@ func TestChallengerCompleteDisputeGame(t *testing.T) { for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { - InitParallel(t) + InitParallel(t, UseExecutor(1)) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -219,7 +219,7 @@ func TestChallengerCompleteDisputeGame(t *testing.T) { } func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { - InitParallel(t) + InitParallel(t, UseExecutor(1)) testCase := func(t *testing.T, isRootCorrect bool) { ctx := context.Background() @@ -267,17 +267,17 @@ func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { } t.Run("RootCorrect", func(t *testing.T) { - InitParallel(t) + InitParallel(t, UseExecutor(1)) testCase(t, true) }) t.Run("RootIncorrect", func(t *testing.T) { - InitParallel(t) + InitParallel(t, UseExecutor(1)) testCase(t, false) }) } func TestCannonDisputeGame(t *testing.T) { - InitParallel(t, UsesCannon) + InitParallel(t, UsesCannon, UseExecutor(1)) tests := []struct { name string @@ -290,7 +290,7 @@ func TestCannonDisputeGame(t *testing.T) { for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { - InitParallel(t) + InitParallel(t, UseExecutor(1)) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -328,7 +328,7 @@ func TestCannonDisputeGame(t *testing.T) { } func TestCannonDefendStep(t *testing.T) { - InitParallel(t, UsesCannon) + InitParallel(t, UsesCannon, UseExecutor(1)) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -370,7 +370,7 @@ func TestCannonDefendStep(t *testing.T) { } func TestCannonProposedOutputRootInvalid(t *testing.T) { - InitParallel(t, UsesCannon) + InitParallel(t, UsesCannon, UseExecutor(1)) // honestStepsFail attempts to perform both an attack and defend step using the correct trace. honestStepsFail := func(ctx context.Context, game *disputegame.CannonGameHelper, correctTrace *disputegame.HonestHelper, parentClaimIdx int64) { // Attack step should fail @@ -421,7 +421,7 @@ func TestCannonProposedOutputRootInvalid(t *testing.T) { for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { - InitParallel(t) + InitParallel(t, UseExecutor(1)) ctx := context.Background() sys, l1Client, game, correctTrace := setupDisputeGameForInvalidOutputRoot(t, test.outputRoot) @@ -448,7 +448,7 @@ func TestCannonProposedOutputRootInvalid(t *testing.T) { } func TestCannonPoisonedPostState(t *testing.T) { - InitParallel(t, UsesCannon) + InitParallel(t, UsesCannon, UseExecutor(1)) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -558,8 +558,10 @@ func setupDisputeGameForInvalidOutputRoot(t *testing.T, outputRoot common.Hash) } func TestCannonChallengeWithCorrectRoot(t *testing.T) { - InitParallel(t, UsesCannon) - + InitParallel(t, UsesCannon, UseExecutor(1)) + if true { + return + } ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) t.Cleanup(sys.Close) diff --git a/op-e2e/helper.go b/op-e2e/helper.go index 0b36458d4780..af0954a7b143 100644 --- a/op-e2e/helper.go +++ b/op-e2e/helper.go @@ -2,23 +2,70 @@ package op_e2e import ( "os" + "strconv" "testing" ) var enableParallelTesting bool = os.Getenv("OP_E2E_DISABLE_PARALLEL") != "true" -func InitParallel(t *testing.T, opts ...func(t *testing.T)) { +type testopts struct { + executor int +} + +func InitParallel(t *testing.T, args ...func(t *testing.T, opts *testopts)) { t.Helper() if enableParallelTesting { t.Parallel() } - for _, opt := range opts { - opt(t) + + opts := &testopts{} + for _, arg := range args { + arg(t, opts) } + checkExecutor(t, opts.executor) } -func UsesCannon(t *testing.T) { +func UsesCannon(t *testing.T, opts *testopts) { if os.Getenv("OP_E2E_CANNON_ENABLED") == "false" { t.Skip("Skipping cannon test") } } + +// UseExecutor allows manually splitting tests between circleci executors +// +// Tests default to run on the first executor but can be moved to the second with: +// InitParallel(t, UseExecutor(1)) +// Any tests assigned to an executor greater than the number available automatically use the last executor. +// Executor indexes start from 0 +func UseExecutor(assignedIdx int) func(t *testing.T, opts *testopts) { + return func(t *testing.T, opts *testopts) { + opts.executor = assignedIdx + } +} + +func checkExecutor(t *testing.T, assignedIdx int) { + envTotal := os.Getenv("CIRCLE_NODE_TOTAL") + envIdx := os.Getenv("CIRCLE_NODE_INDEX") + if envTotal == "" || envIdx == "" { + // Not using test splitting, so ignore assigned executor + t.Logf("Running test. Test splitting not in use.") + return + } + total, err := strconv.Atoi(envTotal) + if err != nil { + t.Fatalf("Could not parse CIRCLE_NODE_TOTAL env var %v: %v", envTotal, err) + } + idx, err := strconv.Atoi(envIdx) + if err != nil { + t.Fatalf("Could not parse CIRCLE_NODE_INDEX env var %v: %v", envIdx, err) + } + if assignedIdx >= total && idx == total-1 { + t.Logf("Running test. Current executor (%v) is the last executor and assigned executor (%v) >= total executors (%v).", idx, assignedIdx, total) + return + } + if idx == assignedIdx { + t.Logf("Running test. Assigned executor (%v) matches current executor (%v) of total (%v)", assignedIdx, idx, total) + return + } + t.Skipf("Skipping test. Assigned executor %v, current executor %v of total %v", assignedIdx, idx, total) +} From 7d51ff39c7d3edfe5a2f9616e1e732c133be39e1 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 16:57:11 +1000 Subject: [PATCH 076/374] op-e2e: Move some tests back to executor 0. --- op-e2e/faultproof_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/op-e2e/faultproof_test.go b/op-e2e/faultproof_test.go index 1998cf6c7516..0cfdbbe97dc8 100644 --- a/op-e2e/faultproof_test.go +++ b/op-e2e/faultproof_test.go @@ -18,7 +18,7 @@ import ( ) func TestMultipleCannonGames(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(1)) + InitParallel(t, UsesCannon, UseExecutor(0)) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -78,7 +78,7 @@ func TestMultipleCannonGames(t *testing.T) { } func TestMultipleGameTypes(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(1)) + InitParallel(t, UsesCannon, UseExecutor(0)) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -370,7 +370,7 @@ func TestCannonDefendStep(t *testing.T) { } func TestCannonProposedOutputRootInvalid(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(1)) + InitParallel(t, UsesCannon, UseExecutor(0)) // honestStepsFail attempts to perform both an attack and defend step using the correct trace. honestStepsFail := func(ctx context.Context, game *disputegame.CannonGameHelper, correctTrace *disputegame.HonestHelper, parentClaimIdx int64) { // Attack step should fail @@ -421,7 +421,7 @@ func TestCannonProposedOutputRootInvalid(t *testing.T) { for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { - InitParallel(t, UseExecutor(1)) + InitParallel(t, UseExecutor(0)) ctx := context.Background() sys, l1Client, game, correctTrace := setupDisputeGameForInvalidOutputRoot(t, test.outputRoot) @@ -448,7 +448,7 @@ func TestCannonProposedOutputRootInvalid(t *testing.T) { } func TestCannonPoisonedPostState(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(1)) + InitParallel(t, UsesCannon, UseExecutor(0)) ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) @@ -558,7 +558,7 @@ func setupDisputeGameForInvalidOutputRoot(t *testing.T, outputRoot common.Hash) } func TestCannonChallengeWithCorrectRoot(t *testing.T) { - InitParallel(t, UsesCannon, UseExecutor(1)) + InitParallel(t, UsesCannon, UseExecutor(0)) if true { return } From 04b4611de9b1f7d1a868e2bdb5dcabae6a20432d Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Fri, 27 Oct 2023 17:27:14 +1000 Subject: [PATCH 077/374] op-e2e: Use unsigned ints to avoid negatives. --- op-e2e/helper.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/op-e2e/helper.go b/op-e2e/helper.go index af0954a7b143..3c8d411b1292 100644 --- a/op-e2e/helper.go +++ b/op-e2e/helper.go @@ -9,7 +9,7 @@ import ( var enableParallelTesting bool = os.Getenv("OP_E2E_DISABLE_PARALLEL") != "true" type testopts struct { - executor int + executor uint64 } func InitParallel(t *testing.T, args ...func(t *testing.T, opts *testopts)) { @@ -37,13 +37,13 @@ func UsesCannon(t *testing.T, opts *testopts) { // InitParallel(t, UseExecutor(1)) // Any tests assigned to an executor greater than the number available automatically use the last executor. // Executor indexes start from 0 -func UseExecutor(assignedIdx int) func(t *testing.T, opts *testopts) { +func UseExecutor(assignedIdx uint64) func(t *testing.T, opts *testopts) { return func(t *testing.T, opts *testopts) { opts.executor = assignedIdx } } -func checkExecutor(t *testing.T, assignedIdx int) { +func checkExecutor(t *testing.T, assignedIdx uint64) { envTotal := os.Getenv("CIRCLE_NODE_TOTAL") envIdx := os.Getenv("CIRCLE_NODE_INDEX") if envTotal == "" || envIdx == "" { @@ -51,11 +51,11 @@ func checkExecutor(t *testing.T, assignedIdx int) { t.Logf("Running test. Test splitting not in use.") return } - total, err := strconv.Atoi(envTotal) + total, err := strconv.ParseUint(envTotal, 10, 0) if err != nil { t.Fatalf("Could not parse CIRCLE_NODE_TOTAL env var %v: %v", envTotal, err) } - idx, err := strconv.Atoi(envIdx) + idx, err := strconv.ParseUint(envIdx, 10, 0) if err != nil { t.Fatalf("Could not parse CIRCLE_NODE_INDEX env var %v: %v", envIdx, err) } From 17de450d52f71cc0bd86d5c777348381a5b9f7c1 Mon Sep 17 00:00:00 2001 From: Lukas Rosario <36800180+lukasrosario@users.noreply.github.com> Date: Fri, 27 Oct 2023 05:02:57 -0400 Subject: [PATCH 078/374] add timestamp to op-indexer withdrawals response --- indexer/api/routes/withdrawals.go | 1 + 1 file changed, 1 insertion(+) diff --git a/indexer/api/routes/withdrawals.go b/indexer/api/routes/withdrawals.go index 1fc2e1d84166..7c3ed399c00e 100644 --- a/indexer/api/routes/withdrawals.go +++ b/indexer/api/routes/withdrawals.go @@ -16,6 +16,7 @@ func newWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) mo item := models.WithdrawalItem{ Guid: withdrawal.L2BridgeWithdrawal.TransactionWithdrawalHash.String(), L2BlockHash: withdrawal.L2BlockHash.String(), + Timestamp: withdrawal.L2BridgeWithdrawal.Tx.Timestamp, From: withdrawal.L2BridgeWithdrawal.Tx.FromAddress.String(), To: withdrawal.L2BridgeWithdrawal.Tx.ToAddress.String(), TransactionHash: withdrawal.L2TransactionHash.String(), From 1a521c94c44804b9972fe9046b3f672bac81f006 Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Fri, 27 Oct 2023 11:09:18 -0400 Subject: [PATCH 079/374] Parameterize python binary in Makefile Although ideally, all python minor versions (3.x) would be backwards compatible, unfortunately that is not the case. Consequently, sometimes developers will have multiple python builds available on their systems, not just a single `python3`. This change simply makes the python binary name a parameter of the Makefile so that affected developers may pass: ``` PYTHON=python-3.9 make ``` Or similar. --- Makefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 8afbb12550db..01a42d947702 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,9 @@ ITESTS_L2_HOST=http://localhost:9545 BEDROCK_TAGS_REMOTE?=origin OP_STACK_GO_BUILDER?=us-docker.pkg.dev/oplabs-tools-artifacts/images/op-stack-go:latest +# Requires at least Python v3.9; specify a minor version below if needed +PYTHON?=python3 + build: build-go build-ts .PHONY: build @@ -114,14 +117,14 @@ pre-devnet: devnet-up: pre-devnet ./ops/scripts/newer-file.sh .devnet/allocs-l1.json ./packages/contracts-bedrock \ || make devnet-allocs - PYTHONPATH=./bedrock-devnet python3 ./bedrock-devnet/main.py --monorepo-dir=. + PYTHONPATH=./bedrock-devnet $(PYTHON) ./bedrock-devnet/main.py --monorepo-dir=. .PHONY: devnet-up # alias for devnet-up devnet-up-deploy: devnet-up devnet-test: pre-devnet - PYTHONPATH=./bedrock-devnet python3 ./bedrock-devnet/main.py --monorepo-dir=. --test + PYTHONPATH=./bedrock-devnet $(PYTHON) ./bedrock-devnet/main.py --monorepo-dir=. --test .PHONY: devnet-test devnet-down: @@ -137,7 +140,7 @@ devnet-clean: .PHONY: devnet-clean devnet-allocs: pre-devnet - PYTHONPATH=./bedrock-devnet python3 ./bedrock-devnet/main.py --monorepo-dir=. --allocs + PYTHONPATH=./bedrock-devnet $(PYTHON) ./bedrock-devnet/main.py --monorepo-dir=. --allocs devnet-logs: @(cd ./ops-bedrock && docker compose logs -f) From d9792367350491c79eedb59ceedc4fe576c4c060 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 27 Oct 2023 09:34:53 -0600 Subject: [PATCH 080/374] contracts-bedrock: goerli protocol versions config Configure the goerli `ProtocolVeresions` recommended and required versions to be `v3.1.0`. This is the same value as on mainnet. The the [notion](https://www.notion.so/oplabs/Goerli-ProtocolVersions-2ad5e3e35e0e47e98e80f76f477c7729?pvs=4) doc for more information. --- packages/contracts-bedrock/deploy-config/goerli.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/deploy-config/goerli.json b/packages/contracts-bedrock/deploy-config/goerli.json index 5c084b4fd36c..a724c1b7dd31 100644 --- a/packages/contracts-bedrock/deploy-config/goerli.json +++ b/packages/contracts-bedrock/deploy-config/goerli.json @@ -40,6 +40,6 @@ "eip1559DenominatorCanyon": 250, "eip1559Elasticity": 10, "systemConfigStartBlock": 8300214, - "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", - "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" + "requiredProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000000", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000000" } From 5393e64d3102baee8ade9015ce7e7a77689c1f5b Mon Sep 17 00:00:00 2001 From: inphi Date: Fri, 27 Oct 2023 11:35:22 -0400 Subject: [PATCH 081/374] ci: enable codecov comments for contracts --- codecov.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/codecov.yml b/codecov.yml index 88f4b4ee729b..953756f48752 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,4 +1,12 @@ -comment: false +codecov: + require_ci_to_pass: false +comment: + layout: "diff, flags, files" + behavior: default + require_changes: false + flags: + - contracts-bedrock-tests + ignore: - "op-e2e" - "**/*.t.sol" @@ -13,6 +21,7 @@ coverage: threshold: 0% # coverage is not allowed to reduce vs. the PR base base: auto informational: true + enabled: true project: default: informational: true From 344e06391b8414eabe9a971a7067704863f5e7df Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 26 Oct 2023 01:06:05 +0200 Subject: [PATCH 082/374] op-node: enable all network options by default --- op-challenger/cmd/main_test.go | 5 ++--- op-node/chaincfg/chains.go | 21 --------------------- op-node/chaincfg/chains_test.go | 2 -- op-node/flags/flags.go | 7 +++---- op-node/service.go | 4 ---- 5 files changed, 5 insertions(+), 34 deletions(-) diff --git a/op-challenger/cmd/main_test.go b/op-challenger/cmd/main_test.go index c749c68bce4a..6c48087985b7 100644 --- a/op-challenger/cmd/main_test.go +++ b/op-challenger/cmd/main_test.go @@ -7,7 +7,6 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-challenger/config" - "github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -17,8 +16,8 @@ import ( var ( l1EthRpc = "http://example.com:8545" gameFactoryAddressValue = "0xbb00000000000000000000000000000000000000" - cannonNetwork = chaincfg.AvailableNetworks()[0] - otherCannonNetwork = chaincfg.AvailableNetworks()[1] + cannonNetwork = "op-mainnet" + otherCannonNetwork = "op-goerli" cannonBin = "./bin/cannon" cannonServer = "./bin/op-program" cannonPreState = "./pre.json" diff --git a/op-node/chaincfg/chains.go b/op-node/chaincfg/chains.go index e864c93a94da..61dece2956a7 100644 --- a/op-node/chaincfg/chains.go +++ b/op-node/chaincfg/chains.go @@ -33,14 +33,7 @@ var L2ChainIDToNetworkDisplayName = func() map[string]string { }() // AvailableNetworks returns the selection of network configurations that is available by default. -// Other configurations that are part of the superchain-registry can be used with the --beta.network flag. func AvailableNetworks() []string { - return []string{"op-mainnet", "op-goerli", "op-sepolia"} -} - -// BetaAvailableNetworks returns all available network configurations in the superchain-registry. -// This set of configurations is experimental, and may change at any time. -func BetaAvailableNetworks() []string { var networks []string for _, cfg := range superchain.OPChains { networks = append(networks, cfg.Chain+"-"+cfg.Superchain) @@ -48,20 +41,6 @@ func BetaAvailableNetworks() []string { return networks } -func IsAvailableNetwork(name string, beta bool) bool { - name = handleLegacyName(name) - available := AvailableNetworks() - if beta { - available = BetaAvailableNetworks() - } - for _, v := range available { - if v == name { - return true - } - } - return false -} - func handleLegacyName(name string) string { switch name { case "goerli": diff --git a/op-node/chaincfg/chains_test.go b/op-node/chaincfg/chains_test.go index da08e6db9113..f2db441a2447 100644 --- a/op-node/chaincfg/chains_test.go +++ b/op-node/chaincfg/chains_test.go @@ -27,8 +27,6 @@ func TestGetRollupConfig(t *testing.T) { } for name, expectedCfg := range configsByName { - require.True(t, IsAvailableNetwork(name, false)) - gotCfg, err := GetRollupConfig(name) require.NoError(t, err) diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go index c660db759acd..f9178ef721a3 100644 --- a/op-node/flags/flags.go +++ b/op-node/flags/flags.go @@ -237,11 +237,10 @@ var ( Value: false, } BetaExtraNetworks = &cli.BoolFlag{ - Name: "beta.extra-networks", - Usage: fmt.Sprintf("Beta feature: enable selection of a predefined-network from the superchain-registry. "+ - "The superchain-registry is experimental, and the availability of configurations may change."+ - "Available networks: %s", strings.Join(chaincfg.BetaAvailableNetworks(), ", ")), + Name: "beta.extra-networks", + Usage: "Legacy flag, ignored, all superchain-registry networks are enabled by default.", EnvVars: prefixEnvVars("BETA_EXTRA_NETWORKS"), + Hidden: true, // hidden, this is deprecated, the flag is not used anymore. } RollupHalt = &cli.StringFlag{ Name: "rollup.halt", diff --git a/op-node/service.go b/op-node/service.go index a243cba25390..2cb5393efd52 100644 --- a/op-node/service.go +++ b/op-node/service.go @@ -194,10 +194,6 @@ Startup will proceed to use the network-parameter and ignore the rollup config. Conflicting configuration is deprecated, and will stop the op-node from starting in the future. `, "network", network, "rollup_config", rollupConfigPath) } - // check that the network is available - if !chaincfg.IsAvailableNetwork(network, ctx.Bool(flags.BetaExtraNetworks.Name)) { - return nil, fmt.Errorf("unavailable network: %q", network) - } config, err := chaincfg.GetRollupConfig(network) if err != nil { return nil, err From 6b2177890ac6601a2862e5eb1f3c22658f9dc246 Mon Sep 17 00:00:00 2001 From: protolambda Date: Fri, 27 Oct 2023 19:20:07 +0200 Subject: [PATCH 083/374] op-node,op-program: update network flag error format --- op-node/chaincfg/chains.go | 2 +- op-program/host/cmd/main_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-node/chaincfg/chains.go b/op-node/chaincfg/chains.go index 61dece2956a7..34ded749fad0 100644 --- a/op-node/chaincfg/chains.go +++ b/op-node/chaincfg/chains.go @@ -70,7 +70,7 @@ func ChainByName(name string) *superchain.ChainConfig { func GetRollupConfig(name string) (*rollup.Config, error) { chainCfg := ChainByName(name) if chainCfg == nil { - return nil, fmt.Errorf("invalid network %s", name) + return nil, fmt.Errorf("invalid network: %q", name) } rollupCfg, err := rollup.LoadOPStackRollupConfig(chainCfg.ChainID) if err != nil { diff --git a/op-program/host/cmd/main_test.go b/op-program/host/cmd/main_test.go index 508f6033bc4a..081136af117b 100644 --- a/op-program/host/cmd/main_test.go +++ b/op-program/host/cmd/main_test.go @@ -75,7 +75,7 @@ func TestDefaultCLIOptionsMatchDefaultConfig(t *testing.T) { func TestNetwork(t *testing.T) { t.Run("Unknown", func(t *testing.T) { - verifyArgsInvalid(t, "unavailable network: \"bar\"", replaceRequiredArg("--network", "bar")) + verifyArgsInvalid(t, "invalid network: \"bar\"", replaceRequiredArg("--network", "bar")) }) t.Run("Required", func(t *testing.T) { From d75c85bd85988148f0f50ba7faaf91cbd28fe619 Mon Sep 17 00:00:00 2001 From: protolambda Date: Fri, 27 Oct 2023 19:35:59 +0200 Subject: [PATCH 084/374] op-node: add extra-networks deprecaction warning log --- op-node/service.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/op-node/service.go b/op-node/service.go index 2cb5393efd52..a7f7b7413bc3 100644 --- a/op-node/service.go +++ b/op-node/service.go @@ -187,6 +187,9 @@ func NewDriverConfig(ctx *cli.Context) *driver.Config { func NewRollupConfig(log log.Logger, ctx *cli.Context) (*rollup.Config, error) { network := ctx.String(flags.Network.Name) rollupConfigPath := ctx.String(flags.RollupConfig.Name) + if ctx.Bool(flags.BetaExtraNetworks.Name) { + log.Warn("The beta.extra-networks flag is deprecated and can be omitted safely.") + } if network != "" { if rollupConfigPath != "" { log.Error(`Cannot configure network and rollup-config at the same time. From 26fdfb8fc3db8266801e649d24cfcfa2d6b66061 Mon Sep 17 00:00:00 2001 From: Felipe Andrade Date: Fri, 27 Oct 2023 15:34:07 -0700 Subject: [PATCH 085/374] feat(proxyd): support eip-1898 in tag rewritting --- proxyd/rewriter.go | 93 ++++++++++++++++++++++++++++------ proxyd/rewriter_test.go | 109 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 179 insertions(+), 23 deletions(-) diff --git a/proxyd/rewriter.go b/proxyd/rewriter.go index 98b59ec1d72b..605787eff312 100644 --- a/proxyd/rewriter.go +++ b/proxyd/rewriter.go @@ -66,25 +66,26 @@ func RewriteRequest(rctx RewriteContext, req *RPCReq, res *RPCRes) (RewriteResul "eth_newFilter": return rewriteRange(rctx, req, res, 0) case "debug_getRawReceipts", "consensus_getReceipts": - return rewriteParam(rctx, req, res, 0, true) + return rewriteParam(rctx, req, res, 0, true, false) case "eth_getBalance", "eth_getCode", "eth_getTransactionCount", "eth_call": - return rewriteParam(rctx, req, res, 1, false) - case "eth_getStorageAt": - return rewriteParam(rctx, req, res, 2, false) + return rewriteParam(rctx, req, res, 1, false, true) + case "eth_getStorageAt", + "eth_getProof": + return rewriteParam(rctx, req, res, 2, false, true) case "eth_getBlockTransactionCountByNumber", "eth_getUncleCountByBlockNumber", "eth_getBlockByNumber", "eth_getTransactionByBlockNumberAndIndex", "eth_getUncleByBlockNumberAndIndex": - return rewriteParam(rctx, req, res, 0, false) + return rewriteParam(rctx, req, res, 0, false, false) } return RewriteNone, nil } -func rewriteParam(rctx RewriteContext, req *RPCReq, res *RPCRes, pos int, required bool) (RewriteResult, error) { +func rewriteParam(rctx RewriteContext, req *RPCReq, res *RPCRes, pos int, required bool, blockNrOrHash bool) (RewriteResult, error) { var p []interface{} err := json.Unmarshal(req.Params, &p) if err != nil { @@ -99,13 +100,38 @@ func rewriteParam(rctx RewriteContext, req *RPCReq, res *RPCRes, pos int, requir return RewriteNone, nil } - s, ok := p[pos].(string) - if !ok { - return RewriteOverrideError, errors.New("expected string") - } - val, rw, err := rewriteTag(rctx, s) - if err != nil { - return RewriteOverrideError, err + // support for https://eips.ethereum.org/EIPS/eip-1898 + var val interface{} + var rw bool + if blockNrOrHash { + bnh, err := remarshalBlockNumberOrHash(p[pos]) + if err != nil { + // fallback to string + s, ok := p[pos].(string) + if ok { + val, rw, err = rewriteTag(rctx, s) + if err != nil { + return RewriteOverrideError, err + } + } else { + return RewriteOverrideError, errors.New("expected BlockNumberOrHash or string") + } + } else { + val, rw, err = rewriteTagBlockNumberOrHash(rctx, bnh) + if err != nil { + return RewriteOverrideError, err + } + } + } else { + s, ok := p[pos].(string) + if !ok { + return RewriteOverrideError, errors.New("expected string") + } + + val, rw, err = rewriteTag(rctx, s) + if err != nil { + return RewriteOverrideError, err + } } if rw { @@ -210,14 +236,23 @@ func rewriteTagMap(rctx RewriteContext, m map[string]interface{}, key string) (b return false, nil } -func rewriteTag(rctx RewriteContext, current string) (string, bool, error) { +func remarshalBlockNumberOrHash(current interface{}) (*rpc.BlockNumberOrHash, error) { jv, err := json.Marshal(current) if err != nil { - return "", false, err + return nil, err } var bnh rpc.BlockNumberOrHash err = bnh.UnmarshalJSON(jv) + if err != nil { + return nil, err + } + + return &bnh, nil +} + +func rewriteTag(rctx RewriteContext, current string) (string, bool, error) { + bnh, err := remarshalBlockNumberOrHash(current) if err != nil { return "", false, err } @@ -245,3 +280,31 @@ func rewriteTag(rctx RewriteContext, current string) (string, bool, error) { return current, false, nil } + +func rewriteTagBlockNumberOrHash(rctx RewriteContext, current *rpc.BlockNumberOrHash) (*rpc.BlockNumberOrHash, bool, error) { + // this is a hash, not a block number + if current.BlockNumber == nil { + return current, false, nil + } + + switch *current.BlockNumber { + case rpc.PendingBlockNumber, + rpc.EarliestBlockNumber: + return current, false, nil + case rpc.FinalizedBlockNumber: + bn := rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(rctx.finalized)) + return &bn, true, nil + case rpc.SafeBlockNumber: + bn := rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(rctx.safe)) + return &bn, true, nil + case rpc.LatestBlockNumber: + bn := rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(rctx.latest)) + return &bn, true, nil + default: + if current.BlockNumber.Int64() > int64(rctx.latest) { + return nil, false, ErrRewriteBlockOutOfRange + } + } + + return current, false, nil +} diff --git a/proxyd/rewriter_test.go b/proxyd/rewriter_test.go index 94bc5c962d33..1f0d80ba25c9 100644 --- a/proxyd/rewriter_test.go +++ b/proxyd/rewriter_test.go @@ -5,7 +5,9 @@ import ( "strings" "testing" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" "github.com/stretchr/testify/require" ) @@ -282,12 +284,14 @@ func TestRewriteRequest(t *testing.T) { }, expected: RewriteOverrideRequest, check: func(t *testing.T, args args) { - var p []string + var p []interface{} err := json.Unmarshal(args.req.Params, &p) require.Nil(t, err) require.Equal(t, 2, len(p)) require.Equal(t, "0x123", p[0]) - require.Equal(t, hexutil.Uint64(100).String(), p[1]) + bnh, err := remarshalBlockNumberOrHash(p[1]) + require.Nil(t, err) + require.Equal(t, rpc.BlockNumberOrHashWithNumber(100), *bnh) }, }, { @@ -314,12 +318,14 @@ func TestRewriteRequest(t *testing.T) { }, expected: RewriteOverrideRequest, check: func(t *testing.T, args args) { - var p []string + var p []interface{} err := json.Unmarshal(args.req.Params, &p) require.Nil(t, err) require.Equal(t, 2, len(p)) require.Equal(t, "0x123", p[0]) - require.Equal(t, hexutil.Uint64(100).String(), p[1]) + bnh, err := remarshalBlockNumberOrHash(p[1]) + require.Nil(t, err) + require.Equal(t, rpc.BlockNumberOrHashWithNumber(100), *bnh) }, }, { @@ -359,13 +365,15 @@ func TestRewriteRequest(t *testing.T) { }, expected: RewriteOverrideRequest, check: func(t *testing.T, args args) { - var p []string + var p []interface{} err := json.Unmarshal(args.req.Params, &p) require.Nil(t, err) require.Equal(t, 3, len(p)) require.Equal(t, "0x123", p[0]) require.Equal(t, "5", p[1]) - require.Equal(t, hexutil.Uint64(100).String(), p[2]) + bnh, err := remarshalBlockNumberOrHash(p[2]) + require.Nil(t, err) + require.Equal(t, rpc.BlockNumberOrHashWithNumber(100), *bnh) }, }, { @@ -377,13 +385,15 @@ func TestRewriteRequest(t *testing.T) { }, expected: RewriteOverrideRequest, check: func(t *testing.T, args args) { - var p []string + var p []interface{} err := json.Unmarshal(args.req.Params, &p) require.Nil(t, err) require.Equal(t, 3, len(p)) require.Equal(t, "0x123", p[0]) require.Equal(t, "5", p[1]) - require.Equal(t, hexutil.Uint64(100).String(), p[2]) + bnh, err := remarshalBlockNumberOrHash(p[2]) + require.Nil(t, err) + require.Equal(t, rpc.BlockNumberOrHashWithNumber(100), *bnh) }, }, { @@ -517,6 +527,88 @@ func TestRewriteRequest(t *testing.T) { }, expected: RewriteNone, }, + // eip1898 + { + name: "eth_getStorageAt using rpc.BlockNumberOrHash at genesis (blockNumber)", + args: args{ + rctx: RewriteContext{latest: hexutil.Uint64(100)}, + req: &RPCReq{Method: "eth_getStorageAt", Params: mustMarshalJSON([]interface{}{ + "0xae851f927ee40de99aabb7461c00f9622ab91d60", + "10", + map[string]interface{}{ + "blockNumber": "0x0", + }})}, + res: nil, + }, + expected: RewriteNone, + }, + { + name: "eth_getStorageAt using rpc.BlockNumberOrHash at genesis (hash)", + args: args{ + rctx: RewriteContext{latest: hexutil.Uint64(100)}, + req: &RPCReq{Method: "eth_getStorageAt", Params: mustMarshalJSON([]interface{}{ + "0xae851f927ee40de99aabb7461c00f9622ab91d60", + "10", + map[string]interface{}{ + "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", + "requireCanonical": true, + }})}, + res: nil, + }, + expected: RewriteNone, + check: func(t *testing.T, args args) { + var p []interface{} + err := json.Unmarshal(args.req.Params, &p) + require.Nil(t, err) + require.Equal(t, 3, len(p)) + require.Equal(t, "0xae851f927ee40de99aabb7461c00f9622ab91d60", p[0]) + require.Equal(t, "10", p[1]) + bnh, err := remarshalBlockNumberOrHash(p[2]) + require.Nil(t, err) + require.Equal(t, rpc.BlockNumberOrHashWithHash(common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"), true), *bnh) + require.True(t, bnh.RequireCanonical) + }, + }, + { + name: "eth_getStorageAt using rpc.BlockNumberOrHash at latest (blockNumber)", + args: args{ + rctx: RewriteContext{latest: hexutil.Uint64(100)}, + req: &RPCReq{Method: "eth_getStorageAt", Params: mustMarshalJSON([]interface{}{ + "0xae851f927ee40de99aabb7461c00f9622ab91d60", + "10", + map[string]interface{}{ + "blockNumber": "latest", + }})}, + res: nil, + }, + expected: RewriteOverrideRequest, + check: func(t *testing.T, args args) { + var p []interface{} + err := json.Unmarshal(args.req.Params, &p) + require.Nil(t, err) + require.Equal(t, 3, len(p)) + require.Equal(t, "0xae851f927ee40de99aabb7461c00f9622ab91d60", p[0]) + require.Equal(t, "10", p[1]) + bnh, err := remarshalBlockNumberOrHash(p[2]) + require.Nil(t, err) + require.Equal(t, rpc.BlockNumberOrHashWithNumber(100), *bnh) + }, + }, + { + name: "eth_getStorageAt using rpc.BlockNumberOrHash out of range", + args: args{ + rctx: RewriteContext{latest: hexutil.Uint64(100)}, + req: &RPCReq{Method: "eth_getStorageAt", Params: mustMarshalJSON([]interface{}{ + "0xae851f927ee40de99aabb7461c00f9622ab91d60", + "10", + map[string]interface{}{ + "blockNumber": "0x111", + }})}, + res: nil, + }, + expected: RewriteOverrideError, + expectedErr: ErrRewriteBlockOutOfRange, + }, } // generalize tests for other methods with same interface and behavior @@ -528,6 +620,7 @@ func TestRewriteRequest(t *testing.T) { tests = generalize(tests, "eth_getBlockByNumber", "eth_getUncleCountByBlockNumber") tests = generalize(tests, "eth_getBlockByNumber", "eth_getTransactionByBlockNumberAndIndex") tests = generalize(tests, "eth_getBlockByNumber", "eth_getUncleByBlockNumberAndIndex") + tests = generalize(tests, "eth_getStorageSlotAt", "eth_getProof") for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 72fc3f0e5a2e9997c6b0575e4c24931d8f0023fc Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Fri, 27 Oct 2023 18:49:32 -0400 Subject: [PATCH 086/374] remove etl batch metrics --- indexer/etl/etl.go | 6 +--- indexer/etl/l1_etl.go | 3 +- indexer/etl/l2_etl.go | 4 +-- indexer/etl/metrics.go | 62 ++++++++---------------------------------- 4 files changed, 15 insertions(+), 60 deletions(-) diff --git a/indexer/etl/etl.go b/indexer/etl/etl.go index f11c69ec7862..a9db86907a30 100644 --- a/indexer/etl/etl.go +++ b/indexer/etl/etl.go @@ -74,7 +74,6 @@ func (etl *ETL) Start(ctx context.Context) error { etl.log.Warn("no new headers. processor unexpectedly at head...") } else { headers = newHeaders - etl.metrics.RecordBatchHeaders(len(newHeaders)) } } @@ -98,7 +97,6 @@ func (etl *ETL) processBatch(headers []types.Header) error { batchLog := etl.log.New("batch_start_block_number", firstHeader.Number, "batch_end_block_number", lastHeader.Number) batchLog.Info("extracting batch", "size", len(headers)) - etl.metrics.RecordBatchLatestHeight(lastHeader.Number) headerMap := make(map[common.Hash]*types.Header, len(headers)) for i := range headers { header := headers[i] @@ -128,6 +126,7 @@ func (etl *ETL) processBatch(headers []types.Header) error { for i := range logs.Logs { log := logs.Logs[i] + headersWithLog[log.BlockHash] = true if _, ok := headerMap[log.BlockHash]; !ok { // NOTE. Definitely an error state if the none of the headers were re-orged out in between // the blocks and logs retrieval operations. Unlikely as long as the confirmation depth has @@ -135,9 +134,6 @@ func (etl *ETL) processBatch(headers []types.Header) error { batchLog.Error("log found with block hash not in the batch", "block_hash", logs.Logs[i].BlockHash, "log_index", logs.Logs[i].Index) return errors.New("parsed log with a block hash not in the batch") } - - etl.metrics.RecordBatchLog(log.Address) - headersWithLog[log.BlockHash] = true } // ensure we use unique downstream references for the etl batch diff --git a/indexer/etl/l1_etl.go b/indexer/etl/l1_etl.go index a4613928b077..490d45fe69ab 100644 --- a/indexer/etl/l1_etl.go +++ b/indexer/etl/l1_etl.go @@ -108,6 +108,7 @@ func (l1Etl *L1ETL) Start(ctx context.Context) error { l1BlockHeaders = append(l1BlockHeaders, database.L1BlockHeader{BlockHeader: database.BlockHeaderFromHeader(&batch.Headers[i])}) } } + if len(l1BlockHeaders) == 0 { batch.Logger.Info("no l1 blocks with logs in batch") continue @@ -117,6 +118,7 @@ func (l1Etl *L1ETL) Start(ctx context.Context) error { for i := range batch.Logs { timestamp := batch.HeaderMap[batch.Logs[i].BlockHash].Time l1ContractEvents[i] = database.L1ContractEvent{ContractEvent: database.ContractEventFromLog(&batch.Logs[i], timestamp)} + l1Etl.ETL.metrics.RecordIndexedLog(batch.Logs[i].Address) } // Continually try to persist this batch. If it fails after 10 attempts, we simply error out @@ -138,7 +140,6 @@ func (l1Etl *L1ETL) Start(ctx context.Context) error { l1Etl.ETL.metrics.RecordIndexedHeaders(len(l1BlockHeaders)) l1Etl.ETL.metrics.RecordIndexedLatestHeight(l1BlockHeaders[len(l1BlockHeaders)-1].Number) - l1Etl.ETL.metrics.RecordIndexedLogs(len(l1ContractEvents)) // a-ok! return nil, nil diff --git a/indexer/etl/l2_etl.go b/indexer/etl/l2_etl.go index 72dfff8c7455..f6b5ab0fabab 100644 --- a/indexer/etl/l2_etl.go +++ b/indexer/etl/l2_etl.go @@ -93,6 +93,7 @@ func (l2Etl *L2ETL) Start(ctx context.Context) error { for i := range batch.Logs { timestamp := batch.HeaderMap[batch.Logs[i].BlockHash].Time l2ContractEvents[i] = database.L2ContractEvent{ContractEvent: database.ContractEventFromLog(&batch.Logs[i], timestamp)} + l2Etl.ETL.metrics.RecordIndexedLog(batch.Logs[i].Address) } // Continually try to persist this batch. If it fails after 10 attempts, we simply error out @@ -115,9 +116,6 @@ func (l2Etl *L2ETL) Start(ctx context.Context) error { l2Etl.ETL.metrics.RecordIndexedHeaders(len(l2BlockHeaders)) l2Etl.ETL.metrics.RecordIndexedLatestHeight(l2BlockHeaders[len(l2BlockHeaders)-1].Number) - if len(l2ContractEvents) > 0 { - l2Etl.ETL.metrics.RecordIndexedLogs(len(l2ContractEvents)) - } // a-ok! return nil, nil diff --git a/indexer/etl/metrics.go b/indexer/etl/metrics.go index 32099ba5eef6..dc07159946b5 100644 --- a/indexer/etl/metrics.go +++ b/indexer/etl/metrics.go @@ -15,29 +15,20 @@ var ( type Metricer interface { RecordInterval() (done func(err error)) - // Batch Extraction - RecordBatchLatestHeight(height *big.Int) - RecordBatchHeaders(size int) - RecordBatchLog(contractAddress common.Address) - // Indexed Batches RecordIndexedLatestHeight(height *big.Int) RecordIndexedHeaders(size int) - RecordIndexedLogs(size int) + RecordIndexedLog(contractAddress common.Address) } type etlMetrics struct { intervalTick prometheus.Counter intervalDuration prometheus.Histogram - - batchFailures prometheus.Counter - batchLatestHeight prometheus.Gauge - batchHeaders prometheus.Counter - batchLogs *prometheus.CounterVec + intervalFailures prometheus.Counter indexedLatestHeight prometheus.Gauge indexedHeaders prometheus.Counter - indexedLogs prometheus.Counter + indexedLogs *prometheus.CounterVec } func NewMetrics(registry *prometheus.Registry, subsystem string) Metricer { @@ -55,31 +46,11 @@ func NewMetrics(registry *prometheus.Registry, subsystem string) Metricer { Name: "interval_seconds", Help: "duration elapsed for during the processing loop", }), - batchFailures: factory.NewCounter(prometheus.CounterOpts{ + intervalFailures: factory.NewCounter(prometheus.CounterOpts{ Namespace: MetricsNamespace, Subsystem: subsystem, Name: "failures_total", - Help: "number of times the etl encountered a failure to extract a batch", - }), - batchLatestHeight: factory.NewGauge(prometheus.GaugeOpts{ - Namespace: MetricsNamespace, - Subsystem: subsystem, - Name: "height", - Help: "the latest block height observed by an etl interval", - }), - batchHeaders: factory.NewCounter(prometheus.CounterOpts{ - Namespace: MetricsNamespace, - Subsystem: subsystem, - Name: "headers_total", - Help: "number of headers observed by the etl", - }), - batchLogs: factory.NewCounterVec(prometheus.CounterOpts{ - Namespace: MetricsNamespace, - Subsystem: subsystem, - Name: "logs_total", - Help: "number of logs observed by the etl", - }, []string{ - "contract", + Help: "number of times the etl encountered a failure during the processing loop", }), indexedLatestHeight: factory.NewGauge(prometheus.GaugeOpts{ Namespace: MetricsNamespace, @@ -93,11 +64,13 @@ func NewMetrics(registry *prometheus.Registry, subsystem string) Metricer { Name: "indexed_headers_total", Help: "number of headers indexed by the etl", }), - indexedLogs: factory.NewCounter(prometheus.CounterOpts{ + indexedLogs: factory.NewCounterVec(prometheus.CounterOpts{ Namespace: MetricsNamespace, Subsystem: subsystem, Name: "indexed_logs_total", Help: "number of logs indexed by the etl", + }, []string{ + "contract", }), } } @@ -107,25 +80,12 @@ func (m *etlMetrics) RecordInterval() func(error) { timer := prometheus.NewTimer(m.intervalDuration) return func(err error) { if err != nil { - m.batchFailures.Inc() + m.intervalFailures.Inc() } - timer.ObserveDuration() } } -func (m *etlMetrics) RecordBatchLatestHeight(height *big.Int) { - m.batchLatestHeight.Set(float64(height.Uint64())) -} - -func (m *etlMetrics) RecordBatchHeaders(size int) { - m.batchHeaders.Add(float64(size)) -} - -func (m *etlMetrics) RecordBatchLog(contractAddress common.Address) { - m.batchLogs.WithLabelValues(contractAddress.String()).Inc() -} - func (m *etlMetrics) RecordIndexedLatestHeight(height *big.Int) { m.indexedLatestHeight.Set(float64(height.Uint64())) } @@ -134,6 +94,6 @@ func (m *etlMetrics) RecordIndexedHeaders(size int) { m.indexedHeaders.Add(float64(size)) } -func (m *etlMetrics) RecordIndexedLogs(size int) { - m.indexedLogs.Add(float64(size)) +func (m *etlMetrics) RecordIndexedLog(addr common.Address) { + m.indexedLogs.WithLabelValues(addr.String()).Inc() } From e9737410f22f50d418348857fadf73bf8108fe1e Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Fri, 27 Oct 2023 19:01:09 -0400 Subject: [PATCH 087/374] report latest header of the connected client --- indexer/etl/etl.go | 1 + indexer/etl/metrics.go | 12 ++++++++++++ indexer/node/header_traversal.go | 22 +++++++++++++++++----- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/indexer/etl/etl.go b/indexer/etl/etl.go index a9db86907a30..be262565dfed 100644 --- a/indexer/etl/etl.go +++ b/indexer/etl/etl.go @@ -73,6 +73,7 @@ func (etl *ETL) Start(ctx context.Context) error { } else if len(newHeaders) == 0 { etl.log.Warn("no new headers. processor unexpectedly at head...") } else { + etl.metrics.RecordLatestHeight(etl.headerTraversal.LatestHeader().Number) headers = newHeaders } } diff --git a/indexer/etl/metrics.go b/indexer/etl/metrics.go index dc07159946b5..2f9ecd3acdb5 100644 --- a/indexer/etl/metrics.go +++ b/indexer/etl/metrics.go @@ -14,6 +14,7 @@ var ( type Metricer interface { RecordInterval() (done func(err error)) + RecordLatestHeight(height *big.Int) // Indexed Batches RecordIndexedLatestHeight(height *big.Int) @@ -25,6 +26,7 @@ type etlMetrics struct { intervalTick prometheus.Counter intervalDuration prometheus.Histogram intervalFailures prometheus.Counter + latestHeight prometheus.Gauge indexedLatestHeight prometheus.Gauge indexedHeaders prometheus.Counter @@ -52,6 +54,12 @@ func NewMetrics(registry *prometheus.Registry, subsystem string) Metricer { Name: "failures_total", Help: "number of times the etl encountered a failure during the processing loop", }), + latestHeight: factory.NewCounter(prometheus.CounterOpts{ + Namespace: MetricsNamespace, + Subsystem: subsystem, + Name: "latest_height", + Help: "the latest height reported by the connected client", + }), indexedLatestHeight: factory.NewGauge(prometheus.GaugeOpts{ Namespace: MetricsNamespace, Subsystem: subsystem, @@ -86,6 +94,10 @@ func (m *etlMetrics) RecordInterval() func(error) { } } +func (m *etlMetrics) RecordLatestHeight(height *big.Int) { + m.latestHeight.Set(float64(height.Uint64())) +} + func (m *etlMetrics) RecordIndexedLatestHeight(height *big.Int) { m.indexedLatestHeight.Set(float64(height.Uint64())) } diff --git a/indexer/node/header_traversal.go b/indexer/node/header_traversal.go index e925747f2185..437d64ddeca2 100644 --- a/indexer/node/header_traversal.go +++ b/indexer/node/header_traversal.go @@ -17,7 +17,9 @@ var ( type HeaderTraversal struct { ethClient EthClient - lastHeader *types.Header + lastHeader *types.Header + latestHeader *types.Header + blockConfirmationDepth *big.Int } @@ -27,8 +29,15 @@ func NewHeaderTraversal(ethClient EthClient, fromHeader *types.Header, confDepth return &HeaderTraversal{ethClient: ethClient, lastHeader: fromHeader, blockConfirmationDepth: confDepth} } -// LastHeader returns the last header that was fetched by the HeaderTraversal -// This is useful for testing the state of the HeaderTraversal +// LatestHeader returns the latest header reported by underlying eth client +func (f *HeaderTraversal) LatestHeader() *types.Header { + return f.latestHeader +} + +// LastHeader returns the last header traversed. +// - This is useful for testing the state of the HeaderTraversal +// - NOTE: LastHeader may be << LatestHeader depending on the number +// headers traversed via `NextFinalizedHeaders`. func (f *HeaderTraversal) LastHeader() *types.Header { return f.lastHeader } @@ -36,12 +45,14 @@ func (f *HeaderTraversal) LastHeader() *types.Header { // NextFinalizedHeaders retrieves the next set of headers that have been // marked as finalized by the connected client, bounded by the supplied size func (f *HeaderTraversal) NextFinalizedHeaders(maxSize uint64) ([]types.Header, error) { - latestBlockHeader, err := f.ethClient.BlockHeaderByNumber(nil) + latestHeader, err := f.ethClient.BlockHeaderByNumber(nil) if err != nil { return nil, fmt.Errorf("unable to query latest block: %w", err) + } else if latestHeader == nil { + return nil, fmt.Errorf("latest header unreported") } - endHeight := new(big.Int).Sub(latestBlockHeader.Number, f.blockConfirmationDepth) + endHeight := new(big.Int).Sub(latestHeader.Number, f.blockConfirmationDepth) if endHeight.Sign() < 0 { // No blocks with the provided confirmation depth available return nil, nil @@ -78,5 +89,6 @@ func (f *HeaderTraversal) NextFinalizedHeaders(maxSize uint64) ([]types.Header, } f.lastHeader = &headers[numHeaders-1] + f.latestHeader = latestHeader return headers, nil } From 2abe032c6abeabb6749f1a381668e9a5c991ab08 Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Fri, 27 Oct 2023 19:04:16 -0400 Subject: [PATCH 088/374] updated indexed l1/l2 heights in the bridge processor --- indexer/processors/bridge.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/indexer/processors/bridge.go b/indexer/processors/bridge.go index 3471b550a961..aed182a70bbb 100644 --- a/indexer/processors/bridge.go +++ b/indexer/processors/bridge.go @@ -231,6 +231,9 @@ func (b *BridgeProcessor) run() error { batchLog.Info("indexed bridge events", "latest_l1_block_number", toL1Height, "latest_l2_block_number", toL2Height) b.LatestL1Header = latestEpoch.L1BlockHeader.RLPHeader.Header() + b.metrics.RecordLatestIndexedL1Height(b.LatestL1Header.Number) + b.LatestL2Header = latestEpoch.L2BlockHeader.RLPHeader.Header() + b.metrics.RecordLatestIndexedL2Height(b.LatestL2Header.Number) return nil } From 1c3f642786e40ecde56798bc3974223f68498ee0 Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Fri, 27 Oct 2023 19:07:51 -0400 Subject: [PATCH 089/374] interval_failures name --- indexer/etl/metrics.go | 4 ++-- indexer/processors/bridge/metrics.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indexer/etl/metrics.go b/indexer/etl/metrics.go index 2f9ecd3acdb5..3a2e70ccc770 100644 --- a/indexer/etl/metrics.go +++ b/indexer/etl/metrics.go @@ -51,10 +51,10 @@ func NewMetrics(registry *prometheus.Registry, subsystem string) Metricer { intervalFailures: factory.NewCounter(prometheus.CounterOpts{ Namespace: MetricsNamespace, Subsystem: subsystem, - Name: "failures_total", + Name: "interval_failures_total", Help: "number of times the etl encountered a failure during the processing loop", }), - latestHeight: factory.NewCounter(prometheus.CounterOpts{ + latestHeight: factory.NewGauge(prometheus.GaugeOpts{ Namespace: MetricsNamespace, Subsystem: subsystem, Name: "latest_height", diff --git a/indexer/processors/bridge/metrics.go b/indexer/processors/bridge/metrics.go index 5808921f63e8..5d8711642c1c 100644 --- a/indexer/processors/bridge/metrics.go +++ b/indexer/processors/bridge/metrics.go @@ -83,7 +83,7 @@ func NewMetrics(registry *prometheus.Registry) Metricer { }), intervalFailures: factory.NewCounter(prometheus.CounterOpts{ Namespace: MetricsNamespace, - Name: "failures_total", + Name: "interval_failures_total", Help: "number of failures encountered", }), latestL1Height: factory.NewGauge(prometheus.GaugeOpts{ From 89c014831d9ff8624ee22ac6034997267ea5cc8f Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 27 Oct 2023 18:35:47 -0400 Subject: [PATCH 090/374] Change revision of nightly foundry in devnet CI --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c669ebcac3bd..16a9fb0f5037 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -989,7 +989,7 @@ jobs: command: | curl -L https://foundry.paradigm.xyz | bash source $HOME/.bashrc - foundryup + foundryup --version nightly-aa257c2fb50814dfc5da4b3688cd3b95b5e3844d echo 'export PATH=$HOME/.foundry/bin:$PATH' >> $BASH_ENV source $HOME/.bashrc forge --version From 80d619ab8bd4b4246336c97bbf662efb49754a5e Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 26 Oct 2023 20:52:26 -0400 Subject: [PATCH 091/374] PoC init --- op-service/rethdb-reader/.gitignore | 2 + op-service/rethdb-reader/Cargo.lock | 7449 +++++++++++++++++++++++++++ op-service/rethdb-reader/Cargo.toml | 12 + op-service/rethdb-reader/README.md | 4 + op-service/rethdb-reader/src/lib.rs | 102 + op-service/sources/receipts.go | 28 +- op-service/sources/reth_db.go | 62 + op-service/sources/reth_db_test.go | 22 + 8 files changed, 7679 insertions(+), 2 deletions(-) create mode 100644 op-service/rethdb-reader/.gitignore create mode 100644 op-service/rethdb-reader/Cargo.lock create mode 100644 op-service/rethdb-reader/Cargo.toml create mode 100644 op-service/rethdb-reader/README.md create mode 100644 op-service/rethdb-reader/src/lib.rs create mode 100644 op-service/sources/reth_db.go create mode 100644 op-service/sources/reth_db_test.go diff --git a/op-service/rethdb-reader/.gitignore b/op-service/rethdb-reader/.gitignore new file mode 100644 index 000000000000..9004537baafa --- /dev/null +++ b/op-service/rethdb-reader/.gitignore @@ -0,0 +1,2 @@ +# Target +target/ diff --git a/op-service/rethdb-reader/Cargo.lock b/op-service/rethdb-reader/Cargo.lock new file mode 100644 index 000000000000..f0fe36055823 --- /dev/null +++ b/op-service/rethdb-reader/Cargo.lock @@ -0,0 +1,7449 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "ctr 0.8.0", + "opaque-debug", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc3be92e19a7ef47457b8e6f90707e12b6ac5d20c6f3866584fa3be0787d839f" +dependencies = [ + "aead", + "aes 0.7.5", + "cipher 0.3.0", + "ctr 0.7.0", + "ghash", + "subtle", +] + +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if", + "getrandom 0.2.10", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "alloy-dyn-abi" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e0daba57ddaba12dc9b21f608b843251f3de017f94a431dca4e7f4f72e5ba9" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-type-parser", + "alloy-sol-types", + "const-hex", + "derive_more", + "itoa", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-json-abi" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63c9319ad8b2b623c6a3ac15899f8ffb71479224762dbaedc385c16efbb6cfe3" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-primitives" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0628ec0ba5b98b3370bb6be17b12f23bfce8ee4ad83823325a20546d9b03b78" +dependencies = [ + "alloy-rlp", + "arbitrary", + "bytes", + "cfg-if", + "const-hex", + "derive_arbitrary", + "derive_more", + "getrandom 0.2.10", + "hex-literal", + "itoa", + "proptest", + "proptest-derive", + "rand 0.8.5", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc0fac0fc16baf1f63f78b47c3d24718f3619b0714076f6a02957d808d52cbef" +dependencies = [ + "alloy-rlp-derive", + "arrayvec", + "bytes", + "smol_str", +] + +[[package]] +name = "alloy-rlp-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0391754c09fab4eae3404d19d0d297aa1c670c1775ab51d8a5312afeca23157" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a98ad1696a2e17f010ae8e43e9f2a1e930ed176a8e3ff77acfeff6dfb07b42c" +dependencies = [ + "const-hex", + "dunce", + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.38", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81c61ccc29e7c58bf16a2f780898852348183f58b127bde03ced6d07ad544787" +dependencies = [ + "winnow", +] + +[[package]] +name = "alloy-sol-types" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d7107bed88e8f09f0ddcc3335622d87bfb6821f3e0c7473329fb1cfad5e015" +dependencies = [ + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "aquamarine" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df752953c49ce90719c7bf1fc587bc8227aed04732ea0c0f85e5397d7fdbd1a1" +dependencies = [ + "include_dir", + "itertools 0.10.5", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "arbitrary" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.0", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "async-compression" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f658e2baef915ba0f26f1f7c42bfb8e12f532a01f449a090ded75ae7a07e9ba2" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", + "zstd 0.13.0", + "zstd-safe 7.0.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "atomic-polyfill" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +dependencies = [ + "critical-section", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "attohttpc" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb8867f378f33f78a811a8eb9bf108ad99430d7aad43315dd9319c827ef6247" +dependencies = [ + "http", + "log", + "url", + "wildmatch", +] + +[[package]] +name = "aurora-engine-modexp" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfacad86e9e138fca0670949eb8ed4ffdf73a55bded8887efe0863cd1a3a6f70" +dependencies = [ + "hex", + "num", +] + +[[package]] +name = "auto_impl" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backon" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1a6197b2120bb2185a267f6515038558b019e92b832bb0320e96d66268dcf9" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "pin-project", + "tokio", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.64.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 1.0.109", +] + +[[package]] +name = "bindgen" +version = "0.66.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" +dependencies = [ + "bitflags 2.4.1", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.38", + "which", +] + +[[package]] +name = "bindgen" +version = "0.68.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" +dependencies = [ + "bitflags 2.4.1", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.38", +] + +[[package]] +name = "binout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "288c7b1c00556959bb7dc822d8adad4a30edd0d3a1fcc6839515792b8f300e5f" + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +dependencies = [ + "arbitrary", + "serde", +] + +[[package]] +name = "bitm" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7becd9fb525c1c507eb025ec37129a0d9320aee17c841085a48101f4f18c0d27" +dependencies = [ + "dyn_size_of", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "serde", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blst" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "boa_ast" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73498e9b2f0aa7db74977afa4d594657611e90587abf0dd564c0b55b4a130163" +dependencies = [ + "bitflags 2.4.1", + "boa_interner", + "boa_macros", + "indexmap 2.0.2", + "num-bigint", + "rustc-hash", +] + +[[package]] +name = "boa_engine" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16377479d5d6d33896e7acdd1cc698d04a8f72004025bbbddf47558cd29146a6" +dependencies = [ + "bitflags 2.4.1", + "boa_ast", + "boa_gc", + "boa_icu_provider", + "boa_interner", + "boa_macros", + "boa_parser", + "boa_profiler", + "chrono", + "dashmap", + "fast-float", + "icu_normalizer", + "indexmap 2.0.2", + "itertools 0.11.0", + "num-bigint", + "num-integer", + "num-traits", + "num_enum 0.6.1", + "once_cell", + "pollster", + "rand 0.8.5", + "regress", + "rustc-hash", + "ryu-js", + "serde", + "serde_json", + "sptr", + "static_assertions", + "tap", + "thin-vec", + "thiserror", +] + +[[package]] +name = "boa_gc" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c97b44beaef9d4452342d117d94607fdfa8d474280f1ba0fd97853834e3a49b2" +dependencies = [ + "boa_macros", + "boa_profiler", + "thin-vec", +] + +[[package]] +name = "boa_icu_provider" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30e52e34e451dd0bfc2c654a9a43ed34b0073dbd4ae3394b40313edda8627aa" +dependencies = [ + "icu_collections", + "icu_normalizer", + "icu_properties", + "icu_provider", + "icu_provider_adapters", + "icu_provider_blob", + "once_cell", +] + +[[package]] +name = "boa_interner" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e5afa991908cfbe79bd3109b824e473a1dc5f74f31fab91bb44c9e245daa77" +dependencies = [ + "boa_gc", + "boa_macros", + "hashbrown 0.14.2", + "indexmap 2.0.2", + "once_cell", + "phf", + "rustc-hash", + "static_assertions", +] + +[[package]] +name = "boa_macros" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "005fa0c5bd20805466dda55eb34cd709bb31a2592bb26927b47714eeed6914d8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", + "synstructure", +] + +[[package]] +name = "boa_parser" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e09afb035377a9044443b598187a7d34cd13164617182a4d7c348522ee3f052" +dependencies = [ + "bitflags 2.4.1", + "boa_ast", + "boa_icu_provider", + "boa_interner", + "boa_macros", + "boa_profiler", + "fast-float", + "icu_locid", + "icu_properties", + "icu_provider", + "icu_provider_macros", + "num-bigint", + "num-traits", + "once_cell", + "regress", + "rustc-hash", + "tinystr", +] + +[[package]] +name = "boa_profiler" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190f92dfe48224adc92881c620f08ccf37ff62b91a094bb357fe53bd5e84647" + +[[package]] +name = "boyer-moore-magiclen" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "116d76fee857b03ecdd95d5f9555e46aa0cd34e5bb348a520e9445d151182a7e" +dependencies = [ + "debug-helper", +] + +[[package]] +name = "brotli" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde", +] + +[[package]] +name = "c-kzg" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac926d808fb72fe09ebf471a091d6d72918876ccf0b4989766093d2d0d24a0ef" +dependencies = [ + "bindgen 0.66.1", + "blst", + "cc", + "glob", + "hex", + "libc", + "serde", +] + +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.48.5", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.10.0", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "codecs-derive" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "convert_case 0.6.0", + "parity-scale-codec", + "proc-macro2", + "quote", + "serde", + "syn 2.0.38", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "comfy-table" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" +dependencies = [ + "crossterm 0.27.0", + "strum", + "strum_macros", + "unicode-width", +] + +[[package]] +name = "confy" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37668cb35145dcfaa1931a5f37fde375eeae8068b4c0d2f289da28a270b2d2c" +dependencies = [ + "directories", + "serde", + "thiserror", + "toml 0.5.11", +] + +[[package]] +name = "const-hex" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c37be52ef5e3b394db27a2341010685ad5103c72ac15ce2e9420a7e8f93f342c" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "const-str" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aca749d3d3f5b87a0d6100509879f9cf486ab510803a4a4e1001da1ff61c2bd6" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossterm" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +dependencies = [ + "bitflags 1.3.2", + "crossterm_winapi", + "libc", + "mio", + "parking_lot 0.12.1", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.4.1", + "crossterm_winapi", + "libc", + "mio", + "parking_lot 0.12.1", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481" +dependencies = [ + "cipher 0.3.0", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher 0.3.0", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher 0.4.4", +] + +[[package]] +name = "cuckoofilter" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18" +dependencies = [ + "byteorder", + "fnv", + "rand 0.7.3", + "serde", + "serde_bytes", + "serde_derive", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version 0.4.0", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core 0.10.2", + "darling_macro 0.10.2", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core 0.20.3", + "darling_macro 0.20.3", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.9.3", + "syn 1.0.109", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.38", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core 0.10.2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core 0.20.3", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "debug-helper" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e" + +[[package]] +name = "delay_map" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4355c25cbf99edcb6b4a0e906f6bdc6956eda149e84455bea49696429b2f8e8" +dependencies = [ + "futures", + "tokio-util", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_arbitrary" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "derive_builder" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" +dependencies = [ + "darling 0.10.2", + "derive_builder_core", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" +dependencies = [ + "darling 0.10.2", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn 1.0.109", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys 0.3.7", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "discv5" +version = "0.3.1" +source = "git+https://github.com/sigp/discv5?rev=f289bbd4c57d499bb1bdb393af3c249600a1c662#f289bbd4c57d499bb1bdb393af3c249600a1c662" +dependencies = [ + "aes 0.7.5", + "aes-gcm", + "arrayvec", + "delay_map", + "enr", + "fnv", + "futures", + "hashlink", + "hex", + "hkdf", + "lazy_static", + "lru 0.12.0", + "more-asserts", + "parking_lot 0.11.2", + "rand 0.8.5", + "rlp", + "smallvec", + "socket2 0.4.10", + "tokio", + "tracing", + "tracing-subscriber", + "uint", + "zeroize", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "dns-lookup" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53ecafc952c4528d9b51a458d1a8904b81783feff9fde08ab6ed2545ff396872" +dependencies = [ + "cfg-if", + "libc", + "socket2 0.4.10", + "winapi", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "dyn-clone" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" + +[[package]] +name = "dyn_size_of" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8adcce29eef18ae1369bbd268fd56bf98144e80281315e9d4a82e34df001c7" + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "serde", + "sha2", + "zeroize", +] + +[[package]] +name = "educe" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0042ff8246a363dbe77d2ceedb073339e85a804b9a47636c6e016a9a32c05f" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "enr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" +dependencies = [ + "base64 0.21.5", + "bytes", + "ed25519-dalek", + "hex", + "k256", + "log", + "rand 0.8.5", + "rlp", + "secp256k1 0.27.0", + "serde", + "sha3", + "zeroize", +] + +[[package]] +name = "enum-as-inner" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "enum-as-inner" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "enum-ordinalize" +version = "3.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf1fa3f06bbff1ea5b1a9c7b14aa992a39657db60a2759457328d7e058f49ee" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "enumn" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ad8cef1d801a4686bfd8919f0b30eac4c8e48968c437a6405ded4fb5272d2b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fast-float" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fdlimit" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4c9e43643f5a3be4ca5b67d26b98031ff9db6806c3440ae32e02e3ceac3f1b" +dependencies = [ + "libc", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +dependencies = [ + "gloo-timers", + "send_wrapper", +] + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-net" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ac9e8288ae2c632fa9f8657ac70bfe38a1530f345282d7ba66a1f70b72b7dc4" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.2", +] + +[[package]] +name = "hdrhistogram" +version = "7.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" +dependencies = [ + "byteorder", + "num-traits", +] + +[[package]] +name = "heapless" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +dependencies = [ + "atomic-polyfill 0.1.11", + "hash32", + "rustc_version 0.4.0", + "serde", + "spin 0.9.8", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "human_bytes" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91f255a4535024abf7640cb288260811fc14794f62b063652ed349f9a6c2348e" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime", + "serde", +] + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-system-resolver" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eea26c5d0b6ab9d72219f65000af310f042a740926f7b2fa3553e774036e2e7" +dependencies = [ + "derive_builder", + "dns-lookup", + "hyper", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8302d8dfd6044d3ddb3f807a5ef3d7bbca9a574959c6d6e4dc39aa7012d0d5" +dependencies = [ + "displaydoc", + "serde", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3003f85dccfc0e238ff567693248c59153a46f4e6125ba4020b973cef4d1d335" +dependencies = [ + "displaydoc", + "litemap", + "serde", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "652869735c9fb9f5a64ba180ee16f2c848390469c116deef517ecc53f4343598" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_properties", + "icu_provider", + "serde", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_properties" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce0e1aa26851f16c9e04412a5911c86b7f8768dac8f8d4c5f1c568a7e5d7a434" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_provider", + "serde", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_provider" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc312a7b6148f7dfe098047ae2494d12d4034f48ade58d4f353000db376e305" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "postcard", + "serde", + "stable_deref_trait", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_adapters" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4ae1e2bd0c41728b77e7c46e9afdec5e2127d1eedacc684724667d50c126bd3" +dependencies = [ + "icu_locid", + "icu_provider", + "serde", + "tinystr", + "yoke", + "zerovec", +] + +[[package]] +name = "icu_provider_blob" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd364c9a01f791a4bc04a74cf2a1d01d9f6926a40fd5ae1c28004e1e70d8338b" +dependencies = [ + "icu_provider", + "postcard", + "serde", + "writeable", + "yoke", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b728b9421e93eff1d9f8681101b78fa745e0748c95c655c83f337044a7e10" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "igd" +version = "0.12.0" +source = "git+https://github.com/stevefan1999-personal/rust-igd?rev=c2d1f83eb1612a462962453cb0703bc93258b173#c2d1f83eb1612a462962453cb0703bc93258b173" +dependencies = [ + "attohttpc", + "bytes", + "futures", + "http", + "hyper", + "log", + "rand 0.8.5", + "tokio", + "url", + "xmltree", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "include_dir" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", + "serde", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.5", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "iri-string" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21859b667d66a4c1dacd9df0863b3efb65785474255face87f5bca39dd8407c0" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "jemalloc-ctl" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cffc705424a344c054e135d12ee591402f4539245e8bbd64e6c9eaa9458b63c" +dependencies = [ + "jemalloc-sys", + "libc", + "paste", +] + +[[package]] +name = "jemalloc-sys" +version = "0.5.4+5.3.0-patched" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "jemallocator" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0de374a9f8e63150e6f5e8a60cc14c668226d7a347d8aee1a45766e3c4dd3bc" +dependencies = [ + "jemalloc-sys", + "libc", +] + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpsee" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-http-client", + "jsonrpsee-proc-macros", + "jsonrpsee-server", + "jsonrpsee-types", + "jsonrpsee-wasm-client", + "jsonrpsee-ws-client", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935" +dependencies = [ + "futures-channel", + "futures-util", + "gloo-net", + "http", + "jsonrpsee-core", + "pin-project", + "rustls-native-certs", + "soketto", + "thiserror", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "url", + "webpki-roots", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" +dependencies = [ + "anyhow", + "async-lock", + "async-trait", + "beef", + "futures-timer", + "futures-util", + "hyper", + "jsonrpsee-types", + "parking_lot 0.12.1", + "rand 0.8.5", + "rustc-hash", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tracing", + "wasm-bindgen-futures", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f80c17f62c7653ce767e3d7288b793dfec920f97067ceb189ebdd3570f2bc20" +dependencies = [ + "async-trait", + "hyper", + "hyper-rustls", + "jsonrpsee-core", + "jsonrpsee-types", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29110019693a4fa2dbda04876499d098fa16d70eba06b1e6e2b3f1b251419515" +dependencies = [ + "heck", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "jsonrpsee-server" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82c39a00449c9ef3f50b84fc00fc4acba20ef8f559f07902244abf4c15c5ab9c" +dependencies = [ + "futures-util", + "http", + "hyper", + "jsonrpsee-core", + "jsonrpsee-types", + "route-recognizer", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "jsonrpsee-wasm-client" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c7cbb3447cf14fd4d2f407c3cc96e6c9634d5440aa1fbed868a31f3c02b27f0" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca9cb3933ccae417eb6b08c3448eb1cb46e39834e5b503e395e5e5bd08546c0" +dependencies = [ + "http", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "url", +] + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.5", + "pem", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libproc" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b18cbf29f8ff3542ba22bdce9ac610fcb75d74bb4e2b306b2a2762242025b4f" +dependencies = [ + "bindgen 0.64.0", + "errno 0.2.8", + "libc", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linked_hash_set" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + +[[package]] +name = "litemap" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a1a2647d5b7134127971a6de0d533c49de2159167e7f259c427195f87168a1" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "lru" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +dependencies = [ + "hashbrown 0.14.2", +] + +[[package]] +name = "lru" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60" +dependencies = [ + "hashbrown 0.14.2", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "lz4_flex" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea9b256699eda7b0387ffbc776dd625e28bde3918446381781245b7a50349d8" + +[[package]] +name = "mach2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" +dependencies = [ + "libc", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memmap2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "metrics" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" +dependencies = [ + "ahash", + "metrics-macros", + "portable-atomic", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a4964177ddfdab1e3a2b37aec7cf320e14169abb0ed73999f558136409178d5" +dependencies = [ + "base64 0.21.5", + "hyper", + "indexmap 1.9.3", + "ipnet", + "metrics", + "metrics-util", + "quanta", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "metrics-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "metrics-process" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c93f6ad342d3f7bc14724147e2dbc6eb6fdbe5a832ace16ea23b73618e8cc17" +dependencies = [ + "libproc", + "mach2", + "metrics", + "once_cell", + "procfs", + "rlimit", + "windows", +] + +[[package]] +name = "metrics-util" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111cb375987443c3de8d503580b536f77dc8416d32db62d9456db5d93bd7ac47" +dependencies = [ + "aho-corasick 0.7.20", + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.13.2", + "indexmap 1.9.3", + "metrics", + "num_cpus", + "ordered-float", + "quanta", + "radix_trie", + "sketches-ddsketch", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "modular-bitfield" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74" +dependencies = [ + "modular-bitfield-impl", + "static_assertions", +] + +[[package]] +name = "modular-bitfield-impl" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "more-asserts" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e" + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-complex" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" +dependencies = [ + "num_enum_derive 0.7.0", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +dependencies = [ + "atomic-polyfill 1.0.3", + "critical-section", +] + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parity-tokio-ipc" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6" +dependencies = [ + "futures", + "libc", + "log", + "rand 0.7.3", + "tokio", + "winapi", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pest" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "ph" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88c6e62e083483e2812a9d2a6eff6b97871302ef4166b5182c6da30624b7e991" +dependencies = [ + "binout", + "bitm", + "dyn_size_of", + "rayon", + "wyhash", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "platforms" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" + +[[package]] +name = "pollster" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b559898e0b4931ed2d3b959ab0c2da4d99cc644c4b0b1a35b4d344027f474023" + +[[package]] +name = "postcard" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +dependencies = [ + "cobs", + "embedded-io", + "heapless", + "serde", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + +[[package]] +name = "prettyplease" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +dependencies = [ + "proc-macro2", + "syn 2.0.38", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "procfs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943ca7f9f29bab5844ecd8fdb3992c5969b6622bb9609b9502fef9b4310e3f1f" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "hex", + "lazy_static", + "rustix 0.36.16", +] + +[[package]] +name = "proptest" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.4.1", + "lazy_static", + "num-traits", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax 0.7.5", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "proptest-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf16337405ca084e9c78985114633b6827711d22b9e6ef6c6c0d665eb3f0b6e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "public-ip" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4c40db5262d93298c363a299f8bc1b3a956a78eecddba3bc0e58b76e2f419a" +dependencies = [ + "dns-lookup", + "futures-core", + "futures-util", + "http", + "hyper", + "hyper-system-resolver", + "pin-project-lite", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "trust-dns-client", + "trust-dns-proto 0.20.4", +] + +[[package]] +name = "quanta" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" +dependencies = [ + "crossbeam-utils", + "libc", + "mach2", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "raw-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.10", + "redox_syscall 0.2.16", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick 1.1.2", + "memchr", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick 1.1.2", + "memchr", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "regress" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82a9ecfa0cb04d0b04dddb99b8ccf4f66bc8dfd23df694b398570bd8ae3a50fb" +dependencies = [ + "hashbrown 0.13.2", + "memchr", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + +[[package]] +name = "reth" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "aquamarine", + "backon", + "boyer-moore-magiclen", + "clap", + "comfy-table", + "confy", + "const-str", + "crossterm 0.27.0", + "dirs-next", + "eyre", + "fdlimit", + "futures", + "human_bytes", + "humantime", + "hyper", + "itertools 0.11.0", + "jemalloc-ctl", + "jemallocator", + "metrics", + "metrics-exporter-prometheus", + "metrics-process", + "metrics-util", + "pin-project", + "pretty_assertions", + "proptest", + "rand 0.8.5", + "reth-auto-seal-consensus", + "reth-basic-payload-builder", + "reth-beacon-consensus", + "reth-blockchain-tree", + "reth-config", + "reth-consensus-common", + "reth-db", + "reth-discv4", + "reth-downloaders", + "reth-interfaces", + "reth-metrics", + "reth-net-nat", + "reth-network", + "reth-network-api", + "reth-nippy-jar", + "reth-payload-builder", + "reth-primitives", + "reth-provider", + "reth-prune", + "reth-revm", + "reth-revm-inspectors", + "reth-rpc", + "reth-rpc-api", + "reth-rpc-builder", + "reth-rpc-engine-api", + "reth-rpc-types", + "reth-rpc-types-compat", + "reth-snapshot", + "reth-stages", + "reth-tasks", + "reth-tracing", + "reth-transaction-pool", + "reth-trie", + "secp256k1 0.27.0", + "serde", + "serde_json", + "shellexpand", + "tempfile", + "thiserror", + "tokio", + "toml 0.8.5", + "tracing", + "tui", + "vergen", +] + +[[package]] +name = "reth-auto-seal-consensus" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "futures-util", + "reth-beacon-consensus", + "reth-interfaces", + "reth-primitives", + "reth-provider", + "reth-revm", + "reth-stages", + "reth-transaction-pool", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "reth-basic-payload-builder" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "futures-core", + "futures-util", + "metrics", + "reth-interfaces", + "reth-metrics", + "reth-payload-builder", + "reth-primitives", + "reth-provider", + "reth-revm", + "reth-tasks", + "reth-transaction-pool", + "revm", + "tokio", + "tracing", +] + +[[package]] +name = "reth-beacon-consensus" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "futures", + "metrics", + "reth-consensus-common", + "reth-db", + "reth-interfaces", + "reth-metrics", + "reth-payload-builder", + "reth-primitives", + "reth-provider", + "reth-prune", + "reth-rpc-types", + "reth-rpc-types-compat", + "reth-snapshot", + "reth-stages", + "reth-tasks", + "reth-tokio-util", + "schnellru", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "reth-blockchain-tree" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "aquamarine", + "linked_hash_set", + "lru 0.11.1", + "metrics", + "parking_lot 0.12.1", + "reth-db", + "reth-interfaces", + "reth-metrics", + "reth-primitives", + "reth-provider", + "reth-stages", + "tokio", + "tracing", +] + +[[package]] +name = "reth-codecs" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "arbitrary", + "bytes", + "codecs-derive", + "proptest", + "proptest-derive", + "revm-primitives", +] + +[[package]] +name = "reth-config" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "confy", + "reth-discv4", + "reth-downloaders", + "reth-net-nat", + "reth-network", + "reth-primitives", + "reth-stages", + "secp256k1 0.27.0", + "serde", + "serde_json", + "tempfile", +] + +[[package]] +name = "reth-consensus-common" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "reth-interfaces", + "reth-primitives", + "reth-provider", +] + +[[package]] +name = "reth-db" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "arbitrary", + "bytes", + "derive_more", + "eyre", + "futures", + "heapless", + "itertools 0.11.0", + "metrics", + "modular-bitfield", + "page_size", + "parity-scale-codec", + "parking_lot 0.12.1", + "paste", + "postcard", + "proptest", + "proptest-derive", + "rand 0.8.5", + "rayon", + "reth-codecs", + "reth-interfaces", + "reth-libmdbx", + "reth-metrics", + "reth-nippy-jar", + "reth-primitives", + "reth-tracing", + "serde", + "tempfile", + "thiserror", + "tokio-stream", + "vergen", +] + +[[package]] +name = "reth-discv4" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "discv5", + "enr", + "generic-array", + "parking_lot 0.12.1", + "reth-net-common", + "reth-net-nat", + "reth-primitives", + "rlp", + "secp256k1 0.27.0", + "serde", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "reth-dns-discovery" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "async-trait", + "data-encoding", + "enr", + "linked_hash_set", + "parking_lot 0.12.1", + "reth-net-common", + "reth-primitives", + "schnellru", + "secp256k1 0.27.0", + "serde", + "serde_with", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "trust-dns-resolver", +] + +[[package]] +name = "reth-downloaders" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "futures", + "futures-util", + "itertools 0.11.0", + "metrics", + "pin-project", + "rayon", + "reth-db", + "reth-interfaces", + "reth-metrics", + "reth-primitives", + "reth-tasks", + "tempfile", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", +] + +[[package]] +name = "reth-ecies" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "aes 0.8.3", + "alloy-rlp", + "block-padding", + "byteorder", + "cipher 0.4.4", + "ctr 0.9.2", + "digest 0.10.7", + "educe", + "futures", + "generic-array", + "hmac", + "pin-project", + "rand 0.8.5", + "reth-net-common", + "reth-primitives", + "secp256k1 0.27.0", + "sha2", + "sha3", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", + "typenum", +] + +[[package]] +name = "reth-eth-wire" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "async-trait", + "bytes", + "futures", + "metrics", + "pin-project", + "reth-codecs", + "reth-discv4", + "reth-ecies", + "reth-metrics", + "reth-primitives", + "serde", + "snap", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", +] + +[[package]] +name = "reth-interfaces" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "async-trait", + "auto_impl", + "clap", + "futures", + "modular-bitfield", + "parity-scale-codec", + "parking_lot 0.12.1", + "rand 0.8.5", + "reth-codecs", + "reth-eth-wire", + "reth-network-api", + "reth-nippy-jar", + "reth-primitives", + "reth-rpc-types", + "revm-primitives", + "secp256k1 0.27.0", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "reth-ipc" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "async-trait", + "bytes", + "futures", + "jsonrpsee", + "parity-tokio-ipc", + "pin-project", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", +] + +[[package]] +name = "reth-libmdbx" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "bitflags 2.4.1", + "byteorder", + "derive_more", + "indexmap 2.0.2", + "libc", + "parking_lot 0.12.1", + "reth-mdbx-sys", + "thiserror", +] + +[[package]] +name = "reth-mdbx-sys" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "bindgen 0.68.1", + "cc", + "libc", +] + +[[package]] +name = "reth-metrics" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "futures", + "metrics", + "reth-metrics-derive", + "tokio", + "tokio-util", +] + +[[package]] +name = "reth-metrics-derive" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "regex", + "syn 2.0.38", +] + +[[package]] +name = "reth-net-common" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "pin-project", + "reth-primitives", + "tokio", +] + +[[package]] +name = "reth-net-nat" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "igd", + "pin-project-lite", + "public-ip", + "serde_with", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "reth-network" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "aquamarine", + "async-trait", + "auto_impl", + "enr", + "fnv", + "futures", + "humantime-serde", + "linked-hash-map", + "linked_hash_set", + "metrics", + "parking_lot 0.12.1", + "pin-project", + "rand 0.8.5", + "reth-discv4", + "reth-dns-discovery", + "reth-ecies", + "reth-eth-wire", + "reth-interfaces", + "reth-metrics", + "reth-net-common", + "reth-network-api", + "reth-primitives", + "reth-provider", + "reth-rpc-types", + "reth-tasks", + "reth-tokio-util", + "reth-transaction-pool", + "secp256k1 0.27.0", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", +] + +[[package]] +name = "reth-network-api" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "async-trait", + "reth-discv4", + "reth-eth-wire", + "reth-primitives", + "reth-rpc-types", + "serde", + "thiserror", + "tokio", +] + +[[package]] +name = "reth-nippy-jar" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "anyhow", + "bincode", + "bytes", + "cuckoofilter", + "hex", + "lz4_flex", + "memmap2", + "ph", + "serde", + "sucds 0.8.1", + "tempfile", + "thiserror", + "tracing", + "tracing-appender", + "zstd 0.12.4", +] + +[[package]] +name = "reth-payload-builder" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "futures-util", + "metrics", + "reth-interfaces", + "reth-metrics", + "reth-primitives", + "reth-rpc-types", + "reth-rpc-types-compat", + "reth-transaction-pool", + "revm-primitives", + "sha2", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "reth-primitives" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "alloy-sol-types", + "arbitrary", + "byteorder", + "bytes", + "c-kzg", + "clap", + "crc", + "derive_more", + "itertools 0.11.0", + "modular-bitfield", + "num_enum 0.7.0", + "once_cell", + "proptest", + "proptest-derive", + "rayon", + "reth-codecs", + "revm", + "revm-primitives", + "secp256k1 0.27.0", + "serde", + "serde_json", + "serde_with", + "sha2", + "strum", + "sucds 0.6.0", + "tempfile", + "thiserror", + "tracing", + "url", + "zstd 0.12.4", +] + +[[package]] +name = "reth-provider" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "auto_impl", + "itertools 0.11.0", + "parking_lot 0.12.1", + "pin-project", + "rayon", + "reth-db", + "reth-interfaces", + "reth-nippy-jar", + "reth-primitives", + "reth-trie", + "revm", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "reth-prune" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "itertools 0.11.0", + "metrics", + "rayon", + "reth-db", + "reth-interfaces", + "reth-metrics", + "reth-primitives", + "reth-provider", + "reth-snapshot", + "reth-tokio-util", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "reth-revm" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "reth-consensus-common", + "reth-interfaces", + "reth-primitives", + "reth-provider", + "reth-revm-inspectors", + "revm", + "tracing", +] + +[[package]] +name = "reth-revm-inspectors" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-sol-types", + "boa_engine", + "boa_gc", + "reth-primitives", + "reth-rpc-types", + "revm", + "serde", + "serde_json", + "thiserror", + "tokio", +] + +[[package]] +name = "reth-rpc" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-dyn-abi", + "alloy-primitives", + "alloy-rlp", + "alloy-sol-types", + "async-trait", + "bytes", + "derive_more", + "futures", + "http", + "http-body", + "hyper", + "jsonrpsee", + "jsonwebtoken", + "lazy_static", + "metrics", + "pin-project", + "rand 0.8.5", + "rayon", + "reth-consensus-common", + "reth-interfaces", + "reth-metrics", + "reth-network-api", + "reth-primitives", + "reth-provider", + "reth-revm", + "reth-rpc-api", + "reth-rpc-engine-api", + "reth-rpc-types", + "reth-rpc-types-compat", + "reth-tasks", + "reth-transaction-pool", + "revm", + "revm-primitives", + "schnellru", + "secp256k1 0.27.0", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", + "tracing-futures", +] + +[[package]] +name = "reth-rpc-api" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "jsonrpsee", + "reth-primitives", + "reth-rpc-types", + "serde_json", +] + +[[package]] +name = "reth-rpc-builder" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "hyper", + "jsonrpsee", + "metrics", + "reth-interfaces", + "reth-ipc", + "reth-metrics", + "reth-network-api", + "reth-primitives", + "reth-provider", + "reth-rpc", + "reth-rpc-api", + "reth-rpc-engine-api", + "reth-rpc-types", + "reth-rpc-types-compat", + "reth-tasks", + "reth-transaction-pool", + "serde", + "strum", + "thiserror", + "tower", + "tower-http", + "tracing", +] + +[[package]] +name = "reth-rpc-engine-api" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "async-trait", + "jsonrpsee-core", + "jsonrpsee-types", + "metrics", + "reth-beacon-consensus", + "reth-interfaces", + "reth-metrics", + "reth-payload-builder", + "reth-primitives", + "reth-provider", + "reth-rpc-api", + "reth-rpc-types", + "reth-rpc-types-compat", + "reth-tasks", + "serde", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "reth-rpc-types" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "itertools 0.11.0", + "jsonrpsee-types", + "reth-primitives", + "serde", + "serde_json", + "serde_with", + "thiserror", +] + +[[package]] +name = "reth-rpc-types-compat" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "reth-primitives", + "reth-rpc-types", +] + +[[package]] +name = "reth-snapshot" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "clap", + "reth-db", + "reth-interfaces", + "reth-nippy-jar", + "reth-primitives", + "reth-provider", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "reth-stages" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "aquamarine", + "async-trait", + "futures-util", + "itertools 0.11.0", + "metrics", + "num-traits", + "pin-project", + "rayon", + "reth-codecs", + "reth-db", + "reth-interfaces", + "reth-metrics", + "reth-primitives", + "reth-provider", + "reth-tokio-util", + "reth-trie", + "revm", + "serde", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "reth-tasks" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "dyn-clone", + "futures-util", + "metrics", + "reth-metrics", + "thiserror", + "tokio", + "tracing", + "tracing-futures", +] + +[[package]] +name = "reth-tokio-util" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "tokio", + "tokio-stream", +] + +[[package]] +name = "reth-tracing" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "rolling-file", + "tracing", + "tracing-appender", + "tracing-journald", + "tracing-subscriber", +] + +[[package]] +name = "reth-transaction-pool" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "aquamarine", + "async-trait", + "auto_impl", + "bitflags 2.4.1", + "fnv", + "futures-util", + "metrics", + "parking_lot 0.12.1", + "paste", + "rand 0.8.5", + "reth-interfaces", + "reth-metrics", + "reth-primitives", + "reth-provider", + "reth-tasks", + "revm", + "serde", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "reth-trie" +version = "0.1.0-alpha.10" +source = "git+https://github.com/paradigmxyz/reth.git#fc4fc936807870b07acb91e1d50c3920b55ff055" +dependencies = [ + "alloy-rlp", + "auto_impl", + "derive_more", + "reth-db", + "reth-interfaces", + "reth-primitives", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "rethdb-reader" +version = "0.1.0" +dependencies = [ + "reth", +] + +[[package]] +name = "revm" +version = "3.5.0" +source = "git+https://github.com/bluealloy/revm?rev=0d78d1eb304a2ce41ddac8f03206f5a316af247b#0d78d1eb304a2ce41ddac8f03206f5a316af247b" +dependencies = [ + "auto_impl", + "revm-interpreter", + "revm-precompile", +] + +[[package]] +name = "revm-interpreter" +version = "1.3.0" +source = "git+https://github.com/bluealloy/revm?rev=0d78d1eb304a2ce41ddac8f03206f5a316af247b#0d78d1eb304a2ce41ddac8f03206f5a316af247b" +dependencies = [ + "revm-primitives", +] + +[[package]] +name = "revm-precompile" +version = "2.2.0" +source = "git+https://github.com/bluealloy/revm?rev=0d78d1eb304a2ce41ddac8f03206f5a316af247b#0d78d1eb304a2ce41ddac8f03206f5a316af247b" +dependencies = [ + "aurora-engine-modexp", + "c-kzg", + "k256", + "once_cell", + "revm-primitives", + "ripemd", + "secp256k1 0.28.0", + "sha2", + "substrate-bn", +] + +[[package]] +name = "revm-primitives" +version = "1.3.0" +source = "git+https://github.com/bluealloy/revm?rev=0d78d1eb304a2ce41ddac8f03206f5a316af247b#0d78d1eb304a2ce41ddac8f03206f5a316af247b" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "auto_impl", + "bitflags 2.4.1", + "bitvec", + "c-kzg", + "derive_more", + "enumn", + "hashbrown 0.14.2", + "hex", + "once_cell", + "serde", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom 0.2.10", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rlimit" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3560f70f30a0f16d11d01ed078a07740fe6b489667abc7c7b029155d9f21c3d8" +dependencies = [ + "libc", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "rolling-file" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8395b4f860856b740f20a296ea2cd4d823e81a2658cf05ef61be22916026a906" +dependencies = [ + "chrono", +] + +[[package]] +name = "route-recognizer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" + +[[package]] +name = "ruint" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95294d6e3a6192f3aabf91c38f56505a625aa495533442744185a36d75a790c4" +dependencies = [ + "alloy-rlp", + "arbitrary", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand 0.8.5", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.20", +] + +[[package]] +name = "rustix" +version = "0.36.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6da3636faa25820d8648e0e31c5d519bbb01f72fdf57131f0f5f7da5fed36eab" +dependencies = [ + "bitflags 1.3.2", + "errno 0.3.5", + "io-lifetimes", + "libc", + "linux-raw-sys 0.1.4", + "windows-sys 0.45.0", +] + +[[package]] +name = "rustix" +version = "0.38.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" +dependencies = [ + "bitflags 2.4.1", + "errno 0.3.5", + "libc", + "linux-raw-sys 0.4.10", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.21.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +dependencies = [ + "log", + "ring 0.17.5", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "ryu-js" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6518fc26bced4d53678a22d6e423e9d8716377def84545fe328236e3af070e7f" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "schnellru" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" +dependencies = [ + "ahash", + "cfg-if", + "hashbrown 0.13.2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "rand 0.8.5", + "secp256k1-sys 0.8.1", + "serde", +] + +[[package]] +name = "secp256k1" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acea373acb8c21ecb5a23741452acd2593ed44ee3d343e72baaa143bc89d0d5" +dependencies = [ + "secp256k1-sys 0.9.0", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + +[[package]] +name = "secp256k1-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e67c467c38fd24bd5499dc9a18183b31575c12ee549197e3e20d57aa4fe3b7" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "serde" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_with" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +dependencies = [ + "base64 0.21.5", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.0.2", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +dependencies = [ + "darling 0.20.3", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shellexpand" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +dependencies = [ + "dirs", +] + +[[package]] +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "sketches-ddsketch" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a406c1882ed7f29cd5e248c9848a80e7cb6ae0fea82346d2746f2f941c07e1" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" + +[[package]] +name = "smol_str" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +dependencies = [ + "serde", +] + +[[package]] +name = "snap" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures", + "http", + "httparse", + "log", + "rand 0.8.5", + "sha-1", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.38", +] + +[[package]] +name = "substrate-bn" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b5bbfa79abbae15dd642ea8176a21a635ff3c00059961d1ea27ad04e5b441c" +dependencies = [ + "byteorder", + "crunchy", + "lazy_static", + "rand 0.8.5", + "rustc-hex", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "sucds" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64accd20141dfbef67ad83c51d588146cff7810616e1bda35a975be369059533" +dependencies = [ + "anyhow", +] + +[[package]] +name = "sucds" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53d46182afe6ed822a94c54a532dc0d59691a8f49226bdc4596529ca864cdd6" +dependencies = [ + "anyhow", + "num-traits", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-solidity" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b837ef12ab88835251726eb12237655e61ec8dc8a280085d1961cdc3dfd047" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "synstructure" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "285ba80e733fac80aa4270fbcdf83772a79b80aa35c97075320abfee4a915b06" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand 2.0.1", + "redox_syscall 0.3.5", + "rustix 0.38.20", + "windows-sys 0.48.0", +] + +[[package]] +name = "thin-vec" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac81b6fd6beb5884b0cf3321b8117e6e5d47ecb6fc89f414cfdcca8b2fe2dd8" + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "libc", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinystr" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8faa444297615a4e020acb64146b0603c9c395c03a97c17fd9028816d3b4d63e" +dependencies = [ + "displaydoc", + "serde", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "slab", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3efaf127c78d5339cc547cce4e4d973bd5e4f56e949a06d091c082ebeef2f800" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.20.5", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.0.2", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "782bf6c2ddf761c1e7855405e8975472acf76f7f36d0d4328bd3b7a2fae12a85" +dependencies = [ + "indexmap 2.0.2", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "hdrhistogram", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +dependencies = [ + "async-compression", + "base64 0.21.5", + "bitflags 2.4.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "httpdate", + "iri-string", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "uuid", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" +dependencies = [ + "crossbeam-channel", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "futures", + "futures-task", + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-journald" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba316a74e8fc3c3896a850dba2375928a9fa171b085ecddfc7c054d39970f3fd" +dependencies = [ + "libc", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trust-dns-client" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b4ef9b9bde0559b78a4abb00339143750085f05e5a453efb7b8bef1061f09dc" +dependencies = [ + "cfg-if", + "data-encoding", + "futures-channel", + "futures-util", + "lazy_static", + "log", + "radix_trie", + "rand 0.8.5", + "thiserror", + "time", + "tokio", + "trust-dns-proto 0.20.4", +] + +[[package]] +name = "trust-dns-proto" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca94d4e9feb6a181c690c4040d7a24ef34018d8313ac5044a61d21222ae24e31" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner 0.3.4", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.2.3", + "ipnet", + "lazy_static", + "log", + "rand 0.8.5", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "url", +] + +[[package]] +name = "trust-dns-proto" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner 0.6.0", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand 0.8.5", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot 0.12.1", + "rand 0.8.5", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", + "trust-dns-proto 0.23.2", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "tui" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1" +dependencies = [ + "bitflags 1.3.2", + "cassowary", + "crossterm 0.25.0", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "universal-hash" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna 0.4.0", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52df8b7fb78e7910d776fccf2e42ceaf3604d55e8e7eb2dbd183cb1441d8a692" + +[[package]] +name = "utf8_iter" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a8922555b9500e3d865caed19330172cd67cbf82203f1a3311d8c305cc9f33" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vergen" +version = "8.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e7dc29b3c54a2ea67ef4f953d5ec0c4085035c0ae2d325be1c0d2144bd9f16" +dependencies = [ + "anyhow", + "rustversion", + "time", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.38", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.20", +] + +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + +[[package]] +name = "wildmatch" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" +dependencies = [ + "windows-core", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0af0c3d13faebf8dda0b5256fa7096a2d5ccb662f7b9f54a40fe201077ab1c2" + +[[package]] +name = "wyhash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf6e163c25e3fac820b4b453185ea2dea3b6a3e0a721d4d23d75bd33734c295" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "xml-rs" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" +dependencies = [ + "xml-rs", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "yoke" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e38c508604d6bbbd292dadb3c02559aa7fff6b654a078a36217cad871636e4" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5e19fb6ed40002bab5403ffa37e53e0e56f914a4450c8765f533018db1db35f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81ba595b9f2772fbee2312de30eeb80ec773b4cb2f1e8098db024afadda6c06f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "772666c41fb6dceaf520b564b962d738a8e1a83b41bd48945f50837aed78bb1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "zerofrom" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655b0814c5c0b19ade497851070c640773304939a6c0fd5f5fb43da0696d05b7" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "zerovec" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "591691014119b87047ead4dcf3e6adfbf73cb7c38ab6980d4f18a32138f35d46" +dependencies = [ + "serde", + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a4a1638a1934450809c2266a70362bfc96cd90550c073f5b8a55014d1010157" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe 6.0.6", +] + +[[package]] +name = "zstd" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +dependencies = [ + "zstd-safe 7.0.0", +] + +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-safe" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/op-service/rethdb-reader/Cargo.toml b/op-service/rethdb-reader/Cargo.toml new file mode 100644 index 000000000000..389172a68335 --- /dev/null +++ b/op-service/rethdb-reader/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rethdb-reader" +description = "A simple library for reading data through Reth's DB abstractions." +version = "0.1.0" +edition = "2021" + +[lib] +name = "rethdbreader" +crate-type = ["cdylib"] + +[dependencies] +reth = { git = "https://github.com/paradigmxyz/reth.git" } diff --git a/op-service/rethdb-reader/README.md b/op-service/rethdb-reader/README.md new file mode 100644 index 000000000000..e8d9f0d26c02 --- /dev/null +++ b/op-service/rethdb-reader/README.md @@ -0,0 +1,4 @@ +# `rethdb-reader` + +Exported Rust code to be used via FFI in `op-service`'s `sources` package for reading information +directly from the `reth` database. diff --git a/op-service/rethdb-reader/src/lib.rs b/op-service/rethdb-reader/src/lib.rs new file mode 100644 index 000000000000..406df15c1e5b --- /dev/null +++ b/op-service/rethdb-reader/src/lib.rs @@ -0,0 +1,102 @@ +use reth::{ + blockchain_tree::noop::NoopBlockchainTree, + primitives::{ + alloy_primitives::private::alloy_rlp::Encodable, BlockHashOrNumber, ChainSpecBuilder, + }, + providers::{providers::BlockchainProvider, ProviderFactory, ReceiptProvider}, + utils::db::open_db_read_only, +}; +use std::{os::raw::c_char, path::Path, sync::Arc}; + +#[repr(C)] +pub struct ByteArray { + data: *mut u8, + len: usize, +} + +#[repr(C)] +pub struct ByteArrays { + data: *mut ByteArray, + len: usize, +} + +/// Read the receipts for a blockhash from the RETH database directly. +/// +/// WARNING: Will panic on error. +/// TODO: Gracefully return OK status. +#[no_mangle] +pub extern "C" fn read_receipts( + block_hash: *const u8, + block_hash_len: usize, + db_path: *const c_char, +) -> ByteArrays { + // Convert the raw pointer and length back to a Rust slice + let block_hash: [u8; 32] = unsafe { std::slice::from_raw_parts(block_hash, block_hash_len) } + .try_into() + .expect("Block hash must be 32 bytes long"); + + // Convert the *const c_char to a Rust &str + let db_path_str = unsafe { + assert!(!db_path.is_null(), "Null pointer for database path"); + std::ffi::CStr::from_ptr(db_path) + .to_str() + .expect("Invalid UTF-8 for database path") + }; + + let db = open_db_read_only(&Path::new(db_path_str), None).expect("Could not open reth DB"); + let spec = Arc::new(ChainSpecBuilder::mainnet().build()); + let factory = ProviderFactory::new(db, spec.clone()); + + // Create a read-only BlockChainProvider + let provider = BlockchainProvider::new(factory, NoopBlockchainTree::default()) + .expect("Failed to create blockchain provider."); + let receipts = provider + .receipts_by_block(BlockHashOrNumber::Hash(block_hash.into())) + .expect("Could not fetch receipts for block") + .expect("No receipts found for block"); + + // Serialize receipts to RLP for the FFI interface. + let receipts_rlp = receipts + .into_iter() + .map(|r| { + // todo - reduce alloc? + // RLP encode the receipt with a bloom filter. + let mut buf = Vec::default(); + r.with_bloom().encode(&mut buf); + + // Return a pointer to the `buf` and its length + let res = ByteArray { + data: buf.as_mut_ptr(), + len: buf.len(), + }; + + // Forget the `buf` so that its memory isn't freed by the + // borrow checker at the end of this scope + std::mem::forget(buf); + + res + }) + .collect::>(); + + let result = ByteArrays { + data: receipts_rlp.as_ptr() as *mut ByteArray, + len: receipts_rlp.len(), + }; + + // Forget the `receipts_rlp` arr so that its memory isn't freed by the + // borrow checker at the end of this scope + std::mem::forget(receipts_rlp); // Prevent Rust from freeing the memory + + result +} + +/// Free the [ByteArrays] data structure and its sub-components when they are no longer needed. +#[no_mangle] +pub extern "C" fn free_byte_arrays(array: ByteArrays) { + unsafe { + let arrays = Vec::from_raw_parts(array.data, array.len, array.len); + for inner_array in arrays { + let _ = Vec::from_raw_parts(inner_array.data, inner_array.len, inner_array.len); + } + } +} diff --git a/op-service/sources/receipts.go b/op-service/sources/receipts.go index e3c8a8713b06..8e9b80506cb0 100644 --- a/op-service/sources/receipts.go +++ b/op-service/sources/receipts.go @@ -124,6 +124,7 @@ const ( RPCKindBasic RPCProviderKind = "basic" // try only the standard most basic receipt fetching RPCKindAny RPCProviderKind = "any" // try any method available RPCKindStandard RPCProviderKind = "standard" // try standard methods, including newer optimized standard RPC methods + RPCKindRethDB RPCProviderKind = "reth_db" // read data directly from reth's MDBX database ) var RPCProviderKinds = []RPCProviderKind{ @@ -137,6 +138,7 @@ var RPCProviderKinds = []RPCProviderKind{ RPCKindBasic, RPCKindAny, RPCKindStandard, + RPCKindRethDB, } func (kind RPCProviderKind) String() string { @@ -268,6 +270,18 @@ const ( // See: // https://github.com/ledgerwatch/erigon/blob/287a3d1d6c90fc6a7a088b5ae320f93600d5a167/cmd/rpcdaemon/commands/erigon_receipts.go#LL391C24-L391C51 ErigonGetBlockReceiptsByBlockHash + // RethGetBlockReceiptsMDBX is a Reth-specific receipt fetching method. It reads the data directly from reth's database, using their + // generic DB abstractions, rather than requesting it from the RPC provider. + // Available in: + // - Reth + // Method: n/a - does not use RPC. + // Params: + // - Reth: string, hex-encoded block hash + // Returns: + // - Reth: array of RLP-encoded receipts + // See: + // - reth's DB crate documentation: https://github.com/paradigmxyz/reth/blob/main/docs/crates/db.md + RethGetBlockReceiptsMDBX // Other: // - 250 credits, not supported, strictly worse than other options. In quicknode price-table. @@ -297,12 +311,14 @@ func AvailableReceiptsFetchingMethods(kind RPCProviderKind) ReceiptsFetchingMeth case RPCKindBasic: return EthGetTransactionReceiptBatch case RPCKindAny: - // if it's any kind of RPC provider, then try all methods + // if it's any kind of RPC provider, then try all methods (except for RethGetBlockReceiptsMDBX) return AlchemyGetTransactionReceipts | EthGetBlockReceipts | DebugGetRawReceipts | ErigonGetBlockReceiptsByBlockHash | ParityGetBlockReceipts | EthGetTransactionReceiptBatch case RPCKindStandard: return EthGetBlockReceipts | EthGetTransactionReceiptBatch + case RPCKindRethDB: + return RethGetBlockReceiptsMDBX default: return EthGetTransactionReceiptBatch } @@ -313,7 +329,9 @@ func AvailableReceiptsFetchingMethods(kind RPCProviderKind) ReceiptsFetchingMeth func PickBestReceiptsFetchingMethod(kind RPCProviderKind, available ReceiptsFetchingMethod, txCount uint64) ReceiptsFetchingMethod { // If we have optimized methods available, it makes sense to use them, but only if the cost is // lower than fetching transactions one by one with the standard receipts RPC method. - if kind == RPCKindAlchemy { + if kind == RPCKindRethDB { + return RethGetBlockReceiptsMDBX + } else if kind == RPCKindAlchemy { if available&AlchemyGetTransactionReceipts != 0 && txCount > 250/15 { return AlchemyGetTransactionReceipts } @@ -460,6 +478,12 @@ func (job *receiptsFetchingJob) runAltMethod(ctx context.Context, m ReceiptsFetc err = job.client.CallContext(ctx, &result, "eth_getBlockReceipts", job.block.Hash) case ErigonGetBlockReceiptsByBlockHash: err = job.client.CallContext(ctx, &result, "erigon_getBlockReceiptsByBlockHash", job.block.Hash) + case RethGetBlockReceiptsMDBX: + res, err := FetchRethReceipts("placeholder", &job.block.Hash) + if err != nil { + return err + } + result = res default: err = fmt.Errorf("unknown receipt fetching method: %d", uint64(m)) } diff --git a/op-service/sources/reth_db.go b/op-service/sources/reth_db.go new file mode 100644 index 000000000000..160ef3d35c2a --- /dev/null +++ b/op-service/sources/reth_db.go @@ -0,0 +1,62 @@ +package sources + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +/* +#cgo LDFLAGS: -L../rethdb-reader/target/release -lrethdbreader +#include +#include + +typedef struct { + uint8_t* data; + size_t len; +} ByteArray; + +typedef struct { + ByteArray* data; + size_t len; +} ByteArrays; + +extern ByteArrays read_receipts(const uint8_t* block_hash, size_t block_hash_len, const char* db_path); +extern void free_byte_arrays(ByteArrays arrays); +*/ +import "C" +import "unsafe" + +// FetchRethReceipts fetches the receipts for the given block hash directly from the Reth Database +// and populates the given results slice pointer with the receipts that were found. +func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, error) { + if blockHash == nil { + return nil, fmt.Errorf("Must provide a block hash to fetch receipts for.") + } + + // Convert the block hash to a C byte array and defer its deallocation + cBlockHash := C.CBytes(blockHash[:]) + defer C.free(cBlockHash) + + // Convert the db path to a C string and defer its deallocation + cDbPath := C.CString(dbPath) + defer C.free(unsafe.Pointer(cDbPath)) + + // Call the C function to fetch the receipts from the Reth Database + byteArrayStruct := C.read_receipts((*C.uint8_t)(cBlockHash), C.size_t(len(blockHash)), cDbPath) + + // Convert the returned receipt RLP byte arrays to decoded Receipts. + data := make(types.Receipts, byteArrayStruct.len) + byteArraySlice := (*[1 << 30]C.ByteArray)(unsafe.Pointer(byteArrayStruct.data))[:byteArrayStruct.len:byteArrayStruct.len] + for i, byteArray := range byteArraySlice { + receipt := types.Receipt{} + receipt.UnmarshalBinary(C.GoBytes(unsafe.Pointer(byteArray.data), C.int(byteArray.len))) + data[i] = &receipt + } + + // Free the memory allocated by the C code + C.free_byte_arrays(byteArrayStruct) + + return data, nil +} diff --git a/op-service/sources/reth_db_test.go b/op-service/sources/reth_db_test.go new file mode 100644 index 000000000000..ecb793895e0d --- /dev/null +++ b/op-service/sources/reth_db_test.go @@ -0,0 +1,22 @@ +package sources + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestRethReceiptsLoad(t *testing.T) { + t.Skip("Skipping test that requires a local L1 Goerli Reth DB") + t.Parallel() + + // block = https://goerli.etherscan.io/block/994113 + blockHash := common.HexToHash("0x6f6f00553e4f74262a9812927afd11c341730c5c9210824fe172367457adb5f6") + res, err := FetchRethReceipts("/path/to/goerli-db", &blockHash) + require.NoError(t, err, "Failed to fetch receipts from Reth DB") + require.Len(t, res, 2, "Expected 2 receipts to be returned") + require.Equal(t, res[0].Type, 0) + require.Equal(t, res[0].CumulativeGasUsed, uint64(93_787)) + require.Equal(t, res[0].Status, uint64(1)) +} From bc5e060e0fccd143a400e02e7f59376d4bae79f3 Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 26 Oct 2023 21:47:59 -0400 Subject: [PATCH 092/374] Add flag to `op-node` --- op-node/flags/flags.go | 7 +++++++ op-node/node/config.go | 3 +++ op-node/node/node.go | 2 ++ op-node/service.go | 6 ++++++ op-service/sources/eth_client.go | 9 ++++++++- op-service/sources/receipts.go | 19 +++++++++++++------ 6 files changed, 39 insertions(+), 7 deletions(-) diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go index c660db759acd..fa6fcd066db6 100644 --- a/op-node/flags/flags.go +++ b/op-node/flags/flags.go @@ -82,6 +82,12 @@ var ( return &out }(), } + L1RethDBPath = &cli.StringFlag{ + Name: "l1.rethdb", + Usage: "The L1 RethDB path, used to fetch receipts for L1 blocks. Only applicable when using the `reth_db` RPC kind with `l1.rpckind`.", + EnvVars: prefixEnvVars("L1_RETHDB"), + Required: false, + } L1RPCRateLimit = &cli.Float64Flag{ Name: "l1.rpc-rate-limit", Usage: "Optional self-imposed global rate-limit on L1 RPC requests, specified in requests / second. Disabled if set to 0.", @@ -304,6 +310,7 @@ var optionalFlags = []cli.Flag{ RollupHalt, RollupLoadProtocolVersions, CanyonOverrideFlag, + L1RethDBPath, } // Flags contains the list of configuration options available to the binary. diff --git a/op-node/node/config.go b/op-node/node/config.go index 6f15e7d710f9..d590bcfc675f 100644 --- a/op-node/node/config.go +++ b/op-node/node/config.go @@ -60,6 +60,9 @@ type Config struct { // Cancel to request a premature shutdown of the node itself, e.g. when halting. This may be nil. Cancel context.CancelCauseFunc + + // [OPTIONAL] The reth DB path to read receipts from + RethDBPath *string } type RPCConfig struct { diff --git a/op-node/node/node.go b/op-node/node/node.go index 594225a006be..78639fec731b 100644 --- a/op-node/node/node.go +++ b/op-node/node/node.go @@ -156,6 +156,8 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error { return fmt.Errorf("failed to get L1 RPC client: %w", err) } + rpcCfg.EthClientConfig.RethDBPath = cfg.RethDBPath + n.l1Source, err = sources.NewL1Client( client.NewInstrumentedRPC(l1Node, n.metrics), n.log, n.metrics.L1SourceCache, rpcCfg) if err != nil { diff --git a/op-node/service.go b/op-node/service.go index a243cba25390..2776ef180e00 100644 --- a/op-node/service.go +++ b/op-node/service.go @@ -71,6 +71,11 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { haltOption = "" } + var rethDBPath *string + if rdb := ctx.String(flags.L1RethDBPath.Name); rdb != "" { + rethDBPath = &rdb + } + cfg := &node.Config{ L1: l1Endpoint, L2: l2Endpoint, @@ -104,6 +109,7 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { ConfigPersistence: configPersistence, Sync: *syncConfig, RollupHalt: haltOption, + RethDBPath: rethDBPath, } if err := cfg.LoadPersisted(log); err != nil { diff --git a/op-service/sources/eth_client.go b/op-service/sources/eth_client.go index 553615857908..b679427f5d68 100644 --- a/op-service/sources/eth_client.go +++ b/op-service/sources/eth_client.go @@ -62,6 +62,9 @@ type EthClientConfig struct { // till we re-attempt the user-preferred methods. // If this is 0 then the client does not fall back to less optimal but available methods. MethodResetDuration time.Duration + + // [OPTIONAL] The reth DB path to fetch receipts from + RethDBPath *string } func (c *EthClientConfig) Check() error { @@ -132,6 +135,9 @@ type EthClient struct { // methodResetDuration defines how long we take till we reset lastMethodsReset methodResetDuration time.Duration + + // [OPTIONAL] The reth DB path to fetch receipts from + rethDbPath *string } func (s *EthClient) PickReceiptsMethod(txCount uint64) ReceiptsFetchingMethod { @@ -179,6 +185,7 @@ func NewEthClient(client client.RPC, log log.Logger, metrics caching.Metrics, co availableReceiptMethods: AvailableReceiptsFetchingMethods(config.RPCProviderKind), lastMethodsReset: time.Now(), methodResetDuration: config.MethodResetDuration, + rethDbPath: config.RethDBPath, }, nil } @@ -357,7 +364,7 @@ func (s *EthClient) FetchReceipts(ctx context.Context, blockHash common.Hash) (e job = v } else { txHashes := eth.TransactionsToHashes(txs) - job = NewReceiptsFetchingJob(s, s.client, s.maxBatchSize, eth.ToBlockID(info), info.ReceiptHash(), txHashes) + job = NewReceiptsFetchingJob(s, s.client, s.maxBatchSize, eth.ToBlockID(info), info.ReceiptHash(), txHashes, s.rethDbPath) s.receiptsCache.Add(blockHash, job) } receipts, err := job.Fetch(ctx) diff --git a/op-service/sources/receipts.go b/op-service/sources/receipts.go index 8e9b80506cb0..4c631797051d 100644 --- a/op-service/sources/receipts.go +++ b/op-service/sources/receipts.go @@ -281,7 +281,7 @@ const ( // - Reth: array of RLP-encoded receipts // See: // - reth's DB crate documentation: https://github.com/paradigmxyz/reth/blob/main/docs/crates/db.md - RethGetBlockReceiptsMDBX + RethGetBlockReceipts // Other: // - 250 credits, not supported, strictly worse than other options. In quicknode price-table. @@ -318,7 +318,7 @@ func AvailableReceiptsFetchingMethods(kind RPCProviderKind) ReceiptsFetchingMeth case RPCKindStandard: return EthGetBlockReceipts | EthGetTransactionReceiptBatch case RPCKindRethDB: - return RethGetBlockReceiptsMDBX + return RethGetBlockReceipts default: return EthGetTransactionReceiptBatch } @@ -330,7 +330,7 @@ func PickBestReceiptsFetchingMethod(kind RPCProviderKind, available ReceiptsFetc // If we have optimized methods available, it makes sense to use them, but only if the cost is // lower than fetching transactions one by one with the standard receipts RPC method. if kind == RPCKindRethDB { - return RethGetBlockReceiptsMDBX + return RethGetBlockReceipts } else if kind == RPCKindAlchemy { if available&AlchemyGetTransactionReceipts != 0 && txCount > 250/15 { return AlchemyGetTransactionReceipts @@ -389,11 +389,14 @@ type receiptsFetchingJob struct { fetcher *IterativeBatchCall[common.Hash, *types.Receipt] + // [OPTIONAL] RethDB path to fetch receipts from + rethDbPath *string + result types.Receipts } func NewReceiptsFetchingJob(requester ReceiptsRequester, client rpcClient, maxBatchSize int, block eth.BlockID, - receiptHash common.Hash, txHashes []common.Hash) *receiptsFetchingJob { + receiptHash common.Hash, txHashes []common.Hash, rethDb *string) *receiptsFetchingJob { return &receiptsFetchingJob{ requester: requester, client: client, @@ -401,6 +404,7 @@ func NewReceiptsFetchingJob(requester ReceiptsRequester, client rpcClient, maxBa block: block, receiptHash: receiptHash, txHashes: txHashes, + rethDbPath: rethDb, } } @@ -478,8 +482,11 @@ func (job *receiptsFetchingJob) runAltMethod(ctx context.Context, m ReceiptsFetc err = job.client.CallContext(ctx, &result, "eth_getBlockReceipts", job.block.Hash) case ErigonGetBlockReceiptsByBlockHash: err = job.client.CallContext(ctx, &result, "erigon_getBlockReceiptsByBlockHash", job.block.Hash) - case RethGetBlockReceiptsMDBX: - res, err := FetchRethReceipts("placeholder", &job.block.Hash) + case RethGetBlockReceipts: + if job.rethDbPath == nil { + return fmt.Errorf("reth_db path not set") + } + res, err := FetchRethReceipts(*job.rethDbPath, &job.block.Hash) if err != nil { return err } From 0d752667667a3d8bc796d40630d23ba8c6650e1e Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 26 Oct 2023 22:33:14 -0400 Subject: [PATCH 093/374] Add error handling in dylib --- op-service/rethdb-reader/src/lib.rs | 136 ++++++++++++++++++---------- op-service/sources/receipts.go | 4 +- op-service/sources/reth_db.go | 19 +++- 3 files changed, 106 insertions(+), 53 deletions(-) diff --git a/op-service/rethdb-reader/src/lib.rs b/op-service/rethdb-reader/src/lib.rs index 406df15c1e5b..b4af373171ec 100644 --- a/op-service/rethdb-reader/src/lib.rs +++ b/op-service/rethdb-reader/src/lib.rs @@ -20,6 +20,38 @@ pub struct ByteArrays { len: usize, } +#[repr(C)] +pub struct ReceiptsResult { + receipts: ByteArrays, + error: bool, +} + +// Implement a default for ByteArrays to be used in error cases +impl Default for ByteArrays { + fn default() -> Self { + ByteArrays { + data: std::ptr::null_mut(), + len: 0, + } + } +} + +impl ReceiptsResult { + pub fn success(receipts: ByteArrays) -> Self { + Self { + receipts, + error: false, + } + } + + pub fn fail() -> Self { + Self { + receipts: ByteArrays::default(), + error: true, + } + } +} + /// Read the receipts for a blockhash from the RETH database directly. /// /// WARNING: Will panic on error. @@ -29,72 +61,82 @@ pub extern "C" fn read_receipts( block_hash: *const u8, block_hash_len: usize, db_path: *const c_char, -) -> ByteArrays { +) -> ReceiptsResult { // Convert the raw pointer and length back to a Rust slice - let block_hash: [u8; 32] = unsafe { std::slice::from_raw_parts(block_hash, block_hash_len) } - .try_into() - .expect("Block hash must be 32 bytes long"); + let Ok(block_hash): Result<[u8; 32], _> = + unsafe { std::slice::from_raw_parts(block_hash, block_hash_len) }.try_into() + else { + return ReceiptsResult::fail(); + }; // Convert the *const c_char to a Rust &str - let db_path_str = unsafe { + let Ok(db_path_str) = unsafe { assert!(!db_path.is_null(), "Null pointer for database path"); std::ffi::CStr::from_ptr(db_path) - .to_str() - .expect("Invalid UTF-8 for database path") + } + .to_str() else { + return ReceiptsResult::fail(); }; - let db = open_db_read_only(&Path::new(db_path_str), None).expect("Could not open reth DB"); + let Ok(db) = open_db_read_only(&Path::new(db_path_str), None) else { + return ReceiptsResult::fail(); + }; let spec = Arc::new(ChainSpecBuilder::mainnet().build()); let factory = ProviderFactory::new(db, spec.clone()); // Create a read-only BlockChainProvider - let provider = BlockchainProvider::new(factory, NoopBlockchainTree::default()) - .expect("Failed to create blockchain provider."); - let receipts = provider - .receipts_by_block(BlockHashOrNumber::Hash(block_hash.into())) - .expect("Could not fetch receipts for block") - .expect("No receipts found for block"); - - // Serialize receipts to RLP for the FFI interface. - let receipts_rlp = receipts - .into_iter() - .map(|r| { - // todo - reduce alloc? - // RLP encode the receipt with a bloom filter. - let mut buf = Vec::default(); - r.with_bloom().encode(&mut buf); - - // Return a pointer to the `buf` and its length - let res = ByteArray { - data: buf.as_mut_ptr(), - len: buf.len(), - }; - - // Forget the `buf` so that its memory isn't freed by the - // borrow checker at the end of this scope - std::mem::forget(buf); - - res - }) - .collect::>(); - - let result = ByteArrays { - data: receipts_rlp.as_ptr() as *mut ByteArray, - len: receipts_rlp.len(), + let Ok(provider) = BlockchainProvider::new(factory, NoopBlockchainTree::default()) else { + return ReceiptsResult::fail(); + }; + + let Ok(receipts) = provider.receipts_by_block(BlockHashOrNumber::Hash(block_hash.into())) + else { + return ReceiptsResult::fail(); }; - // Forget the `receipts_rlp` arr so that its memory isn't freed by the - // borrow checker at the end of this scope - std::mem::forget(receipts_rlp); // Prevent Rust from freeing the memory + if let Some(receipts) = receipts { + let receipts_rlp = receipts + .into_iter() + .map(|r| { + // todo - reduce alloc? + // RLP encode the receipt with a bloom filter. + let mut buf = Vec::default(); + r.with_bloom().encode(&mut buf); - result + // Return a pointer to the `buf` and its length + let res = ByteArray { + data: buf.as_mut_ptr(), + len: buf.len(), + }; + + // Forget the `buf` so that its memory isn't freed by the + // borrow checker at the end of this scope + std::mem::forget(buf); + + res + }) + .collect::>(); + + let result = ByteArrays { + data: receipts_rlp.as_ptr() as *mut ByteArray, + len: receipts_rlp.len(), + }; + + // Forget the `receipts_rlp` arr so that its memory isn't freed by the + // borrow checker at the end of this scope + std::mem::forget(receipts_rlp); // Prevent Rust from freeing the memory + + ReceiptsResult::success(result) + } else { + return ReceiptsResult::fail(); + } } /// Free the [ByteArrays] data structure and its sub-components when they are no longer needed. #[no_mangle] -pub extern "C" fn free_byte_arrays(array: ByteArrays) { +pub extern "C" fn free_byte_arrays(arrays: ByteArrays) { unsafe { - let arrays = Vec::from_raw_parts(array.data, array.len, array.len); + let arrays = Vec::from_raw_parts(arrays.data, arrays.len, arrays.len); for inner_array in arrays { let _ = Vec::from_raw_parts(inner_array.data, inner_array.len, inner_array.len); } diff --git a/op-service/sources/receipts.go b/op-service/sources/receipts.go index 4c631797051d..624379129707 100644 --- a/op-service/sources/receipts.go +++ b/op-service/sources/receipts.go @@ -124,7 +124,7 @@ const ( RPCKindBasic RPCProviderKind = "basic" // try only the standard most basic receipt fetching RPCKindAny RPCProviderKind = "any" // try any method available RPCKindStandard RPCProviderKind = "standard" // try standard methods, including newer optimized standard RPC methods - RPCKindRethDB RPCProviderKind = "reth_db" // read data directly from reth's MDBX database + RPCKindRethDB RPCProviderKind = "reth_db" // read data directly from reth's database ) var RPCProviderKinds = []RPCProviderKind{ @@ -311,7 +311,7 @@ func AvailableReceiptsFetchingMethods(kind RPCProviderKind) ReceiptsFetchingMeth case RPCKindBasic: return EthGetTransactionReceiptBatch case RPCKindAny: - // if it's any kind of RPC provider, then try all methods (except for RethGetBlockReceiptsMDBX) + // if it's any kind of RPC provider, then try all methods (except for RethGetBlockReceipts) return AlchemyGetTransactionReceipts | EthGetBlockReceipts | DebugGetRawReceipts | ErigonGetBlockReceiptsByBlockHash | ParityGetBlockReceipts | EthGetTransactionReceiptBatch diff --git a/op-service/sources/reth_db.go b/op-service/sources/reth_db.go index 160ef3d35c2a..58a4aebe0f5a 100644 --- a/op-service/sources/reth_db.go +++ b/op-service/sources/reth_db.go @@ -11,6 +11,7 @@ import ( #cgo LDFLAGS: -L../rethdb-reader/target/release -lrethdbreader #include #include +#include typedef struct { uint8_t* data; @@ -22,7 +23,13 @@ typedef struct { size_t len; } ByteArrays; -extern ByteArrays read_receipts(const uint8_t* block_hash, size_t block_hash_len, const char* db_path); +// Define ReceiptsResult with a bool for error +typedef struct { + ByteArrays receipts; + bool error; +} ReceiptsResult; + +extern ReceiptsResult read_receipts(const uint8_t* block_hash, size_t block_hash_len, const char* db_path); extern void free_byte_arrays(ByteArrays arrays); */ import "C" @@ -46,9 +53,13 @@ func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, e // Call the C function to fetch the receipts from the Reth Database byteArrayStruct := C.read_receipts((*C.uint8_t)(cBlockHash), C.size_t(len(blockHash)), cDbPath) + if byteArrayStruct.error { + return nil, fmt.Errorf("Error fetching receipts from Reth Database.") + } + // Convert the returned receipt RLP byte arrays to decoded Receipts. - data := make(types.Receipts, byteArrayStruct.len) - byteArraySlice := (*[1 << 30]C.ByteArray)(unsafe.Pointer(byteArrayStruct.data))[:byteArrayStruct.len:byteArrayStruct.len] + data := make(types.Receipts, byteArrayStruct.receipts.len) + byteArraySlice := (*[1 << 30]C.ByteArray)(unsafe.Pointer(byteArrayStruct.receipts.data))[:byteArrayStruct.receipts.len:byteArrayStruct.receipts.len] for i, byteArray := range byteArraySlice { receipt := types.Receipt{} receipt.UnmarshalBinary(C.GoBytes(unsafe.Pointer(byteArray.data), C.int(byteArray.len))) @@ -56,7 +67,7 @@ func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, e } // Free the memory allocated by the C code - C.free_byte_arrays(byteArrayStruct) + C.free_byte_arrays(byteArrayStruct.receipts) return data, nil } From 7d603267486a6bb037104791815b3049e19a083e Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 26 Oct 2023 23:07:08 -0400 Subject: [PATCH 094/374] test: hydrated receipts --- op-service/rethdb-reader/Cargo.lock | 2 + op-service/rethdb-reader/Cargo.toml | 2 + op-service/rethdb-reader/src/lib.rs | 193 +++++++++++++++++++--------- op-service/sources/reth_db.go | 40 ++---- 4 files changed, 152 insertions(+), 85 deletions(-) diff --git a/op-service/rethdb-reader/Cargo.lock b/op-service/rethdb-reader/Cargo.lock index f0fe36055823..ef918a166b1f 100644 --- a/op-service/rethdb-reader/Cargo.lock +++ b/op-service/rethdb-reader/Cargo.lock @@ -5361,6 +5361,8 @@ name = "rethdb-reader" version = "0.1.0" dependencies = [ "reth", + "serde", + "serde_json", ] [[package]] diff --git a/op-service/rethdb-reader/Cargo.toml b/op-service/rethdb-reader/Cargo.toml index 389172a68335..ac53bea511b8 100644 --- a/op-service/rethdb-reader/Cargo.toml +++ b/op-service/rethdb-reader/Cargo.toml @@ -10,3 +10,5 @@ crate-type = ["cdylib"] [dependencies] reth = { git = "https://github.com/paradigmxyz/reth.git" } +serde = "1.0.190" +serde_json = "1.0.107" diff --git a/op-service/rethdb-reader/src/lib.rs b/op-service/rethdb-reader/src/lib.rs index b4af373171ec..9eb2442a3159 100644 --- a/op-service/rethdb-reader/src/lib.rs +++ b/op-service/rethdb-reader/src/lib.rs @@ -1,52 +1,36 @@ use reth::{ blockchain_tree::noop::NoopBlockchainTree, primitives::{ - alloy_primitives::private::alloy_rlp::Encodable, BlockHashOrNumber, ChainSpecBuilder, + BlockHashOrNumber, ChainSpecBuilder, Receipt, TransactionMeta, TransactionSigned, U128, + U256, U64, }, - providers::{providers::BlockchainProvider, ProviderFactory, ReceiptProvider}, + providers::{providers::BlockchainProvider, BlockReader, ProviderFactory, ReceiptProvider}, + revm::primitives::calc_blob_gasprice, + rpc::types::{Log, TransactionReceipt}, utils::db::open_db_read_only, }; use std::{os::raw::c_char, path::Path, sync::Arc}; -#[repr(C)] -pub struct ByteArray { - data: *mut u8, - len: usize, -} - -#[repr(C)] -pub struct ByteArrays { - data: *mut ByteArray, - len: usize, -} - #[repr(C)] pub struct ReceiptsResult { - receipts: ByteArrays, + data: *mut char, + data_len: usize, error: bool, } -// Implement a default for ByteArrays to be used in error cases -impl Default for ByteArrays { - fn default() -> Self { - ByteArrays { - data: std::ptr::null_mut(), - len: 0, - } - } -} - impl ReceiptsResult { - pub fn success(receipts: ByteArrays) -> Self { + pub fn success(data: *mut char, data_len: usize) -> Self { Self { - receipts, + data, + data_len, error: false, } } pub fn fail() -> Self { Self { - receipts: ByteArrays::default(), + data: std::ptr::null_mut(), + data_len: 0, error: true, } } @@ -89,56 +73,147 @@ pub extern "C" fn read_receipts( return ReceiptsResult::fail(); }; + let Ok(block) = provider.block_by_hash(block_hash.into()) else { + return ReceiptsResult::fail(); + }; + let Ok(receipts) = provider.receipts_by_block(BlockHashOrNumber::Hash(block_hash.into())) else { return ReceiptsResult::fail(); }; - if let Some(receipts) = receipts { - let receipts_rlp = receipts + if let (Some(block), Some(receipts)) = (block, receipts) { + let block_number = block.number; + let base_fee = block.base_fee_per_gas; + let block_hash = block.hash_slow(); + let excess_blob_gas = block.excess_blob_gas; + let Some(receipts) = block + .body .into_iter() - .map(|r| { - // todo - reduce alloc? - // RLP encode the receipt with a bloom filter. - let mut buf = Vec::default(); - r.with_bloom().encode(&mut buf); - - // Return a pointer to the `buf` and its length - let res = ByteArray { - data: buf.as_mut_ptr(), - len: buf.len(), + .zip(receipts.clone()) + .enumerate() + .map(|(idx, (tx, receipt))| { + let meta = TransactionMeta { + tx_hash: tx.hash, + index: idx as u64, + block_hash, + block_number, + base_fee, + excess_blob_gas, }; - - // Forget the `buf` so that its memory isn't freed by the - // borrow checker at the end of this scope - std::mem::forget(buf); - - res + build_transaction_receipt_with_block_receipts(tx, meta, receipt, &receipts) }) - .collect::>(); + .collect::>>() + else { + return ReceiptsResult::fail(); + }; - let result = ByteArrays { - data: receipts_rlp.as_ptr() as *mut ByteArray, - len: receipts_rlp.len(), + // Convert the receipts to JSON for transport + let Ok(mut receipts_json) = serde_json::to_string(&receipts) else { + return ReceiptsResult::fail(); }; - // Forget the `receipts_rlp` arr so that its memory isn't freed by the + let res = + ReceiptsResult::success(receipts_json.as_mut_ptr() as *mut char, receipts_json.len()); + + // Forget the `receipts_json` string so that its memory isn't freed by the // borrow checker at the end of this scope - std::mem::forget(receipts_rlp); // Prevent Rust from freeing the memory + std::mem::forget(receipts_json); // Prevent Rust from freeing the memory - ReceiptsResult::success(result) + res } else { - return ReceiptsResult::fail(); + ReceiptsResult::fail() } } -/// Free the [ByteArrays] data structure and its sub-components when they are no longer needed. +/// Free a string that was allocated in Rust and passed to C. #[no_mangle] -pub extern "C" fn free_byte_arrays(arrays: ByteArrays) { +pub extern "C" fn free_string(string: *mut c_char) { unsafe { - let arrays = Vec::from_raw_parts(arrays.data, arrays.len, arrays.len); - for inner_array in arrays { - let _ = Vec::from_raw_parts(inner_array.data, inner_array.len, inner_array.len); + // Convert the raw pointer back to a CString and let it go out of scope, + // which will deallocate the memory. + if !string.is_null() { + let _ = std::ffi::CString::from_raw(string); + } + } +} + +pub(crate) fn build_transaction_receipt_with_block_receipts( + tx: TransactionSigned, + meta: TransactionMeta, + receipt: Receipt, + all_receipts: &[Receipt], +) -> Option { + let transaction = tx.clone().into_ecrecovered()?; + + // get the previous transaction cumulative gas used + let gas_used = if meta.index == 0 { + receipt.cumulative_gas_used + } else { + let prev_tx_idx = (meta.index - 1) as usize; + all_receipts + .get(prev_tx_idx) + .map(|prev_receipt| receipt.cumulative_gas_used - prev_receipt.cumulative_gas_used) + .unwrap_or_default() + }; + + let mut res_receipt = TransactionReceipt { + transaction_hash: Some(meta.tx_hash), + transaction_index: U64::from(meta.index), + block_hash: Some(meta.block_hash), + block_number: Some(U256::from(meta.block_number)), + from: transaction.signer(), + to: None, + cumulative_gas_used: U256::from(receipt.cumulative_gas_used), + gas_used: Some(U256::from(gas_used)), + contract_address: None, + logs: Vec::with_capacity(receipt.logs.len()), + effective_gas_price: U128::from(transaction.effective_gas_price(meta.base_fee)), + transaction_type: tx.transaction.tx_type().into(), + // TODO pre-byzantium receipts have a post-transaction state root + state_root: None, + logs_bloom: receipt.bloom_slow(), + status_code: if receipt.success { + Some(U64::from(1)) + } else { + Some(U64::from(0)) + }, + + // EIP-4844 fields + blob_gas_price: meta.excess_blob_gas.map(calc_blob_gasprice).map(U128::from), + blob_gas_used: transaction.transaction.blob_gas_used().map(U128::from), + }; + + match tx.transaction.kind() { + reth::primitives::TransactionKind::Create => { + res_receipt.contract_address = + Some(transaction.signer().create(tx.transaction.nonce())); + } + reth::primitives::TransactionKind::Call(addr) => { + res_receipt.to = Some(*addr); } } + + // get number of logs in the block + let mut num_logs = 0; + for prev_receipt in all_receipts.iter().take(meta.index as usize) { + num_logs += prev_receipt.logs.len(); + } + + for (tx_log_idx, log) in receipt.logs.into_iter().enumerate() { + let rpclog = Log { + address: log.address, + topics: log.topics, + data: log.data, + block_hash: Some(meta.block_hash), + block_number: Some(U256::from(meta.block_number)), + transaction_hash: Some(meta.tx_hash), + transaction_index: Some(U256::from(meta.index)), + log_index: Some(U256::from(num_logs + tx_log_idx)), + removed: false, + }; + res_receipt.logs.push(rpclog); + } + + Some(res_receipt) } diff --git a/op-service/sources/reth_db.go b/op-service/sources/reth_db.go index 58a4aebe0f5a..a7c1da5f9dff 100644 --- a/op-service/sources/reth_db.go +++ b/op-service/sources/reth_db.go @@ -1,8 +1,11 @@ package sources import ( + "encoding/json" "fmt" + "unsafe" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) @@ -14,26 +17,15 @@ import ( #include typedef struct { - uint8_t* data; - size_t len; -} ByteArray; - -typedef struct { - ByteArray* data; - size_t len; -} ByteArrays; - -// Define ReceiptsResult with a bool for error -typedef struct { - ByteArrays receipts; + char* data; + size_t data_len; bool error; } ReceiptsResult; extern ReceiptsResult read_receipts(const uint8_t* block_hash, size_t block_hash_len, const char* db_path); -extern void free_byte_arrays(ByteArrays arrays); +extern void free_string(char* string); */ import "C" -import "unsafe" // FetchRethReceipts fetches the receipts for the given block hash directly from the Reth Database // and populates the given results slice pointer with the receipts that were found. @@ -51,23 +43,19 @@ func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, e defer C.free(unsafe.Pointer(cDbPath)) // Call the C function to fetch the receipts from the Reth Database - byteArrayStruct := C.read_receipts((*C.uint8_t)(cBlockHash), C.size_t(len(blockHash)), cDbPath) + receiptsResult := C.read_receipts((*C.uint8_t)(cBlockHash), C.size_t(len(blockHash)), cDbPath) - if byteArrayStruct.error { + if receiptsResult.error { return nil, fmt.Errorf("Error fetching receipts from Reth Database.") } - // Convert the returned receipt RLP byte arrays to decoded Receipts. - data := make(types.Receipts, byteArrayStruct.receipts.len) - byteArraySlice := (*[1 << 30]C.ByteArray)(unsafe.Pointer(byteArrayStruct.receipts.data))[:byteArrayStruct.receipts.len:byteArrayStruct.receipts.len] - for i, byteArray := range byteArraySlice { - receipt := types.Receipt{} - receipt.UnmarshalBinary(C.GoBytes(unsafe.Pointer(byteArray.data), C.int(byteArray.len))) - data[i] = &receipt - } + // Convert the returned JSON string to Go string and parse it + receiptsJSON := C.GoStringN(receiptsResult.data, C.int(receiptsResult.data_len)) + var receipts types.Receipts + json.Unmarshal([]byte(receiptsJSON), &receipts) // Free the memory allocated by the C code - C.free_byte_arrays(byteArrayStruct.receipts) + C.free_string(receiptsResult.data) - return data, nil + return receipts, nil } From 4aacef463858f97af7f0853ed2e863773a2d3459 Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 26 Oct 2023 23:32:12 -0400 Subject: [PATCH 095/374] :broom: --- op-node/node/node.go | 1 + op-service/rethdb-reader/src/lib.rs | 3 ++- op-service/sources/reth_db.go | 4 +++- op-service/sources/reth_db_test.go | 22 ---------------------- 4 files changed, 6 insertions(+), 24 deletions(-) delete mode 100644 op-service/sources/reth_db_test.go diff --git a/op-node/node/node.go b/op-node/node/node.go index 78639fec731b..c2bcedb0b893 100644 --- a/op-node/node/node.go +++ b/op-node/node/node.go @@ -156,6 +156,7 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error { return fmt.Errorf("failed to get L1 RPC client: %w", err) } + // Set the RethDB path in the EthClientConfig, if there is one configured. rpcCfg.EthClientConfig.RethDBPath = cfg.RethDBPath n.l1Source, err = sources.NewL1Client( diff --git a/op-service/rethdb-reader/src/lib.rs b/op-service/rethdb-reader/src/lib.rs index 9eb2442a3159..0d94747ddbd4 100644 --- a/op-service/rethdb-reader/src/lib.rs +++ b/op-service/rethdb-reader/src/lib.rs @@ -138,7 +138,8 @@ pub extern "C" fn free_string(string: *mut c_char) { } } -pub(crate) fn build_transaction_receipt_with_block_receipts( +#[inline(always)] +fn build_transaction_receipt_with_block_receipts( tx: TransactionSigned, meta: TransactionMeta, receipt: Receipt, diff --git a/op-service/sources/reth_db.go b/op-service/sources/reth_db.go index a7c1da5f9dff..d507e2f45f38 100644 --- a/op-service/sources/reth_db.go +++ b/op-service/sources/reth_db.go @@ -52,7 +52,9 @@ func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, e // Convert the returned JSON string to Go string and parse it receiptsJSON := C.GoStringN(receiptsResult.data, C.int(receiptsResult.data_len)) var receipts types.Receipts - json.Unmarshal([]byte(receiptsJSON), &receipts) + if err := json.Unmarshal([]byte(receiptsJSON), &receipts); err != nil { + return nil, err + } // Free the memory allocated by the C code C.free_string(receiptsResult.data) diff --git a/op-service/sources/reth_db_test.go b/op-service/sources/reth_db_test.go deleted file mode 100644 index ecb793895e0d..000000000000 --- a/op-service/sources/reth_db_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package sources - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" -) - -func TestRethReceiptsLoad(t *testing.T) { - t.Skip("Skipping test that requires a local L1 Goerli Reth DB") - t.Parallel() - - // block = https://goerli.etherscan.io/block/994113 - blockHash := common.HexToHash("0x6f6f00553e4f74262a9812927afd11c341730c5c9210824fe172367457adb5f6") - res, err := FetchRethReceipts("/path/to/goerli-db", &blockHash) - require.NoError(t, err, "Failed to fetch receipts from Reth DB") - require.Len(t, res, 2, "Expected 2 receipts to be returned") - require.Equal(t, res[0].Type, 0) - require.Equal(t, res[0].CumulativeGasUsed, uint64(93_787)) - require.Equal(t, res[0].Status, uint64(1)) -} From 0a25b054e0f206f0d13e1b9ed3137ab6417d495f Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 26 Oct 2023 23:39:05 -0400 Subject: [PATCH 096/374] Stub out rethdb receipt fetcher with `rethdb` build tag --- op-service/sources/reth_db.go | 2 ++ op-service/sources/reth_db_stub.go | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 op-service/sources/reth_db_stub.go diff --git a/op-service/sources/reth_db.go b/op-service/sources/reth_db.go index d507e2f45f38..71b8d2a78c9f 100644 --- a/op-service/sources/reth_db.go +++ b/op-service/sources/reth_db.go @@ -1,3 +1,5 @@ +//go:build rethdb + package sources import ( diff --git a/op-service/sources/reth_db_stub.go b/op-service/sources/reth_db_stub.go new file mode 100644 index 000000000000..d55db52ef851 --- /dev/null +++ b/op-service/sources/reth_db_stub.go @@ -0,0 +1,13 @@ +//go:build !rethdb + +package sources + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// FetchRethReceipts fetches the receipts for the given block hash... +func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, error) { + panic("unimplemented!") +} From 7f12a6dc49baead76cc64e227fb2c289febfa4d5 Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 27 Oct 2023 00:17:07 -0400 Subject: [PATCH 097/374] Update op-service/sources/reth_db_stub.go --- op-service/sources/reth_db_stub.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/op-service/sources/reth_db_stub.go b/op-service/sources/reth_db_stub.go index d55db52ef851..be685a1d5a9c 100644 --- a/op-service/sources/reth_db_stub.go +++ b/op-service/sources/reth_db_stub.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) -// FetchRethReceipts fetches the receipts for the given block hash... +// FetchRethReceipts stub; Not available without `rethdb` build tag. func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, error) { - panic("unimplemented!") + panic("unimplemented! Did you forget to enable the `rethdb` build tag?") } From b2bc54308eac4c0174fc3863e76016e9ab5842f8 Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 27 Oct 2023 00:17:43 -0400 Subject: [PATCH 098/374] update comment --- op-service/sources/receipts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-service/sources/receipts.go b/op-service/sources/receipts.go index 624379129707..2d60bb959716 100644 --- a/op-service/sources/receipts.go +++ b/op-service/sources/receipts.go @@ -278,7 +278,7 @@ const ( // Params: // - Reth: string, hex-encoded block hash // Returns: - // - Reth: array of RLP-encoded receipts + // - Reth: string, json-ified receipts // See: // - reth's DB crate documentation: https://github.com/paradigmxyz/reth/blob/main/docs/crates/db.md RethGetBlockReceipts From 51da1fcf3fb8c988116577e99f27d543b6b7fa31 Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 27 Oct 2023 01:08:37 -0400 Subject: [PATCH 099/374] :broom: --- op-service/rethdb-reader/src/lib.rs | 63 ++++++++++++++++------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/op-service/rethdb-reader/src/lib.rs b/op-service/rethdb-reader/src/lib.rs index 0d94747ddbd4..c7852000115a 100644 --- a/op-service/rethdb-reader/src/lib.rs +++ b/op-service/rethdb-reader/src/lib.rs @@ -1,15 +1,14 @@ use reth::{ blockchain_tree::noop::NoopBlockchainTree, primitives::{ - BlockHashOrNumber, ChainSpecBuilder, Receipt, TransactionMeta, TransactionSigned, U128, - U256, U64, + BlockHashOrNumber, Receipt, TransactionKind, TransactionMeta, TransactionSigned, MAINNET, + U128, U256, U64, }, providers::{providers::BlockchainProvider, BlockReader, ProviderFactory, ReceiptProvider}, - revm::primitives::calc_blob_gasprice, rpc::types::{Log, TransactionReceipt}, utils::db::open_db_read_only, }; -use std::{os::raw::c_char, path::Path, sync::Arc}; +use std::{os::raw::c_char, path::Path}; #[repr(C)] pub struct ReceiptsResult { @@ -38,45 +37,51 @@ impl ReceiptsResult { /// Read the receipts for a blockhash from the RETH database directly. /// -/// WARNING: Will panic on error. -/// TODO: Gracefully return OK status. +/// # Safety +/// - All possible nil pointer dereferences are checked, and the function will return a +/// failing [ReceiptsResult] if any are found. #[no_mangle] -pub extern "C" fn read_receipts( +pub unsafe extern "C" fn read_receipts( block_hash: *const u8, block_hash_len: usize, db_path: *const c_char, ) -> ReceiptsResult { // Convert the raw pointer and length back to a Rust slice - let Ok(block_hash): Result<[u8; 32], _> = - unsafe { std::slice::from_raw_parts(block_hash, block_hash_len) }.try_into() - else { + let Ok(block_hash): Result<[u8; 32], _> = { + if block_hash.is_null() { + return ReceiptsResult::fail(); + } + std::slice::from_raw_parts(block_hash, block_hash_len) + } + .try_into() else { return ReceiptsResult::fail(); }; // Convert the *const c_char to a Rust &str - let Ok(db_path_str) = unsafe { - assert!(!db_path.is_null(), "Null pointer for database path"); + let Ok(db_path_str) = { + if db_path.is_null() { + return ReceiptsResult::fail(); + } std::ffi::CStr::from_ptr(db_path) } .to_str() else { return ReceiptsResult::fail(); }; - let Ok(db) = open_db_read_only(&Path::new(db_path_str), None) else { + let Ok(db) = open_db_read_only(Path::new(db_path_str), None) else { return ReceiptsResult::fail(); }; - let spec = Arc::new(ChainSpecBuilder::mainnet().build()); - let factory = ProviderFactory::new(db, spec.clone()); + let factory = ProviderFactory::new(db, MAINNET.clone()); // Create a read-only BlockChainProvider let Ok(provider) = BlockchainProvider::new(factory, NoopBlockchainTree::default()) else { return ReceiptsResult::fail(); }; + // Fetch the block and the receipts within it let Ok(block) = provider.block_by_hash(block_hash.into()) else { return ReceiptsResult::fail(); }; - let Ok(receipts) = provider.receipts_by_block(BlockHashOrNumber::Hash(block_hash.into())) else { return ReceiptsResult::fail(); @@ -86,7 +91,6 @@ pub extern "C" fn read_receipts( let block_number = block.number; let base_fee = block.base_fee_per_gas; let block_hash = block.hash_slow(); - let excess_blob_gas = block.excess_blob_gas; let Some(receipts) = block .body .into_iter() @@ -99,7 +103,7 @@ pub extern "C" fn read_receipts( block_hash, block_number, base_fee, - excess_blob_gas, + excess_blob_gas: None, }; build_transaction_receipt_with_block_receipts(tx, meta, receipt, &receipts) }) @@ -127,14 +131,15 @@ pub extern "C" fn read_receipts( } /// Free a string that was allocated in Rust and passed to C. +/// +/// # Safety +/// - All possible nil pointer dereferences are checked. #[no_mangle] -pub extern "C" fn free_string(string: *mut c_char) { - unsafe { - // Convert the raw pointer back to a CString and let it go out of scope, - // which will deallocate the memory. - if !string.is_null() { - let _ = std::ffi::CString::from_raw(string); - } +pub unsafe extern "C" fn free_string(string: *mut c_char) { + // Convert the raw pointer back to a CString and let it go out of scope, + // which will deallocate the memory. + if !string.is_null() { + let _ = std::ffi::CString::from_raw(string); } } @@ -181,16 +186,16 @@ fn build_transaction_receipt_with_block_receipts( }, // EIP-4844 fields - blob_gas_price: meta.excess_blob_gas.map(calc_blob_gasprice).map(U128::from), - blob_gas_used: transaction.transaction.blob_gas_used().map(U128::from), + blob_gas_price: None, + blob_gas_used: None, }; match tx.transaction.kind() { - reth::primitives::TransactionKind::Create => { + TransactionKind::Create => { res_receipt.contract_address = Some(transaction.signer().create(tx.transaction.nonce())); } - reth::primitives::TransactionKind::Call(addr) => { + TransactionKind::Call(addr) => { res_receipt.to = Some(*addr); } } From e9a8f81af8b7a2eccf72ee258952fe9d0b13fc31 Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 27 Oct 2023 01:18:40 -0400 Subject: [PATCH 100/374] Add C header rustdoc --- op-service/rethdb-reader/README.md | 37 ++++++++++++++++++++++++++++- op-service/rethdb-reader/src/lib.rs | 14 +++++++++++ op-service/sources/reth_db_test.go | 16 +++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 op-service/sources/reth_db_test.go diff --git a/op-service/rethdb-reader/README.md b/op-service/rethdb-reader/README.md index e8d9f0d26c02..878cfd2c8662 100644 --- a/op-service/rethdb-reader/README.md +++ b/op-service/rethdb-reader/README.md @@ -1,4 +1,39 @@ # `rethdb-reader` -Exported Rust code to be used via FFI in `op-service`'s `sources` package for reading information +A dylib to be accessed via FFI in `op-service`'s `sources` package for reading information directly from the `reth` database. + +### C Header + +```c +#include +#include +#include +#include +#include + +struct ReceiptsResult { + uint32_t *data; + uintptr_t data_len; + bool error; +}; + +extern "C" { + +/// Read the receipts for a blockhash from the RETH database directly. +/// +/// # Safety +/// - All possible nil pointer dereferences are checked, and the function will return a +/// failing [ReceiptsResult] if any are found. +ReceiptsResult read_receipts(const uint8_t *block_hash, + uintptr_t block_hash_len, + const char *db_path); + +/// Free a string that was allocated in Rust and passed to C. +/// +/// # Safety +/// - All possible nil pointer dereferences are checked. +void free_string(char *string); + +} +``` diff --git a/op-service/rethdb-reader/src/lib.rs b/op-service/rethdb-reader/src/lib.rs index c7852000115a..2382f480623a 100644 --- a/op-service/rethdb-reader/src/lib.rs +++ b/op-service/rethdb-reader/src/lib.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("../README.md")] + use reth::{ blockchain_tree::noop::NoopBlockchainTree, primitives::{ @@ -10,6 +12,12 @@ use reth::{ }; use std::{os::raw::c_char, path::Path}; +/// A [ReceiptsResult] is a wrapper around a JSON string containing serialized [TransactionReceipt]s +/// as well as an error status that is compatible with FFI. +/// +/// # Safety +/// - When the `error` field is false, the `data` pointer is guaranteed to be valid. +/// - When the `error` field is true, the `data` pointer is guaranteed to be null. #[repr(C)] pub struct ReceiptsResult { data: *mut char, @@ -18,6 +26,7 @@ pub struct ReceiptsResult { } impl ReceiptsResult { + /// Constructs a successful [ReceiptsResult] from a JSON string. pub fn success(data: *mut char, data_len: usize) -> Self { Self { data, @@ -26,6 +35,7 @@ impl ReceiptsResult { } } + /// Constructs a failing [ReceiptsResult] with a null pointer to the data. pub fn fail() -> Self { Self { data: std::ptr::null_mut(), @@ -143,6 +153,10 @@ pub unsafe extern "C" fn free_string(string: *mut c_char) { } } +/// Builds a hydrated [TransactionReceipt] from information in the passed transaction, +/// receipt, and block receipts. +/// +/// Returns [None] if the transaction's sender could not be recovered from the signature. #[inline(always)] fn build_transaction_receipt_with_block_receipts( tx: TransactionSigned, diff --git a/op-service/sources/reth_db_test.go b/op-service/sources/reth_db_test.go new file mode 100644 index 000000000000..73048f7be0d2 --- /dev/null +++ b/op-service/sources/reth_db_test.go @@ -0,0 +1,16 @@ +package sources + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +func TestRethDBRead(t *testing.T) { + t.Parallel() + + _, err := FetchRethReceipts("/test", &common.Hash{}) + if err != nil { + panic("test") + } +} From 679eb237d63faec1ba861b09664f0586d4039b5a Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 27 Oct 2023 01:44:34 -0400 Subject: [PATCH 101/374] :broom: dylib --- op-service/rethdb-reader/.gitignore | 3 + op-service/rethdb-reader/Cargo.lock | 1 + op-service/rethdb-reader/Cargo.toml | 1 + op-service/rethdb-reader/README.md | 94 +++++++--- op-service/rethdb-reader/headgen.sh | 16 ++ op-service/rethdb-reader/src/lib.rs | 214 +---------------------- op-service/rethdb-reader/src/receipts.rs | 211 ++++++++++++++++++++++ op-service/sources/reth_db_test.go | 16 -- 8 files changed, 305 insertions(+), 251 deletions(-) create mode 100755 op-service/rethdb-reader/headgen.sh create mode 100644 op-service/rethdb-reader/src/receipts.rs delete mode 100644 op-service/sources/reth_db_test.go diff --git a/op-service/rethdb-reader/.gitignore b/op-service/rethdb-reader/.gitignore index 9004537baafa..96359724ffbc 100644 --- a/op-service/rethdb-reader/.gitignore +++ b/op-service/rethdb-reader/.gitignore @@ -1,2 +1,5 @@ # Target target/ + +# Bindings +rdb.h diff --git a/op-service/rethdb-reader/Cargo.lock b/op-service/rethdb-reader/Cargo.lock index ef918a166b1f..14622c0a8c03 100644 --- a/op-service/rethdb-reader/Cargo.lock +++ b/op-service/rethdb-reader/Cargo.lock @@ -5360,6 +5360,7 @@ dependencies = [ name = "rethdb-reader" version = "0.1.0" dependencies = [ + "anyhow", "reth", "serde", "serde_json", diff --git a/op-service/rethdb-reader/Cargo.toml b/op-service/rethdb-reader/Cargo.toml index ac53bea511b8..c73662970ad1 100644 --- a/op-service/rethdb-reader/Cargo.toml +++ b/op-service/rethdb-reader/Cargo.toml @@ -12,3 +12,4 @@ crate-type = ["cdylib"] reth = { git = "https://github.com/paradigmxyz/reth.git" } serde = "1.0.190" serde_json = "1.0.107" +anyhow = "1.0.75" diff --git a/op-service/rethdb-reader/README.md b/op-service/rethdb-reader/README.md index 878cfd2c8662..430fe8f96b0b 100644 --- a/op-service/rethdb-reader/README.md +++ b/op-service/rethdb-reader/README.md @@ -3,37 +3,81 @@ A dylib to be accessed via FFI in `op-service`'s `sources` package for reading information directly from the `reth` database. +## Developing + +**Building** + +To build the dylib, you must first have the [Rust Toolchain][rust-toolchain] installed. + +```sh +cargo build --release +``` + +**Docs** + +Documentation is available via rustdoc. + +```sh +cargo doc --open +``` + +**Linting** + +```sh +cargo +nightly fmt -- && cargo +nightly clippy --all --all-features -- -D warnings +``` + +**Generating the C header** + +To generate the C header, first install `cbindgen` via `cargo install cbindgen --force`. Then, run the generation script: + +```sh +./headgen.sh +``` + ### C Header +The C header below is generated by `cbindgen`, and it is the interface that consumers of the dylib use to call its exported +functions. Currently, the only exported functions pertain to reading fully hydrated block receipts from the database. + ```c -#include -#include -#include -#include -#include +#include +#include +#include +#include -struct ReceiptsResult { +/** + * A [ReceiptsResult] is a wrapper around a JSON string containing serialized [TransactionReceipt]s + * as well as an error status that is compatible with FFI. + * + * # Safety + * - When the `error` field is false, the `data` pointer is guaranteed to be valid. + * - When the `error` field is true, the `data` pointer is guaranteed to be null. + */ +typedef struct ReceiptsResult { uint32_t *data; uintptr_t data_len; bool error; -}; - -extern "C" { - -/// Read the receipts for a blockhash from the RETH database directly. -/// -/// # Safety -/// - All possible nil pointer dereferences are checked, and the function will return a -/// failing [ReceiptsResult] if any are found. -ReceiptsResult read_receipts(const uint8_t *block_hash, - uintptr_t block_hash_len, - const char *db_path); - -/// Free a string that was allocated in Rust and passed to C. -/// -/// # Safety -/// - All possible nil pointer dereferences are checked. -void free_string(char *string); +} ReceiptsResult; + +/** + * Read the receipts for a blockhash from the RETH database directly. + * + * # Safety + * - All possible nil pointer dereferences are checked, and the function will return a + * failing [ReceiptsResult] if any are found. + */ +struct ReceiptsResult read_receipts(const uint8_t *block_hash, + uintptr_t block_hash_len, + const char *db_path); -} +/** + * Free a string that was allocated in Rust and passed to C. + * + * # Safety + * - All possible nil pointer dereferences are checked. + */ +void free_string(char *string); ``` + +[rust-toolchain]: https://rustup.rs/ diff --git a/op-service/rethdb-reader/headgen.sh b/op-service/rethdb-reader/headgen.sh new file mode 100755 index 000000000000..e7f7daf676d4 --- /dev/null +++ b/op-service/rethdb-reader/headgen.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Generate rdb.h +cbindgen --crate rethdb-reader --output rdb.h -l C + +# Process README.md to replace the content within the specified code block +awk ' + BEGIN { in_code_block=0; } + /^```c/ { in_code_block=1; print; next; } + /^```/ && in_code_block { in_code_block=0; while ((getline line < "rdb.h") > 0) print line; } + !in_code_block { print; } +' README.md > README.tmp && mv README.tmp README.md + +echo "Generated C header successfully" diff --git a/op-service/rethdb-reader/src/lib.rs b/op-service/rethdb-reader/src/lib.rs index 2382f480623a..1d3f3b0eb10c 100644 --- a/op-service/rethdb-reader/src/lib.rs +++ b/op-service/rethdb-reader/src/lib.rs @@ -1,49 +1,9 @@ #![doc = include_str!("../README.md")] -use reth::{ - blockchain_tree::noop::NoopBlockchainTree, - primitives::{ - BlockHashOrNumber, Receipt, TransactionKind, TransactionMeta, TransactionSigned, MAINNET, - U128, U256, U64, - }, - providers::{providers::BlockchainProvider, BlockReader, ProviderFactory, ReceiptProvider}, - rpc::types::{Log, TransactionReceipt}, - utils::db::open_db_read_only, -}; -use std::{os::raw::c_char, path::Path}; +use receipts::{read_receipts_inner, ReceiptsResult}; +use std::os::raw::c_char; -/// A [ReceiptsResult] is a wrapper around a JSON string containing serialized [TransactionReceipt]s -/// as well as an error status that is compatible with FFI. -/// -/// # Safety -/// - When the `error` field is false, the `data` pointer is guaranteed to be valid. -/// - When the `error` field is true, the `data` pointer is guaranteed to be null. -#[repr(C)] -pub struct ReceiptsResult { - data: *mut char, - data_len: usize, - error: bool, -} - -impl ReceiptsResult { - /// Constructs a successful [ReceiptsResult] from a JSON string. - pub fn success(data: *mut char, data_len: usize) -> Self { - Self { - data, - data_len, - error: false, - } - } - - /// Constructs a failing [ReceiptsResult] with a null pointer to the data. - pub fn fail() -> Self { - Self { - data: std::ptr::null_mut(), - data_len: 0, - error: true, - } - } -} +mod receipts; /// Read the receipts for a blockhash from the RETH database directly. /// @@ -56,88 +16,7 @@ pub unsafe extern "C" fn read_receipts( block_hash_len: usize, db_path: *const c_char, ) -> ReceiptsResult { - // Convert the raw pointer and length back to a Rust slice - let Ok(block_hash): Result<[u8; 32], _> = { - if block_hash.is_null() { - return ReceiptsResult::fail(); - } - std::slice::from_raw_parts(block_hash, block_hash_len) - } - .try_into() else { - return ReceiptsResult::fail(); - }; - - // Convert the *const c_char to a Rust &str - let Ok(db_path_str) = { - if db_path.is_null() { - return ReceiptsResult::fail(); - } - std::ffi::CStr::from_ptr(db_path) - } - .to_str() else { - return ReceiptsResult::fail(); - }; - - let Ok(db) = open_db_read_only(Path::new(db_path_str), None) else { - return ReceiptsResult::fail(); - }; - let factory = ProviderFactory::new(db, MAINNET.clone()); - - // Create a read-only BlockChainProvider - let Ok(provider) = BlockchainProvider::new(factory, NoopBlockchainTree::default()) else { - return ReceiptsResult::fail(); - }; - - // Fetch the block and the receipts within it - let Ok(block) = provider.block_by_hash(block_hash.into()) else { - return ReceiptsResult::fail(); - }; - let Ok(receipts) = provider.receipts_by_block(BlockHashOrNumber::Hash(block_hash.into())) - else { - return ReceiptsResult::fail(); - }; - - if let (Some(block), Some(receipts)) = (block, receipts) { - let block_number = block.number; - let base_fee = block.base_fee_per_gas; - let block_hash = block.hash_slow(); - let Some(receipts) = block - .body - .into_iter() - .zip(receipts.clone()) - .enumerate() - .map(|(idx, (tx, receipt))| { - let meta = TransactionMeta { - tx_hash: tx.hash, - index: idx as u64, - block_hash, - block_number, - base_fee, - excess_blob_gas: None, - }; - build_transaction_receipt_with_block_receipts(tx, meta, receipt, &receipts) - }) - .collect::>>() - else { - return ReceiptsResult::fail(); - }; - - // Convert the receipts to JSON for transport - let Ok(mut receipts_json) = serde_json::to_string(&receipts) else { - return ReceiptsResult::fail(); - }; - - let res = - ReceiptsResult::success(receipts_json.as_mut_ptr() as *mut char, receipts_json.len()); - - // Forget the `receipts_json` string so that its memory isn't freed by the - // borrow checker at the end of this scope - std::mem::forget(receipts_json); // Prevent Rust from freeing the memory - - res - } else { - ReceiptsResult::fail() - } + read_receipts_inner(block_hash, block_hash_len, db_path).unwrap_or(ReceiptsResult::fail()) } /// Free a string that was allocated in Rust and passed to C. @@ -152,88 +31,3 @@ pub unsafe extern "C" fn free_string(string: *mut c_char) { let _ = std::ffi::CString::from_raw(string); } } - -/// Builds a hydrated [TransactionReceipt] from information in the passed transaction, -/// receipt, and block receipts. -/// -/// Returns [None] if the transaction's sender could not be recovered from the signature. -#[inline(always)] -fn build_transaction_receipt_with_block_receipts( - tx: TransactionSigned, - meta: TransactionMeta, - receipt: Receipt, - all_receipts: &[Receipt], -) -> Option { - let transaction = tx.clone().into_ecrecovered()?; - - // get the previous transaction cumulative gas used - let gas_used = if meta.index == 0 { - receipt.cumulative_gas_used - } else { - let prev_tx_idx = (meta.index - 1) as usize; - all_receipts - .get(prev_tx_idx) - .map(|prev_receipt| receipt.cumulative_gas_used - prev_receipt.cumulative_gas_used) - .unwrap_or_default() - }; - - let mut res_receipt = TransactionReceipt { - transaction_hash: Some(meta.tx_hash), - transaction_index: U64::from(meta.index), - block_hash: Some(meta.block_hash), - block_number: Some(U256::from(meta.block_number)), - from: transaction.signer(), - to: None, - cumulative_gas_used: U256::from(receipt.cumulative_gas_used), - gas_used: Some(U256::from(gas_used)), - contract_address: None, - logs: Vec::with_capacity(receipt.logs.len()), - effective_gas_price: U128::from(transaction.effective_gas_price(meta.base_fee)), - transaction_type: tx.transaction.tx_type().into(), - // TODO pre-byzantium receipts have a post-transaction state root - state_root: None, - logs_bloom: receipt.bloom_slow(), - status_code: if receipt.success { - Some(U64::from(1)) - } else { - Some(U64::from(0)) - }, - - // EIP-4844 fields - blob_gas_price: None, - blob_gas_used: None, - }; - - match tx.transaction.kind() { - TransactionKind::Create => { - res_receipt.contract_address = - Some(transaction.signer().create(tx.transaction.nonce())); - } - TransactionKind::Call(addr) => { - res_receipt.to = Some(*addr); - } - } - - // get number of logs in the block - let mut num_logs = 0; - for prev_receipt in all_receipts.iter().take(meta.index as usize) { - num_logs += prev_receipt.logs.len(); - } - - for (tx_log_idx, log) in receipt.logs.into_iter().enumerate() { - let rpclog = Log { - address: log.address, - topics: log.topics, - data: log.data, - block_hash: Some(meta.block_hash), - block_number: Some(U256::from(meta.block_number)), - transaction_hash: Some(meta.tx_hash), - transaction_index: Some(U256::from(meta.index)), - log_index: Some(U256::from(num_logs + tx_log_idx)), - removed: false, - }; - res_receipt.logs.push(rpclog); - } - - Some(res_receipt) -} diff --git a/op-service/rethdb-reader/src/receipts.rs b/op-service/rethdb-reader/src/receipts.rs new file mode 100644 index 000000000000..3f17daff74bd --- /dev/null +++ b/op-service/rethdb-reader/src/receipts.rs @@ -0,0 +1,211 @@ +//! This module contains the logic for reading a block's fully hydrated receipts directly from the +//! [reth] database. + +use anyhow::{anyhow, Result}; +use reth::{ + blockchain_tree::noop::NoopBlockchainTree, + primitives::{ + BlockHashOrNumber, Receipt, TransactionKind, TransactionMeta, TransactionSigned, MAINNET, + U128, U256, U64, + }, + providers::{providers::BlockchainProvider, BlockReader, ProviderFactory, ReceiptProvider}, + rpc::types::{Log, TransactionReceipt}, + utils::db::open_db_read_only, +}; +use std::{ffi::c_char, path::Path}; + +/// A [ReceiptsResult] is a wrapper around a JSON string containing serialized [TransactionReceipt]s +/// as well as an error status that is compatible with FFI. +/// +/// # Safety +/// - When the `error` field is false, the `data` pointer is guaranteed to be valid. +/// - When the `error` field is true, the `data` pointer is guaranteed to be null. +#[repr(C)] +pub struct ReceiptsResult { + data: *mut char, + data_len: usize, + error: bool, +} + +impl ReceiptsResult { + /// Constructs a successful [ReceiptsResult] from a JSON string. + pub fn success(data: *mut char, data_len: usize) -> Self { + Self { + data, + data_len, + error: false, + } + } + + /// Constructs a failing [ReceiptsResult] with a null pointer to the data. + pub fn fail() -> Self { + Self { + data: std::ptr::null_mut(), + data_len: 0, + error: true, + } + } +} + +/// Read the receipts for a blockhash from the RETH database directly. +/// +/// # Safety +/// - All possible nil pointer dereferences are checked, and the function will return a +/// failing [ReceiptsResult] if any are found. +#[inline(always)] +pub(crate) unsafe fn read_receipts_inner( + block_hash: *const u8, + block_hash_len: usize, + db_path: *const c_char, +) -> Result { + // Convert the raw pointer and length back to a Rust slice + let block_hash: [u8; 32] = { + if block_hash.is_null() { + anyhow::bail!("block_hash pointer is null"); + } + std::slice::from_raw_parts(block_hash, block_hash_len) + } + .try_into()?; + + // Convert the *const c_char to a Rust &str + let db_path_str = { + if db_path.is_null() { + anyhow::bail!("db path pointer is null"); + } + std::ffi::CStr::from_ptr(db_path) + } + .to_str()?; + + let db = open_db_read_only(Path::new(db_path_str), None).map_err(|e| anyhow!(e))?; + let factory = ProviderFactory::new(db, MAINNET.clone()); + + // Create a read-only BlockChainProvider + let provider = BlockchainProvider::new(factory, NoopBlockchainTree::default())?; + + // Fetch the block and the receipts within it + let block = provider + .block_by_hash(block_hash.into())? + .ok_or(anyhow!("Failed to fetch block"))?; + let receipts = provider + .receipts_by_block(BlockHashOrNumber::Hash(block_hash.into()))? + .ok_or(anyhow!("Failed to fetch block receipts"))?; + + let block_number = block.number; + let base_fee = block.base_fee_per_gas; + let block_hash = block.hash_slow(); + let receipts = block + .body + .into_iter() + .zip(receipts.clone()) + .enumerate() + .map(|(idx, (tx, receipt))| { + let meta = TransactionMeta { + tx_hash: tx.hash, + index: idx as u64, + block_hash, + block_number, + base_fee, + excess_blob_gas: None, + }; + build_transaction_receipt_with_block_receipts(tx, meta, receipt, &receipts) + }) + .collect::>>() + .ok_or(anyhow!("Failed to build receipts"))?; + + // Convert the receipts to JSON for transport + let mut receipts_json = serde_json::to_string(&receipts)?; + + // Create a ReceiptsResult with a pointer to the json-ified receipts + let res = ReceiptsResult::success(receipts_json.as_mut_ptr() as *mut char, receipts_json.len()); + + // Forget the `receipts_json` string so that its memory isn't freed by the + // borrow checker at the end of this scope + std::mem::forget(receipts_json); // Prevent Rust from freeing the memory + + Ok(res) +} + +/// Builds a hydrated [TransactionReceipt] from information in the passed transaction, +/// receipt, and block receipts. +/// +/// Returns [None] if the transaction's sender could not be recovered from the signature. +#[inline(always)] +fn build_transaction_receipt_with_block_receipts( + tx: TransactionSigned, + meta: TransactionMeta, + receipt: Receipt, + all_receipts: &[Receipt], +) -> Option { + let transaction = tx.clone().into_ecrecovered()?; + + // get the previous transaction cumulative gas used + let gas_used = if meta.index == 0 { + receipt.cumulative_gas_used + } else { + let prev_tx_idx = (meta.index - 1) as usize; + all_receipts + .get(prev_tx_idx) + .map(|prev_receipt| receipt.cumulative_gas_used - prev_receipt.cumulative_gas_used) + .unwrap_or_default() + }; + + let mut res_receipt = TransactionReceipt { + transaction_hash: Some(meta.tx_hash), + transaction_index: U64::from(meta.index), + block_hash: Some(meta.block_hash), + block_number: Some(U256::from(meta.block_number)), + from: transaction.signer(), + to: None, + cumulative_gas_used: U256::from(receipt.cumulative_gas_used), + gas_used: Some(U256::from(gas_used)), + contract_address: None, + logs: Vec::with_capacity(receipt.logs.len()), + effective_gas_price: U128::from(transaction.effective_gas_price(meta.base_fee)), + transaction_type: tx.transaction.tx_type().into(), + // TODO pre-byzantium receipts have a post-transaction state root + state_root: None, + logs_bloom: receipt.bloom_slow(), + status_code: if receipt.success { + Some(U64::from(1)) + } else { + Some(U64::from(0)) + }, + + // EIP-4844 fields + blob_gas_price: None, + blob_gas_used: None, + }; + + match tx.transaction.kind() { + TransactionKind::Create => { + res_receipt.contract_address = + Some(transaction.signer().create(tx.transaction.nonce())); + } + TransactionKind::Call(addr) => { + res_receipt.to = Some(*addr); + } + } + + // get number of logs in the block + let mut num_logs = 0; + for prev_receipt in all_receipts.iter().take(meta.index as usize) { + num_logs += prev_receipt.logs.len(); + } + + for (tx_log_idx, log) in receipt.logs.into_iter().enumerate() { + let rpclog = Log { + address: log.address, + topics: log.topics, + data: log.data, + block_hash: Some(meta.block_hash), + block_number: Some(U256::from(meta.block_number)), + transaction_hash: Some(meta.tx_hash), + transaction_index: Some(U256::from(meta.index)), + log_index: Some(U256::from(num_logs + tx_log_idx)), + removed: false, + }; + res_receipt.logs.push(rpclog); + } + + Some(res_receipt) +} diff --git a/op-service/sources/reth_db_test.go b/op-service/sources/reth_db_test.go deleted file mode 100644 index 73048f7be0d2..000000000000 --- a/op-service/sources/reth_db_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package sources - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func TestRethDBRead(t *testing.T) { - t.Parallel() - - _, err := FetchRethReceipts("/test", &common.Hash{}) - if err != nil { - panic("test") - } -} From c87d94bb0d2bfa2c27762b814da2662fabe50473 Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 27 Oct 2023 16:53:54 -0400 Subject: [PATCH 102/374] @inphi nits Co-Authored-By: inphi --- op-node/node/config.go | 2 +- op-node/service.go | 7 +------ op-service/rethdb-reader/README.md | 8 ++++---- op-service/rethdb-reader/src/lib.rs | 4 ++-- op-service/sources/eth_client.go | 4 ++-- op-service/sources/receipts.go | 8 ++++---- op-service/sources/reth_db.go | 12 ++++++------ 7 files changed, 20 insertions(+), 25 deletions(-) diff --git a/op-node/node/config.go b/op-node/node/config.go index d590bcfc675f..cb970d5ebfd3 100644 --- a/op-node/node/config.go +++ b/op-node/node/config.go @@ -62,7 +62,7 @@ type Config struct { Cancel context.CancelCauseFunc // [OPTIONAL] The reth DB path to read receipts from - RethDBPath *string + RethDBPath string } type RPCConfig struct { diff --git a/op-node/service.go b/op-node/service.go index 2776ef180e00..2569e7af83b6 100644 --- a/op-node/service.go +++ b/op-node/service.go @@ -71,11 +71,6 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { haltOption = "" } - var rethDBPath *string - if rdb := ctx.String(flags.L1RethDBPath.Name); rdb != "" { - rethDBPath = &rdb - } - cfg := &node.Config{ L1: l1Endpoint, L2: l2Endpoint, @@ -109,7 +104,7 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) { ConfigPersistence: configPersistence, Sync: *syncConfig, RollupHalt: haltOption, - RethDBPath: rethDBPath, + RethDBPath: ctx.String(flags.L1RethDBPath.Name), } if err := cfg.LoadPersisted(log); err != nil { diff --git a/op-service/rethdb-reader/README.md b/op-service/rethdb-reader/README.md index 430fe8f96b0b..2ef313ef413e 100644 --- a/op-service/rethdb-reader/README.md +++ b/op-service/rethdb-reader/README.md @@ -67,9 +67,9 @@ typedef struct ReceiptsResult { * - All possible nil pointer dereferences are checked, and the function will return a * failing [ReceiptsResult] if any are found. */ -struct ReceiptsResult read_receipts(const uint8_t *block_hash, - uintptr_t block_hash_len, - const char *db_path); +struct ReceiptsResult rdb_read_receipts(const uint8_t *block_hash, + uintptr_t block_hash_len, + const char *db_path); /** * Free a string that was allocated in Rust and passed to C. @@ -77,7 +77,7 @@ struct ReceiptsResult read_receipts(const uint8_t *block_hash, * # Safety * - All possible nil pointer dereferences are checked. */ -void free_string(char *string); +void rdb_free_string(char *string); ``` [rust-toolchain]: https://rustup.rs/ diff --git a/op-service/rethdb-reader/src/lib.rs b/op-service/rethdb-reader/src/lib.rs index 1d3f3b0eb10c..20aabb1f1391 100644 --- a/op-service/rethdb-reader/src/lib.rs +++ b/op-service/rethdb-reader/src/lib.rs @@ -11,7 +11,7 @@ mod receipts; /// - All possible nil pointer dereferences are checked, and the function will return a /// failing [ReceiptsResult] if any are found. #[no_mangle] -pub unsafe extern "C" fn read_receipts( +pub unsafe extern "C" fn rdb_read_receipts( block_hash: *const u8, block_hash_len: usize, db_path: *const c_char, @@ -24,7 +24,7 @@ pub unsafe extern "C" fn read_receipts( /// # Safety /// - All possible nil pointer dereferences are checked. #[no_mangle] -pub unsafe extern "C" fn free_string(string: *mut c_char) { +pub unsafe extern "C" fn rdb_free_string(string: *mut c_char) { // Convert the raw pointer back to a CString and let it go out of scope, // which will deallocate the memory. if !string.is_null() { diff --git a/op-service/sources/eth_client.go b/op-service/sources/eth_client.go index b679427f5d68..7a54a5838f85 100644 --- a/op-service/sources/eth_client.go +++ b/op-service/sources/eth_client.go @@ -64,7 +64,7 @@ type EthClientConfig struct { MethodResetDuration time.Duration // [OPTIONAL] The reth DB path to fetch receipts from - RethDBPath *string + RethDBPath string } func (c *EthClientConfig) Check() error { @@ -137,7 +137,7 @@ type EthClient struct { methodResetDuration time.Duration // [OPTIONAL] The reth DB path to fetch receipts from - rethDbPath *string + rethDbPath string } func (s *EthClient) PickReceiptsMethod(txCount uint64) ReceiptsFetchingMethod { diff --git a/op-service/sources/receipts.go b/op-service/sources/receipts.go index 2d60bb959716..f5520624a7f7 100644 --- a/op-service/sources/receipts.go +++ b/op-service/sources/receipts.go @@ -390,13 +390,13 @@ type receiptsFetchingJob struct { fetcher *IterativeBatchCall[common.Hash, *types.Receipt] // [OPTIONAL] RethDB path to fetch receipts from - rethDbPath *string + rethDbPath string result types.Receipts } func NewReceiptsFetchingJob(requester ReceiptsRequester, client rpcClient, maxBatchSize int, block eth.BlockID, - receiptHash common.Hash, txHashes []common.Hash, rethDb *string) *receiptsFetchingJob { + receiptHash common.Hash, txHashes []common.Hash, rethDb string) *receiptsFetchingJob { return &receiptsFetchingJob{ requester: requester, client: client, @@ -483,10 +483,10 @@ func (job *receiptsFetchingJob) runAltMethod(ctx context.Context, m ReceiptsFetc case ErigonGetBlockReceiptsByBlockHash: err = job.client.CallContext(ctx, &result, "erigon_getBlockReceiptsByBlockHash", job.block.Hash) case RethGetBlockReceipts: - if job.rethDbPath == nil { + if job.rethDbPath == "" { return fmt.Errorf("reth_db path not set") } - res, err := FetchRethReceipts(*job.rethDbPath, &job.block.Hash) + res, err := FetchRethReceipts(job.rethDbPath, &job.block.Hash) if err != nil { return err } diff --git a/op-service/sources/reth_db.go b/op-service/sources/reth_db.go index 71b8d2a78c9f..2579b95f3f87 100644 --- a/op-service/sources/reth_db.go +++ b/op-service/sources/reth_db.go @@ -24,8 +24,8 @@ typedef struct { bool error; } ReceiptsResult; -extern ReceiptsResult read_receipts(const uint8_t* block_hash, size_t block_hash_len, const char* db_path); -extern void free_string(char* string); +extern ReceiptsResult rdb_read_receipts(const uint8_t* block_hash, size_t block_hash_len, const char* db_path); +extern void rdb_free_string(char* string); */ import "C" @@ -45,12 +45,15 @@ func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, e defer C.free(unsafe.Pointer(cDbPath)) // Call the C function to fetch the receipts from the Reth Database - receiptsResult := C.read_receipts((*C.uint8_t)(cBlockHash), C.size_t(len(blockHash)), cDbPath) + receiptsResult := C.rdb_read_receipts((*C.uint8_t)(cBlockHash), C.size_t(len(blockHash)), cDbPath) if receiptsResult.error { return nil, fmt.Errorf("Error fetching receipts from Reth Database.") } + // Free the memory allocated by the C code + defer C.rdb_free_string(receiptsResult.data) + // Convert the returned JSON string to Go string and parse it receiptsJSON := C.GoStringN(receiptsResult.data, C.int(receiptsResult.data_len)) var receipts types.Receipts @@ -58,8 +61,5 @@ func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, e return nil, err } - // Free the memory allocated by the C code - C.free_string(receiptsResult.data) - return receipts, nil } From d766780e677e7505e3621145c6e4bb4017793d09 Mon Sep 17 00:00:00 2001 From: clabby Date: Sat, 28 Oct 2023 02:27:47 -0400 Subject: [PATCH 103/374] Remove version pin on `foundryup` in devnet job --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 16a9fb0f5037..c669ebcac3bd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -989,7 +989,7 @@ jobs: command: | curl -L https://foundry.paradigm.xyz | bash source $HOME/.bashrc - foundryup --version nightly-aa257c2fb50814dfc5da4b3688cd3b95b5e3844d + foundryup echo 'export PATH=$HOME/.foundry/bin:$PATH' >> $BASH_ENV source $HOME/.bashrc forge --version From d91633678077bc01f515d793d8063203b4ad355b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 27 Sep 2023 13:31:10 -0400 Subject: [PATCH 104/374] feat(ctb): Add outline for Safe liveness checks --- .gitmodules | 3 - .../src/Safe/LivenessGuard.sol | 105 ++++++++++++++ .../src/Safe/LivenessModule.sol | 1 + .../test/SafeLivenessChecking.t.sol | 129 ++++++++++++++++++ 4 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 packages/contracts-bedrock/src/Safe/LivenessGuard.sol create mode 100644 packages/contracts-bedrock/src/Safe/LivenessModule.sol create mode 100644 packages/contracts-bedrock/test/SafeLivenessChecking.t.sol diff --git a/.gitmodules b/.gitmodules index 802f78e7a218..e3bf55582296 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,6 +17,3 @@ path = packages/contracts-bedrock/lib/safe-contracts url = https://github.com/safe-global/safe-contracts branch = v1.4.0 - - - diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol new file mode 100644 index 000000000000..a1c99fb689b3 --- /dev/null +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Safe } from "safe-contracts/Safe.sol"; +import { BaseGuard } from "safe-contracts/base/GuardManager.sol"; +import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; +import { Enum } from "safe-contracts/common/Enum.sol"; + +contract LivenessGuard is SignatureDecoder, BaseGuard { + Safe public safe; + mapping(address => uint256) public lastSigned; + + constructor(Safe _safe) { + safe = _safe; + } + + /// @notice We just need to satisfy the BaseGuard interfae, but we don't actually need to use this method. + function checkAfterExecution(bytes32 txHash, bool success) external { + return; + } + + /// @notice This checkTransaction implementation records the most recent time which any owner has signed a + /// transaction. + function checkTransaction( + address to, + uint256 value, + bytes memory data, + Enum.Operation operation, + uint256 safeTxGas, + uint256 baseGas, + uint256 gasPrice, + address gasToken, + address payable refundReceiver, + bytes memory signatures, + address msgSender + ) + external + { + require(msg.sender == address(safe), "LivenessGuard: only Safe can call this function"); + if (to == address(safe) && data[0:4] == bytes4(keccak256("setGuard(address)"))) { + // We can't allow the guard to be disabled, or else the upgrade delay can be bypassed. + // TODO(Maurelian): Figure out how to best address this. + } + + // This is a bit of a hack, maybe just replicate the functionality here rather than calling home + bytes memory txHashData = Safe(payable(msg.sender)).encodeTransactionData( + // Transaction info + to, + value, + data, + operation, + safeTxGas, + // Payment info + baseGas, + gasPrice, + gasToken, + refundReceiver, + // Signature info + Safe(payable(msg.sender)).nonce() // check that this works + ); + address[] memory signers = _getNSigners(keccak256(txHashData), signatures); + for (uint256 i = 0; i < signers.length; i++) { + lastSigned[signers[i]] = block.timestamp; + } + } + + function _getNSigners(bytes32 dataHash, bytes memory signatures) internal returns (address[] memory _owners) { + uint256 numSignatures = signatures.length / 65; // division OK? + _owners = new address[](numSignatures); + + // The following code is extracted from the Safe.checkNSignatures() method. It removes the signature validation + // code, + // and keeps only the parsing code necessary to extract the owner addresses from the signatures. + // We do not double check if the owner derived from a signature is valid. As tHis is handled in + // the final require statement of Safe.checkNSignatures(). + address currentOwner; + uint8 v; + bytes32 r; + bytes32 s; + uint256 i; + for (i = 0; i < numSignatures; i++) { + (v, r, s) = signatureSplit(signatures, i); + if (v == 0) { + // If v is 0 then it is a contract signature + // When handling contract signatures the address of the contract is encoded into r + currentOwner = address(uint160(uint256(r))); + } else if (v == 1) { + // If v is 1 then it is an approved hash + // When handling approved hashes the address of the approver is encoded into r + currentOwner = address(uint160(uint256(r))); + } else if (v > 30) { + // If v > 30 then default va (27,28) has been adjusted for eth_sign flow + // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix + // before applying ecrecover + currentOwner = + ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", dataHash)), v - 4, r, s); + } else { + // Default is the ecrecover flow with the provided data hash + // Use ecrecover with the messageHash for EOA signatures + currentOwner = ecrecover(dataHash, v, r, s); + } + _owners[i] = currentOwner; + } + } +} diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -0,0 +1 @@ + diff --git a/packages/contracts-bedrock/test/SafeLivenessChecking.t.sol b/packages/contracts-bedrock/test/SafeLivenessChecking.t.sol new file mode 100644 index 000000000000..fff70e690c9d --- /dev/null +++ b/packages/contracts-bedrock/test/SafeLivenessChecking.t.sol @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test } from "forge-std/Test.sol"; +import { Safe } from "safe-contracts/Safe.sol"; +import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; +import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; +import { Enum } from "safe-contracts/common/Enum.sol"; + +import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; + +contract LivnessGuard_TestInit is Test { + struct Signer { + address owner; + uint256 pk; + } + + LivenessGuard livenessGuard; + Safe safe; + string mnemonic = "test test test test test test test test test test test junk"; + + Signer[] signers; + + function newSigner(uint256 index) public returns (Signer memory signer_) { + signer_.pk = vm.deriveKey(mnemonic, uint32(index)); + signer_.owner = vm.addr(signer_.pk); + } + + function signTransaction( + uint256 _pk, + address _to, + uint256 _value, + bytes memory _data + ) + public + view + returns (bytes memory sig_) + { + bytes32 txDataHash; + { + txDataHash = safe.getTransactionHash({ + to: _to, + value: _value, + data: _data, + operation: Enum.Operation.Call, + safeTxGas: 0, + baseGas: 0, + gasPrice: 0, + gasToken: address(0), + refundReceiver: address(0), + _nonce: safe.nonce() + }); + } + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_pk, txDataHash); + sig_ = abi.encodePacked(v, r, s); + } + + function exec(Signer[] memory _signers, address _to, bytes memory _data) internal { + bytes memory sig; + for (uint256 i; i < _signers.length; i++) { + bytes.concat(sig, signTransaction(_signers[i].pk, address(safe), 0, _data)); + } + safe.execTransaction({ + to: _to, + value: 0, + data: _data, + operation: Enum.Operation.Call, + safeTxGas: 0, + baseGas: 0, + gasPrice: 0, + gasToken: address(0), + refundReceiver: payable(0), + signatures: sig + }); + } + + // @dev Create a new Safe instance with a minimimal proxy and implementation. + function newSafe(Signer[] memory _signers) internal returns (Safe safe_) { + SafeProxyFactory safeProxyFactory = new SafeProxyFactory(); + Safe safeSingleton = new Safe(); + + bytes memory initData = abi.encodeWithSelector( + Safe.setup.selector, _signers, 2, address(0), hex"", address(0), address(0), 0, address(0) + ); + + safe_ = Safe(payable(safeProxyFactory.createProxyWithNonce(address(safeSingleton), initData, block.timestamp))); + } + + function setUp() public { + // Create 3 signers + for (uint256 i; i < 3; i++) { + signers.push(newSigner(i)); + } + + Signer[] memory signers_ = signers; + safe = newSafe(signers_); + livenessGuard = new LivenessGuard(safe); + + // enable the module + bytes memory data = abi.encodeCall(ModuleManager.enableModule, (address(livenessGuard))); + bytes memory sig1 = signTransaction(signers[0].pk, address(safe), 0, data); + bytes memory sig2 = signTransaction(signers[1].pk, address(safe), 0, data); + bytes memory sigs = bytes.concat(sig1, sig2); + safe.execTransaction({ + to: address(safe), + value: 0, + data: data, + operation: Enum.Operation.Call, + safeTxGas: 0, + baseGas: 0, + gasPrice: 0, + gasToken: address(0), + refundReceiver: payable(0), + signatures: sigs + }); + } +} + +contract LivnessGuard_TestCheckTx is LivnessGuard_TestInit { + function test_checkTransaction_succeeds() external { + Signer[] memory signers_ = signers; + exec(signers, address(1111), hex"abba"); + + for (uint256 i; i < signers.length; i++) { + assertEq(livenessGuard.lastSigned(signers[i].owner), block.timestamp); + } + } +} From 55fe9711c81801dba3a6c8eb669d29a17b559f3b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 30 Sep 2023 23:07:37 -0400 Subject: [PATCH 105/374] safe-tools: vendor in safe-tools lib --- .../CompatibilityFallbackHandler_1_3_0.sol | 212 ++++++++ .../test/safe-tools/SafeTestTools.sol | 467 ++++++++++++++++++ 2 files changed, 679 insertions(+) create mode 100644 packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol create mode 100644 packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol diff --git a/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol b/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol new file mode 100644 index 000000000000..68e46e8e88e2 --- /dev/null +++ b/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity >=0.7.0 <0.9.0; + +import "safe-contracts/interfaces/ERC1155TokenReceiver.sol"; +import "safe-contracts/interfaces/ERC721TokenReceiver.sol"; +import "safe-contracts/interfaces/ERC777TokensRecipient.sol"; +import "safe-contracts/interfaces/IERC165.sol"; +import "safe-contracts/interfaces/ISignatureValidator.sol"; +import "safe-contracts/GnosisSafe.sol"; + +/// @dev NOTE: removed VERSION and NAME due to inheritance conflicts +contract DefaultCallbackHandler is ERC1155TokenReceiver, ERC777TokensRecipient, ERC721TokenReceiver, IERC165 { + function onERC1155Received( + address, + address, + uint256, + uint256, + bytes calldata + ) + external + pure + override + returns (bytes4) + { + return 0xf23a6e61; + } + + function onERC1155BatchReceived( + address, + address, + uint256[] calldata, + uint256[] calldata, + bytes calldata + ) + external + pure + override + returns (bytes4) + { + return 0xbc197c81; + } + + function onERC721Received(address, address, uint256, bytes calldata) external pure override returns (bytes4) { + return 0x150b7a02; + } + + function tokensReceived( + address, + address, + address, + uint256, + bytes calldata, + bytes calldata + ) + external + pure + override + { + // We implement this for completeness, doesn't really have any value + } + + function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool) { + return interfaceId == type(ERC1155TokenReceiver).interfaceId + || interfaceId == type(ERC721TokenReceiver).interfaceId || interfaceId == type(IERC165).interfaceId; + } +} + +address constant SENTINEL_MODULES = address(0x1); + +/// @title Compatibility Fallback Handler - fallback handler to provider compatibility between pre 1.3.0 and 1.3.0+ Safe +/// contracts +/// @author Richard Meissner - +contract CompatibilityFallbackHandler is DefaultCallbackHandler, ISignatureValidator { + //keccak256( + // "SafeMessage(bytes message)" + //); + bytes32 private constant SAFE_MSG_TYPEHASH = 0x60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca; + + bytes4 internal constant SIMULATE_SELECTOR = bytes4(keccak256("simulate(address,bytes)")); + + bytes4 internal constant UPDATED_MAGIC_VALUE = 0x1626ba7e; + + /** + * Implementation of ISignatureValidator (see `interfaces/ISignatureValidator.sol`) + * @dev Should return whether the signature provided is valid for the provided data. + * @param _data Arbitrary length data signed on the behalf of address(msg.sender) + * @param _signature Signature byte array associated with _data + * @return a bool upon valid or invalid signature with corresponding _data + */ + function isValidSignature(bytes memory _data, bytes memory _signature) public view override returns (bytes4) { + // Caller should be a Safe + GnosisSafe safe = GnosisSafe(payable(msg.sender)); + bytes32 messageHash = getMessageHashForSafe(safe, _data); + if (_signature.length == 0) { + require(safe.signedMessages(messageHash) != 0, "Hash not approved"); + } else { + safe.checkSignatures(messageHash, _data, _signature); + } + return EIP1271_MAGIC_VALUE; + } + + /// @dev Returns hash of a message that can be signed by owners. + /// @param message Message that should be hashed + /// @return Message hash. + function getMessageHash(bytes memory message) public view returns (bytes32) { + return getMessageHashForSafe(GnosisSafe(payable(msg.sender)), message); + } + + /// @dev Returns hash of a message that can be signed by owners. + /// @param safe Safe to which the message is targeted + /// @param message Message that should be hashed + /// @return Message hash. + function getMessageHashForSafe(GnosisSafe safe, bytes memory message) public view returns (bytes32) { + bytes32 safeMessageHash = keccak256(abi.encode(SAFE_MSG_TYPEHASH, keccak256(message))); + return keccak256(abi.encodePacked(bytes1(0x19), bytes1(0x01), safe.domainSeparator(), safeMessageHash)); + } + + /** + * Implementation of updated EIP-1271 + * @dev Should return whether the signature provided is valid for the provided data. + * The save does not implement the interface since `checkSignatures` is not a view method. + * The method will not perform any state changes (see parameters of `checkSignatures`) + * @param _dataHash Hash of the data signed on the behalf of address(msg.sender) + * @param _signature Signature byte array associated with _dataHash + * @return a bool upon valid or invalid signature with corresponding _dataHash + * @notice See + * https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol + */ + function isValidSignature(bytes32 _dataHash, bytes calldata _signature) external view returns (bytes4) { + ISignatureValidator validator = ISignatureValidator(msg.sender); + bytes4 value = validator.isValidSignature(abi.encode(_dataHash), _signature); + return (value == EIP1271_MAGIC_VALUE) ? UPDATED_MAGIC_VALUE : bytes4(0); + } + + /// @dev Returns array of first 10 modules. + /// @return Array of modules. + function getModules() external view returns (address[] memory) { + // Caller should be a Safe + GnosisSafe safe = GnosisSafe(payable(msg.sender)); + (address[] memory array,) = safe.getModulesPaginated(SENTINEL_MODULES, 10); + return array; + } + + /** + * @dev Performs a delegetecall on a targetContract in the context of self. + * Internally reverts execution to avoid side effects (making it static). Catches revert and returns encoded result + * as bytes. + * @param targetContract Address of the contract containing the code to execute. + * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments). + */ + function simulate( + address targetContract, + bytes calldata calldataPayload + ) + external + returns (bytes memory response) + { + // Suppress compiler warnings about not using parameters, while allowing + // parameters to keep names for documentation purposes. This does not + // generate code. + targetContract; + calldataPayload; + + // solhint-disable-next-line no-inline-assembly + assembly { + let internalCalldata := mload(0x40) + // Store `simulateAndRevert.selector`. + // String representation is used to force right padding + mstore(internalCalldata, "\xb4\xfa\xba\x09") + // Abuse the fact that both this and the internal methods have the + // same signature, and differ only in symbol name (and therefore, + // selector) and copy calldata directly. This saves us approximately + // 250 bytes of code and 300 gas at runtime over the + // `abi.encodeWithSelector` builtin. + calldatacopy(add(internalCalldata, 0x04), 0x04, sub(calldatasize(), 0x04)) + + // `pop` is required here by the compiler, as top level expressions + // can't have return values in inline assembly. `call` typically + // returns a 0 or 1 value indicated whether or not it reverted, but + // since we know it will always revert, we can safely ignore it. + pop( + call( + gas(), + // address() has been changed to caller() to use the implementation of the Safe + caller(), + 0, + internalCalldata, + calldatasize(), + // The `simulateAndRevert` call always reverts, and + // instead encodes whether or not it was successful in the return + // data. The first 32-byte word of the return data contains the + // `success` value, so write it to memory address 0x00 (which is + // reserved Solidity scratch space and OK to use). + 0x00, + 0x20 + ) + ) + + // Allocate and copy the response bytes, making sure to increment + // the free memory pointer accordingly (in case this method is + // called as an internal function). The remaining `returndata[0x20:]` + // contains the ABI encoded response bytes, so we can just write it + // as is to memory. + let responseSize := sub(returndatasize(), 0x20) + response := mload(0x40) + mstore(0x40, add(response, responseSize)) + returndatacopy(response, 0x20, responseSize) + + if iszero(mload(0x00)) { revert(add(response, 0x20), mload(response)) } + } + } +} diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol new file mode 100644 index 000000000000..e09b6ed80677 --- /dev/null +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -0,0 +1,467 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "forge-std/Test.sol"; +import "solady/utils/LibSort.sol"; +import "safe-contracts/GnosisSafe.sol"; +import "safe-contracts/proxies/GnosisSafeProxyFactory.sol"; +import "safe-contracts/examples/libraries/SignMessage.sol"; +import "./CompatibilityFallbackHandler_1_3_0.sol"; +import "safe-contracts/examples/libraries/SignMessage.sol"; + +address constant VM_ADDR = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; +bytes12 constant ADDR_MASK = 0xffffffffffffffffffffffff; + +function getAddr(uint256 pk) pure returns (address) { + return Vm(VM_ADDR).addr(pk); +} + +function encodeSmartContractWalletAsPK(address addr) pure returns (uint256 encodedPK) { + assembly { + let addr_b32 := addr + encodedPK := or(addr, ADDR_MASK) + } +} + +function decodeSmartContractWalletAsAddress(uint256 pk) pure returns (address decodedAddr) { + assembly { + let addr := shl(96, pk) + decodedAddr := shr(96, addr) + } +} + +function isSmartContractPK(uint256 pk) pure returns (bool isEncoded) { + assembly { + isEncoded := eq(shr(160, pk), shr(160, ADDR_MASK)) + } +} + +library Sort { + function sort(address[] memory arr) public pure returns (address[] memory) { + LibSort.sort(arr); + return arr; + } +} + +function sortPKsByComputedAddress(uint256[] memory _pks) pure returns (uint256[] memory) { + uint256[] memory sortedPKs = new uint256[](_pks.length); + + address[] memory addresses = new address[](_pks.length); + bytes32[2][] memory accounts = new bytes32[2][](_pks.length); + + for (uint256 i; i < _pks.length; i++) { + address signer = getAddr(_pks[i]); + addresses[i] = signer; + accounts[i][0] = bytes32(abi.encode(signer)); + accounts[i][1] = bytes32(_pks[i]); + } + + addresses = Sort.sort(addresses); + + uint256 found; + for (uint256 j; j < addresses.length; j++) { + address signer = addresses[j]; + uint256 pk; + for (uint256 k; k < accounts.length; k++) { + if (address(uint160(uint256(accounts[k][0]))) == signer) { + pk = uint256(accounts[k][1]); + found++; + } + } + + sortedPKs[j] = pk; + } + + if (found < _pks.length) { + revert("SAFETESTTOOLS: issue with private key sorting, please open a ticket on github"); + } + return sortedPKs; +} + +// collapsed interface that includes comapatibilityfallback handler calls +abstract contract DeployedSafe is GnosisSafe, CompatibilityFallbackHandler { } + +struct AdvancedSafeInitParams { + bool includeFallbackHandler; + uint256 saltNonce; + address setupModulesCall_to; + bytes setupModulesCall_data; + uint256 refundAmount; + address refundToken; + address payable refundReceiver; + bytes initData; +} + +struct SafeInstance { + uint256 instanceId; + uint256[] ownerPKs; + address[] owners; + uint256 threshold; + DeployedSafe safe; +} + +library SafeTestLib { + function execTransaction( + SafeInstance memory instance, + address to, + uint256 value, + bytes memory data, + Enum.Operation operation, + uint256 safeTxGas, + uint256 baseGas, + uint256 gasPrice, + address gasToken, + address refundReceiver, + bytes memory signatures + ) + public + returns (bool) + { + if (instance.owners.length == 0) { + revert("SAFETEST: Instance not initialized. Call _setupSafe() to initialize a test safe"); + } + + bytes32 safeTxHash; + { + uint256 _nonce = instance.safe.nonce(); + safeTxHash = instance.safe.getTransactionHash({ + to: to, + value: value, + data: data, + operation: operation, + safeTxGas: safeTxGas, + baseGas: baseGas, + gasPrice: gasPrice, + gasToken: gasToken, + refundReceiver: refundReceiver, + _nonce: _nonce + }); + } + + if (signatures.length == 0) { + for (uint256 i; i < instance.ownerPKs.length; ++i) { + uint256 pk = instance.ownerPKs[i]; + (uint8 v, bytes32 r, bytes32 s) = Vm(VM_ADDR).sign(pk, safeTxHash); + if (isSmartContractPK(pk)) { + v = 0; + address addr = decodeSmartContractWalletAsAddress(pk); + assembly { + r := addr + } + console.logBytes32(r); + } + signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); + } + } + + return instance.safe.execTransaction({ + to: to, + value: value, + data: data, + operation: operation, + safeTxGas: safeTxGas, + baseGas: baseGas, + gasPrice: gasPrice, + gasToken: gasToken, + refundReceiver: payable(refundReceiver), + signatures: signatures + }); + } + + function execTransaction( + SafeInstance memory instance, + address to, + uint256 value, + bytes memory data, + Enum.Operation operation + ) + public + returns (bool) + { + return execTransaction(instance, to, value, data, operation, 0, 0, 0, address(0), address(0), ""); + } + + /// @dev performs a noraml "call" + function execTransaction( + SafeInstance memory instance, + address to, + uint256 value, + bytes memory data + ) + public + returns (bool) + { + return execTransaction(instance, to, value, data, Enum.Operation.Call, 0, 0, 0, address(0), address(0), ""); + } + + function enableModule(SafeInstance memory instance, address module) public { + execTransaction( + instance, + address(instance.safe), + 0, + abi.encodeWithSelector(ModuleManager.enableModule.selector, module), + Enum.Operation.Call, + 0, + 0, + 0, + address(0), + address(0), + "" + ); + } + + function disableModule(SafeInstance memory instance, address module) public { + (address[] memory modules,) = instance.safe.getModulesPaginated(SENTINEL_MODULES, 1000); + address prevModule = SENTINEL_MODULES; + bool moduleFound; + for (uint256 i; i < modules.length; i++) { + if (modules[i] == module) { + moduleFound = true; + break; + } + prevModule = modules[i]; + } + if (!moduleFound) revert("SAFETESTTOOLS: cannot disable module that is not enabled"); + + execTransaction( + instance, + address(instance.safe), + 0, + abi.encodeWithSelector(ModuleManager.disableModule.selector, prevModule, module), + Enum.Operation.Call, + 0, + 0, + 0, + address(0), + address(0), + "" + ); + } + + function EIP1271Sign(SafeInstance memory instance, bytes memory data) public { + address signMessageLib = address(new SignMessageLib()); + execTransaction({ + instance: instance, + to: signMessageLib, + value: 0, + data: abi.encodeWithSelector(SignMessageLib.signMessage.selector, data), + operation: Enum.Operation.DelegateCall, + safeTxGas: 0, + baseGas: 0, + gasPrice: 0, + gasToken: address(0), + refundReceiver: payable(address(0)), + signatures: "" + }); + } + + function EIP1271Sign(SafeInstance memory instance, bytes32 digest) public { + EIP1271Sign(instance, abi.encodePacked(digest)); + } + + function signTransaction( + SafeInstance memory instance, + uint256 pk, + address to, + uint256 value, + bytes memory data, + Enum.Operation operation, + uint256 safeTxGas, + uint256 baseGas, + uint256 gasPrice, + address gasToken, + address refundReceiver + ) + public + view + returns (uint8 v, bytes32 r, bytes32 s) + { + bytes32 txDataHash; + { + uint256 _nonce = instance.safe.nonce(); + txDataHash = instance.safe.getTransactionHash({ + to: to, + value: value, + data: data, + operation: operation, + safeTxGas: safeTxGas, + baseGas: baseGas, + gasPrice: gasPrice, + gasToken: gasToken, + refundReceiver: refundReceiver, + _nonce: _nonce + }); + } + + (v, r, s) = Vm(VM_ADDR).sign(pk, txDataHash); + } + + function incrementNonce(SafeInstance memory instance) public returns (uint256 newNonce) { + execTransaction(instance, address(0), 0, "", Enum.Operation.Call, 0, 0, 0, address(0), address(0), ""); + return instance.safe.nonce(); + } +} + +contract SafeTestTools { + using SafeTestLib for SafeInstance; + + GnosisSafe internal singleton = new GnosisSafe(); + GnosisSafeProxyFactory internal proxyFactory = new GnosisSafeProxyFactory(); + CompatibilityFallbackHandler internal handler = new CompatibilityFallbackHandler(); + + SafeInstance[] internal instances; + + /// @dev can be called to reinitialize the singleton, proxyFactory and handler. Useful for forking. + function _initializeSafeTools() internal { + singleton = new GnosisSafe(); + proxyFactory = new GnosisSafeProxyFactory(); + handler = new CompatibilityFallbackHandler(); + } + + function _setupSafe( + uint256[] memory ownerPKs, + uint256 threshold, + uint256 initialBalance, + AdvancedSafeInitParams memory advancedParams + ) + public + returns (SafeInstance memory) + { + uint256[] memory sortedPKs = sortPKsByComputedAddress(ownerPKs); + address[] memory owners = new address[](sortedPKs.length); + + for (uint256 i; i < sortedPKs.length; i++) { + if (isSmartContractPK(sortedPKs[i])) { + owners[i] = decodeSmartContractWalletAsAddress(sortedPKs[i]); + } else { + owners[i] = getAddr(sortedPKs[i]); + } + } + // store the initialization parameters + + bytes memory initData = advancedParams.initData.length > 0 + ? advancedParams.initData + : abi.encodeWithSelector( + GnosisSafe.setup.selector, + owners, + threshold, + advancedParams.setupModulesCall_to, + advancedParams.setupModulesCall_data, + advancedParams.includeFallbackHandler ? address(handler) : address(0), + advancedParams.refundToken, + advancedParams.refundAmount, + advancedParams.refundReceiver + ); + + DeployedSafe safe0 = DeployedSafe( + payable( + advancedParams.saltNonce != 0 + ? proxyFactory.createProxyWithNonce(address(singleton), initData, advancedParams.saltNonce) + : proxyFactory.createProxy(address(singleton), initData) + ) + ); + + SafeInstance memory instance0 = SafeInstance({ + instanceId: instances.length, + ownerPKs: sortedPKs, + owners: owners, + threshold: threshold, + // setup safe ecosystem, singleton, proxy factory, fallback handler, and create a new safe + safe: safe0 + }); + instances.push(instance0); + + Vm(VM_ADDR).deal(address(safe0), initialBalance); + + return instance0; + } + + function _setupSafe( + uint256[] memory ownerPKs, + uint256 threshold, + uint256 initialBalance + ) + public + returns (SafeInstance memory) + { + return _setupSafe( + ownerPKs, + threshold, + initialBalance, + AdvancedSafeInitParams({ + includeFallbackHandler: true, + initData: "", + saltNonce: 0, + setupModulesCall_to: address(0), + setupModulesCall_data: "", + refundAmount: 0, + refundToken: address(0), + refundReceiver: payable(address(0)) + }) + ); + } + + function _setupSafe(uint256[] memory ownerPKs, uint256 threshold) public returns (SafeInstance memory) { + return _setupSafe( + ownerPKs, + threshold, + 10000 ether, + AdvancedSafeInitParams({ + includeFallbackHandler: true, + initData: "", + saltNonce: 0, + setupModulesCall_to: address(0), + setupModulesCall_data: "", + refundAmount: 0, + refundToken: address(0), + refundReceiver: payable(address(0)) + }) + ); + } + + function _setupSafe() public returns (SafeInstance memory) { + string[3] memory users; + users[0] = "SAFETEST: Signer 0"; + users[1] = "SAFETEST: Signer 1"; + users[2] = "SAFETEST: Signer 2"; + + uint256[] memory defaultPKs = new uint256[](3); + defaultPKs[0] = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80; + defaultPKs[1] = 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d; + defaultPKs[2] = 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a; + + for (uint256 i; i < 3; i++) { + Vm(VM_ADDR).label(getAddr(defaultPKs[i]), users[i]); + } + + return _setupSafe( + defaultPKs, + 2, + 10000 ether, + AdvancedSafeInitParams({ + includeFallbackHandler: true, + initData: "", + saltNonce: uint256(keccak256(bytes("SAFE TEST"))), + setupModulesCall_to: address(0), + setupModulesCall_data: "", + refundAmount: 0, + refundToken: address(0), + refundReceiver: payable(address(0)) + }) + ); + } + + function getSafe() public view returns (SafeInstance memory) { + if (instances.length == 0) { + revert("SAFETESTTOOLS: Test Safe has not been deployed, use _setupSafe() calling safe()"); + } + return instances[0]; + } + + function getSafe(address _safe) public view returns (SafeInstance memory) { + for (uint256 i; i < instances.length; ++i) { + if (address(instances[i].safe) == _safe) return instances[i]; + } + revert("SAFETESTTOOLS: Safe instance not found"); + } +} From 5910878d323be4a2d29266832f5a2e51c30db0af Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 30 Sep 2023 23:17:53 -0400 Subject: [PATCH 106/374] safe-tools: Light edits to fix compatibility issues --- .../CompatibilityFallbackHandler_1_3_0.sol | 2 +- .../test/safe-tools/SafeTestTools.sol | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol b/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol index 68e46e8e88e2..046a0eda43f0 100644 --- a/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol +++ b/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol @@ -6,7 +6,7 @@ import "safe-contracts/interfaces/ERC721TokenReceiver.sol"; import "safe-contracts/interfaces/ERC777TokensRecipient.sol"; import "safe-contracts/interfaces/IERC165.sol"; import "safe-contracts/interfaces/ISignatureValidator.sol"; -import "safe-contracts/GnosisSafe.sol"; +import { Safe as GnosisSafe } from "safe-contracts/Safe.sol"; /// @dev NOTE: removed VERSION and NAME due to inheritance conflicts contract DefaultCallbackHandler is ERC1155TokenReceiver, ERC777TokensRecipient, ERC721TokenReceiver, IERC165 { diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index e09b6ed80677..0b167a61c3d4 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -2,12 +2,12 @@ pragma solidity >=0.7.0 <0.9.0; import "forge-std/Test.sol"; -import "solady/utils/LibSort.sol"; -import "safe-contracts/GnosisSafe.sol"; -import "safe-contracts/proxies/GnosisSafeProxyFactory.sol"; -import "safe-contracts/examples/libraries/SignMessage.sol"; +import "scripts/libraries/LibSort.sol"; +import { ModuleManager, Safe as GnosisSafe } from "safe-contracts/Safe.sol"; +import { SafeProxyFactory as GnosisSafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; +import { Enum } from "safe-contracts/common/Enum.sol"; +import { SignMessageLib } from "safe-contracts/libraries/SignMessageLib.sol"; import "./CompatibilityFallbackHandler_1_3_0.sol"; -import "safe-contracts/examples/libraries/SignMessage.sol"; address constant VM_ADDR = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; bytes12 constant ADDR_MASK = 0xffffffffffffffffffffffff; @@ -354,11 +354,7 @@ contract SafeTestTools { ); DeployedSafe safe0 = DeployedSafe( - payable( - advancedParams.saltNonce != 0 - ? proxyFactory.createProxyWithNonce(address(singleton), initData, advancedParams.saltNonce) - : proxyFactory.createProxy(address(singleton), initData) - ) + payable(proxyFactory.createProxyWithNonce(address(singleton), initData, advancedParams.saltNonce)) ); SafeInstance memory instance0 = SafeInstance({ From 3de35b69974b4b230c444f6008ea5f3eb1ff8862 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sun, 1 Oct 2023 14:31:15 -0400 Subject: [PATCH 107/374] safe-tools: Add setGuard method --- .../test/safe-tools/SafeTestTools.sol | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 0b167a61c3d4..6de3906de6fb 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -3,7 +3,7 @@ pragma solidity >=0.7.0 <0.9.0; import "forge-std/Test.sol"; import "scripts/libraries/LibSort.sol"; -import { ModuleManager, Safe as GnosisSafe } from "safe-contracts/Safe.sol"; +import { ModuleManager, GuardManager, Safe as GnosisSafe } from "safe-contracts/Safe.sol"; import { SafeProxyFactory as GnosisSafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import { SignMessageLib } from "safe-contracts/libraries/SignMessageLib.sol"; @@ -238,6 +238,22 @@ library SafeTestLib { ); } + function setGuard(SafeInstance memory instance, address guard) public { + execTransaction( + instance, + address(instance.safe), + 0, + abi.encodeWithSelector(GuardManager.setGuard.selector, guard), + Enum.Operation.Call, + 0, + 0, + 0, + address(0), + address(0), + "" + ); + } + function EIP1271Sign(SafeInstance memory instance, bytes memory data) public { address signMessageLib = address(new SignMessageLib()); execTransaction({ From 0d9784bfd2bd69b5ca30c1f27ab9b0c4745d4240 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 30 Sep 2023 23:36:20 -0400 Subject: [PATCH 108/374] feat(ctb): Simplify check tests with safe-tools --- .../test/LivenessGuard.t.sol | 63 +++++++++ .../test/SafeLivenessChecking.t.sol | 129 ------------------ 2 files changed, 63 insertions(+), 129 deletions(-) create mode 100644 packages/contracts-bedrock/test/LivenessGuard.t.sol delete mode 100644 packages/contracts-bedrock/test/SafeLivenessChecking.t.sol diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol new file mode 100644 index 000000000000..dcfcf52d4c1b --- /dev/null +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test } from "forge-std/Test.sol"; +import { Safe } from "safe-contracts/Safe.sol"; +import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; +import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; +import { Enum } from "safe-contracts/common/Enum.sol"; +import "test/safe-tools/SafeTestTools.sol"; + +import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; + +// Todo(Maurelian): +// Other tests needed: +// - EIP1271 signatures +// - Signatures from contracts +// - Signatures from non-owners +// - Signers may call directly to prove liveness (must be an owner). +// - Unexpected length of signature data + +contract LivnessGuard_TestInit is Test, SafeTestTools { + using SafeTestLib for SafeInstance; + + LivenessGuard livenessGuard; + SafeInstance safeInstance; + + function setUp() public { + safeInstance = _setupSafe(); + livenessGuard = new LivenessGuard(safeInstance.safe); + safeInstance.enableModule(address(livenessGuard)); + } +} + +contract LivnessGuard_TestCheckTx is LivnessGuard_TestInit { + using SafeTestLib for SafeInstance; + + function test_checkTransaction_succeeds() external { + safeInstance.execTransaction({ to: address(1111), value: 0, data: hex"abba" }); + + // bug signers need to be sorted from low to high + for (uint256 i; i < safeInstance.owners.length; i++) { + assertEq(livenessGuard.lastSigned(safeInstance.owners[i]), block.timestamp); + } + } +} + +contract LivenessGuard_ShowLiveness_Test is LivnessGuard_TestInit { + function test_showLiveness_succeeds() external { + // Cache the caller + address caller = safeInstance.owners[0]; + + // Construct a signers array with just the caller to identify the expected event. + address[] memory signers = new address[](1); + signers[0] = caller; + vm.expectEmit(address(livenessGuard)); + emit SignersRecorded(0x0, signers); + + vm.prank(caller); + livenessGuard.showLiveness(); + + assertEq(livenessGuard.lastSigned(caller), block.timestamp); + } +} diff --git a/packages/contracts-bedrock/test/SafeLivenessChecking.t.sol b/packages/contracts-bedrock/test/SafeLivenessChecking.t.sol deleted file mode 100644 index fff70e690c9d..000000000000 --- a/packages/contracts-bedrock/test/SafeLivenessChecking.t.sol +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { Test } from "forge-std/Test.sol"; -import { Safe } from "safe-contracts/Safe.sol"; -import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; -import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; -import { Enum } from "safe-contracts/common/Enum.sol"; - -import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; - -contract LivnessGuard_TestInit is Test { - struct Signer { - address owner; - uint256 pk; - } - - LivenessGuard livenessGuard; - Safe safe; - string mnemonic = "test test test test test test test test test test test junk"; - - Signer[] signers; - - function newSigner(uint256 index) public returns (Signer memory signer_) { - signer_.pk = vm.deriveKey(mnemonic, uint32(index)); - signer_.owner = vm.addr(signer_.pk); - } - - function signTransaction( - uint256 _pk, - address _to, - uint256 _value, - bytes memory _data - ) - public - view - returns (bytes memory sig_) - { - bytes32 txDataHash; - { - txDataHash = safe.getTransactionHash({ - to: _to, - value: _value, - data: _data, - operation: Enum.Operation.Call, - safeTxGas: 0, - baseGas: 0, - gasPrice: 0, - gasToken: address(0), - refundReceiver: address(0), - _nonce: safe.nonce() - }); - } - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(_pk, txDataHash); - sig_ = abi.encodePacked(v, r, s); - } - - function exec(Signer[] memory _signers, address _to, bytes memory _data) internal { - bytes memory sig; - for (uint256 i; i < _signers.length; i++) { - bytes.concat(sig, signTransaction(_signers[i].pk, address(safe), 0, _data)); - } - safe.execTransaction({ - to: _to, - value: 0, - data: _data, - operation: Enum.Operation.Call, - safeTxGas: 0, - baseGas: 0, - gasPrice: 0, - gasToken: address(0), - refundReceiver: payable(0), - signatures: sig - }); - } - - // @dev Create a new Safe instance with a minimimal proxy and implementation. - function newSafe(Signer[] memory _signers) internal returns (Safe safe_) { - SafeProxyFactory safeProxyFactory = new SafeProxyFactory(); - Safe safeSingleton = new Safe(); - - bytes memory initData = abi.encodeWithSelector( - Safe.setup.selector, _signers, 2, address(0), hex"", address(0), address(0), 0, address(0) - ); - - safe_ = Safe(payable(safeProxyFactory.createProxyWithNonce(address(safeSingleton), initData, block.timestamp))); - } - - function setUp() public { - // Create 3 signers - for (uint256 i; i < 3; i++) { - signers.push(newSigner(i)); - } - - Signer[] memory signers_ = signers; - safe = newSafe(signers_); - livenessGuard = new LivenessGuard(safe); - - // enable the module - bytes memory data = abi.encodeCall(ModuleManager.enableModule, (address(livenessGuard))); - bytes memory sig1 = signTransaction(signers[0].pk, address(safe), 0, data); - bytes memory sig2 = signTransaction(signers[1].pk, address(safe), 0, data); - bytes memory sigs = bytes.concat(sig1, sig2); - safe.execTransaction({ - to: address(safe), - value: 0, - data: data, - operation: Enum.Operation.Call, - safeTxGas: 0, - baseGas: 0, - gasPrice: 0, - gasToken: address(0), - refundReceiver: payable(0), - signatures: sigs - }); - } -} - -contract LivnessGuard_TestCheckTx is LivnessGuard_TestInit { - function test_checkTransaction_succeeds() external { - Signer[] memory signers_ = signers; - exec(signers, address(1111), hex"abba"); - - for (uint256 i; i < signers.length; i++) { - assertEq(livenessGuard.lastSigned(signers[i].owner), block.timestamp); - } - } -} From da17f609bf44895b2fc4a3ee2f82292fce064754 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sun, 1 Oct 2023 14:38:28 -0400 Subject: [PATCH 109/374] feat(ctb): Working signature recording --- .../src/Safe/LivenessGuard.sol | 26 +++++++++---------- .../test/LivenessGuard.t.sol | 3 +-- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index a1c99fb689b3..719259cce153 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -15,12 +15,11 @@ contract LivenessGuard is SignatureDecoder, BaseGuard { } /// @notice We just need to satisfy the BaseGuard interfae, but we don't actually need to use this method. - function checkAfterExecution(bytes32 txHash, bool success) external { + function checkAfterExecution(bytes32, bool) external pure { return; } - /// @notice This checkTransaction implementation records the most recent time which any owner has signed a - /// transaction. + /// @notice Records the most recent time which any owner has signed a transaction. function checkTransaction( address to, uint256 value, @@ -32,7 +31,7 @@ contract LivenessGuard is SignatureDecoder, BaseGuard { address gasToken, address payable refundReceiver, bytes memory signatures, - address msgSender + address ) external { @@ -43,7 +42,7 @@ contract LivenessGuard is SignatureDecoder, BaseGuard { } // This is a bit of a hack, maybe just replicate the functionality here rather than calling home - bytes memory txHashData = Safe(payable(msg.sender)).encodeTransactionData( + bytes32 txHash = Safe(payable(msg.sender)).getTransactionHash( // Transaction info to, value, @@ -56,23 +55,22 @@ contract LivenessGuard is SignatureDecoder, BaseGuard { gasToken, refundReceiver, // Signature info - Safe(payable(msg.sender)).nonce() // check that this works ); - address[] memory signers = _getNSigners(keccak256(txHashData), signatures); + address[] memory signers = _getNSigners(txHash, signatures); for (uint256 i = 0; i < signers.length; i++) { lastSigned[signers[i]] = block.timestamp; } } - function _getNSigners(bytes32 dataHash, bytes memory signatures) internal returns (address[] memory _owners) { - uint256 numSignatures = signatures.length / 65; // division OK? + /// @notice Exctract the signers from a set of signatures. + function _getNSigners(bytes32 dataHash, bytes memory signatures) internal pure returns (address[] memory _owners) { + uint256 numSignatures = signatures.length / 65; _owners = new address[](numSignatures); - // The following code is extracted from the Safe.checkNSignatures() method. It removes the signature validation - // code, - // and keeps only the parsing code necessary to extract the owner addresses from the signatures. - // We do not double check if the owner derived from a signature is valid. As tHis is handled in - // the final require statement of Safe.checkNSignatures(). + /// The following code is extracted from the Safe.checkNSignatures() method. It removes the signature + /// validation code, and keeps only the parsing code necessary to extract the owner addresses from the + /// signatures. We do not double check if the owner derived from a signature is valid. As this is handled + /// in the final require statement of Safe.checkNSignatures(). address currentOwner; uint8 v; bytes32 r; diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index dcfcf52d4c1b..c36247a16acd 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -27,7 +27,7 @@ contract LivnessGuard_TestInit is Test, SafeTestTools { function setUp() public { safeInstance = _setupSafe(); livenessGuard = new LivenessGuard(safeInstance.safe); - safeInstance.enableModule(address(livenessGuard)); + safeInstance.setGuard(address(livenessGuard)); } } @@ -37,7 +37,6 @@ contract LivnessGuard_TestCheckTx is LivnessGuard_TestInit { function test_checkTransaction_succeeds() external { safeInstance.execTransaction({ to: address(1111), value: 0, data: hex"abba" }); - // bug signers need to be sorted from low to high for (uint256 i; i < safeInstance.owners.length; i++) { assertEq(livenessGuard.lastSigned(safeInstance.owners[i]), block.timestamp); } From 8e2a6dec82dd3cde592a3589b306256a1dceab5e Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 2 Oct 2023 12:00:31 -0400 Subject: [PATCH 110/374] safe-tools: Add some natspec comments --- .../test/safe-tools/SafeTestTools.sol | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 6de3906de6fb..138e6feb215b 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -12,10 +12,12 @@ import "./CompatibilityFallbackHandler_1_3_0.sol"; address constant VM_ADDR = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; bytes12 constant ADDR_MASK = 0xffffffffffffffffffffffff; +/// @dev Get the address from a private key function getAddr(uint256 pk) pure returns (address) { return Vm(VM_ADDR).addr(pk); } +/// @dev Encode a smart contract wallet as a private key function encodeSmartContractWalletAsPK(address addr) pure returns (uint256 encodedPK) { assembly { let addr_b32 := addr @@ -23,6 +25,7 @@ function encodeSmartContractWalletAsPK(address addr) pure returns (uint256 encod } } +/// @dev Decode a smart contract wallet as an address from a private key function decodeSmartContractWalletAsAddress(uint256 pk) pure returns (address decodedAddr) { assembly { let addr := shl(96, pk) @@ -30,6 +33,7 @@ function decodeSmartContractWalletAsAddress(uint256 pk) pure returns (address de } } +/// @dev Checks if a private key is an encoded smart contract address function isSmartContractPK(uint256 pk) pure returns (bool isEncoded) { assembly { isEncoded := eq(shr(160, pk), shr(160, ADDR_MASK)) @@ -37,12 +41,14 @@ function isSmartContractPK(uint256 pk) pure returns (bool isEncoded) { } library Sort { + /// @dev Sorts an array of addresses in place function sort(address[] memory arr) public pure returns (address[] memory) { LibSort.sort(arr); return arr; } } +/// @dev Sorts an array of private keys by the computed address function sortPKsByComputedAddress(uint256[] memory _pks) pure returns (uint256[] memory) { uint256[] memory sortedPKs = new uint256[](_pks.length); @@ -101,6 +107,8 @@ struct SafeInstance { } library SafeTestLib { + /// @dev A wrapper for the full execTransaction method, if no signatures are provided it will + /// generate them for all owners. function execTransaction( SafeInstance memory instance, address to, @@ -168,6 +176,7 @@ library SafeTestLib { }); } + /// @dev Executes either a CALL or DELEGATECALL transaction. function execTransaction( SafeInstance memory instance, address to, @@ -181,7 +190,7 @@ library SafeTestLib { return execTransaction(instance, to, value, data, operation, 0, 0, 0, address(0), address(0), ""); } - /// @dev performs a noraml "call" + /// @dev Executes a CALL transaction. function execTransaction( SafeInstance memory instance, address to, @@ -194,6 +203,7 @@ library SafeTestLib { return execTransaction(instance, to, value, data, Enum.Operation.Call, 0, 0, 0, address(0), address(0), ""); } + /// @dev Enables a module on the Safe. function enableModule(SafeInstance memory instance, address module) public { execTransaction( instance, @@ -210,6 +220,7 @@ library SafeTestLib { ); } + /// @dev Disables a module on the Safe. function disableModule(SafeInstance memory instance, address module) public { (address[] memory modules,) = instance.safe.getModulesPaginated(SENTINEL_MODULES, 1000); address prevModule = SENTINEL_MODULES; @@ -238,6 +249,9 @@ library SafeTestLib { ); } + /// @dev Sets the guard address on the Safe. Unlike modules there can only be one guard, so + /// this method will remove the previous guard. If the guard is set to the 0 address, the + /// guard will be disabled. function setGuard(SafeInstance memory instance, address guard) public { execTransaction( instance, @@ -254,6 +268,7 @@ library SafeTestLib { ); } + /// @dev Signs message data using EIP1271: Standard Signature Validation Method for Contracts function EIP1271Sign(SafeInstance memory instance, bytes memory data) public { address signMessageLib = address(new SignMessageLib()); execTransaction({ @@ -271,10 +286,12 @@ library SafeTestLib { }); } + /// @dev Signs a data hash using EIP1271: Standard Signature Validation Method for Contracts function EIP1271Sign(SafeInstance memory instance, bytes32 digest) public { EIP1271Sign(instance, abi.encodePacked(digest)); } + /// @dev Sign a transaction as a safe owner with a private key. function signTransaction( SafeInstance memory instance, uint256 pk, @@ -312,12 +329,14 @@ library SafeTestLib { (v, r, s) = Vm(VM_ADDR).sign(pk, txDataHash); } + /// @dev Increments the nonce of the Safe by sending an empty transaction. function incrementNonce(SafeInstance memory instance) public returns (uint256 newNonce) { execTransaction(instance, address(0), 0, "", Enum.Operation.Call, 0, 0, 0, address(0), address(0), ""); return instance.safe.nonce(); } } +/// @dev SafeTestTools implements a set of helper functions for testing Safe contracts. contract SafeTestTools { using SafeTestLib for SafeInstance; From 6b67dc7c80a73069c5842b0c477a3841a238e1d4 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 2 Oct 2023 12:08:40 -0400 Subject: [PATCH 111/374] feat(ctb): Emit SignersRecorded event --- packages/contracts-bedrock/src/Safe/LivenessGuard.sol | 9 ++++++++- packages/contracts-bedrock/test/LivenessGuard.t.sol | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 719259cce153..ccbebd1e86e2 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -7,6 +7,10 @@ import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; contract LivenessGuard is SignatureDecoder, BaseGuard { + /// @notice Emitted when a new set of signers is recorded. + /// @param signers An arrary of signer addresses. + event SignersRecorded(bytes32 indexed txHash, address[] signers); + Safe public safe; mapping(address => uint256) public lastSigned; @@ -41,7 +45,8 @@ contract LivenessGuard is SignatureDecoder, BaseGuard { // TODO(Maurelian): Figure out how to best address this. } - // This is a bit of a hack, maybe just replicate the functionality here rather than calling home + // This call will reenter to the Safe which is calling it. This is OK because it is only reading the + // nonce, and using the getTransactionHash() method. bytes32 txHash = Safe(payable(msg.sender)).getTransactionHash( // Transaction info to, @@ -55,11 +60,13 @@ contract LivenessGuard is SignatureDecoder, BaseGuard { gasToken, refundReceiver, // Signature info + Safe(payable(msg.sender)).nonce() - 1 ); address[] memory signers = _getNSigners(txHash, signatures); for (uint256 i = 0; i < signers.length; i++) { lastSigned[signers[i]] = block.timestamp; } + emit SignersRecorded(txHash, signers); } /// @notice Exctract the signers from a set of signatures. diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index c36247a16acd..198ed9a2dc72 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -21,6 +21,8 @@ import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; contract LivnessGuard_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; + event SignersRecorded(bytes32 indexed txHash, address[] signers); + LivenessGuard livenessGuard; SafeInstance safeInstance; @@ -35,6 +37,9 @@ contract LivnessGuard_TestCheckTx is LivnessGuard_TestInit { using SafeTestLib for SafeInstance; function test_checkTransaction_succeeds() external { + // Don't check topic1 so that we can avoid the ugly txHash calculation. + vm.expectEmit(false, true, true, true, address(livenessGuard)); + emit SignersRecorded(0x0, safeInstance.owners); safeInstance.execTransaction({ to: address(1111), value: 0, data: hex"abba" }); for (uint256 i; i < safeInstance.owners.length; i++) { From 57a5f220a20531ec95bb86326e3a0ad099e9ab8c Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 2 Oct 2023 12:09:20 -0400 Subject: [PATCH 112/374] feat(ctb): Allow signers to call directly to prove liveness From fa0db2a672db989bf09a85ee954ccee1a6a2fb90 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 2 Oct 2023 12:31:37 -0400 Subject: [PATCH 113/374] feat(ctb): Add showLiveness method --- .../contracts-bedrock/src/Safe/LivenessGuard.sol | 14 ++++++++++++++ .../contracts-bedrock/test/LivenessGuard.t.sol | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index ccbebd1e86e2..fb32fcb7a187 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -107,4 +107,18 @@ contract LivenessGuard is SignatureDecoder, BaseGuard { _owners[i] = currentOwner; } } + + /// @notice Enables an owner to demonstrate liveness by calling this method directly. + /// This is useful for owners who have not recently signed a transaction via the Safe. + function showLiveness() external { + require(safe.isOwner(msg.sender), "LivenessGuard: only Safe owners may demontstrate liveness"); + lastSigned[msg.sender] = block.timestamp; + address[] memory signers = new address[](1); + signers[0] = msg.sender; + + // todo(maurelian): Is there any need for this event to be differentiated from the one emitted in + // checkTransaction? + // Technically the 0x0 txHash does serve to identiy a call to this method. + emit SignersRecorded(0x0, signers); + } } diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 198ed9a2dc72..823311888932 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -33,7 +33,7 @@ contract LivnessGuard_TestInit is Test, SafeTestTools { } } -contract LivnessGuard_TestCheckTx is LivnessGuard_TestInit { +contract LivnessGuard_CheckTx_Test is LivnessGuard_TestInit { using SafeTestLib for SafeInstance; function test_checkTransaction_succeeds() external { From a56e6c7576adad9340f0b4bfaef19c312629e5e2 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 4 Oct 2023 01:25:28 -0400 Subject: [PATCH 114/374] feat(ctb): Add liveness module --- .../src/Safe/LivenessGuard.sol | 19 ++- .../src/Safe/LivenessModule.sol | 124 ++++++++++++++++++ .../test/LivenessModule.t.sol | 51 +++++++ 3 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 packages/contracts-bedrock/test/LivenessModule.t.sol diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index fb32fcb7a187..c9408d479830 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -2,7 +2,8 @@ pragma solidity 0.8.15; import { Safe } from "safe-contracts/Safe.sol"; -import { BaseGuard } from "safe-contracts/base/GuardManager.sol"; +import { BaseGuard, GuardManager } from "safe-contracts/base/GuardManager.sol"; +import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; @@ -40,9 +41,19 @@ contract LivenessGuard is SignatureDecoder, BaseGuard { external { require(msg.sender == address(safe), "LivenessGuard: only Safe can call this function"); - if (to == address(safe) && data[0:4] == bytes4(keccak256("setGuard(address)"))) { - // We can't allow the guard to be disabled, or else the upgrade delay can be bypassed. - // TODO(Maurelian): Figure out how to best address this. + + // There are a number of ways in which we need to constrain this safe so that it cannot remove + // this guard, nor the LivenessModule. + // TODO(Maurelian): Figure out how to best address this. The following is just intended to outline the + // known mathods by which a Safe could remove the liveness checks. + // TODO(Maurelian): Do we _need_ to have this feature at all? + bytes4 dataSig = bytes4(data); + if ( + to == address(safe) + && (dataSig == GuardManager.setGuard.selector || dataSig == ModuleManager.enableModule.selector) + || operation == Enum.Operation.DelegateCall + ) { + revert("LivenessGuard: cannot remove LivenessGuard or LivenessModule"); } // This call will reenter to the Safe which is calling it. This is OK because it is only reading the diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 8b137891791f..09be58314472 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -1 +1,125 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; +import { Safe } from "safe-contracts/Safe.sol"; +import { Enum } from "safe-contracts/common/Enum.sol"; +import { OwnerManager } from "safe-contracts/base/OwnerManager.sol"; +import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; + +/// @title LivenessModule +/// @notice This module is intended to be used in conjunction with the LivenessGuard. It should be able to +/// execute a transaction on the Safe in only a small number of cases: +contract LivenessModule { + /// @notice The Safe contract instance + Safe public safe; + + /// @notice The LivenessGuard contract instance + LivenessGuard public livenessGuard; + + /// @notice The interval, in seconds, during which an owner must have demonstrated liveness + uint256 public livenessInterval; + + /// @notice The minimum number of owners before ownership of the safe is transferred to the fallback owner. + uint256 public minOwners; + + /// @notice The fallback owner of the Safe + address public fallbackOwner; + + // Constructor to initialize the Safe and baseModule instances + constructor( + Safe _safe, + LivenessGuard _livenessGuard, + uint256 _livenessInterval, + uint256 _minOwners, + address _fallbackOwner + ) { + safe = _safe; + livenessGuard = _livenessGuard; + livenessInterval = _livenessInterval; + minOwners = _minOwners; + fallbackOwner = _fallbackOwner; + } + + /// @notice This function can be called by anyone to remove an owner that has not signed a transaction + /// during the livness interval. If the number of owners drops below + function removeOwner(address owner) external { + // Check that the owner has not signed a transaction in the last 30 days + require( + livenessGuard.lastSigned(owner) < block.timestamp - livenessInterval, + "LivenessModule: owner has signed recently" + ); + + // Calculate the new threshold + uint256 numOwnersAfter = safe.getOwners().length - 1; + uint256 thresholdAfter = get75PercentThreshold(numOwnersAfter); + if (numOwnersAfter >= 8) { + safe.execTransactionFromModule({ + to: address(safe), + value: 0, + data: abi.encodeCall( + // Call the Safe to remove the owner + OwnerManager.removeOwner, + (getPrevOwner(owner), owner, thresholdAfter) + ), + operation: Enum.Operation.Call + }); + } else { + // The number of owners is dangerously low, so we wish to transfer the ownership of this Safe to a new + // to the fallback owner. + // Remove owners one at a time starting from the last owner. + // Since we're removing them in order, the ordering will remain constant, + // and we shouldn't need to query the list of owners again. + address[] memory owners = safe.getOwners(); + for (uint256 i = owners.length - 1; i >= 0; i--) { + address currentOwner = owners[i]; + if (currentOwner != address(this)) { + safe.execTransactionFromModule({ + to: address(safe), + value: 0, + data: abi.encodeCall( + // Call the Safe to remove the owner + OwnerManager.removeOwner, + ( + getPrevOwner(currentOwner), + currentOwner, + 1 // The threshold is 1 because we are removing all owners except the fallback owner + ) + ), + operation: Enum.Operation.Call + }); + } + } + + // Add the fallback owner as the sole owner of the Safe + safe.execTransactionFromModule({ + to: address(safe), + value: 0, + data: abi.encodeCall(OwnerManager.addOwnerWithThreshold, (fallbackOwner, 1)), + operation: Enum.Operation.Call + }); + + address[] memory ownersAfter = safe.getOwners(); + require( + ownersAfter.length == 1 && ownersAfter[0] == fallbackOwner, + "LivenessModule: fallback owner was not added as the sole owner" + ); + } + } + + /// @notice Get the previous owner in the linked list of owners + function getPrevOwner(address owner) public view returns (address prevOwner_) { + address[] memory owners = safe.getOwners(); + prevOwner_ = address(0); + for (uint256 i = 0; i < owners.length; i++) { + if (owners[i] == owner) { + prevOwner_ = owners[i - 1]; + break; + } + } + } + + /// @notice For a given number of owners, return the lowest threshold which is greater than 75. + function get75PercentThreshold(uint256 _numOwners) public view returns (uint256 threshold_) { + threshold_ = (_numOwners * 75 + 99) / 100; + } +} diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol new file mode 100644 index 000000000000..151c3aea61b5 --- /dev/null +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test, StdUtils } from "forge-std/Test.sol"; +import { Safe } from "safe-contracts/Safe.sol"; +import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; +import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; +import { Enum } from "safe-contracts/common/Enum.sol"; +import "test/safe-tools/SafeTestTools.sol"; + +import { LivenessModule } from "src/Safe/LivenessModule.sol"; +import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; + +contract LivnessModule_TestInit is Test, SafeTestTools { + using SafeTestLib for SafeInstance; + + event SignersRecorded(bytes32 indexed txHash, address[] signers); + + LivenessModule livenessModule; + LivenessGuard livenessGuard; + SafeInstance safeInstance; + + function makeKeys(uint256 num) public pure returns (uint256[] memory) { + uint256[] memory keys = new uint256[](num); + for (uint256 i; i < num; i++) { + keys[i] = uint256(keccak256(abi.encodePacked(i))); + } + } + + function setUp() public { + // Create a Safe with 10 owners + uint256[] memory keys = makeKeys(10); + safeInstance = _setupSafe(keys, 8); + livenessGuard = new LivenessGuard(safeInstance.safe); + livenessModule = new LivenessModule({ + _safe: safeInstance.safe, + _livenessGuard: livenessGuard, + _livenessInterval: 30 days, + _minOwners: 6, + _fallbackOwner: makeAddr("fallbackOwner") + }); + safeInstance.enableModule(address(livenessModule)); + } +} + +contract LivenessModule_RemoveOwner_Test is LivnessModule_TestInit { + function test_removeOwner_succeeds() external { + vm.warp(block.timestamp + 30 days); + livenessModule.removeOwner(safeInstance.owners[0]); + } +} From f683806754db0b7be95f6013560d650896de4c30 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 4 Oct 2023 10:06:30 -0400 Subject: [PATCH 115/374] feat(ctb): Add _verifyFinal state in removeOwner() --- .../src/Safe/LivenessModule.sol | 63 +++++++++++++------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 09be58314472..6db3bf9bea12 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -6,6 +6,9 @@ import { Enum } from "safe-contracts/common/Enum.sol"; import { OwnerManager } from "safe-contracts/base/OwnerManager.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; +// TODO(maurelian): remove me +import { console2 as console } from "forge-std/console2.sol"; + /// @title LivenessModule /// @notice This module is intended to be used in conjunction with the LivenessGuard. It should be able to /// execute a transaction on the Safe in only a small number of cases: @@ -50,28 +53,38 @@ contract LivenessModule { ); // Calculate the new threshold - uint256 numOwnersAfter = safe.getOwners().length - 1; - uint256 thresholdAfter = get75PercentThreshold(numOwnersAfter); - if (numOwnersAfter >= 8) { + address[] memory owners = safe.getOwners(); + uint256 numOwners = owners.length - 1; + uint256 thresholdAfter; + if (numOwners > minOwners) { + // Preserves the invariant that the Safe has at least 8 owners + + thresholdAfter = get75PercentThreshold(numOwners); + console.log("removing one owner. numOwners: %s, thresholdAfter: %s", numOwners, thresholdAfter); safe.execTransactionFromModule({ to: address(safe), value: 0, data: abi.encodeCall( // Call the Safe to remove the owner OwnerManager.removeOwner, - (getPrevOwner(owner), owner, thresholdAfter) + (getPrevOwner(owner, owners), owner, thresholdAfter) ), operation: Enum.Operation.Call }); } else { + console.log("removing all owners. numOwnersAfter: %s", numOwners); // The number of owners is dangerously low, so we wish to transfer the ownership of this Safe to a new // to the fallback owner. + + // The threshold will be 1 because we are removing all owners except the fallback owner + thresholdAfter = 1; + // Remove owners one at a time starting from the last owner. // Since we're removing them in order, the ordering will remain constant, // and we shouldn't need to query the list of owners again. - address[] memory owners = safe.getOwners(); for (uint256 i = owners.length - 1; i >= 0; i--) { address currentOwner = owners[i]; + address prevOwner = getPrevOwner(currentOwner, owners); if (currentOwner != address(this)) { safe.execTransactionFromModule({ to: address(safe), @@ -79,11 +92,7 @@ contract LivenessModule { data: abi.encodeCall( // Call the Safe to remove the owner OwnerManager.removeOwner, - ( - getPrevOwner(currentOwner), - currentOwner, - 1 // The threshold is 1 because we are removing all owners except the fallback owner - ) + (prevOwner, currentOwner, 1) ), operation: Enum.Operation.Call }); @@ -97,21 +106,35 @@ contract LivenessModule { data: abi.encodeCall(OwnerManager.addOwnerWithThreshold, (fallbackOwner, 1)), operation: Enum.Operation.Call }); - - address[] memory ownersAfter = safe.getOwners(); - require( - ownersAfter.length == 1 && ownersAfter[0] == fallbackOwner, - "LivenessModule: fallback owner was not added as the sole owner" - ); } + _verifyFinalState(); } - /// @notice Get the previous owner in the linked list of owners - function getPrevOwner(address owner) public view returns (address prevOwner_) { + /// @notice A FREI-PI invariant check enforcing requirements on number of owners and threshold. + function _verifyFinalState() internal view { address[] memory owners = safe.getOwners(); - prevOwner_ = address(0); + uint256 numOwners = owners.length; + require( + (numOwners == 1 && owners[0] == fallbackOwner) || (numOwners >= minOwners), + "LivenessModule: Safe must have at least 1 owner or minOwners" + ); + + // Check that the threshold is correct + uint256 threshold = safe.getThreshold(); + require( + threshold == get75PercentThreshold(numOwners) || (numOwners == 1 && threshold == 1), + "LivenessModule: threshold must be 75% of the number of owners, or 1 if there is only 1 owner" + ); + } + + /// @notice Get the previous owner in the linked list of owners + function getPrevOwner(address owner, address[] memory owners) public pure returns (address prevOwner_) { for (uint256 i = 0; i < owners.length; i++) { if (owners[i] == owner) { + if (i == 0) { + prevOwner_ = address(0x1); // OwnerManager.SENTINEL_OWNERS + break; + } prevOwner_ = owners[i - 1]; break; } @@ -119,7 +142,7 @@ contract LivenessModule { } /// @notice For a given number of owners, return the lowest threshold which is greater than 75. - function get75PercentThreshold(uint256 _numOwners) public view returns (uint256 threshold_) { + function get75PercentThreshold(uint256 _numOwners) public pure returns (uint256 threshold_) { threshold_ = (_numOwners * 75 + 99) / 100; } } From baa0fa5b169660f929a65352b3eb392d6ec4a452 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 4 Oct 2023 10:07:26 -0400 Subject: [PATCH 116/374] test(ctb): Add test for transferring to fallback owner --- .../test/LivenessModule.t.sol | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 151c3aea61b5..f375ee6af69f 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -20,10 +20,10 @@ contract LivnessModule_TestInit is Test, SafeTestTools { LivenessGuard livenessGuard; SafeInstance safeInstance; - function makeKeys(uint256 num) public pure returns (uint256[] memory) { - uint256[] memory keys = new uint256[](num); + function makeKeys(uint256 num) public pure returns (uint256[] memory keys_) { + keys_ = new uint256[](num); for (uint256 i; i < num; i++) { - keys[i] = uint256(keccak256(abi.encodePacked(i))); + keys_[i] = uint256(keccak256(abi.encodePacked(i))); } } @@ -44,8 +44,18 @@ contract LivnessModule_TestInit is Test, SafeTestTools { } contract LivenessModule_RemoveOwner_Test is LivnessModule_TestInit { - function test_removeOwner_succeeds() external { + function test_removeOwner_oneOwner_succeeds() external { + uint256 ownersBefore = safeInstance.owners.length; vm.warp(block.timestamp + 30 days); livenessModule.removeOwner(safeInstance.owners[0]); + assertEq(safeInstance.safe.getOwners().length, ownersBefore - 1); + } + + function test_removeOwner_allOwners_succeeds() external { + vm.warp(block.timestamp + 30 days); + // The safe is initialized with 10 owners, so we need to remove 3 to get below the minOwners threshold + livenessModule.removeOwner(safeInstance.owners[0]); + livenessModule.removeOwner(safeInstance.owners[1]); + livenessModule.removeOwner(safeInstance.owners[2]); } } From 0b690016bb051f6b8f31201a22c0d2dc5588e367 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 4 Oct 2023 10:38:11 -0400 Subject: [PATCH 117/374] chore(ctb): Attribution for safe-tools --- packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 138e6feb215b..0730a6bc3bc8 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -9,6 +9,9 @@ import { Enum } from "safe-contracts/common/Enum.sol"; import { SignMessageLib } from "safe-contracts/libraries/SignMessageLib.sol"; import "./CompatibilityFallbackHandler_1_3_0.sol"; +// Tools to simplify testing Safe contracts +// Author: Colin Nielsen (https://github.com/colinnielsen/safe-tools) + address constant VM_ADDR = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; bytes12 constant ADDR_MASK = 0xffffffffffffffffffffffff; From 0e2030249df3708722270528b3cfe90251c5f811 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 6 Oct 2023 14:13:38 -0400 Subject: [PATCH 118/374] feat(ctb): Remove notes/poc of guard removal prevention --- .../contracts-bedrock/src/Safe/LivenessGuard.sol | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index c9408d479830..e95f15dfe13e 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -42,20 +42,6 @@ contract LivenessGuard is SignatureDecoder, BaseGuard { { require(msg.sender == address(safe), "LivenessGuard: only Safe can call this function"); - // There are a number of ways in which we need to constrain this safe so that it cannot remove - // this guard, nor the LivenessModule. - // TODO(Maurelian): Figure out how to best address this. The following is just intended to outline the - // known mathods by which a Safe could remove the liveness checks. - // TODO(Maurelian): Do we _need_ to have this feature at all? - bytes4 dataSig = bytes4(data); - if ( - to == address(safe) - && (dataSig == GuardManager.setGuard.selector || dataSig == ModuleManager.enableModule.selector) - || operation == Enum.Operation.DelegateCall - ) { - revert("LivenessGuard: cannot remove LivenessGuard or LivenessModule"); - } - // This call will reenter to the Safe which is calling it. This is OK because it is only reading the // nonce, and using the getTransactionHash() method. bytes32 txHash = Safe(payable(msg.sender)).getTransactionHash( From 8032387236b0ff41dca66b8f58132b1a1db3ddcc Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 6 Oct 2023 14:14:22 -0400 Subject: [PATCH 119/374] feat(ctb): Make guard.safe var immutable --- packages/contracts-bedrock/src/Safe/LivenessGuard.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index e95f15dfe13e..6ce1a474c871 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -12,7 +12,7 @@ contract LivenessGuard is SignatureDecoder, BaseGuard { /// @param signers An arrary of signer addresses. event SignersRecorded(bytes32 indexed txHash, address[] signers); - Safe public safe; + Safe public immutable safe; mapping(address => uint256) public lastSigned; constructor(Safe _safe) { From 53fb127aaa2a16a29ad8002f986fe8ecb77e9251 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 17 Oct 2023 06:40:51 -0400 Subject: [PATCH 120/374] feat(ctb): Make Safe Module and Guard ISemver --- packages/contracts-bedrock/src/Safe/LivenessGuard.sol | 7 ++++++- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 6ce1a474c871..4ec9690c03a8 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -6,12 +6,17 @@ import { BaseGuard, GuardManager } from "safe-contracts/base/GuardManager.sol"; import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; +import { ISemver } from "src/universal/ISemver.sol"; -contract LivenessGuard is SignatureDecoder, BaseGuard { +contract LivenessGuard is ISemver, SignatureDecoder, BaseGuard { /// @notice Emitted when a new set of signers is recorded. /// @param signers An arrary of signer addresses. event SignersRecorded(bytes32 indexed txHash, address[] signers); + /// @notice Semantic version. + /// @custom:semver 1.0.0 + string public constant version = "1.0.0"; + Safe public immutable safe; mapping(address => uint256) public lastSigned; diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 6db3bf9bea12..de44ae5bff05 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -5,6 +5,7 @@ import { Safe } from "safe-contracts/Safe.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import { OwnerManager } from "safe-contracts/base/OwnerManager.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; +import { ISemver } from "src/universal/ISemver.sol"; // TODO(maurelian): remove me import { console2 as console } from "forge-std/console2.sol"; @@ -28,6 +29,10 @@ contract LivenessModule { /// @notice The fallback owner of the Safe address public fallbackOwner; + /// @notice Semantic version. + /// @custom:semver 1.0.0 + string public constant version = "1.0.0"; + // Constructor to initialize the Safe and baseModule instances constructor( Safe _safe, From 108f1fe88a9f8e6c2e85f874817911007809abbe Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 17 Oct 2023 06:41:38 -0400 Subject: [PATCH 121/374] feat(ctb): Commenting cleanup --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index de44ae5bff05..46f1f40a15f5 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -12,8 +12,8 @@ import { console2 as console } from "forge-std/console2.sol"; /// @title LivenessModule /// @notice This module is intended to be used in conjunction with the LivenessGuard. It should be able to -/// execute a transaction on the Safe in only a small number of cases: -contract LivenessModule { +/// execute a transaction on the Safe in only a small number of cases. +contract LivenessModule is ISemver { /// @notice The Safe contract instance Safe public safe; From 542bc578ad55926f3e0c31bc33bbe7948f62259c Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 17 Oct 2023 13:46:40 -0400 Subject: [PATCH 122/374] feat(ctb): Add makeAddrsAndKeys to SafeTestTools --- .../test/LivenessModule.t.sol | 9 +----- .../test/safe-tools/SafeTestTools.sol | 30 +++++++++++-------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index f375ee6af69f..1276e689362e 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -20,16 +20,9 @@ contract LivnessModule_TestInit is Test, SafeTestTools { LivenessGuard livenessGuard; SafeInstance safeInstance; - function makeKeys(uint256 num) public pure returns (uint256[] memory keys_) { - keys_ = new uint256[](num); - for (uint256 i; i < num; i++) { - keys_[i] = uint256(keccak256(abi.encodePacked(i))); - } - } - function setUp() public { // Create a Safe with 10 owners - uint256[] memory keys = makeKeys(10); + (, uint256[] memory keys) = makeAddrsAndKeys(10); safeInstance = _setupSafe(keys, 8); livenessGuard = new LivenessGuard(safeInstance.safe); livenessModule = new LivenessModule({ diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 0730a6bc3bc8..042b18aeaca0 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -20,6 +20,22 @@ function getAddr(uint256 pk) pure returns (address) { return Vm(VM_ADDR).addr(pk); } +/// @dev Get arrays of addresses and private keys. The arrays are sorted by address, and the addresses are labelled +function makeAddrsAndKeys(uint256 num) returns (address[] memory addrs, uint256[] memory keys) { + keys = new uint256[](num); + addrs = new address[](num); + for (uint256 i; i < num; i++) { + uint256 key = uint256(keccak256(abi.encodePacked(i))); + keys[i] = key; + } + + keys = sortPKsByComputedAddress(keys); + for (uint256 i; i < num; i++) { + addrs[i] = Vm(VM_ADDR).addr(keys[i]); + Vm(VM_ADDR).label(getAddr(keys[i]), string.concat("SAFETEST: Signer ", string(abi.encodePacked(bytes32(i))))); + } +} + /// @dev Encode a smart contract wallet as a private key function encodeSmartContractWalletAsPK(address addr) pure returns (uint256 encodedPK) { assembly { @@ -454,19 +470,7 @@ contract SafeTestTools { } function _setupSafe() public returns (SafeInstance memory) { - string[3] memory users; - users[0] = "SAFETEST: Signer 0"; - users[1] = "SAFETEST: Signer 1"; - users[2] = "SAFETEST: Signer 2"; - - uint256[] memory defaultPKs = new uint256[](3); - defaultPKs[0] = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80; - defaultPKs[1] = 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d; - defaultPKs[2] = 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a; - - for (uint256 i; i < 3; i++) { - Vm(VM_ADDR).label(getAddr(defaultPKs[i]), users[i]); - } + (, uint256[] memory defaultPKs) = makeAddrsAndKeys(3); return _setupSafe( defaultPKs, From c5b6f88849d3380499dface0f0d1b4349afdd41a Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 17 Oct 2023 14:28:51 -0400 Subject: [PATCH 123/374] refactor(ctb): Move _getNSigners() to inheritable contract --- .../contracts-bedrock/src/Safe/GetSigners.sol | 45 +++++++++++++++++++ .../src/Safe/LivenessGuard.sol | 45 ++----------------- 2 files changed, 49 insertions(+), 41 deletions(-) create mode 100644 packages/contracts-bedrock/src/Safe/GetSigners.sol diff --git a/packages/contracts-bedrock/src/Safe/GetSigners.sol b/packages/contracts-bedrock/src/Safe/GetSigners.sol new file mode 100644 index 000000000000..f10d0424f23e --- /dev/null +++ b/packages/contracts-bedrock/src/Safe/GetSigners.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; + +abstract contract GetSigners is SignatureDecoder { + /// @notice Extract the signers from a set of signatures. + function _getNSigners(bytes32 dataHash, bytes memory signatures) internal pure returns (address[] memory _owners) { + uint256 numSignatures = signatures.length / 65; + _owners = new address[](numSignatures); + + /// The following code is extracted from the Safe.checkNSignatures() method. It removes the signature + /// validation code, and keeps only the parsing code necessary to extract the owner addresses from the + /// signatures. We do not double check if the owner derived from a signature is valid. As this is handled + /// in the final require statement of Safe.checkNSignatures(). + address currentOwner; + uint8 v; + bytes32 r; + bytes32 s; + uint256 i; + for (i = 0; i < numSignatures; i++) { + (v, r, s) = signatureSplit(signatures, i); + if (v == 0) { + // If v is 0 then it is a contract signature + // When handling contract signatures the address of the contract is encoded into r + currentOwner = address(uint160(uint256(r))); + } else if (v == 1) { + // If v is 1 then it is an approved hash + // When handling approved hashes the address of the approver is encoded into r + currentOwner = address(uint160(uint256(r))); + } else if (v > 30) { + // If v > 30 then default va (27,28) has been adjusted for eth_sign flow + // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix + // before applying ecrecover + currentOwner = + ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", dataHash)), v - 4, r, s); + } else { + // Default is the ecrecover flow with the provided data hash + // Use ecrecover with the messageHash for EOA signatures + currentOwner = ecrecover(dataHash, v, r, s); + } + _owners[i] = currentOwner; + } + } +} diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 4ec9690c03a8..cd69eb357069 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -4,11 +4,11 @@ pragma solidity 0.8.15; import { Safe } from "safe-contracts/Safe.sol"; import { BaseGuard, GuardManager } from "safe-contracts/base/GuardManager.sol"; import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; -import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; +import { GetSigners } from "src/Safe/GetSigners.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import { ISemver } from "src/universal/ISemver.sol"; -contract LivenessGuard is ISemver, SignatureDecoder, BaseGuard { +contract LivenessGuard is ISemver, GetSigners, BaseGuard { /// @notice Emitted when a new set of signers is recorded. /// @param signers An arrary of signer addresses. event SignersRecorded(bytes32 indexed txHash, address[] signers); @@ -30,6 +30,8 @@ contract LivenessGuard is ISemver, SignatureDecoder, BaseGuard { } /// @notice Records the most recent time which any owner has signed a transaction. + /// @dev This method is called by the Safe contract, it is critical that it does not revert, otherwise + /// the Safe contract will be unable to execute transactions. function checkTransaction( address to, uint256 value, @@ -71,45 +73,6 @@ contract LivenessGuard is ISemver, SignatureDecoder, BaseGuard { emit SignersRecorded(txHash, signers); } - /// @notice Exctract the signers from a set of signatures. - function _getNSigners(bytes32 dataHash, bytes memory signatures) internal pure returns (address[] memory _owners) { - uint256 numSignatures = signatures.length / 65; - _owners = new address[](numSignatures); - - /// The following code is extracted from the Safe.checkNSignatures() method. It removes the signature - /// validation code, and keeps only the parsing code necessary to extract the owner addresses from the - /// signatures. We do not double check if the owner derived from a signature is valid. As this is handled - /// in the final require statement of Safe.checkNSignatures(). - address currentOwner; - uint8 v; - bytes32 r; - bytes32 s; - uint256 i; - for (i = 0; i < numSignatures; i++) { - (v, r, s) = signatureSplit(signatures, i); - if (v == 0) { - // If v is 0 then it is a contract signature - // When handling contract signatures the address of the contract is encoded into r - currentOwner = address(uint160(uint256(r))); - } else if (v == 1) { - // If v is 1 then it is an approved hash - // When handling approved hashes the address of the approver is encoded into r - currentOwner = address(uint160(uint256(r))); - } else if (v > 30) { - // If v > 30 then default va (27,28) has been adjusted for eth_sign flow - // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix - // before applying ecrecover - currentOwner = - ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", dataHash)), v - 4, r, s); - } else { - // Default is the ecrecover flow with the provided data hash - // Use ecrecover with the messageHash for EOA signatures - currentOwner = ecrecover(dataHash, v, r, s); - } - _owners[i] = currentOwner; - } - } - /// @notice Enables an owner to demonstrate liveness by calling this method directly. /// This is useful for owners who have not recently signed a transaction via the Safe. function showLiveness() external { From 3f7947b7a61172bf51a0d4d04da422b1c7d2cb5e Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 17 Oct 2023 14:34:30 -0400 Subject: [PATCH 124/374] test(ctb): Add GetSigners diff test --- .../contracts-bedrock/test/GetSigners.t.sol | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 packages/contracts-bedrock/test/GetSigners.t.sol diff --git a/packages/contracts-bedrock/test/GetSigners.t.sol b/packages/contracts-bedrock/test/GetSigners.t.sol new file mode 100644 index 000000000000..0eeb34e9c20c --- /dev/null +++ b/packages/contracts-bedrock/test/GetSigners.t.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test } from "forge-std/Test.sol"; +import { Safe } from "safe-contracts/Safe.sol"; +import { GetSigners } from "src/Safe/GetSigners.sol"; +import "test/safe-tools/SafeTestTools.sol"; + +import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; + +contract GetSigners_Test is Test, SafeTestTools, GetSigners { + /// @dev Test that for a given set of signatures: + /// 1. safe.checkNSignatures() succeeds + /// 2. the getSigners() method returns the expected signers + /// 3. the expected signers are all owners of the safe. + /// Demonstrating these three properties is sufficient to prove that the getSigners() method + /// returns the same signatures as those recovered by safe.checkNSignatures(). + /// todo(maurelian): include tests for EIP1271 signatures, and contract signatures. + function testDiff_getSignaturesVsCheckSignatures_succeeds(uint256 _numSigs, bytes32 _digest) external { + uint256 numSigs = bound(_numSigs, 1, 100); + (, uint256[] memory keys) = makeAddrsAndKeys(numSigs); + SafeInstance memory safeInstance = SafeTestTools._setupSafe(keys, numSigs, 0); + + bytes memory signatures; + for (uint256 i; i < numSigs; i++) { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(keys[i], _digest); + + // Safe signatures are encoded as r, s, v, not v, r, s. + signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); + } + + // Signature checking on the Safe should succeed. + safeInstance.safe.checkNSignatures(_digest, hex"", signatures, numSigs); + + // Recover the signatures using the getSigners() method. + address[] memory gotSigners = _getNSigners(_digest, signatures); + + // Compare the recovered signers to the expected signers. + assertEq(gotSigners.length, numSigs); + assertEq(gotSigners.length, safeInstance.owners.length); + for (uint256 i; i < numSigs; i++) { + assertEq(safeInstance.owners[i], gotSigners[i]); + } + } +} From 017e0480ccb039a13aa26e1bc25a8160ac0f0ff5 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 19 Oct 2023 13:14:22 -0400 Subject: [PATCH 125/374] feat(ctb): Record comment about numsignatures calc --- packages/contracts-bedrock/src/Safe/GetSigners.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/src/Safe/GetSigners.sol b/packages/contracts-bedrock/src/Safe/GetSigners.sol index f10d0424f23e..6c7f01862295 100644 --- a/packages/contracts-bedrock/src/Safe/GetSigners.sol +++ b/packages/contracts-bedrock/src/Safe/GetSigners.sol @@ -6,7 +6,8 @@ import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; abstract contract GetSigners is SignatureDecoder { /// @notice Extract the signers from a set of signatures. function _getNSigners(bytes32 dataHash, bytes memory signatures) internal pure returns (address[] memory _owners) { - uint256 numSignatures = signatures.length / 65; + uint256 numSignatures = signatures.length / 65; // this is wrong. There can be extra data appended to the + // signatures for contract signatures. We should use SignatureDecoder to parse the signatures. _owners = new address[](numSignatures); /// The following code is extracted from the Safe.checkNSignatures() method. It removes the signature From 5011159887e587b1a3bdd35fcc65e03ad3e21735 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 19 Oct 2023 14:04:41 -0400 Subject: [PATCH 126/374] test(ctb): Add eth_sign types to GetSigners test --- .../contracts-bedrock/test/GetSigners.t.sol | 68 +++++++++++++++++-- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/test/GetSigners.t.sol b/packages/contracts-bedrock/test/GetSigners.t.sol index 0eeb34e9c20c..a01bc88b0e54 100644 --- a/packages/contracts-bedrock/test/GetSigners.t.sol +++ b/packages/contracts-bedrock/test/GetSigners.t.sol @@ -9,6 +9,22 @@ import "test/safe-tools/SafeTestTools.sol"; import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; contract GetSigners_Test is Test, SafeTestTools, GetSigners { + struct SigTypeCount { + uint256 numEoaSigs; + uint256 numEthSignSigs; + uint256 numApprovedHashSigs; + uint256 numContractSigs; + } + + enum SigType { + Eoa, + EthSign, + ApprovedHash, + Contract + } + + mapping(uint256 => SigType) public sigTypes; + /// @dev Test that for a given set of signatures: /// 1. safe.checkNSignatures() succeeds /// 2. the getSigners() method returns the expected signers @@ -16,20 +32,60 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners { /// Demonstrating these three properties is sufficient to prove that the getSigners() method /// returns the same signatures as those recovered by safe.checkNSignatures(). /// todo(maurelian): include tests for EIP1271 signatures, and contract signatures. - function testDiff_getSignaturesVsCheckSignatures_succeeds(uint256 _numSigs, bytes32 _digest) external { - uint256 numSigs = bound(_numSigs, 1, 100); + function testDiff_getSignaturesVsCheckSignatures_succeeds(bytes32 _digest, SigTypeCount memory _split) external { + // Limit the number of each signature type to 25 + uint256 numEoaSigs = bound(_split.numEoaSigs, 1, 25); + uint256 numEthSignSigs = bound(_split.numEthSignSigs, 1, 25); + // uint256 numContractSigs = bound(_split.numContractSigs, 1, 25); + // uint256 numApprovedHashSigs = bound(_split.numApprovedHashSigs, 1, 25); + + // uint256 numSigs = numEoaSigs + numApprovedHashSigs + numContractSigs + numEthSignSigs; + uint256 numSigs = numEoaSigs + numEthSignSigs; + (, uint256[] memory keys) = makeAddrsAndKeys(numSigs); + + // record the signature types for each key + for (uint256 i; i < numSigs; i++) { + // Generate EOA keys for both EOA and ETH Sign signatures + if (i < numEoaSigs) { + sigTypes[keys[i]] = SigType.Eoa; + } else if (i < numEoaSigs + numEthSignSigs) { + sigTypes[keys[i]] = SigType.EthSign; + } else { + // Generate approved hash signatures + // Generate eth_sign signatures + revert("not implemented"); + } + } + + // Now sort the keys array. By doing this after assigning a signature type to each key, + // we ensure that the signature types are randomly ordered. It probably doesn't matter either + // way, but this is more realistic. + keys = sortPKsByComputedAddress(keys); + + // Create a new safeInstance with M=N, so that it requires a signature from each key. SafeInstance memory safeInstance = SafeTestTools._setupSafe(keys, numSigs, 0); + // Create an empty array of signature data bytes memory signatures; - for (uint256 i; i < numSigs; i++) { - (uint8 v, bytes32 r, bytes32 s) = vm.sign(keys[i], _digest); - // Safe signatures are encoded as r, s, v, not v, r, s. - signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); + // Populate the signatures by iterating over the safeInstance owners list. + // is a requirement for the ordering of signatures in the Safe contract. + for (uint256 i; i < keys.length; i++) { + if (sigTypes[keys[i]] == SigType.Eoa) { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(keys[i], _digest); + // Safe signatures are encoded as r, s, v, not v, r, s. + signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); + } else if (sigTypes[keys[i]] == SigType.EthSign) { + (uint8 v, bytes32 r, bytes32 s) = + vm.sign(keys[i], keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _digest))); + v += 4; + signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); + } } // Signature checking on the Safe should succeed. + // temp note: the second arg is the data, which is only used in the contract signatures type. safeInstance.safe.checkNSignatures(_digest, hex"", signatures, numSigs); // Recover the signatures using the getSigners() method. From 0a443dd4cd25f9969c45da3df698c375c3b3ae09 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 19 Oct 2023 14:21:56 -0400 Subject: [PATCH 127/374] feat(safe-tools): Do not force generated list of keys to be sorted --- packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 042b18aeaca0..41aa65fc605b 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -29,7 +29,6 @@ function makeAddrsAndKeys(uint256 num) returns (address[] memory addrs, uint256[ keys[i] = key; } - keys = sortPKsByComputedAddress(keys); for (uint256 i; i < num; i++) { addrs[i] = Vm(VM_ADDR).addr(keys[i]); Vm(VM_ADDR).label(getAddr(keys[i]), string.concat("SAFETEST: Signer ", string(abi.encodePacked(bytes32(i))))); From 411da0fd245265f1752b0005db52f375a3bf1585 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 20 Oct 2023 14:02:10 -0400 Subject: [PATCH 128/374] refactor(safe-tools): Cache priv-key during sorting loop this change is more readable --- .../contracts-bedrock/test/safe-tools/SafeTestTools.sol | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 41aa65fc605b..acd5cacb0eef 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -67,6 +67,7 @@ library Sort { } /// @dev Sorts an array of private keys by the computed address +/// If the private key is a smart contract wallet, it will be decoded and sorted by the address function sortPKsByComputedAddress(uint256[] memory _pks) pure returns (uint256[] memory) { uint256[] memory sortedPKs = new uint256[](_pks.length); @@ -74,10 +75,14 @@ function sortPKsByComputedAddress(uint256[] memory _pks) pure returns (uint256[] bytes32[2][] memory accounts = new bytes32[2][](_pks.length); for (uint256 i; i < _pks.length; i++) { - address signer = getAddr(_pks[i]); + uint256 pk = _pks[i]; + address signer = getAddr(pk); + if (isSmartContractPK(pk)) { + signer = decodeSmartContractWalletAsAddress(pk); + } addresses[i] = signer; accounts[i][0] = bytes32(abi.encode(signer)); - accounts[i][1] = bytes32(_pks[i]); + accounts[i][1] = bytes32(pk); } addresses = Sort.sort(addresses); From 040c34f7c01a0eaf61e5e42fd78d9a3d9778acc7 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 19 Oct 2023 15:50:44 -0400 Subject: [PATCH 129/374] test(ctb): Add approved hash checking to GetSigners test working for approvedHashes --- .../contracts-bedrock/test/GetSigners.t.sol | 82 +++++++++---------- 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/packages/contracts-bedrock/test/GetSigners.t.sol b/packages/contracts-bedrock/test/GetSigners.t.sol index a01bc88b0e54..ed5ce5e767ca 100644 --- a/packages/contracts-bedrock/test/GetSigners.t.sol +++ b/packages/contracts-bedrock/test/GetSigners.t.sol @@ -9,21 +9,19 @@ import "test/safe-tools/SafeTestTools.sol"; import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; contract GetSigners_Test is Test, SafeTestTools, GetSigners { - struct SigTypeCount { - uint256 numEoaSigs; - uint256 numEthSignSigs; - uint256 numApprovedHashSigs; - uint256 numContractSigs; - } + bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b; - enum SigType { + enum SigTypes { Eoa, EthSign, - ApprovedHash, - Contract + ApprovedHash //, + // Contract } - mapping(uint256 => SigType) public sigTypes; + function sigType(uint256 _key) internal view returns (SigTypes sigType_) { + uint256 t = _key % 3; //4; + sigType_ = SigTypes(t); + } /// @dev Test that for a given set of signatures: /// 1. safe.checkNSignatures() succeeds @@ -32,35 +30,11 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners { /// Demonstrating these three properties is sufficient to prove that the getSigners() method /// returns the same signatures as those recovered by safe.checkNSignatures(). /// todo(maurelian): include tests for EIP1271 signatures, and contract signatures. - function testDiff_getSignaturesVsCheckSignatures_succeeds(bytes32 _digest, SigTypeCount memory _split) external { + function testDiff_getSignaturesVsCheckSignatures_succeeds(bytes32 _digest, uint256 _numSigs) external { // Limit the number of each signature type to 25 - uint256 numEoaSigs = bound(_split.numEoaSigs, 1, 25); - uint256 numEthSignSigs = bound(_split.numEthSignSigs, 1, 25); - // uint256 numContractSigs = bound(_split.numContractSigs, 1, 25); - // uint256 numApprovedHashSigs = bound(_split.numApprovedHashSigs, 1, 25); - - // uint256 numSigs = numEoaSigs + numApprovedHashSigs + numContractSigs + numEthSignSigs; - uint256 numSigs = numEoaSigs + numEthSignSigs; + uint256 numSigs = bound(_numSigs, 1, 25); (, uint256[] memory keys) = makeAddrsAndKeys(numSigs); - - // record the signature types for each key - for (uint256 i; i < numSigs; i++) { - // Generate EOA keys for both EOA and ETH Sign signatures - if (i < numEoaSigs) { - sigTypes[keys[i]] = SigType.Eoa; - } else if (i < numEoaSigs + numEthSignSigs) { - sigTypes[keys[i]] = SigType.EthSign; - } else { - // Generate approved hash signatures - // Generate eth_sign signatures - revert("not implemented"); - } - } - - // Now sort the keys array. By doing this after assigning a signature type to each key, - // we ensure that the signature types are randomly ordered. It probably doesn't matter either - // way, but this is more realistic. keys = sortPKsByComputedAddress(keys); // Create a new safeInstance with M=N, so that it requires a signature from each key. @@ -69,21 +43,39 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners { // Create an empty array of signature data bytes memory signatures; - // Populate the signatures by iterating over the safeInstance owners list. - // is a requirement for the ordering of signatures in the Safe contract. + // Populate the signatures by iterating over the keys, and choosing the signature type based + // on the key. + uint8 v; + bytes32 r; + bytes32 s; for (uint256 i; i < keys.length; i++) { - if (sigTypes[keys[i]] == SigType.Eoa) { - (uint8 v, bytes32 r, bytes32 s) = vm.sign(keys[i], _digest); + if (sigType(keys[i]) == SigTypes.Eoa) { + (v, r, s) = vm.sign(keys[i], _digest); // Safe signatures are encoded as r, s, v, not v, r, s. signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); - } else if (sigTypes[keys[i]] == SigType.EthSign) { - (uint8 v, bytes32 r, bytes32 s) = - vm.sign(keys[i], keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _digest))); + } else if (sigType(keys[i]) == SigTypes.EthSign) { + (v, r, s) = vm.sign(keys[i], keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _digest))); v += 4; signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); - } + } else if (sigType(keys[i]) == SigTypes.ApprovedHash) { + vm.prank(getAddr(keys[i])); + safeInstance.safe.approveHash(_digest); + v = 1; + s; // s is not checked on approved hash signatures. + r = bytes32(uint256(uint160(getAddr(keys[i])))); + signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); + } // else if (sigType(keys[i]) == SigTypes.Contract) { + // address addr = decodeSmartContractWalletAsAddress(keys[i]); + // r = bytes32(uint256(uint160(addr))); + // vm.mockCall( + // addr, abi.encodeWithSignature("isValidSignature(bytes,bytes)"), + // abi.encode(EIP1271_MAGIC_VALUE) + // ); + // v = 1; + // s; // s is not checked on approved hash signatures. + // signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); + // } } - // Signature checking on the Safe should succeed. // temp note: the second arg is the data, which is only used in the contract signatures type. safeInstance.safe.checkNSignatures(_digest, hex"", signatures, numSigs); From 7636b5e44c43e790a9e3cef138a1fc9c4742812b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 20 Oct 2023 14:05:38 -0400 Subject: [PATCH 130/374] fix(ctb): getNSigners is limited to the threshold This change fixes a bug in getNSigners which incorrectly assumed that the length of the signature data could be used to directly determine the number of signatures provided. This is wrong because contract signatures append additional data used for the EIP1271 signature validation. --- .../contracts-bedrock/src/Safe/GetSigners.sol | 19 ++++++++++++++----- .../src/Safe/LivenessGuard.sol | 6 +++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/GetSigners.sol b/packages/contracts-bedrock/src/Safe/GetSigners.sol index 6c7f01862295..0d9642bf6125 100644 --- a/packages/contracts-bedrock/src/Safe/GetSigners.sol +++ b/packages/contracts-bedrock/src/Safe/GetSigners.sol @@ -5,10 +5,19 @@ import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; abstract contract GetSigners is SignatureDecoder { /// @notice Extract the signers from a set of signatures. - function _getNSigners(bytes32 dataHash, bytes memory signatures) internal pure returns (address[] memory _owners) { - uint256 numSignatures = signatures.length / 65; // this is wrong. There can be extra data appended to the - // signatures for contract signatures. We should use SignatureDecoder to parse the signatures. - _owners = new address[](numSignatures); + /// @param dataHash Hash of the data. + /// @param signatures Signature data for identifying signers. + /// @param requiredSignatures Amount of required valid signatures. + function _getNSigners( + bytes32 dataHash, + bytes memory signatures, + uint256 requiredSignatures + ) + internal + pure + returns (address[] memory _owners) + { + _owners = new address[](requiredSignatures); /// The following code is extracted from the Safe.checkNSignatures() method. It removes the signature /// validation code, and keeps only the parsing code necessary to extract the owner addresses from the @@ -19,7 +28,7 @@ abstract contract GetSigners is SignatureDecoder { bytes32 r; bytes32 s; uint256 i; - for (i = 0; i < numSignatures; i++) { + for (i = 0; i < requiredSignatures; i++) { (v, r, s) = signatureSplit(signatures, i); if (v == 0) { // If v is 0 then it is a contract signature diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index cd69eb357069..2abe1d3b2be9 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -66,7 +66,11 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { // Signature info Safe(payable(msg.sender)).nonce() - 1 ); - address[] memory signers = _getNSigners(txHash, signatures); + + uint256 threshold = safe.getThreshold(); + address[] memory signers = + _getNSigners({ dataHash: txHash, signatures: signatures, requiredSignatures: threshold }); + for (uint256 i = 0; i < signers.length; i++) { lastSigned[signers[i]] = block.timestamp; } From a9312b79fe5621385038ed78b02c4f4a815793e2 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 20 Oct 2023 14:06:27 -0400 Subject: [PATCH 131/374] test(ctb): Add contract signatures testing --- .../contracts-bedrock/test/GetSigners.t.sol | 97 +++++++++++-------- 1 file changed, 57 insertions(+), 40 deletions(-) diff --git a/packages/contracts-bedrock/test/GetSigners.t.sol b/packages/contracts-bedrock/test/GetSigners.t.sol index ed5ce5e767ca..03cfd711860c 100644 --- a/packages/contracts-bedrock/test/GetSigners.t.sol +++ b/packages/contracts-bedrock/test/GetSigners.t.sol @@ -14,12 +14,15 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners { enum SigTypes { Eoa, EthSign, - ApprovedHash //, - // Contract + ApprovedHash, + Contract } - function sigType(uint256 _key) internal view returns (SigTypes sigType_) { - uint256 t = _key % 3; //4; + /// @dev Maps every key to one of the 4 signatures types. + /// This is used in the tests below as a pseudorandom mechanism for determining which + /// signature type to use for each key. + function sigType(uint256 _key) internal pure returns (SigTypes sigType_) { + uint256 t = _key % 4; sigType_ = SigTypes(t); } @@ -29,61 +32,75 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners { /// 3. the expected signers are all owners of the safe. /// Demonstrating these three properties is sufficient to prove that the getSigners() method /// returns the same signatures as those recovered by safe.checkNSignatures(). - /// todo(maurelian): include tests for EIP1271 signatures, and contract signatures. - function testDiff_getSignaturesVsCheckSignatures_succeeds(bytes32 _digest, uint256 _numSigs) external { - // Limit the number of each signature type to 25 + function testDiff_getSignaturesVsCheckSignatures_succeeds(bytes memory _data, uint256 _numSigs) external { + bytes32 digest = keccak256(_data); + + // Limit the number of signatures to 25 uint256 numSigs = bound(_numSigs, 1, 25); (, uint256[] memory keys) = makeAddrsAndKeys(numSigs); - keys = sortPKsByComputedAddress(keys); + for (uint256 i = 0; i < keys.length; i++) { + if (sigType(keys[i]) == SigTypes.Contract) { + keys[i] = encodeSmartContractWalletAsPK(decodeSmartContractWalletAsAddress(keys[i])); + } + } // Create a new safeInstance with M=N, so that it requires a signature from each key. SafeInstance memory safeInstance = SafeTestTools._setupSafe(keys, numSigs, 0); - // Create an empty array of signature data - bytes memory signatures; - - // Populate the signatures by iterating over the keys, and choosing the signature type based - // on the key. + // Next we will generate signatures by iterating over the keys, and choosing the signature type + // based on the key. uint8 v; bytes32 r; bytes32 s; - for (uint256 i; i < keys.length; i++) { - if (sigType(keys[i]) == SigTypes.Eoa) { - (v, r, s) = vm.sign(keys[i], _digest); - // Safe signatures are encoded as r, s, v, not v, r, s. + uint256 contractSigs; + bytes memory signatures; + uint256[] memory pks = safeInstance.ownerPKs; + for (uint256 i; i < pks.length; i++) { + if (sigType(pks[i]) == SigTypes.Eoa) { + (v, r, s) = vm.sign(pks[i], digest); signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); - } else if (sigType(keys[i]) == SigTypes.EthSign) { - (v, r, s) = vm.sign(keys[i], keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _digest))); + } else if (sigType(pks[i]) == SigTypes.EthSign) { + (v, r, s) = vm.sign(pks[i], keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", digest))); v += 4; signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); - } else if (sigType(keys[i]) == SigTypes.ApprovedHash) { - vm.prank(getAddr(keys[i])); - safeInstance.safe.approveHash(_digest); + } else if (sigType(pks[i]) == SigTypes.ApprovedHash) { + vm.prank(getAddr(pks[i])); + safeInstance.safe.approveHash(digest); v = 1; - s; // s is not checked on approved hash signatures. - r = bytes32(uint256(uint160(getAddr(keys[i])))); + // s is not checked on approved hash signatures, so we can leave it as zero. + r = bytes32(uint256(uint160(getAddr(pks[i])))); signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); - } // else if (sigType(keys[i]) == SigTypes.Contract) { - // address addr = decodeSmartContractWalletAsAddress(keys[i]); - // r = bytes32(uint256(uint160(addr))); - // vm.mockCall( - // addr, abi.encodeWithSignature("isValidSignature(bytes,bytes)"), - // abi.encode(EIP1271_MAGIC_VALUE) - // ); - // v = 1; - // s; // s is not checked on approved hash signatures. - // signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); - // } + } else if (sigType(pks[i]) == SigTypes.Contract) { + contractSigs++; + address addr = decodeSmartContractWalletAsAddress(pks[i]); + r = bytes32(uint256(uint160(addr))); + vm.mockCall( + addr, abi.encodeWithSignature("isValidSignature(bytes,bytes)"), abi.encode(EIP1271_MAGIC_VALUE) + ); + v = 0; + // s needs to point to data that comes after the signatures + s = bytes32(numSigs * 65); + signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); + } + } + + // For each contract sig, add 64 bytes to the signature data. This is necessary to satisfy + // the validation checks that the Safe contract performs on the value of s on contract + // signatures. The Safe contract checks that s correctly points to additional data appended + // after the signatures, and that the length of the data is within bounds. + for (uint256 i = 0; i < contractSigs; i++) { + signatures = bytes.concat(signatures, abi.encode(32, 1)); } + // Signature checking on the Safe should succeed. - // temp note: the second arg is the data, which is only used in the contract signatures type. - safeInstance.safe.checkNSignatures(_digest, hex"", signatures, numSigs); + safeInstance.safe.checkNSignatures(digest, _data, signatures, numSigs); - // Recover the signatures using the getSigners() method. - address[] memory gotSigners = _getNSigners(_digest, signatures); + // Recover the signatures using the _getNSigners() method. + address[] memory gotSigners = + _getNSigners({ dataHash: digest, signatures: signatures, requiredSignatures: numSigs }); - // Compare the recovered signers to the expected signers. + // Compare the list of recovered signers to the expected signers. assertEq(gotSigners.length, numSigs); assertEq(gotSigners.length, safeInstance.owners.length); for (uint256 i; i < numSigs; i++) { From 0493c40b9a0ae072212af3e43ea4bb30ffe81041 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 20 Oct 2023 15:12:33 -0400 Subject: [PATCH 132/374] test(ctb): Fixes and improvements to checkTransaction test --- .../contracts-bedrock/test/LivenessGuard.t.sol | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 823311888932..d85466081c57 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { Safe } from "safe-contracts/Safe.sol"; +import { Safe, OwnerManager } from "safe-contracts/Safe.sol"; import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; @@ -37,12 +37,20 @@ contract LivnessGuard_CheckTx_Test is LivnessGuard_TestInit { using SafeTestLib for SafeInstance; function test_checkTransaction_succeeds() external { + // Create an array of the addresses who will sign the transaction. SafeTestTools + // will generate these signatures up to the threshold by iterating over the owners array. + address[] memory signers = new address[](safeInstance.threshold); + signers[0] = safeInstance.owners[0]; + signers[1] = safeInstance.owners[1]; + // Don't check topic1 so that we can avoid the ugly txHash calculation. vm.expectEmit(false, true, true, true, address(livenessGuard)); - emit SignersRecorded(0x0, safeInstance.owners); + emit SignersRecorded(0x0, signers); + vm.expectCall(address(safeInstance.safe), abi.encodeWithSignature("nonce()")); + vm.expectCall(address(safeInstance.safe), abi.encodeCall(OwnerManager.getThreshold, ())); safeInstance.execTransaction({ to: address(1111), value: 0, data: hex"abba" }); - for (uint256 i; i < safeInstance.owners.length; i++) { + for (uint256 i; i < safeInstance.threshold; i++) { assertEq(livenessGuard.lastSigned(safeInstance.owners[i]), block.timestamp); } } From d5600eb8628bf63ffc4b97ecc450e6175d072226 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 20 Oct 2023 15:34:27 -0400 Subject: [PATCH 133/374] chore(ctb): Remove todo note from LivenessGuard --- packages/contracts-bedrock/src/Safe/LivenessGuard.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 2abe1d3b2be9..38f07fe4c684 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -85,9 +85,6 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { address[] memory signers = new address[](1); signers[0] = msg.sender; - // todo(maurelian): Is there any need for this event to be differentiated from the one emitted in - // checkTransaction? - // Technically the 0x0 txHash does serve to identiy a call to this method. emit SignersRecorded(0x0, signers); } } From b6a38049e59a804e4364ae1fe4e94b52a164920d Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 29 Sep 2023 16:48:03 -0400 Subject: [PATCH 134/374] specs: Add specs for Liveness Checking --- specs/safe-liveness-checking.md | 68 +++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 specs/safe-liveness-checking.md diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md new file mode 100644 index 000000000000..b4d145c50ce2 --- /dev/null +++ b/specs/safe-liveness-checking.md @@ -0,0 +1,68 @@ +# Safe Liveness Checking + + + +**Table of Contents** + +- [Liveness Checking Mechanism](#liveness-checking-mechanism) +- [Liveness checking methodology](#liveness-checking-methodology) + - [The Liveness Guard](#the-liveness-guard) + - [The Liveness Module](#the-liveness-module) + - [Shutdown](#shutdown) + - [Security Properties](#security-properties) + + + +## Liveness Checking Mechanism + +The Security Security Council uses a specially extended Safe multisig contract to ensure that +any loss of access to a signer's keys is identified and addressed within a predictable period of +time. + +## Liveness checking methodology + +This is achieved using two types of contracts which the Safe contract has built-in support for: + +1. **Guard contracts:** can execute pre- and post- transaction checks. +1. **Module contracts:** a contract which is added to the Safe by the signers, and thenceforth is + authorized to execute transactions via the Safe. This means the module must properly implement + auth conditions internally. + +### The Liveness Guard + +For implementing liveness checks a `LivenessGuard` is created which receives the signatures from +each executed transaction, and tracks the latest time at which a transaction was signed by each +signer. This time is made publicly available by calling a `lastSigned(address)(Timestamp)` method. + +Signers may also call the contract directly in order to prove liveness. + +### The Liveness Module + +A `LivenessModule` is also created which does the following: + +1. Has a function `removeSigner()` that anyone may call to specify a signer to be removed from the + Safe. +1. The Module would then check the `LivenessGuard.lastSigned()` to determine if the signer is + eligible for removal. +1. If so, it will call the Safe's `removeSigner()` to remove the non-live signer, and if necessary + reduce the threshold. +1. When a member is removed, the signing parameters are modified such that `M/N` is the lowest ratio + which remains above 75%. These ratios are (9 of 12, 9 of 11, 8 of 10, 7 of 9, 6 of 8). Using + integer math, this can be expressed as `M = (N * 75 + 99) / 100`. + +### Shutdown + +In the unlikely event that the signer set (`N`) is reduced below 8, then (and only then) is a + shutdown mechanism activated which removes the existing signers, and hands control of the + multisig over to a predetermined entity. + +### Security Properties + +1. Signatures are assigned to the correct signer. +2. Non-signers are unable to create a record of having signed. +3. A signer cannot be censored or grieffed such that their signing is not recorded. +4. Signers may demonstrate liveness either by signing a transaction or by calling directly to the + guard. +5. The module implements the correct checks priort to removing a signer. +6. The module sets the correct threshold upon removing a signer. +7. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1. From 3033dd632e23e111e0c1f6805b0eb471128d171a Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 20 Oct 2023 16:06:12 -0400 Subject: [PATCH 135/374] feat(ctb): Remove redundant check in LivenessModule test(ctb): Add test for get75PercentThreshold --- packages/contracts-bedrock/.gas-snapshot | 5 ++++ packages/contracts-bedrock/semver-lock.json | 2 ++ .../src/Safe/LivenessModule.sol | 16 ++++++----- .../test/LivenessModule.t.sol | 27 +++++++++++++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 449fd2dcba8c..67e01fb5ddb4 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -305,6 +305,11 @@ LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12957) LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10755) LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34524) LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689) +LivenessGuard_ShowLiveness_Test:test_showLiveness_succeeds() (gas: 51339) +LivenessModule_Get75PercentThreshold_Test:test_get75PercentThreshold_Works() (gas: 26339) +LivenessModule_RemoveOwner_Test:test_removeOwner_allOwners_succeeds() (gas: 159764) +LivenessModule_RemoveOwner_Test:test_removeOwner_oneOwner_succeeds() (gas: 109028) +LivnessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 160454) MIPS_Test:test_add_succeeds() (gas: 122932) MIPS_Test:test_addiSign_succeeds() (gas: 122923) MIPS_Test:test_addi_succeeds() (gas: 123120) diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 4c56a35e20aa..07382eba2e82 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -18,6 +18,8 @@ "src/L2/L2StandardBridge.sol": "0x284ebf5569c75d98f2d1920a276d1116524399355708c4a60ea5892283c56719", "src/L2/L2ToL1MessagePasser.sol": "0xafc710b4d320ef450586d96a61cbd58cac814cb3b0c4fdc280eace3efdcdf321", "src/L2/SequencerFeeVault.sol": "0x883e434a69b4789997a4a9a32060dbbd2e12db6f1970927f1310820336119575", + "src/Safe/LivenessGuard.sol": "0x31b4ecc88c982490243ab42914c3de75e5acfa421ffc0ea0d0f0997dcc0341b5", + "src/Safe/LivenessModule.sol": "0xb8c8178c1f4f78eed4777846a40eda6a3a0c1710085822d92267339ae752799b", "src/dispute/BlockOracle.sol": "0x7e724b1ee0116dfd744f556e6237af449c2f40c6426d6f1462ae2a47589283bb", "src/dispute/DisputeGameFactory.sol": "0xfdfa141408d7f8de7e230ff4bef088e30d0e4d569ca743d60d292abdd21ff270", "src/dispute/FaultDisputeGame.sol": "0x0766707ab32338a6586c2340ddfbfd4e9023eeb9dfa3ef87e4b404fb0260479f", diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 46f1f40a15f5..20c6bf72e12f 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Safe } from "safe-contracts/Safe.sol"; +import { Safe, OwnerManager } from "safe-contracts/Safe.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import { OwnerManager } from "safe-contracts/base/OwnerManager.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; @@ -29,6 +29,9 @@ contract LivenessModule is ISemver { /// @notice The fallback owner of the Safe address public fallbackOwner; + /// @notice The address of the first owner in the linked list of owners + address internal constant SENTINEL_OWNERS = address(0x1); + /// @notice Semantic version. /// @custom:semver 1.0.0 string public constant version = "1.0.0"; @@ -120,15 +123,15 @@ contract LivenessModule is ISemver { address[] memory owners = safe.getOwners(); uint256 numOwners = owners.length; require( - (numOwners == 1 && owners[0] == fallbackOwner) || (numOwners >= minOwners), - "LivenessModule: Safe must have at least 1 owner or minOwners" + (numOwners >= minOwners) || (numOwners == 1 && owners[0] == fallbackOwner), + "LivenessModule: Safe must have the minimum number of owners, or be owned solely by the fallback owner" ); // Check that the threshold is correct uint256 threshold = safe.getThreshold(); require( - threshold == get75PercentThreshold(numOwners) || (numOwners == 1 && threshold == 1), - "LivenessModule: threshold must be 75% of the number of owners, or 1 if there is only 1 owner" + threshold == get75PercentThreshold(numOwners), + "LivenessModule: threshold must be 75% of the number of owners" ); } @@ -137,7 +140,7 @@ contract LivenessModule is ISemver { for (uint256 i = 0; i < owners.length; i++) { if (owners[i] == owner) { if (i == 0) { - prevOwner_ = address(0x1); // OwnerManager.SENTINEL_OWNERS + prevOwner_ = SENTINEL_OWNERS; break; } prevOwner_ = owners[i - 1]; @@ -147,6 +150,7 @@ contract LivenessModule is ISemver { } /// @notice For a given number of owners, return the lowest threshold which is greater than 75. + /// Note: this function returns 1 for numOwners == 1. function get75PercentThreshold(uint256 _numOwners) public pure returns (uint256 threshold_) { threshold_ = (_numOwners * 75 + 99) / 100; } diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 1276e689362e..9e4ebdbf5ca4 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -36,6 +36,33 @@ contract LivnessModule_TestInit is Test, SafeTestTools { } } +contract LivenessModule_Get75PercentThreshold_Test is LivnessModule_TestInit { + /// @dev check the return values of the get75PercentThreshold function against manually + /// calculated values. + function test_get75PercentThreshold_Works() external { + assertEq(livenessModule.get75PercentThreshold(20), 15); + assertEq(livenessModule.get75PercentThreshold(19), 15); + assertEq(livenessModule.get75PercentThreshold(18), 14); + assertEq(livenessModule.get75PercentThreshold(17), 13); + assertEq(livenessModule.get75PercentThreshold(16), 12); + assertEq(livenessModule.get75PercentThreshold(15), 12); + assertEq(livenessModule.get75PercentThreshold(14), 11); + assertEq(livenessModule.get75PercentThreshold(13), 10); + assertEq(livenessModule.get75PercentThreshold(12), 9); + assertEq(livenessModule.get75PercentThreshold(11), 9); + assertEq(livenessModule.get75PercentThreshold(10), 8); + assertEq(livenessModule.get75PercentThreshold(9), 7); + assertEq(livenessModule.get75PercentThreshold(8), 6); + assertEq(livenessModule.get75PercentThreshold(7), 6); + assertEq(livenessModule.get75PercentThreshold(6), 5); + assertEq(livenessModule.get75PercentThreshold(5), 4); + assertEq(livenessModule.get75PercentThreshold(4), 3); + assertEq(livenessModule.get75PercentThreshold(3), 3); + assertEq(livenessModule.get75PercentThreshold(2), 2); + assertEq(livenessModule.get75PercentThreshold(1), 1); + } +} + contract LivenessModule_RemoveOwner_Test is LivnessModule_TestInit { function test_removeOwner_oneOwner_succeeds() external { uint256 ownersBefore = safeInstance.owners.length; From 0831cd6dc288bd90016847b4ff9d7aa0924ca918 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 12:50:22 -0400 Subject: [PATCH 136/374] feat(ctb): Ensure adding and removing owners is handled correctly OZ's EnumerableSet library is used to store the set of owners prior to execution, and then to compare with the set of owners after execution, and to add/remove those addresses from the mapping accordingly. --- .../src/Safe/LivenessGuard.sol | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 38f07fe4c684..1de36297f70d 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -7,8 +7,11 @@ import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; import { GetSigners } from "src/Safe/GetSigners.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import { ISemver } from "src/universal/ISemver.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; contract LivenessGuard is ISemver, GetSigners, BaseGuard { + using EnumerableSet for EnumerableSet.AddressSet; + /// @notice Emitted when a new set of signers is recorded. /// @param signers An arrary of signer addresses. event SignersRecorded(bytes32 indexed txHash, address[] signers); @@ -20,12 +23,33 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { Safe public immutable safe; mapping(address => uint256) public lastSigned; + EnumerableSet.AddressSet private ownersBefore; + constructor(Safe _safe) { safe = _safe; } - /// @notice We just need to satisfy the BaseGuard interfae, but we don't actually need to use this method. - function checkAfterExecution(bytes32, bool) external pure { + /// @notice We use this post execution hook to compare the set of owners before and after. + /// If the set of owners has changed then we: + /// 1. Add new owners to the lastSigned mapping + /// 2. Delete removed owners from the lastSigned mapping + function checkAfterExecution(bytes32, bool) external { + address[] memory ownersAfter = safe.getOwners(); + for (uint256 i = 0; i < ownersAfter.length; i++) { + if (ownersBefore.contains(ownersAfter[i])) { + // This address was already present, no change, remove it from the set. + ownersBefore.remove(ownersAfter[i]); + } else { + // This address is newly added, add it to the lastSigned mapping + lastSigned[ownersAfter[i]] = block.timestamp; + } + // Iterate over ownersSet. Any remaining addresses are no longer an owner, so we delete + // it from the lastSigned mapping. + for (uint256 j = 0; j < ownersBefore.length(); j++) { + address owner = ownersBefore.at(j); + delete lastSigned[owner]; + } + } return; } @@ -49,6 +73,13 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { { require(msg.sender == address(safe), "LivenessGuard: only Safe can call this function"); + // Cache the set of owners prior to execution. + // This will be used in the checkAfterExecution method. + address[] memory owners = safe.getOwners(); + for (uint256 i = 0; i < owners.length; i++) { + ownersBefore.add(owners[i]); + } + // This call will reenter to the Safe which is calling it. This is OK because it is only reading the // nonce, and using the getTransactionHash() method. bytes32 txHash = Safe(payable(msg.sender)).getTransactionHash( From 5a1baf8f85c4f6f003c4d55e1b82fe31ee22ba87 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 12:57:29 -0400 Subject: [PATCH 137/374] feat(ctb): Clean up and comment the checkAfterExecution hook --- .../src/Safe/LivenessGuard.sol | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 1de36297f70d..39da08c2775f 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -34,21 +34,22 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { /// 1. Add new owners to the lastSigned mapping /// 2. Delete removed owners from the lastSigned mapping function checkAfterExecution(bytes32, bool) external { + // Get the current set of owners address[] memory ownersAfter = safe.getOwners(); + + // Iterate over the current owners, and remove one at a time from the ownersBefore set. for (uint256 i = 0; i < ownersAfter.length; i++) { - if (ownersBefore.contains(ownersAfter[i])) { - // This address was already present, no change, remove it from the set. - ownersBefore.remove(ownersAfter[i]); - } else { - // This address is newly added, add it to the lastSigned mapping + // If the value was present, remove() returns true. + if (ownersBefore.remove(ownersAfter[i]) == false) { + // This address was not already an owner, add it to the lastSigned mapping lastSigned[ownersAfter[i]] = block.timestamp; } - // Iterate over ownersSet. Any remaining addresses are no longer an owner, so we delete - // it from the lastSigned mapping. - for (uint256 j = 0; j < ownersBefore.length(); j++) { - address owner = ownersBefore.at(j); - delete lastSigned[owner]; - } + } + // Now iterate over the remaining ownersBefore entries. Any remaining addresses are no longer an owner, so we + // delete them from the lastSigned mapping. + for (uint256 j = 0; j < ownersBefore.length(); j++) { + address owner = ownersBefore.at(j); + delete lastSigned[owner]; } return; } From e8f9e2e6226d90047c2ae73c02ced1509d5114ce Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 16:01:57 -0400 Subject: [PATCH 138/374] specs: Apply suggested edits from review h/t @mds1 Co-authored-by: Matt Solomon --- specs/safe-liveness-checking.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md index b4d145c50ce2..8a891d2b6d3d 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/safe-liveness-checking.md @@ -40,7 +40,7 @@ Signers may also call the contract directly in order to prove liveness. A `LivenessModule` is also created which does the following: -1. Has a function `removeSigner()` that anyone may call to specify a signer to be removed from the +1. Has a function `removeOwner()` that anyone may call to specify an owner to be removed from the Safe. 1. The Module would then check the `LivenessGuard.lastSigned()` to determine if the signer is eligible for removal. @@ -58,11 +58,13 @@ In the unlikely event that the signer set (`N`) is reduced below 8, then (and on ### Security Properties +The following security properties must be upheld: + 1. Signatures are assigned to the correct signer. 2. Non-signers are unable to create a record of having signed. -3. A signer cannot be censored or grieffed such that their signing is not recorded. +3. A signer cannot be censored or griefed such that their signing is not recorded. 4. Signers may demonstrate liveness either by signing a transaction or by calling directly to the guard. -5. The module implements the correct checks priort to removing a signer. +5. The module implements the correct checks prior to removing a signer. 6. The module sets the correct threshold upon removing a signer. 7. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1. From 38f828d054668ebdcddaa36e4961a16e7e849bab Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 13:09:24 -0400 Subject: [PATCH 139/374] feat(ctb): Rename lastSigned to more accurate lastLive This is more accurate because of the fact that showLiveness can be used without approving a transaction. --- packages/contracts-bedrock/src/Safe/LivenessGuard.sol | 10 +++++----- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 2 +- packages/contracts-bedrock/test/LivenessGuard.t.sol | 4 ++-- specs/safe-liveness-checking.md | 7 +++---- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 39da08c2775f..310e771f27c5 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -21,8 +21,8 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { string public constant version = "1.0.0"; Safe public immutable safe; - mapping(address => uint256) public lastSigned; + mapping(address => uint256) public lastLive; EnumerableSet.AddressSet private ownersBefore; constructor(Safe _safe) { @@ -42,14 +42,14 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { // If the value was present, remove() returns true. if (ownersBefore.remove(ownersAfter[i]) == false) { // This address was not already an owner, add it to the lastSigned mapping - lastSigned[ownersAfter[i]] = block.timestamp; + lastLive[ownersAfter[i]] = block.timestamp; } } // Now iterate over the remaining ownersBefore entries. Any remaining addresses are no longer an owner, so we // delete them from the lastSigned mapping. for (uint256 j = 0; j < ownersBefore.length(); j++) { address owner = ownersBefore.at(j); - delete lastSigned[owner]; + delete lastLive[owner]; } return; } @@ -104,7 +104,7 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { _getNSigners({ dataHash: txHash, signatures: signatures, requiredSignatures: threshold }); for (uint256 i = 0; i < signers.length; i++) { - lastSigned[signers[i]] = block.timestamp; + lastLive[signers[i]] = block.timestamp; } emit SignersRecorded(txHash, signers); } @@ -113,7 +113,7 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { /// This is useful for owners who have not recently signed a transaction via the Safe. function showLiveness() external { require(safe.isOwner(msg.sender), "LivenessGuard: only Safe owners may demontstrate liveness"); - lastSigned[msg.sender] = block.timestamp; + lastLive[msg.sender] = block.timestamp; address[] memory signers = new address[](1); signers[0] = msg.sender; diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 20c6bf72e12f..a7ccbf42c713 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -56,7 +56,7 @@ contract LivenessModule is ISemver { function removeOwner(address owner) external { // Check that the owner has not signed a transaction in the last 30 days require( - livenessGuard.lastSigned(owner) < block.timestamp - livenessInterval, + livenessGuard.lastLive(owner) < block.timestamp - livenessInterval, "LivenessModule: owner has signed recently" ); diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index d85466081c57..8046fb01b0ad 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -51,7 +51,7 @@ contract LivnessGuard_CheckTx_Test is LivnessGuard_TestInit { safeInstance.execTransaction({ to: address(1111), value: 0, data: hex"abba" }); for (uint256 i; i < safeInstance.threshold; i++) { - assertEq(livenessGuard.lastSigned(safeInstance.owners[i]), block.timestamp); + assertEq(livenessGuard.lastLive(safeInstance.owners[i]), block.timestamp); } } } @@ -70,6 +70,6 @@ contract LivenessGuard_ShowLiveness_Test is LivnessGuard_TestInit { vm.prank(caller); livenessGuard.showLiveness(); - assertEq(livenessGuard.lastSigned(caller), block.timestamp); + assertEq(livenessGuard.lastLive(caller), block.timestamp); } } diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md index 8a891d2b6d3d..1a71cfee83fa 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/safe-liveness-checking.md @@ -32,7 +32,7 @@ This is achieved using two types of contracts which the Safe contract has built- For implementing liveness checks a `LivenessGuard` is created which receives the signatures from each executed transaction, and tracks the latest time at which a transaction was signed by each -signer. This time is made publicly available by calling a `lastSigned(address)(Timestamp)` method. +signer. This time is made publicly available by calling a `lastLive(address)(Timestamp)` method. Signers may also call the contract directly in order to prove liveness. @@ -42,13 +42,12 @@ A `LivenessModule` is also created which does the following: 1. Has a function `removeOwner()` that anyone may call to specify an owner to be removed from the Safe. -1. The Module would then check the `LivenessGuard.lastSigned()` to determine if the signer is +1. The Module would then check the `LivenessGuard.lastLive()` to determine if the signer is eligible for removal. 1. If so, it will call the Safe's `removeSigner()` to remove the non-live signer, and if necessary reduce the threshold. 1. When a member is removed, the signing parameters are modified such that `M/N` is the lowest ratio - which remains above 75%. These ratios are (9 of 12, 9 of 11, 8 of 10, 7 of 9, 6 of 8). Using - integer math, this can be expressed as `M = (N * 75 + 99) / 100`. + which remains above 75%. Using integer math, this can be expressed as `M = (N * 75 + 99) / 100`. ### Shutdown From 2ce7314d481a0d73fe8c1590cd16aa1f0a3994eb Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 13:10:56 -0400 Subject: [PATCH 140/374] feat(ctb): Add missing natspec to LivenessGuard and LivenessModule --- packages/contracts-bedrock/src/Safe/LivenessGuard.sol | 9 +++++++++ packages/contracts-bedrock/src/Safe/LivenessModule.sol | 7 +++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 310e771f27c5..a472c3229d44 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -20,11 +20,20 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { /// @custom:semver 1.0.0 string public constant version = "1.0.0"; + /// @notice The safe account for which this contract will be the guard. Safe public immutable safe; + /// @notice A mapping of the timestamp at which an owner last participated in signing a + /// an executed transaction. mapping(address => uint256) public lastLive; + + /// @notice An enumerable set of addresses used to store the list of owners before execution, + /// and then to update the lastSigned mapping according to changes in the set observed + /// after execution. EnumerableSet.AddressSet private ownersBefore; + /// @notice Constructor. + /// @param _safe The safe account for which this contract will be the guard. constructor(Safe _safe) { safe = _safe; } diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index a7ccbf42c713..795c2fcc85c0 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -11,8 +11,11 @@ import { ISemver } from "src/universal/ISemver.sol"; import { console2 as console } from "forge-std/console2.sol"; /// @title LivenessModule -/// @notice This module is intended to be used in conjunction with the LivenessGuard. It should be able to -/// execute a transaction on the Safe in only a small number of cases. +/// @notice This module is intended to be used in conjunction with the LivenessGuard. In the event +/// that an owner of the safe is not recorded by the guard during the liveness interval, +/// the owner will be considered inactive and will be removed from the list of owners. +/// If the number of owners falls below the minimum number of owners, the ownership of the +/// safe will be transferred to the fallback owner. contract LivenessModule is ISemver { /// @notice The Safe contract instance Safe public safe; From aef990f387fca34cff5bf2f71cd1d2a222ceb207 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 13:27:56 -0400 Subject: [PATCH 141/374] feat(ctb): Make guard state immutable --- .../src/Safe/LivenessModule.sol | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 795c2fcc85c0..0954ab7c517f 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -18,19 +18,23 @@ import { console2 as console } from "forge-std/console2.sol"; /// safe will be transferred to the fallback owner. contract LivenessModule is ISemver { /// @notice The Safe contract instance - Safe public safe; + Safe public immutable safe; /// @notice The LivenessGuard contract instance - LivenessGuard public livenessGuard; + /// This can be updated by replacing with a new module and switching out the guard. + LivenessGuard public immutable livenessGuard; /// @notice The interval, in seconds, during which an owner must have demonstrated liveness - uint256 public livenessInterval; + /// This can be updated by replacing with a new module. + uint256 public immutable livenessInterval; /// @notice The minimum number of owners before ownership of the safe is transferred to the fallback owner. - uint256 public minOwners; + /// This can be updated by replacing with a new module. + uint256 public immutable minOwners; /// @notice The fallback owner of the Safe - address public fallbackOwner; + /// This can be updated by replacing with a new module. + address public immutable fallbackOwner; /// @notice The address of the first owner in the linked list of owners address internal constant SENTINEL_OWNERS = address(0x1); @@ -55,8 +59,12 @@ contract LivenessModule is ISemver { } /// @notice This function can be called by anyone to remove an owner that has not signed a transaction - /// during the livness interval. If the number of owners drops below + /// during the liveness interval. If the number of owners drops below the minimum, then the + /// ownership of the Safe is transferred to the fallback owner. function removeOwner(address owner) external { + // Check that the guard has not been changed + require(livenessGuard == safe.getGuard(), "LivenessModule: guard has been changed"); + // Check that the owner has not signed a transaction in the last 30 days require( livenessGuard.lastLive(owner) < block.timestamp - livenessInterval, @@ -67,7 +75,7 @@ contract LivenessModule is ISemver { address[] memory owners = safe.getOwners(); uint256 numOwners = owners.length - 1; uint256 thresholdAfter; - if (numOwners > minOwners) { + if (hasMinOwners(numOwners)) { // Preserves the invariant that the Safe has at least 8 owners thresholdAfter = get75PercentThreshold(numOwners); @@ -126,7 +134,7 @@ contract LivenessModule is ISemver { address[] memory owners = safe.getOwners(); uint256 numOwners = owners.length; require( - (numOwners >= minOwners) || (numOwners == 1 && owners[0] == fallbackOwner), + hasMinOwners(numOwners) || (numOwners == 1 && owners[0] == fallbackOwner), "LivenessModule: Safe must have the minimum number of owners, or be owned solely by the fallback owner" ); @@ -157,4 +165,11 @@ contract LivenessModule is ISemver { function get75PercentThreshold(uint256 _numOwners) public pure returns (uint256 threshold_) { threshold_ = (_numOwners * 75 + 99) / 100; } + + /// @notice Check if the number of owners is greater than or equal to the minimum number of owners. + /// @param numOwners The number of owners. + /// @return A boolean indicating if the number of owners is greater than or equal to the minimum number of owners. + function hasMinOwners(uint256 numOwners) public view returns (bool) { + return numOwners >= minOwners; + } } From 20a0c6c432beac9ab595c3c9a335cb5221f8f347 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 13:58:39 -0400 Subject: [PATCH 142/374] feat(ctb): ensure guard has not changed before calling removeOwner --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 9 ++++++++- packages/contracts-bedrock/test/LivenessModule.t.sol | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 0954ab7c517f..f7efcdb253bb 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -36,6 +36,10 @@ contract LivenessModule is ISemver { /// This can be updated by replacing with a new module. address public immutable fallbackOwner; + /// @notice The storage slot used in the safe to store the guard address + /// keccak256("guard_manager.guard.address") + uint256 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8; + /// @notice The address of the first owner in the linked list of owners address internal constant SENTINEL_OWNERS = address(0x1); @@ -63,7 +67,10 @@ contract LivenessModule is ISemver { /// ownership of the Safe is transferred to the fallback owner. function removeOwner(address owner) external { // Check that the guard has not been changed - require(livenessGuard == safe.getGuard(), "LivenessModule: guard has been changed"); + require( + address(livenessGuard) == address(uint160(uint256(bytes32(safe.getStorageAt(GUARD_STORAGE_SLOT, 1))))), + "LivenessModule: guard has been changed" + ); // Check that the owner has not signed a transaction in the last 30 days require( diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 9e4ebdbf5ca4..0e7a262af036 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -33,6 +33,7 @@ contract LivnessModule_TestInit is Test, SafeTestTools { _fallbackOwner: makeAddr("fallbackOwner") }); safeInstance.enableModule(address(livenessModule)); + safeInstance.setGuard(address(livenessGuard)); } } From da8a1f235c18e70b83f5b4bcaa6a37a76d03a6cd Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 15:14:26 -0400 Subject: [PATCH 143/374] refactor(ctb): Extract execTransactionFromModule calls into helper functions --- .../src/Safe/LivenessModule.sol | 81 ++++++++++--------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index f7efcdb253bb..3213a2e23ad2 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -83,59 +83,64 @@ contract LivenessModule is ISemver { uint256 numOwners = owners.length - 1; uint256 thresholdAfter; if (hasMinOwners(numOwners)) { - // Preserves the invariant that the Safe has at least 8 owners + // Preserves the invariant that the Safe has at least numOwners thresholdAfter = get75PercentThreshold(numOwners); console.log("removing one owner. numOwners: %s, thresholdAfter: %s", numOwners, thresholdAfter); - safe.execTransactionFromModule({ - to: address(safe), - value: 0, - data: abi.encodeCall( - // Call the Safe to remove the owner - OwnerManager.removeOwner, - (getPrevOwner(owner, owners), owner, thresholdAfter) - ), - operation: Enum.Operation.Call - }); + address prevOwner = _getPrevOwner(owner, owners); + // Call the Safe to remove the owner + _removeOwner({ _prevOwner: prevOwner, _owner: owner, _threshold: thresholdAfter }); } else { console.log("removing all owners. numOwnersAfter: %s", numOwners); - // The number of owners is dangerously low, so we wish to transfer the ownership of this Safe to a new + // The number of owners is dangerously low, so we wish to transfer the ownership of this Safe // to the fallback owner. // The threshold will be 1 because we are removing all owners except the fallback owner - thresholdAfter = 1; + // thresholdAfter = 1; // todo: why is this here? We should be able to delete it. // Remove owners one at a time starting from the last owner. - // Since we're removing them in order, the ordering will remain constant, - // and we shouldn't need to query the list of owners again. + // Since we're removing them in order from last to first, the ordering will remain constant, + // and we shouldn't need to query the list of owners again. for (uint256 i = owners.length - 1; i >= 0; i--) { address currentOwner = owners[i]; - address prevOwner = getPrevOwner(currentOwner, owners); + address prevOwner = _getPrevOwner(currentOwner, owners); if (currentOwner != address(this)) { - safe.execTransactionFromModule({ - to: address(safe), - value: 0, - data: abi.encodeCall( - // Call the Safe to remove the owner - OwnerManager.removeOwner, - (prevOwner, currentOwner, 1) - ), - operation: Enum.Operation.Call - }); + // Call the Safe to remove the owner + _removeOwner({ _prevOwner: prevOwner, _owner: currentOwner, _threshold: 1 }); } } // Add the fallback owner as the sole owner of the Safe - safe.execTransactionFromModule({ - to: address(safe), - value: 0, - data: abi.encodeCall(OwnerManager.addOwnerWithThreshold, (fallbackOwner, 1)), - operation: Enum.Operation.Call - }); + _addOwnerWithThreshold({ _owner: fallbackOwner, _threshold: 1 }); } _verifyFinalState(); } + /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`. + /// @param _owner New owner address. + /// @param _threshold New threshold. + function _addOwnerWithThreshold(address _owner, uint256 _threshold) internal { + safe.execTransactionFromModule({ + to: address(safe), + value: 0, + operation: Enum.Operation.Call, + data: abi.encodeCall(OwnerManager.addOwnerWithThreshold, (_owner, _threshold)) + }); + } + + /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`. + /// @param _prevOwner Owner that pointed to the owner to be removed in the linked list + /// @param _owner Owner address to be removed. + /// @param _threshold New threshold. + function _removeOwner(address _prevOwner, address _owner, uint256 _threshold) internal { + safe.execTransactionFromModule({ + to: address(safe), + value: 0, + operation: Enum.Operation.Call, + data: abi.encodeCall(OwnerManager.removeOwner, (_prevOwner, _owner, _threshold)) + }); + } + /// @notice A FREI-PI invariant check enforcing requirements on number of owners and threshold. function _verifyFinalState() internal view { address[] memory owners = safe.getOwners(); @@ -154,16 +159,14 @@ contract LivenessModule is ISemver { } /// @notice Get the previous owner in the linked list of owners - function getPrevOwner(address owner, address[] memory owners) public pure returns (address prevOwner_) { + function _getPrevOwner(address owner, address[] memory owners) internal pure returns (address prevOwner_) { for (uint256 i = 0; i < owners.length; i++) { - if (owners[i] == owner) { - if (i == 0) { - prevOwner_ = SENTINEL_OWNERS; - break; - } - prevOwner_ = owners[i - 1]; + if (owners[i] != owner) continue; + if (i == 0) { + prevOwner_ = SENTINEL_OWNERS; break; } + prevOwner_ = owners[i - 1]; } } From 66a0eee4772cfdfc9ceae635842fe4bd6169555c Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 15:22:39 -0400 Subject: [PATCH 144/374] refactor(ctb): Abstract addOwner method to giveToFallbackOwner --- .../contracts-bedrock/src/Safe/LivenessModule.sol | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 3213a2e23ad2..52b96a29b373 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -111,20 +111,19 @@ contract LivenessModule is ISemver { } // Add the fallback owner as the sole owner of the Safe - _addOwnerWithThreshold({ _owner: fallbackOwner, _threshold: 1 }); + _giveToFallbackOwner(); } + _verifyFinalState(); } - /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`. - /// @param _owner New owner address. - /// @param _threshold New threshold. - function _addOwnerWithThreshold(address _owner, uint256 _threshold) internal { + /// @notice Sets the fallback owner as the sole owner of the Safe with a threshold of 1 + function _giveToFallbackOwner() internal { safe.execTransactionFromModule({ to: address(safe), value: 0, operation: Enum.Operation.Call, - data: abi.encodeCall(OwnerManager.addOwnerWithThreshold, (_owner, _threshold)) + data: abi.encodeCall(OwnerManager.addOwnerWithThreshold, (fallbackOwner, 1)) }); } From 139751ad945ac80062c176b053cc86ae57b0cb30 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 15:23:13 -0400 Subject: [PATCH 145/374] feat(ctb): Clean up removeOwner method on module --- .../contracts-bedrock/src/Safe/LivenessModule.sol | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 52b96a29b373..e1b4d6459767 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -72,7 +72,7 @@ contract LivenessModule is ISemver { "LivenessModule: guard has been changed" ); - // Check that the owner has not signed a transaction in the last 30 days + // Check that the owner to remove has not signed a transaction in the last 30 days require( livenessGuard.lastLive(owner) < block.timestamp - livenessInterval, "LivenessModule: owner has signed recently" @@ -83,21 +83,14 @@ contract LivenessModule is ISemver { uint256 numOwners = owners.length - 1; uint256 thresholdAfter; if (hasMinOwners(numOwners)) { - // Preserves the invariant that the Safe has at least numOwners - + // Call the Safe to remove the owner and update the threshold thresholdAfter = get75PercentThreshold(numOwners); - console.log("removing one owner. numOwners: %s, thresholdAfter: %s", numOwners, thresholdAfter); address prevOwner = _getPrevOwner(owner, owners); - // Call the Safe to remove the owner _removeOwner({ _prevOwner: prevOwner, _owner: owner, _threshold: thresholdAfter }); } else { - console.log("removing all owners. numOwnersAfter: %s", numOwners); // The number of owners is dangerously low, so we wish to transfer the ownership of this Safe // to the fallback owner. - // The threshold will be 1 because we are removing all owners except the fallback owner - // thresholdAfter = 1; // todo: why is this here? We should be able to delete it. - // Remove owners one at a time starting from the last owner. // Since we're removing them in order from last to first, the ordering will remain constant, // and we shouldn't need to query the list of owners again. From b157425580013d861231d240e871462dafe7f428 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 15:23:44 -0400 Subject: [PATCH 146/374] feat(ctb): Add guard check to _verifyState --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index e1b4d6459767..c90a81b71479 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -148,6 +148,12 @@ contract LivenessModule is ISemver { threshold == get75PercentThreshold(numOwners), "LivenessModule: threshold must be 75% of the number of owners" ); + + // Check that the guard has not been changed + require( + address(livenessGuard) == address(uint160(uint256(bytes32(safe.getStorageAt(GUARD_STORAGE_SLOT, 1))))), + "LivenessModule: guard has been changed" + ); } /// @notice Get the previous owner in the linked list of owners From 4a042355f231d650d465edfefde868f46e84a496 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 15:48:38 -0400 Subject: [PATCH 147/374] refactor(ctb): Make GetSigners into a library rather than contract This required copy/pasting the SignatureDecoder code from the Safe repo. --- .../contracts-bedrock/src/Safe/GetSigners.sol | 39 +++++++++++++++++-- .../src/Safe/LivenessGuard.sol | 4 +- .../contracts-bedrock/test/GetSigners.t.sol | 4 +- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/GetSigners.sol b/packages/contracts-bedrock/src/Safe/GetSigners.sol index 0d9642bf6125..7ef639f675b9 100644 --- a/packages/contracts-bedrock/src/Safe/GetSigners.sol +++ b/packages/contracts-bedrock/src/Safe/GetSigners.sol @@ -1,14 +1,47 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; +library GetSigners { + /// @notice Splits signature bytes into `uint8 v, bytes32 r, bytes32 s`. + /// Copied directly from + /// https://github.com/safe-global/safe-contracts/blob/e870f514ad34cd9654c72174d6d4a839e3c6639f/contracts/common/SignatureDecoder.sol + /// @dev Make sure to perform a bounds check for @param pos, to avoid out of bounds access on @param signatures + /// The signature format is a compact form of {bytes32 r}{bytes32 s}{uint8 v} + /// Compact means uint8 is not padded to 32 bytes. + /// @param pos Which signature to read. + /// A prior bounds check of this parameter should be performed, to avoid out of bounds access. + /// @param signatures Concatenated {r, s, v} signatures. + /// @return v Recovery ID or Safe signature type. + /// @return r Output value r of the signature. + /// @return s Output value s of the signature. + function signatureSplit( + bytes memory signatures, + uint256 pos + ) + internal + pure + returns (uint8 v, bytes32 r, bytes32 s) + { + // solhint-disable-next-line no-inline-assembly + assembly { + let signaturePos := mul(0x41, pos) + r := mload(add(signatures, add(signaturePos, 0x20))) + s := mload(add(signatures, add(signaturePos, 0x40))) + /** + * Here we are loading the last 32 bytes, including 31 bytes + * of 's'. There is no 'mload8' to do this. + * 'byte' is not working due to the Solidity parser, so lets + * use the second best option, 'and' + */ + v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff) + } + } -abstract contract GetSigners is SignatureDecoder { /// @notice Extract the signers from a set of signatures. /// @param dataHash Hash of the data. /// @param signatures Signature data for identifying signers. /// @param requiredSignatures Amount of required valid signatures. - function _getNSigners( + function getNSigners( bytes32 dataHash, bytes memory signatures, uint256 requiredSignatures diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index a472c3229d44..2d7cca663f96 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -9,7 +9,7 @@ import { Enum } from "safe-contracts/common/Enum.sol"; import { ISemver } from "src/universal/ISemver.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -contract LivenessGuard is ISemver, GetSigners, BaseGuard { +contract LivenessGuard is ISemver, BaseGuard { using EnumerableSet for EnumerableSet.AddressSet; /// @notice Emitted when a new set of signers is recorded. @@ -110,7 +110,7 @@ contract LivenessGuard is ISemver, GetSigners, BaseGuard { uint256 threshold = safe.getThreshold(); address[] memory signers = - _getNSigners({ dataHash: txHash, signatures: signatures, requiredSignatures: threshold }); + GetSigners.getNSigners({ dataHash: txHash, signatures: signatures, requiredSignatures: threshold }); for (uint256 i = 0; i < signers.length; i++) { lastLive[signers[i]] = block.timestamp; diff --git a/packages/contracts-bedrock/test/GetSigners.t.sol b/packages/contracts-bedrock/test/GetSigners.t.sol index 03cfd711860c..7b1de0952482 100644 --- a/packages/contracts-bedrock/test/GetSigners.t.sol +++ b/packages/contracts-bedrock/test/GetSigners.t.sol @@ -8,7 +8,7 @@ import "test/safe-tools/SafeTestTools.sol"; import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; -contract GetSigners_Test is Test, SafeTestTools, GetSigners { +contract GetSigners_Test is Test, SafeTestTools { bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b; enum SigTypes { @@ -98,7 +98,7 @@ contract GetSigners_Test is Test, SafeTestTools, GetSigners { // Recover the signatures using the _getNSigners() method. address[] memory gotSigners = - _getNSigners({ dataHash: digest, signatures: signatures, requiredSignatures: numSigs }); + GetSigners.getNSigners({ dataHash: digest, signatures: signatures, requiredSignatures: numSigs }); // Compare the list of recovered signers to the expected signers. assertEq(gotSigners.length, numSigs); From 2103d61dffd0b12cdf9d035fa66baf31a110c216 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 23 Oct 2023 16:03:47 -0400 Subject: [PATCH 148/374] refactor(ctb): Extract guard check into _verifyGuard() --- .../contracts-bedrock/src/Safe/LivenessModule.sol | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index c90a81b71479..ee7eefea7101 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -67,10 +67,7 @@ contract LivenessModule is ISemver { /// ownership of the Safe is transferred to the fallback owner. function removeOwner(address owner) external { // Check that the guard has not been changed - require( - address(livenessGuard) == address(uint160(uint256(bytes32(safe.getStorageAt(GUARD_STORAGE_SLOT, 1))))), - "LivenessModule: guard has been changed" - ); + _verifyGuard(); // Check that the owner to remove has not signed a transaction in the last 30 days require( @@ -142,14 +139,20 @@ contract LivenessModule is ISemver { "LivenessModule: Safe must have the minimum number of owners, or be owned solely by the fallback owner" ); - // Check that the threshold is correct + // Check that the threshold is correct. This check is also correct when there is a single + // owner, because get75PercentThreshold(1) returns 1. uint256 threshold = safe.getThreshold(); require( threshold == get75PercentThreshold(numOwners), "LivenessModule: threshold must be 75% of the number of owners" ); - // Check that the guard has not been changed + // Check that the guard has not been changed. + _verifyGuard(); + } + + /// @notice Reverts if the guard address does not match the expected value. + function _verifyGuard() internal view { require( address(livenessGuard) == address(uint160(uint256(bytes32(safe.getStorageAt(GUARD_STORAGE_SLOT, 1))))), "LivenessModule: guard has been changed" From 7f474593fc2e2d04e33c51f5e6067893e195a644 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 10:28:05 -0400 Subject: [PATCH 149/374] chore(ctb): Rename lib to SafeSigners --- packages/contracts-bedrock/src/Safe/LivenessGuard.sol | 4 ++-- .../src/Safe/{GetSigners.sol => SafeSigners.sol} | 5 +++-- .../test/{GetSigners.t.sol => SafeSigners.t.sol} | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) rename packages/contracts-bedrock/src/Safe/{GetSigners.sol => SafeSigners.sol} (97%) rename packages/contracts-bedrock/test/{GetSigners.t.sol => SafeSigners.t.sol} (95%) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 2d7cca663f96..042e47619f7c 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { Safe } from "safe-contracts/Safe.sol"; import { BaseGuard, GuardManager } from "safe-contracts/base/GuardManager.sol"; import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; -import { GetSigners } from "src/Safe/GetSigners.sol"; +import { SafeSigners } from "src/Safe/SafeSigners.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import { ISemver } from "src/universal/ISemver.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; @@ -110,7 +110,7 @@ contract LivenessGuard is ISemver, BaseGuard { uint256 threshold = safe.getThreshold(); address[] memory signers = - GetSigners.getNSigners({ dataHash: txHash, signatures: signatures, requiredSignatures: threshold }); + SafeSigners.getNSigners({ dataHash: txHash, signatures: signatures, requiredSignatures: threshold }); for (uint256 i = 0; i < signers.length; i++) { lastLive[signers[i]] = block.timestamp; diff --git a/packages/contracts-bedrock/src/Safe/GetSigners.sol b/packages/contracts-bedrock/src/Safe/SafeSigners.sol similarity index 97% rename from packages/contracts-bedrock/src/Safe/GetSigners.sol rename to packages/contracts-bedrock/src/Safe/SafeSigners.sol index 7ef639f675b9..20033b26c644 100644 --- a/packages/contracts-bedrock/src/Safe/GetSigners.sol +++ b/packages/contracts-bedrock/src/Safe/SafeSigners.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity ^0.8.0; -library GetSigners { +library SafeSigners { /// @notice Splits signature bytes into `uint8 v, bytes32 r, bytes32 s`. /// Copied directly from /// https://github.com/safe-global/safe-contracts/blob/e870f514ad34cd9654c72174d6d4a839e3c6639f/contracts/common/SignatureDecoder.sol @@ -41,6 +41,7 @@ library GetSigners { /// @param dataHash Hash of the data. /// @param signatures Signature data for identifying signers. /// @param requiredSignatures Amount of required valid signatures. + /// @return _owners List of unique signers. function getNSigners( bytes32 dataHash, bytes memory signatures, diff --git a/packages/contracts-bedrock/test/GetSigners.t.sol b/packages/contracts-bedrock/test/SafeSigners.t.sol similarity index 95% rename from packages/contracts-bedrock/test/GetSigners.t.sol rename to packages/contracts-bedrock/test/SafeSigners.t.sol index 7b1de0952482..a9edbb1ca52e 100644 --- a/packages/contracts-bedrock/test/GetSigners.t.sol +++ b/packages/contracts-bedrock/test/SafeSigners.t.sol @@ -3,12 +3,12 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { Safe } from "safe-contracts/Safe.sol"; -import { GetSigners } from "src/Safe/GetSigners.sol"; +import { SafeSigners } from "src/Safe/SafeSigners.sol"; import "test/safe-tools/SafeTestTools.sol"; import { SignatureDecoder } from "safe-contracts/common/SignatureDecoder.sol"; -contract GetSigners_Test is Test, SafeTestTools { +contract SafeSigners_Test is Test, SafeTestTools { bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b; enum SigTypes { @@ -98,7 +98,7 @@ contract GetSigners_Test is Test, SafeTestTools { // Recover the signatures using the _getNSigners() method. address[] memory gotSigners = - GetSigners.getNSigners({ dataHash: digest, signatures: signatures, requiredSignatures: numSigs }); + SafeSigners.getNSigners({ dataHash: digest, signatures: signatures, requiredSignatures: numSigs }); // Compare the list of recovered signers to the expected signers. assertEq(gotSigners.length, numSigs); From 6368229c0609e80cfd2f000fa105afb4e797aa1d Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 10:29:06 -0400 Subject: [PATCH 150/374] refactor(ctb): Make function _isAboveMinOwners --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index ee7eefea7101..214212485349 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -79,7 +79,7 @@ contract LivenessModule is ISemver { address[] memory owners = safe.getOwners(); uint256 numOwners = owners.length - 1; uint256 thresholdAfter; - if (hasMinOwners(numOwners)) { + if (_isAboveMinOwners(numOwners)) { // Call the Safe to remove the owner and update the threshold thresholdAfter = get75PercentThreshold(numOwners); address prevOwner = _getPrevOwner(owner, owners); @@ -135,8 +135,8 @@ contract LivenessModule is ISemver { address[] memory owners = safe.getOwners(); uint256 numOwners = owners.length; require( - hasMinOwners(numOwners) || (numOwners == 1 && owners[0] == fallbackOwner), - "LivenessModule: Safe must have the minimum number of owners, or be owned solely by the fallback owner" + _isAboveMinOwners(numOwners) || (numOwners == 1 && owners[0] == fallbackOwner), + "LivenessModule: Safe must have the minimum number of owners or be owned solely by the fallback owner" ); // Check that the threshold is correct. This check is also correct when there is a single @@ -180,7 +180,7 @@ contract LivenessModule is ISemver { /// @notice Check if the number of owners is greater than or equal to the minimum number of owners. /// @param numOwners The number of owners. /// @return A boolean indicating if the number of owners is greater than or equal to the minimum number of owners. - function hasMinOwners(uint256 numOwners) public view returns (bool) { + function _isAboveMinOwners(uint256 numOwners) internal view returns (bool) { return numOwners >= minOwners; } } From c7d5b2b9d40975d811604df25826792fd6a9552b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 10:29:41 -0400 Subject: [PATCH 151/374] refactor(ctb): Clean up in LivenessGuard --- .../src/Safe/LivenessGuard.sol | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 042e47619f7c..9b32dea66f0e 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -47,20 +47,21 @@ contract LivenessGuard is ISemver, BaseGuard { address[] memory ownersAfter = safe.getOwners(); // Iterate over the current owners, and remove one at a time from the ownersBefore set. - for (uint256 i = 0; i < ownersAfter.length; i++) { + uint256 ownersAfterLength = ownersAfter.length; + for (uint256 i = 0; i < ownersAfterLength; i++) { // If the value was present, remove() returns true. - if (ownersBefore.remove(ownersAfter[i]) == false) { + address ownerAfter = ownersAfter[i]; + if (ownersBefore.remove(ownerAfter) == false) { // This address was not already an owner, add it to the lastSigned mapping - lastLive[ownersAfter[i]] = block.timestamp; + lastLive[ownerAfter] = block.timestamp; } } // Now iterate over the remaining ownersBefore entries. Any remaining addresses are no longer an owner, so we // delete them from the lastSigned mapping. for (uint256 j = 0; j < ownersBefore.length(); j++) { - address owner = ownersBefore.at(j); - delete lastLive[owner]; + address ownerBefore = ownersBefore.at(j); + delete lastLive[ownerBefore]; } - return; } /// @notice Records the most recent time which any owner has signed a transaction. @@ -92,21 +93,18 @@ contract LivenessGuard is ISemver, BaseGuard { // This call will reenter to the Safe which is calling it. This is OK because it is only reading the // nonce, and using the getTransactionHash() method. - bytes32 txHash = Safe(payable(msg.sender)).getTransactionHash( - // Transaction info - to, - value, - data, - operation, - safeTxGas, - // Payment info - baseGas, - gasPrice, - gasToken, - refundReceiver, - // Signature info - Safe(payable(msg.sender)).nonce() - 1 - ); + bytes32 txHash = Safe(payable(msg.sender)).getTransactionHash({ + to: to, + value: value, + data: data, + operation: operation, + safeTxGas: safeTxGas, + baseGas: baseGas, + gasPrice: gasPrice, + gasToken: gasToken, + refundReceiver: refundReceiver, + _nonce: Safe(payable(msg.sender)).nonce() - 1 + }); uint256 threshold = safe.getThreshold(); address[] memory signers = From b51e604e3afa0b0e0baf7236c84adb9dd25d0887 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 10:34:40 -0400 Subject: [PATCH 152/374] feat(ctb): Improve commenting on LivenessGuard --- .../src/Safe/LivenessGuard.sol | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 9b32dea66f0e..edfdf13b34d0 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -9,6 +9,12 @@ import { Enum } from "safe-contracts/common/Enum.sol"; import { ISemver } from "src/universal/ISemver.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +/// @title LivenessGuard +/// @notice This Guard contract is used to track the liveness of Safe owners. +/// @dev It keeps track of the last time each owner participated in signing a transaction. +/// If an owner does not participate in a transaction for a certain period of time, they are considered inactive. +/// This Guard is intended to be used in conjunction with the LivenessModule contract, but does +/// not depend on it. contract LivenessGuard is ISemver, BaseGuard { using EnumerableSet for EnumerableSet.AddressSet; @@ -24,11 +30,11 @@ contract LivenessGuard is ISemver, BaseGuard { Safe public immutable safe; /// @notice A mapping of the timestamp at which an owner last participated in signing a - /// an executed transaction. + /// an executed transaction, or called showLiveness. mapping(address => uint256) public lastLive; /// @notice An enumerable set of addresses used to store the list of owners before execution, - /// and then to update the lastSigned mapping according to changes in the set observed + /// and then to update the lastLive mapping according to changes in the set observed /// after execution. EnumerableSet.AddressSet private ownersBefore; @@ -40,8 +46,8 @@ contract LivenessGuard is ISemver, BaseGuard { /// @notice We use this post execution hook to compare the set of owners before and after. /// If the set of owners has changed then we: - /// 1. Add new owners to the lastSigned mapping - /// 2. Delete removed owners from the lastSigned mapping + /// 1. Add new owners to the lastLive mapping + /// 2. Delete removed owners from the lastLive mapping function checkAfterExecution(bytes32, bool) external { // Get the current set of owners address[] memory ownersAfter = safe.getOwners(); @@ -52,12 +58,12 @@ contract LivenessGuard is ISemver, BaseGuard { // If the value was present, remove() returns true. address ownerAfter = ownersAfter[i]; if (ownersBefore.remove(ownerAfter) == false) { - // This address was not already an owner, add it to the lastSigned mapping + // This address was not already an owner, add it to the lastLive mapping lastLive[ownerAfter] = block.timestamp; } } // Now iterate over the remaining ownersBefore entries. Any remaining addresses are no longer an owner, so we - // delete them from the lastSigned mapping. + // delete them from the lastLive mapping. for (uint256 j = 0; j < ownersBefore.length(); j++) { address ownerBefore = ownersBefore.at(j); delete lastLive[ownerBefore]; From 2c7ddd0eb7329beccfa7338d99eba39be9c1b94e Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 11:48:11 -0400 Subject: [PATCH 153/374] refactor(ctb): Make immutables screaming snake in Liveness code --- .../src/Safe/LivenessGuard.sol | 20 +++-- .../src/Safe/LivenessModule.sol | 74 +++++++++++++------ .../test/LivenessGuard.t.sol | 7 ++ .../test/LivenessModule.t.sol | 14 +++- 4 files changed, 85 insertions(+), 30 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index edfdf13b34d0..011884b3ad68 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -27,7 +27,7 @@ contract LivenessGuard is ISemver, BaseGuard { string public constant version = "1.0.0"; /// @notice The safe account for which this contract will be the guard. - Safe public immutable safe; + Safe internal immutable SAFE; /// @notice A mapping of the timestamp at which an owner last participated in signing a /// an executed transaction, or called showLiveness. @@ -41,7 +41,7 @@ contract LivenessGuard is ISemver, BaseGuard { /// @notice Constructor. /// @param _safe The safe account for which this contract will be the guard. constructor(Safe _safe) { - safe = _safe; + SAFE = _safe; } /// @notice We use this post execution hook to compare the set of owners before and after. @@ -50,7 +50,7 @@ contract LivenessGuard is ISemver, BaseGuard { /// 2. Delete removed owners from the lastLive mapping function checkAfterExecution(bytes32, bool) external { // Get the current set of owners - address[] memory ownersAfter = safe.getOwners(); + address[] memory ownersAfter = SAFE.getOwners(); // Iterate over the current owners, and remove one at a time from the ownersBefore set. uint256 ownersAfterLength = ownersAfter.length; @@ -88,11 +88,11 @@ contract LivenessGuard is ISemver, BaseGuard { ) external { - require(msg.sender == address(safe), "LivenessGuard: only Safe can call this function"); + require(msg.sender == address(SAFE), "LivenessGuard: only Safe can call this function"); // Cache the set of owners prior to execution. // This will be used in the checkAfterExecution method. - address[] memory owners = safe.getOwners(); + address[] memory owners = SAFE.getOwners(); for (uint256 i = 0; i < owners.length; i++) { ownersBefore.add(owners[i]); } @@ -112,7 +112,7 @@ contract LivenessGuard is ISemver, BaseGuard { _nonce: Safe(payable(msg.sender)).nonce() - 1 }); - uint256 threshold = safe.getThreshold(); + uint256 threshold = SAFE.getThreshold(); address[] memory signers = SafeSigners.getNSigners({ dataHash: txHash, signatures: signatures, requiredSignatures: threshold }); @@ -125,11 +125,17 @@ contract LivenessGuard is ISemver, BaseGuard { /// @notice Enables an owner to demonstrate liveness by calling this method directly. /// This is useful for owners who have not recently signed a transaction via the Safe. function showLiveness() external { - require(safe.isOwner(msg.sender), "LivenessGuard: only Safe owners may demontstrate liveness"); + require(SAFE.isOwner(msg.sender), "LivenessGuard: only Safe owners may demontstrate liveness"); lastLive[msg.sender] = block.timestamp; address[] memory signers = new address[](1); signers[0] = msg.sender; emit SignersRecorded(0x0, signers); } + + /// @notice Getter function for the Safe contract instance + /// @return safe_ The Safe contract instance + function safe() public view returns (Safe safe_) { + safe_ = SAFE; + } } diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 214212485349..c11f70c6dac4 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -18,23 +18,23 @@ import { console2 as console } from "forge-std/console2.sol"; /// safe will be transferred to the fallback owner. contract LivenessModule is ISemver { /// @notice The Safe contract instance - Safe public immutable safe; + Safe internal immutable SAFE; /// @notice The LivenessGuard contract instance /// This can be updated by replacing with a new module and switching out the guard. - LivenessGuard public immutable livenessGuard; + LivenessGuard internal immutable LIVENESS_GUARD; /// @notice The interval, in seconds, during which an owner must have demonstrated liveness /// This can be updated by replacing with a new module. - uint256 public immutable livenessInterval; + uint256 internal immutable LIVENESS_INTERVAL; /// @notice The minimum number of owners before ownership of the safe is transferred to the fallback owner. /// This can be updated by replacing with a new module. - uint256 public immutable minOwners; + uint256 internal immutable MIN_OWNERS; /// @notice The fallback owner of the Safe /// This can be updated by replacing with a new module. - address public immutable fallbackOwner; + address internal immutable FALLBACK_OWNER; /// @notice The storage slot used in the safe to store the guard address /// keccak256("guard_manager.guard.address") @@ -55,11 +55,11 @@ contract LivenessModule is ISemver { uint256 _minOwners, address _fallbackOwner ) { - safe = _safe; - livenessGuard = _livenessGuard; - livenessInterval = _livenessInterval; - minOwners = _minOwners; - fallbackOwner = _fallbackOwner; + SAFE = _safe; + LIVENESS_GUARD = _livenessGuard; + LIVENESS_INTERVAL = _livenessInterval; + MIN_OWNERS = _minOwners; + FALLBACK_OWNER = _fallbackOwner; } /// @notice This function can be called by anyone to remove an owner that has not signed a transaction @@ -71,12 +71,12 @@ contract LivenessModule is ISemver { // Check that the owner to remove has not signed a transaction in the last 30 days require( - livenessGuard.lastLive(owner) < block.timestamp - livenessInterval, + LIVENESS_GUARD.lastLive(owner) < block.timestamp - LIVENESS_INTERVAL, "LivenessModule: owner has signed recently" ); // Calculate the new threshold - address[] memory owners = safe.getOwners(); + address[] memory owners = SAFE.getOwners(); uint256 numOwners = owners.length - 1; uint256 thresholdAfter; if (_isAboveMinOwners(numOwners)) { @@ -109,11 +109,11 @@ contract LivenessModule is ISemver { /// @notice Sets the fallback owner as the sole owner of the Safe with a threshold of 1 function _giveToFallbackOwner() internal { - safe.execTransactionFromModule({ - to: address(safe), + SAFE.execTransactionFromModule({ + to: address(SAFE), value: 0, operation: Enum.Operation.Call, - data: abi.encodeCall(OwnerManager.addOwnerWithThreshold, (fallbackOwner, 1)) + data: abi.encodeCall(OwnerManager.addOwnerWithThreshold, (FALLBACK_OWNER, 1)) }); } @@ -122,8 +122,8 @@ contract LivenessModule is ISemver { /// @param _owner Owner address to be removed. /// @param _threshold New threshold. function _removeOwner(address _prevOwner, address _owner, uint256 _threshold) internal { - safe.execTransactionFromModule({ - to: address(safe), + SAFE.execTransactionFromModule({ + to: address(SAFE), value: 0, operation: Enum.Operation.Call, data: abi.encodeCall(OwnerManager.removeOwner, (_prevOwner, _owner, _threshold)) @@ -132,16 +132,16 @@ contract LivenessModule is ISemver { /// @notice A FREI-PI invariant check enforcing requirements on number of owners and threshold. function _verifyFinalState() internal view { - address[] memory owners = safe.getOwners(); + address[] memory owners = SAFE.getOwners(); uint256 numOwners = owners.length; require( - _isAboveMinOwners(numOwners) || (numOwners == 1 && owners[0] == fallbackOwner), + _isAboveMinOwners(numOwners) || (numOwners == 1 && owners[0] == FALLBACK_OWNER), "LivenessModule: Safe must have the minimum number of owners or be owned solely by the fallback owner" ); // Check that the threshold is correct. This check is also correct when there is a single // owner, because get75PercentThreshold(1) returns 1. - uint256 threshold = safe.getThreshold(); + uint256 threshold = SAFE.getThreshold(); require( threshold == get75PercentThreshold(numOwners), "LivenessModule: threshold must be 75% of the number of owners" @@ -154,7 +154,7 @@ contract LivenessModule is ISemver { /// @notice Reverts if the guard address does not match the expected value. function _verifyGuard() internal view { require( - address(livenessGuard) == address(uint160(uint256(bytes32(safe.getStorageAt(GUARD_STORAGE_SLOT, 1))))), + address(LIVENESS_GUARD) == address(uint160(uint256(bytes32(SAFE.getStorageAt(GUARD_STORAGE_SLOT, 1))))), "LivenessModule: guard has been changed" ); } @@ -181,6 +181,36 @@ contract LivenessModule is ISemver { /// @param numOwners The number of owners. /// @return A boolean indicating if the number of owners is greater than or equal to the minimum number of owners. function _isAboveMinOwners(uint256 numOwners) internal view returns (bool) { - return numOwners >= minOwners; + return numOwners >= MIN_OWNERS; + } + + /// @notice Getter function for the Safe contract instance + /// @return safe_ The Safe contract instance + function safe() public view returns (Safe safe_) { + safe_ = SAFE; + } + + /// @notice Getter function for the LivenessGuard contract instance + /// @return livenessGuard_ The LivenessGuard contract instance + function livenessGuard() public view returns (LivenessGuard livenessGuard_) { + livenessGuard_ = LIVENESS_GUARD; + } + + /// @notice Getter function for the liveness interval + /// @return livenessInterval_ The liveness interval, in seconds + function livenessInterval() public view returns (uint256 livenessInterval_) { + livenessInterval_ = LIVENESS_INTERVAL; + } + + /// @notice Getter function for the minimum number of owners + /// @return minOwners_ The minimum number of owners + function minOwners() public view returns (uint256 minOwners_) { + minOwners_ = MIN_OWNERS; + } + + /// @notice Getter function for the fallback owner + /// @return fallbackOwner_ The fallback owner of the Safe + function fallbackOwner() public view returns (address fallbackOwner_) { + fallbackOwner_ = FALLBACK_OWNER; } } diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 8046fb01b0ad..132a36fa5c11 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -33,6 +33,13 @@ contract LivnessGuard_TestInit is Test, SafeTestTools { } } +contract LivenessGuard_Getters_Test is LivnessGuard_TestInit { + function test_getters_works() external { + assertEq(address(livenessGuard.safe()), address(safeInstance.safe)); + assertEq(livenessGuard.lastLive(address(0)), 0); + } +} + contract LivnessGuard_CheckTx_Test is LivnessGuard_TestInit { using SafeTestLib for SafeInstance; diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 0e7a262af036..39a51f6370c8 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -19,24 +19,36 @@ contract LivnessModule_TestInit is Test, SafeTestTools { LivenessModule livenessModule; LivenessGuard livenessGuard; SafeInstance safeInstance; + address fallbackOwner; function setUp() public { // Create a Safe with 10 owners (, uint256[] memory keys) = makeAddrsAndKeys(10); safeInstance = _setupSafe(keys, 8); livenessGuard = new LivenessGuard(safeInstance.safe); + fallbackOwner = makeAddr("fallbackOwner"); livenessModule = new LivenessModule({ _safe: safeInstance.safe, _livenessGuard: livenessGuard, _livenessInterval: 30 days, _minOwners: 6, - _fallbackOwner: makeAddr("fallbackOwner") + _fallbackOwner: fallbackOwner }); safeInstance.enableModule(address(livenessModule)); safeInstance.setGuard(address(livenessGuard)); } } +contract LivenessModule_Getters_Test is LivnessModule_TestInit { + function test_getters_works() external { + assertEq(address(livenessModule.safe()), address(safeInstance.safe)); + assertEq(address(livenessModule.livenessGuard()), address(livenessGuard)); + assertEq(livenessModule.livenessInterval(), 30 days); + assertEq(livenessModule.minOwners(), 6); + assertEq(livenessModule.fallbackOwner(), fallbackOwner); + } +} + contract LivenessModule_Get75PercentThreshold_Test is LivnessModule_TestInit { /// @dev check the return values of the get75PercentThreshold function against manually /// calculated values. From 26c1ac545abe97f6618f10473333c3e046a91d0d Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 12:56:10 -0400 Subject: [PATCH 154/374] feat(ctb): Document requirements for non-reverting in the Guard Also reorders the functions in the order they are called. --- .../src/Safe/LivenessGuard.sol | 61 ++++++++++--------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 011884b3ad68..f5d8d71adfa3 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -15,6 +15,9 @@ import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableS /// If an owner does not participate in a transaction for a certain period of time, they are considered inactive. /// This Guard is intended to be used in conjunction with the LivenessModule contract, but does /// not depend on it. +/// Note: Both `checkTransaction` and `checkAfterExecution` are called once each by the Safe contract +/// before and after the execution of a transaction. It is critical that neither function revert, +/// otherwise the Safe contract will be unable to execute a transaction. contract LivenessGuard is ISemver, BaseGuard { using EnumerableSet for EnumerableSet.AddressSet; @@ -44,35 +47,8 @@ contract LivenessGuard is ISemver, BaseGuard { SAFE = _safe; } - /// @notice We use this post execution hook to compare the set of owners before and after. - /// If the set of owners has changed then we: - /// 1. Add new owners to the lastLive mapping - /// 2. Delete removed owners from the lastLive mapping - function checkAfterExecution(bytes32, bool) external { - // Get the current set of owners - address[] memory ownersAfter = SAFE.getOwners(); - - // Iterate over the current owners, and remove one at a time from the ownersBefore set. - uint256 ownersAfterLength = ownersAfter.length; - for (uint256 i = 0; i < ownersAfterLength; i++) { - // If the value was present, remove() returns true. - address ownerAfter = ownersAfter[i]; - if (ownersBefore.remove(ownerAfter) == false) { - // This address was not already an owner, add it to the lastLive mapping - lastLive[ownerAfter] = block.timestamp; - } - } - // Now iterate over the remaining ownersBefore entries. Any remaining addresses are no longer an owner, so we - // delete them from the lastLive mapping. - for (uint256 j = 0; j < ownersBefore.length(); j++) { - address ownerBefore = ownersBefore.at(j); - delete lastLive[ownerBefore]; - } - } - /// @notice Records the most recent time which any owner has signed a transaction. - /// @dev This method is called by the Safe contract, it is critical that it does not revert, otherwise - /// the Safe contract will be unable to execute transactions. + /// @dev Called by the Safe contract before execution of a transaction. function checkTransaction( address to, uint256 value, @@ -122,6 +98,35 @@ contract LivenessGuard is ISemver, BaseGuard { emit SignersRecorded(txHash, signers); } + /// @notice Update the lastLive mapping according to the set of owners before and after execution. + /// @dev Called by the Safe contract after the execution of a transaction. + /// We use this post execution hook to compare the set of owners before and after. + /// If the set of owners has changed then we: + /// 1. Add new owners to the lastLive mapping + /// 2. Delete removed owners from the lastLive mapping + function checkAfterExecution(bytes32, bool) external { + + // Get the current set of owners + address[] memory ownersAfter = SAFE.getOwners(); + + // Iterate over the current owners, and remove one at a time from the ownersBefore set. + uint256 ownersAfterLength = ownersAfter.length; + for (uint256 i = 0; i < ownersAfterLength; i++) { + // If the value was present, remove() returns true. + address ownerAfter = ownersAfter[i]; + if (ownersBefore.remove(ownerAfter) == false) { + // This address was not already an owner, add it to the lastLive mapping + lastLive[ownerAfter] = block.timestamp; + } + } + // Now iterate over the remaining ownersBefore entries. Any remaining addresses are no longer an owner, so we + // delete them from the lastLive mapping. + for (uint256 j = 0; j < ownersBefore.length(); j++) { + address ownerBefore = ownersBefore.at(j); + delete lastLive[ownerBefore]; + } + } + /// @notice Enables an owner to demonstrate liveness by calling this method directly. /// This is useful for owners who have not recently signed a transaction via the Safe. function showLiveness() external { From 8215444c6856a5d4e8aff06cd5dd7126d198a13f Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 12:56:31 -0400 Subject: [PATCH 155/374] feat(ctb): Remove redundant _verifyGuard call --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index c11f70c6dac4..f97a846104a5 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -66,9 +66,6 @@ contract LivenessModule is ISemver { /// during the liveness interval. If the number of owners drops below the minimum, then the /// ownership of the Safe is transferred to the fallback owner. function removeOwner(address owner) external { - // Check that the guard has not been changed - _verifyGuard(); - // Check that the owner to remove has not signed a transaction in the last 30 days require( LIVENESS_GUARD.lastLive(owner) < block.timestamp - LIVENESS_INTERVAL, From 410310eaffb8e3cadb4a52e9378f165783882b5e Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 14:17:07 -0400 Subject: [PATCH 156/374] fix(ctb): Add auth to guard checkAfterExecution Also added regression tests. --- .../src/Safe/LivenessGuard.sol | 4 ++- .../test/LivenessGuard.t.sol | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index f5d8d71adfa3..1e2ffe761ca6 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -60,10 +60,11 @@ contract LivenessGuard is ISemver, BaseGuard { address gasToken, address payable refundReceiver, bytes memory signatures, - address + address msgSender ) external { + msgSender; // silence unused variable warning require(msg.sender == address(SAFE), "LivenessGuard: only Safe can call this function"); // Cache the set of owners prior to execution. @@ -105,6 +106,7 @@ contract LivenessGuard is ISemver, BaseGuard { /// 1. Add new owners to the lastLive mapping /// 2. Delete removed owners from the lastLive mapping function checkAfterExecution(bytes32, bool) external { + require(msg.sender == address(SAFE), "LivenessGuard: only Safe can call this function"); // Get the current set of owners address[] memory ownersAfter = SAFE.getOwners(); diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 132a36fa5c11..77ed8d58148a 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -40,6 +40,25 @@ contract LivenessGuard_Getters_Test is LivnessGuard_TestInit { } } +contract LivnessGuard_CheckTx_TestFails is LivnessGuard_TestInit { + function test_checkTransaction_callerIsNotSafe_revert() external { + vm.expectRevert("LivenessGuard: only Safe can call this function"); + livenessGuard.checkTransaction({ + to: address(0), + value: 0, + data: hex"00", + operation: Enum.Operation.Call, + safeTxGas: 0, + baseGas: 0, + gasPrice: 0, + gasToken: address(0), + refundReceiver: payable(address(0)), + signatures: hex"00", + msgSender: address(0) + }); + } +} + contract LivnessGuard_CheckTx_Test is LivnessGuard_TestInit { using SafeTestLib for SafeInstance; @@ -63,6 +82,15 @@ contract LivnessGuard_CheckTx_Test is LivnessGuard_TestInit { } } +contract LivnessGuard_CheckAfterExecution_TestFails is LivnessGuard_TestInit { + function test_checkAfterExecution_callerIsNotSafe_revert() external { + vm.expectRevert("LivenessGuard: only Safe can call this function"); + livenessGuard.checkAfterExecution(bytes32(0), false); + } +} + +contract LivnessGuard_CheckAfterExecution_Test is LivnessGuard_TestInit { } + contract LivenessGuard_ShowLiveness_Test is LivnessGuard_TestInit { function test_showLiveness_succeeds() external { // Cache the caller From 2d7e3ba8e4f8e00b8a5288ece940fefd03307c6a Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 14:18:28 -0400 Subject: [PATCH 157/374] feat(ctb): Fix typo Livness in test files --- .../contracts-bedrock/test/LivenessGuard.t.sol | 14 +++++++------- .../contracts-bedrock/test/LivenessModule.t.sol | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 77ed8d58148a..35fb2c1e0d68 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -18,7 +18,7 @@ import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; // - Signers may call directly to prove liveness (must be an owner). // - Unexpected length of signature data -contract LivnessGuard_TestInit is Test, SafeTestTools { +contract LivenessGuard_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; event SignersRecorded(bytes32 indexed txHash, address[] signers); @@ -33,14 +33,14 @@ contract LivnessGuard_TestInit is Test, SafeTestTools { } } -contract LivenessGuard_Getters_Test is LivnessGuard_TestInit { +contract LivenessGuard_Getters_Test is LivenessGuard_TestInit { function test_getters_works() external { assertEq(address(livenessGuard.safe()), address(safeInstance.safe)); assertEq(livenessGuard.lastLive(address(0)), 0); } } -contract LivnessGuard_CheckTx_TestFails is LivnessGuard_TestInit { +contract LivenessGuard_CheckTx_TestFails is LivenessGuard_TestInit { function test_checkTransaction_callerIsNotSafe_revert() external { vm.expectRevert("LivenessGuard: only Safe can call this function"); livenessGuard.checkTransaction({ @@ -59,7 +59,7 @@ contract LivnessGuard_CheckTx_TestFails is LivnessGuard_TestInit { } } -contract LivnessGuard_CheckTx_Test is LivnessGuard_TestInit { +contract LivenessGuard_CheckTx_Test is LivenessGuard_TestInit { using SafeTestLib for SafeInstance; function test_checkTransaction_succeeds() external { @@ -82,16 +82,16 @@ contract LivnessGuard_CheckTx_Test is LivnessGuard_TestInit { } } -contract LivnessGuard_CheckAfterExecution_TestFails is LivnessGuard_TestInit { +contract LivenessGuard_CheckAfterExecution_TestFails is LivenessGuard_TestInit { function test_checkAfterExecution_callerIsNotSafe_revert() external { vm.expectRevert("LivenessGuard: only Safe can call this function"); livenessGuard.checkAfterExecution(bytes32(0), false); } } -contract LivnessGuard_CheckAfterExecution_Test is LivnessGuard_TestInit { } +contract LivenessGuard_CheckAfterExecution_Test is LivenessGuard_TestInit { } -contract LivenessGuard_ShowLiveness_Test is LivnessGuard_TestInit { +contract LivenessGuard_ShowLiveness_Test is LivenessGuard_TestInit { function test_showLiveness_succeeds() external { // Cache the caller address caller = safeInstance.owners[0]; diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 39a51f6370c8..04f69980980a 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -11,7 +11,7 @@ import "test/safe-tools/SafeTestTools.sol"; import { LivenessModule } from "src/Safe/LivenessModule.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; -contract LivnessModule_TestInit is Test, SafeTestTools { +contract LivenessModule_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; event SignersRecorded(bytes32 indexed txHash, address[] signers); @@ -39,7 +39,7 @@ contract LivnessModule_TestInit is Test, SafeTestTools { } } -contract LivenessModule_Getters_Test is LivnessModule_TestInit { +contract LivenessModule_Getters_Test is LivenessModule_TestInit { function test_getters_works() external { assertEq(address(livenessModule.safe()), address(safeInstance.safe)); assertEq(address(livenessModule.livenessGuard()), address(livenessGuard)); @@ -49,7 +49,7 @@ contract LivenessModule_Getters_Test is LivnessModule_TestInit { } } -contract LivenessModule_Get75PercentThreshold_Test is LivnessModule_TestInit { +contract LivenessModule_Get75PercentThreshold_Test is LivenessModule_TestInit { /// @dev check the return values of the get75PercentThreshold function against manually /// calculated values. function test_get75PercentThreshold_Works() external { @@ -76,7 +76,7 @@ contract LivenessModule_Get75PercentThreshold_Test is LivnessModule_TestInit { } } -contract LivenessModule_RemoveOwner_Test is LivnessModule_TestInit { +contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { function test_removeOwner_oneOwner_succeeds() external { uint256 ownersBefore = safeInstance.owners.length; vm.warp(block.timestamp + 30 days); From a5a723d382e7fbc488c89c75d2308e89cba7b0d8 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 14:42:17 -0400 Subject: [PATCH 158/374] feat(ctb): numOwnersAfter is a better var name --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index f97a846104a5..d82dc8b52133 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -74,11 +74,11 @@ contract LivenessModule is ISemver { // Calculate the new threshold address[] memory owners = SAFE.getOwners(); - uint256 numOwners = owners.length - 1; + uint256 numOwnersAfter = owners.length - 1; uint256 thresholdAfter; - if (_isAboveMinOwners(numOwners)) { + if (_isAboveMinOwners(numOwnersAfter)) { // Call the Safe to remove the owner and update the threshold - thresholdAfter = get75PercentThreshold(numOwners); + thresholdAfter = get75PercentThreshold(numOwnersAfter); address prevOwner = _getPrevOwner(owner, owners); _removeOwner({ _prevOwner: prevOwner, _owner: owner, _threshold: thresholdAfter }); } else { From 927bcaaa1e04e4e05bbe30b85c3f001eb716a1d1 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 14:50:26 -0400 Subject: [PATCH 159/374] fix(ctb): Fix off-by-one in removeOwner There was a bug in the remove all owners flow that would leave two owners on the safe. Fixing that bug required using `swapOwners` in order to remove and replace the last signer, since you cannot remove the only owner and then add a new one (even when calling from a module). --- .../src/Safe/LivenessModule.sol | 31 +++++++++++-------- .../test/LivenessModule.t.sol | 16 +++++++--- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index d82dc8b52133..134c80190bc6 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -88,29 +88,32 @@ contract LivenessModule is ISemver { // Remove owners one at a time starting from the last owner. // Since we're removing them in order from last to first, the ordering will remain constant, // and we shouldn't need to query the list of owners again. - for (uint256 i = owners.length - 1; i >= 0; i--) { + address prevOwner; + for (uint256 i = owners.length - 1; i > 0; i--) { address currentOwner = owners[i]; - address prevOwner = _getPrevOwner(currentOwner, owners); - if (currentOwner != address(this)) { - // Call the Safe to remove the owner - _removeOwner({ _prevOwner: prevOwner, _owner: currentOwner, _threshold: 1 }); - } + prevOwner = _getPrevOwner(currentOwner, owners); + + // Call the Safe to remove the owner + _removeOwner({ _prevOwner: prevOwner, _owner: currentOwner, _threshold: 1 }); } + prevOwner = _getPrevOwner(owners[0], owners); // Add the fallback owner as the sole owner of the Safe - _giveToFallbackOwner(); + _swapToFallbackOwner({ _prevOwner: prevOwner, _oldOwner: owners[0] }); } _verifyFinalState(); } /// @notice Sets the fallback owner as the sole owner of the Safe with a threshold of 1 - function _giveToFallbackOwner() internal { + /// @param _prevOwner Owner that pointed to the owner to be replaced in the linked list + /// @param _oldOwner Owner address to be replaced. + function _swapToFallbackOwner(address _prevOwner, address _oldOwner) internal { SAFE.execTransactionFromModule({ to: address(SAFE), value: 0, operation: Enum.Operation.Call, - data: abi.encodeCall(OwnerManager.addOwnerWithThreshold, (FALLBACK_OWNER, 1)) + data: abi.encodeCall(OwnerManager.swapOwner, (_prevOwner, _oldOwner, FALLBACK_OWNER)) }); } @@ -157,14 +160,16 @@ contract LivenessModule is ISemver { } /// @notice Get the previous owner in the linked list of owners - function _getPrevOwner(address owner, address[] memory owners) internal pure returns (address prevOwner_) { - for (uint256 i = 0; i < owners.length; i++) { - if (owners[i] != owner) continue; + /// @param _owner The owner whose previous owner we want to find + /// @param _owners The list of owners + function _getPrevOwner(address _owner, address[] memory _owners) internal pure returns (address prevOwner_) { + for (uint256 i = 0; i < _owners.length; i++) { + if (_owners[i] != _owner) continue; if (i == 0) { prevOwner_ = SENTINEL_OWNERS; break; } - prevOwner_ = owners[i - 1]; + prevOwner_ = _owners[i - 1]; } } diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 04f69980980a..6b669442e810 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -86,9 +86,17 @@ contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { function test_removeOwner_allOwners_succeeds() external { vm.warp(block.timestamp + 30 days); - // The safe is initialized with 10 owners, so we need to remove 3 to get below the minOwners threshold - livenessModule.removeOwner(safeInstance.owners[0]); - livenessModule.removeOwner(safeInstance.owners[1]); - livenessModule.removeOwner(safeInstance.owners[2]); + uint256 numOwners = safeInstance.owners.length; + uint256 minOwners = livenessModule.minOwners(); + + // Remove enough owners to trigger the transfer to the fallbackOwner + uint256 numToRemove = numOwners - minOwners + 1; + + for (uint256 i = 0; i < numToRemove; i++) { + livenessModule.removeOwner(safeInstance.owners[i]); + } + assertEq(safeInstance.safe.getOwners().length, 1); + assertEq(safeInstance.safe.getOwners()[0], fallbackOwner); + assertEq(safeInstance.safe.getThreshold(), 1); } } From 7ce3e4dcea9f36d952fbdb8b07ea85a3751c2ac1 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 15:23:38 -0400 Subject: [PATCH 160/374] refactor(ctb): Only emit a single address from SignerRecorded --- .../contracts-bedrock/src/Safe/LivenessGuard.sol | 12 +++++------- .../contracts-bedrock/test/LivenessGuard.t.sol | 15 +++++++-------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 1e2ffe761ca6..62b492732246 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -21,9 +21,9 @@ import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableS contract LivenessGuard is ISemver, BaseGuard { using EnumerableSet for EnumerableSet.AddressSet; - /// @notice Emitted when a new set of signers is recorded. - /// @param signers An arrary of signer addresses. - event SignersRecorded(bytes32 indexed txHash, address[] signers); + /// @notice Emitted when a signer is recorded. + /// @param signer The signer's address. + event SignerRecorded(bytes32 indexed txHash, address signer); /// @notice Semantic version. /// @custom:semver 1.0.0 @@ -95,8 +95,8 @@ contract LivenessGuard is ISemver, BaseGuard { for (uint256 i = 0; i < signers.length; i++) { lastLive[signers[i]] = block.timestamp; + emit SignerRecorded(txHash, signers[i]); } - emit SignersRecorded(txHash, signers); } /// @notice Update the lastLive mapping according to the set of owners before and after execution. @@ -134,10 +134,8 @@ contract LivenessGuard is ISemver, BaseGuard { function showLiveness() external { require(SAFE.isOwner(msg.sender), "LivenessGuard: only Safe owners may demontstrate liveness"); lastLive[msg.sender] = block.timestamp; - address[] memory signers = new address[](1); - signers[0] = msg.sender; - emit SignersRecorded(0x0, signers); + emit SignerRecorded(0x0, msg.sender); } /// @notice Getter function for the Safe contract instance diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 35fb2c1e0d68..c93872be3a8b 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -21,7 +21,7 @@ import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; contract LivenessGuard_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; - event SignersRecorded(bytes32 indexed txHash, address[] signers); + event SignerRecorded(bytes32 indexed txHash, address signer); LivenessGuard livenessGuard; SafeInstance safeInstance; @@ -69,9 +69,11 @@ contract LivenessGuard_CheckTx_Test is LivenessGuard_TestInit { signers[0] = safeInstance.owners[0]; signers[1] = safeInstance.owners[1]; - // Don't check topic1 so that we can avoid the ugly txHash calculation. - vm.expectEmit(false, true, true, true, address(livenessGuard)); - emit SignersRecorded(0x0, signers); + for (uint256 i; i < signers.length; i++) { + // Don't check topic1 so that we can avoid the ugly txHash calculation. + vm.expectEmit(false, true, true, true, address(livenessGuard)); + emit SignerRecorded(0x0, signers[i]); + } vm.expectCall(address(safeInstance.safe), abi.encodeWithSignature("nonce()")); vm.expectCall(address(safeInstance.safe), abi.encodeCall(OwnerManager.getThreshold, ())); safeInstance.execTransaction({ to: address(1111), value: 0, data: hex"abba" }); @@ -96,11 +98,8 @@ contract LivenessGuard_ShowLiveness_Test is LivenessGuard_TestInit { // Cache the caller address caller = safeInstance.owners[0]; - // Construct a signers array with just the caller to identify the expected event. - address[] memory signers = new address[](1); - signers[0] = caller; vm.expectEmit(address(livenessGuard)); - emit SignersRecorded(0x0, signers); + emit SignerRecorded(0x0, caller); vm.prank(caller); livenessGuard.showLiveness(); From fbc6adede9c133eaec4fe0d7af24c31ef768ad10 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 15:47:28 -0400 Subject: [PATCH 161/374] docs(ctb): Some commenting fixes --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 3 +-- packages/contracts-bedrock/src/Safe/SafeSigners.sol | 8 ++++---- .../safe-tools/CompatibilityFallbackHandler_1_3_0.sol | 3 ++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 134c80190bc6..a631232b080b 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -75,10 +75,9 @@ contract LivenessModule is ISemver { // Calculate the new threshold address[] memory owners = SAFE.getOwners(); uint256 numOwnersAfter = owners.length - 1; - uint256 thresholdAfter; if (_isAboveMinOwners(numOwnersAfter)) { // Call the Safe to remove the owner and update the threshold - thresholdAfter = get75PercentThreshold(numOwnersAfter); + uint256 thresholdAfter = get75PercentThreshold(numOwnersAfter); address prevOwner = _getPrevOwner(owner, owners); _removeOwner({ _prevOwner: prevOwner, _owner: owner, _threshold: thresholdAfter }); } else { diff --git a/packages/contracts-bedrock/src/Safe/SafeSigners.sol b/packages/contracts-bedrock/src/Safe/SafeSigners.sol index 20033b26c644..f0ad74fc67ed 100644 --- a/packages/contracts-bedrock/src/Safe/SafeSigners.sol +++ b/packages/contracts-bedrock/src/Safe/SafeSigners.sol @@ -53,10 +53,10 @@ library SafeSigners { { _owners = new address[](requiredSignatures); - /// The following code is extracted from the Safe.checkNSignatures() method. It removes the signature - /// validation code, and keeps only the parsing code necessary to extract the owner addresses from the - /// signatures. We do not double check if the owner derived from a signature is valid. As this is handled - /// in the final require statement of Safe.checkNSignatures(). + // The following code is extracted from the Safe.checkNSignatures() method. It removes the signature + // validation code, and keeps only the parsing code necessary to extract the owner addresses from the + // signatures. We do not double check if the owner derived from a signature is valid. As this is handled + // in the final require statement of Safe.checkNSignatures(). address currentOwner; uint8 v; bytes32 r; diff --git a/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol b/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol index 046a0eda43f0..30c002f119f1 100644 --- a/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol +++ b/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol @@ -8,7 +8,8 @@ import "safe-contracts/interfaces/IERC165.sol"; import "safe-contracts/interfaces/ISignatureValidator.sol"; import { Safe as GnosisSafe } from "safe-contracts/Safe.sol"; -/// @dev NOTE: removed VERSION and NAME due to inheritance conflicts +/// @author: Colin Nielsen +/// https://github.com/colinnielsen/safe-tools/blob/ce6c654a76d91b619ab7778c77d1a76b3ced6666/src/CompatibilityFallbackHandler_1_3_0.sol contract DefaultCallbackHandler is ERC1155TokenReceiver, ERC777TokensRecipient, ERC721TokenReceiver, IERC165 { function onERC1155Received( address, From 7d974663143e150e7c54ccf0f46664f414e21226 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 16:13:26 -0400 Subject: [PATCH 162/374] feat(ctb): Naming improvements Standardizing on the term owner rather than signer except in and around calls to _getNSigners. --- packages/contracts-bedrock/src/Safe/LivenessGuard.sol | 10 +++++----- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 4 ++-- packages/contracts-bedrock/test/LivenessGuard.t.sol | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 62b492732246..2e257697b55c 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -21,9 +21,9 @@ import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableS contract LivenessGuard is ISemver, BaseGuard { using EnumerableSet for EnumerableSet.AddressSet; - /// @notice Emitted when a signer is recorded. - /// @param signer The signer's address. - event SignerRecorded(bytes32 indexed txHash, address signer); + /// @notice Emitted when an owner is recorded. + /// @param owner The owner's address. + event OwnerRecorded(bytes32 indexed txHash, address owner); /// @notice Semantic version. /// @custom:semver 1.0.0 @@ -95,7 +95,7 @@ contract LivenessGuard is ISemver, BaseGuard { for (uint256 i = 0; i < signers.length; i++) { lastLive[signers[i]] = block.timestamp; - emit SignerRecorded(txHash, signers[i]); + emit OwnerRecorded(txHash, signers[i]); } } @@ -135,7 +135,7 @@ contract LivenessGuard is ISemver, BaseGuard { require(SAFE.isOwner(msg.sender), "LivenessGuard: only Safe owners may demontstrate liveness"); lastLive[msg.sender] = block.timestamp; - emit SignerRecorded(0x0, msg.sender); + emit OwnerRecorded(0x0, msg.sender); } /// @notice Getter function for the Safe contract instance diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index a631232b080b..2a492add9749 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -147,11 +147,11 @@ contract LivenessModule is ISemver { ); // Check that the guard has not been changed. - _verifyGuard(); + _requireCorrectGuard(); } /// @notice Reverts if the guard address does not match the expected value. - function _verifyGuard() internal view { + function _requireCorrectGuard() internal view { require( address(LIVENESS_GUARD) == address(uint160(uint256(bytes32(SAFE.getStorageAt(GUARD_STORAGE_SLOT, 1))))), "LivenessModule: guard has been changed" diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index c93872be3a8b..206f27df8e5d 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -21,7 +21,7 @@ import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; contract LivenessGuard_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; - event SignerRecorded(bytes32 indexed txHash, address signer); + event OwnerRecorded(bytes32 indexed txHash, address signer); LivenessGuard livenessGuard; SafeInstance safeInstance; @@ -72,7 +72,7 @@ contract LivenessGuard_CheckTx_Test is LivenessGuard_TestInit { for (uint256 i; i < signers.length; i++) { // Don't check topic1 so that we can avoid the ugly txHash calculation. vm.expectEmit(false, true, true, true, address(livenessGuard)); - emit SignerRecorded(0x0, signers[i]); + emit OwnerRecorded(0x0, signers[i]); } vm.expectCall(address(safeInstance.safe), abi.encodeWithSignature("nonce()")); vm.expectCall(address(safeInstance.safe), abi.encodeCall(OwnerManager.getThreshold, ())); @@ -99,7 +99,7 @@ contract LivenessGuard_ShowLiveness_Test is LivenessGuard_TestInit { address caller = safeInstance.owners[0]; vm.expectEmit(address(livenessGuard)); - emit SignerRecorded(0x0, caller); + emit OwnerRecorded(0x0, caller); vm.prank(caller); livenessGuard.showLiveness(); From 7efcfc3c06f75c3db89182dab8fb4d80ae0136b7 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 13:22:11 -0400 Subject: [PATCH 163/374] specs: Apply code review suggestions Co-authored-by: Matt Solomon --- specs/safe-liveness-checking.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md index 1a71cfee83fa..5dfb66a701af 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/safe-liveness-checking.md @@ -34,7 +34,7 @@ For implementing liveness checks a `LivenessGuard` is created which receives the each executed transaction, and tracks the latest time at which a transaction was signed by each signer. This time is made publicly available by calling a `lastLive(address)(Timestamp)` method. -Signers may also call the contract directly in order to prove liveness. +Signers may also call the contract's `showLiveness()()` method directly in order to prove liveness. ### The Liveness Module @@ -47,7 +47,7 @@ A `LivenessModule` is also created which does the following: 1. If so, it will call the Safe's `removeSigner()` to remove the non-live signer, and if necessary reduce the threshold. 1. When a member is removed, the signing parameters are modified such that `M/N` is the lowest ratio - which remains above 75%. Using integer math, this can be expressed as `M = (N * 75 + 99) / 100`. + which remains greater than or equal to 75%. Using integer math, this can be expressed as `M = (N * 75 + 99) / 100`. ### Shutdown From ce97143813e4442a41d66ffc8fa0f53e3a8edc0b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 24 Oct 2023 15:47:28 -0400 Subject: [PATCH 164/374] docs(ctb): Some commenting fixes --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 3 --- .../test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 2a492add9749..cb90bb739a04 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -7,9 +7,6 @@ import { OwnerManager } from "safe-contracts/base/OwnerManager.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; import { ISemver } from "src/universal/ISemver.sol"; -// TODO(maurelian): remove me -import { console2 as console } from "forge-std/console2.sol"; - /// @title LivenessModule /// @notice This module is intended to be used in conjunction with the LivenessGuard. In the event /// that an owner of the safe is not recorded by the guard during the liveness interval, diff --git a/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol b/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol index 30c002f119f1..a0efa0e68b26 100644 --- a/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol +++ b/packages/contracts-bedrock/test/safe-tools/CompatibilityFallbackHandler_1_3_0.sol @@ -8,8 +8,8 @@ import "safe-contracts/interfaces/IERC165.sol"; import "safe-contracts/interfaces/ISignatureValidator.sol"; import { Safe as GnosisSafe } from "safe-contracts/Safe.sol"; -/// @author: Colin Nielsen -/// https://github.com/colinnielsen/safe-tools/blob/ce6c654a76d91b619ab7778c77d1a76b3ced6666/src/CompatibilityFallbackHandler_1_3_0.sol +/// author: Colin Nielsen +/// https://github.com/colinnielsen/safe-tools/blob/ce6c654a76d91b619ab7778c77d1a76b3ced6666/src/CompatibilityFallbackHandler_1_3_0.sol contract DefaultCallbackHandler is ERC1155TokenReceiver, ERC777TokensRecipient, ERC721TokenReceiver, IERC165 { function onERC1155Received( address, From e2eb747af969c8dbe299436cebb96cf60511f86b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 09:02:51 -0400 Subject: [PATCH 165/374] feat(ctb): Add min owners sanity check in Liveness Module constructor --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index cb90bb739a04..2bd1729a63ee 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -55,8 +55,11 @@ contract LivenessModule is ISemver { SAFE = _safe; LIVENESS_GUARD = _livenessGuard; LIVENESS_INTERVAL = _livenessInterval; - MIN_OWNERS = _minOwners; FALLBACK_OWNER = _fallbackOwner; + MIN_OWNERS = _minOwners; + require( + _minOwners < _safe.getOwners().length, "LivenessModule: minOwners must be less than the number of owners" + ); } /// @notice This function can be called by anyone to remove an owner that has not signed a transaction From 432f22c2bc35365bbb59ad79a5481f47b748e3b9 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 13:56:04 -0400 Subject: [PATCH 166/374] WIP: Add mermaid graph --- specs/safe-liveness-checking.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md index 5dfb66a701af..86cb4054a9d0 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/safe-liveness-checking.md @@ -49,6 +49,25 @@ A `LivenessModule` is also created which does the following: 1. When a member is removed, the signing parameters are modified such that `M/N` is the lowest ratio which remains greater than or equal to 75%. Using integer math, this can be expressed as `M = (N * 75 + 99) / 100`. +### Owner removal call flow + +The following diagram illustrates the flow for removing a single owner. + +```mermaid +sequenceDiagram + participant User + participant LivenessModule + participant LivenessGuard + participant Safe + User->>LivenessModule: removeOwner(owner) + LivenessModule->>LivenessGuard: lastLive(owner) + LivenessModule->>Safe: getOwners() + LivenessModule->>LivenessModule: get75PercentThreshold(numOwnersAfter) + LivenessModule->>LivenessModule: _getPrevOwner(owner, owners) + LivenessModule->>LivenessModule: _removeOwner(prevOwner, owner, thresholdAfter) + LivenessModule->>LivenessModule: _verifyFinalState() +``` + ### Shutdown In the unlikely event that the signer set (`N`) is reduced below 8, then (and only then) is a From 67a17c319db98d3469cc3e149f8e6d23913f5b84 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 15:31:59 -0400 Subject: [PATCH 167/374] refactor(ctb): Change to removeOwners This commit introduces the ability to remove multiple owners at once in the LivenessModule.sol contract. A new function removeOwners has been added, which accepts arrays of previous owners and owners to be removed. The existing removeOwner function has been updated to use a new internal function _removeOwner. The _getPrevOwner function has been removed as it is no longer needed. --- .../src/Safe/LivenessModule.sol | 101 ++++++++---------- .../test/LivenessModule.t.sol | 57 ++++++++-- 2 files changed, 93 insertions(+), 65 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 2bd1729a63ee..79e764b12449 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -37,9 +37,6 @@ contract LivenessModule is ISemver { /// keccak256("guard_manager.guard.address") uint256 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8; - /// @notice The address of the first owner in the linked list of owners - address internal constant SENTINEL_OWNERS = address(0x1); - /// @notice Semantic version. /// @custom:semver 1.0.0 string public constant version = "1.0.0"; @@ -62,71 +59,73 @@ contract LivenessModule is ISemver { ); } + function removeOwners(address[] memory _previousOwners, address[] memory _ownersToRemove) external { + require(_previousOwners.length == _ownersToRemove.length, "LivenessModule: arrays must be the same length"); + for (uint256 i = 0; i < _previousOwners.length; i++) { + _removeOwner(_previousOwners[i], _ownersToRemove[i]); + } + _verifyFinalState(); + } + /// @notice This function can be called by anyone to remove an owner that has not signed a transaction /// during the liveness interval. If the number of owners drops below the minimum, then the /// ownership of the Safe is transferred to the fallback owner. - function removeOwner(address owner) external { - // Check that the owner to remove has not signed a transaction in the last 30 days - require( - LIVENESS_GUARD.lastLive(owner) < block.timestamp - LIVENESS_INTERVAL, - "LivenessModule: owner has signed recently" - ); - + function _removeOwner(address _prevOwner, address _ownerToRemove) internal { // Calculate the new threshold address[] memory owners = SAFE.getOwners(); uint256 numOwnersAfter = owners.length - 1; if (_isAboveMinOwners(numOwnersAfter)) { + // Check that the owner to remove has not signed a transaction in the last 30 days + require( + LIVENESS_GUARD.lastLive(_ownerToRemove) < block.timestamp - LIVENESS_INTERVAL, + "LivenessModule: owner has signed recently" + ); // Call the Safe to remove the owner and update the threshold uint256 thresholdAfter = get75PercentThreshold(numOwnersAfter); - address prevOwner = _getPrevOwner(owner, owners); - _removeOwner({ _prevOwner: prevOwner, _owner: owner, _threshold: thresholdAfter }); + _removeOwnerSafeCall({ _prevOwner: _prevOwner, _owner: _ownerToRemove, _threshold: thresholdAfter }); } else { // The number of owners is dangerously low, so we wish to transfer the ownership of this Safe - // to the fallback owner. - - // Remove owners one at a time starting from the last owner. - // Since we're removing them in order from last to first, the ordering will remain constant, - // and we shouldn't need to query the list of owners again. - address prevOwner; - for (uint256 i = owners.length - 1; i > 0; i--) { - address currentOwner = owners[i]; - prevOwner = _getPrevOwner(currentOwner, owners); - - // Call the Safe to remove the owner - _removeOwner({ _prevOwner: prevOwner, _owner: currentOwner, _threshold: 1 }); + // to the fallback owner. Therefore we no longer need to validate the liveness of the owners + // before removing them. + if (numOwnersAfter == 0) { + // Add the fallback owner as the sole owner of the Safe + _swapToFallbackOwnerSafeCall({ _prevOwner: _prevOwner, _oldOwner: _ownerToRemove }); + } else { + // Remove the owner and set the threshold to 1 + _removeOwnerSafeCall({ _prevOwner: _prevOwner, _owner: _ownerToRemove, _threshold: 1 }); } - - prevOwner = _getPrevOwner(owners[0], owners); - // Add the fallback owner as the sole owner of the Safe - _swapToFallbackOwner({ _prevOwner: prevOwner, _oldOwner: owners[0] }); } - - _verifyFinalState(); } /// @notice Sets the fallback owner as the sole owner of the Safe with a threshold of 1 /// @param _prevOwner Owner that pointed to the owner to be replaced in the linked list /// @param _oldOwner Owner address to be replaced. - function _swapToFallbackOwner(address _prevOwner, address _oldOwner) internal { - SAFE.execTransactionFromModule({ - to: address(SAFE), - value: 0, - operation: Enum.Operation.Call, - data: abi.encodeCall(OwnerManager.swapOwner, (_prevOwner, _oldOwner, FALLBACK_OWNER)) - }); + function _swapToFallbackOwnerSafeCall(address _prevOwner, address _oldOwner) internal { + require( + SAFE.execTransactionFromModule({ + to: address(SAFE), + value: 0, + operation: Enum.Operation.Call, + data: abi.encodeCall(OwnerManager.swapOwner, (_prevOwner, _oldOwner, FALLBACK_OWNER)) + }), + "LivenessModule: failed to swap to fallback owner" + ); } /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`. /// @param _prevOwner Owner that pointed to the owner to be removed in the linked list /// @param _owner Owner address to be removed. /// @param _threshold New threshold. - function _removeOwner(address _prevOwner, address _owner, uint256 _threshold) internal { - SAFE.execTransactionFromModule({ - to: address(SAFE), - value: 0, - operation: Enum.Operation.Call, - data: abi.encodeCall(OwnerManager.removeOwner, (_prevOwner, _owner, _threshold)) - }); + function _removeOwnerSafeCall(address _prevOwner, address _owner, uint256 _threshold) internal { + require( + SAFE.execTransactionFromModule({ + to: address(SAFE), + value: 0, + operation: Enum.Operation.Call, + data: abi.encodeCall(OwnerManager.removeOwner, (_prevOwner, _owner, _threshold)) + }), + "LivenessModule: failed to remove owner" + ); } /// @notice A FREI-PI invariant check enforcing requirements on number of owners and threshold. @@ -158,20 +157,6 @@ contract LivenessModule is ISemver { ); } - /// @notice Get the previous owner in the linked list of owners - /// @param _owner The owner whose previous owner we want to find - /// @param _owners The list of owners - function _getPrevOwner(address _owner, address[] memory _owners) internal pure returns (address prevOwner_) { - for (uint256 i = 0; i < _owners.length; i++) { - if (_owners[i] != _owner) continue; - if (i == 0) { - prevOwner_ = SENTINEL_OWNERS; - break; - } - prevOwner_ = _owners[i - 1]; - } - } - /// @notice For a given number of owners, return the lowest threshold which is greater than 75. /// Note: this function returns 1 for numOwners == 1. function get75PercentThreshold(uint256 _numOwners) public pure returns (uint256 threshold_) { diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 6b669442e810..c2b9936b7d37 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -5,26 +5,57 @@ import { Test, StdUtils } from "forge-std/Test.sol"; import { Safe } from "safe-contracts/Safe.sol"; import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; +import { OwnerManager } from "safe-contracts/base/OwnerManager.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import "test/safe-tools/SafeTestTools.sol"; import { LivenessModule } from "src/Safe/LivenessModule.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; +contract OwnerSimulator is OwnerManager { + constructor(address[] memory _owners, uint256 _threshold) { + setupOwners(_owners, _threshold); + } + + function removeOwnerWrapped(address prevOwner, address owner, uint256 _threshold) public { + OwnerManager(address(this)).removeOwner(prevOwner, owner, _threshold); + } +} + contract LivenessModule_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; + /// @notice The address of the first owner in the linked list of owners + address internal constant SENTINEL_OWNERS = address(0x1); + event SignersRecorded(bytes32 indexed txHash, address[] signers); LivenessModule livenessModule; LivenessGuard livenessGuard; SafeInstance safeInstance; + OwnerSimulator ownerSimulator; address fallbackOwner; + /// @notice Get the previous owner in the linked list of owners + /// @param _owner The owner whose previous owner we want to find + /// @param _owners The list of owners + function _getPrevOwner(address _owner, address[] memory _owners) internal pure returns (address prevOwner_) { + for (uint256 i = 0; i < _owners.length; i++) { + if (_owners[i] != _owner) continue; + if (i == 0) { + prevOwner_ = SENTINEL_OWNERS; + break; + } + prevOwner_ = _owners[i - 1]; + } + } + function setUp() public { // Create a Safe with 10 owners (, uint256[] memory keys) = makeAddrsAndKeys(10); safeInstance = _setupSafe(keys, 8); + ownerSimulator = new OwnerSimulator(safeInstance.owners, 1); + livenessGuard = new LivenessGuard(safeInstance.safe); fallbackOwner = makeAddr("fallbackOwner"); livenessModule = new LivenessModule({ @@ -79,22 +110,34 @@ contract LivenessModule_Get75PercentThreshold_Test is LivenessModule_TestInit { contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { function test_removeOwner_oneOwner_succeeds() external { uint256 ownersBefore = safeInstance.owners.length; + address[] memory prevOwners = new address[](1); + address[] memory ownersToRemove = new address[](1); + ownersToRemove[0] = safeInstance.owners[0]; + prevOwners[0] = _getPrevOwner(safeInstance.owners[0], safeInstance.owners); + + address ownerToRemove = safeInstance.owners[0]; vm.warp(block.timestamp + 30 days); - livenessModule.removeOwner(safeInstance.owners[0]); + + livenessModule.removeOwners(prevOwners, ownersToRemove); assertEq(safeInstance.safe.getOwners().length, ownersBefore - 1); } function test_removeOwner_allOwners_succeeds() external { vm.warp(block.timestamp + 30 days); uint256 numOwners = safeInstance.owners.length; - uint256 minOwners = livenessModule.minOwners(); - - // Remove enough owners to trigger the transfer to the fallbackOwner - uint256 numToRemove = numOwners - minOwners + 1; - for (uint256 i = 0; i < numToRemove; i++) { - livenessModule.removeOwner(safeInstance.owners[i]); + address[] memory prevOwners = new address[](numOwners); + address[] memory ownersToRemove = new address[](numOwners); + address[] memory currentOwners; + for (uint256 i = 0; i < numOwners; i++) { + currentOwners = ownerSimulator.getOwners(); + ownersToRemove[i] = safeInstance.owners[i]; + prevOwners[i] = _getPrevOwner(safeInstance.owners[i], currentOwners); + if (currentOwners.length == 1) break; + ownerSimulator.removeOwnerWrapped(prevOwners[i], ownersToRemove[i], 1); } + + livenessModule.removeOwners(prevOwners, ownersToRemove); assertEq(safeInstance.safe.getOwners().length, 1); assertEq(safeInstance.safe.getOwners()[0], fallbackOwner); assertEq(safeInstance.safe.getThreshold(), 1); From 377dcdaf6ce3f6722daafd07f4d7e9b701c495b1 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 21:23:49 -0400 Subject: [PATCH 168/374] refactor(ctb): Simplify removal logic This refactor removes a few different variable which were unnecessary and added to the confusion. --- .../src/Safe/LivenessModule.sol | 55 +++++++++++-------- .../test/LivenessModule.t.sol | 1 - 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 79e764b12449..11a04252aa67 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -61,8 +61,18 @@ contract LivenessModule is ISemver { function removeOwners(address[] memory _previousOwners, address[] memory _ownersToRemove) external { require(_previousOwners.length == _ownersToRemove.length, "LivenessModule: arrays must be the same length"); + + // We will remove at least one owner, so we'll initialize the newOwners count to the current number of owners + // minus one. + uint256 newOwnersCount = SAFE.getOwners().length; for (uint256 i = 0; i < _previousOwners.length; i++) { - _removeOwner(_previousOwners[i], _ownersToRemove[i]); + newOwnersCount--; + _removeOwner({ + _prevOwner: _previousOwners[i], + _ownerToRemove: _ownersToRemove[i], + _newOwnersCount: newOwnersCount, + _newThreshold: get75PercentThreshold(newOwnersCount) + }); } _verifyFinalState(); } @@ -70,30 +80,27 @@ contract LivenessModule is ISemver { /// @notice This function can be called by anyone to remove an owner that has not signed a transaction /// during the liveness interval. If the number of owners drops below the minimum, then the /// ownership of the Safe is transferred to the fallback owner. - function _removeOwner(address _prevOwner, address _ownerToRemove) internal { - // Calculate the new threshold - address[] memory owners = SAFE.getOwners(); - uint256 numOwnersAfter = owners.length - 1; - if (_isAboveMinOwners(numOwnersAfter)) { - // Check that the owner to remove has not signed a transaction in the last 30 days - require( - LIVENESS_GUARD.lastLive(_ownerToRemove) < block.timestamp - LIVENESS_INTERVAL, - "LivenessModule: owner has signed recently" - ); - // Call the Safe to remove the owner and update the threshold - uint256 thresholdAfter = get75PercentThreshold(numOwnersAfter); - _removeOwnerSafeCall({ _prevOwner: _prevOwner, _owner: _ownerToRemove, _threshold: thresholdAfter }); - } else { - // The number of owners is dangerously low, so we wish to transfer the ownership of this Safe - // to the fallback owner. Therefore we no longer need to validate the liveness of the owners - // before removing them. - if (numOwnersAfter == 0) { - // Add the fallback owner as the sole owner of the Safe - _swapToFallbackOwnerSafeCall({ _prevOwner: _prevOwner, _oldOwner: _ownerToRemove }); - } else { - // Remove the owner and set the threshold to 1 - _removeOwnerSafeCall({ _prevOwner: _prevOwner, _owner: _ownerToRemove, _threshold: 1 }); + function _removeOwner( + address _prevOwner, + address _ownerToRemove, + uint256 _newOwnersCount, + uint256 _newThreshold + ) + internal + { + if (_newOwnersCount > 0) { + if (_isAboveMinOwners(_newOwnersCount)) { + // Check that the owner to remove has not signed a transaction in the last 30 days + require( + LIVENESS_GUARD.lastLive(_ownerToRemove) < block.timestamp - LIVENESS_INTERVAL, + "LivenessModule: owner has signed recently" + ); } + // Remove the owner and update the threshold + _removeOwnerSafeCall({ _prevOwner: _prevOwner, _owner: _ownerToRemove, _threshold: _newThreshold }); + } else { + // Add the fallback owner as the sole owner of the Safe + _swapToFallbackOwnerSafeCall({ _prevOwner: _prevOwner, _oldOwner: _ownerToRemove }); } } diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index c2b9936b7d37..4aeae7ca9809 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -115,7 +115,6 @@ contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { ownersToRemove[0] = safeInstance.owners[0]; prevOwners[0] = _getPrevOwner(safeInstance.owners[0], safeInstance.owners); - address ownerToRemove = safeInstance.owners[0]; vm.warp(block.timestamp + 30 days); livenessModule.removeOwners(prevOwners, ownersToRemove); From 40c997f13bd7531a009921d2a7301382e3d158c2 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 21:54:17 -0400 Subject: [PATCH 169/374] refactor(ctb): Reduce branching on pre-removal check --- .../contracts-bedrock/src/Safe/LivenessModule.sol | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 11a04252aa67..7c9134fc9eaf 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -88,14 +88,12 @@ contract LivenessModule is ISemver { ) internal { + require( + !_isAboveMinOwners(_newOwnersCount) + || LIVENESS_GUARD.lastLive(_ownerToRemove) < block.timestamp - LIVENESS_INTERVAL, + "LivenessModule: owner has signed recently" + ); if (_newOwnersCount > 0) { - if (_isAboveMinOwners(_newOwnersCount)) { - // Check that the owner to remove has not signed a transaction in the last 30 days - require( - LIVENESS_GUARD.lastLive(_ownerToRemove) < block.timestamp - LIVENESS_INTERVAL, - "LivenessModule: owner has signed recently" - ); - } // Remove the owner and update the threshold _removeOwnerSafeCall({ _prevOwner: _prevOwner, _owner: _ownerToRemove, _threshold: _newThreshold }); } else { From a725a3c28394fc4727097bb377f1fed914f9f982 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 22:15:18 -0400 Subject: [PATCH 170/374] refactor(ctb): Better helper functions for pre-removal check --- .../src/Safe/LivenessModule.sol | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 7c9134fc9eaf..8f9026d22038 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -89,9 +89,8 @@ contract LivenessModule is ISemver { internal { require( - !_isAboveMinOwners(_newOwnersCount) - || LIVENESS_GUARD.lastLive(_ownerToRemove) < block.timestamp - LIVENESS_INTERVAL, - "LivenessModule: owner has signed recently" + _newOwnersCount < MIN_OWNERS || _canRemove(_ownerToRemove), + "LivenessModule: the safe still has sufficient owners, or the owner to remove has signed recently" ); if (_newOwnersCount > 0) { // Remove the owner and update the threshold @@ -133,12 +132,19 @@ contract LivenessModule is ISemver { ); } + /// @notice Checks if the owner can be removed + /// @param _owner The owner to be removed + /// @return canRemove_ bool indicating if the owner can be removed + function _canRemove(address _owner) internal view returns (bool canRemove_) { + canRemove_ = LIVENESS_GUARD.lastLive(_owner) + LIVENESS_INTERVAL < block.timestamp; + } + /// @notice A FREI-PI invariant check enforcing requirements on number of owners and threshold. function _verifyFinalState() internal view { address[] memory owners = SAFE.getOwners(); uint256 numOwners = owners.length; require( - _isAboveMinOwners(numOwners) || (numOwners == 1 && owners[0] == FALLBACK_OWNER), + numOwners >= MIN_OWNERS || (numOwners == 1 && owners[0] == FALLBACK_OWNER), "LivenessModule: Safe must have the minimum number of owners or be owned solely by the fallback owner" ); @@ -168,13 +174,6 @@ contract LivenessModule is ISemver { threshold_ = (_numOwners * 75 + 99) / 100; } - /// @notice Check if the number of owners is greater than or equal to the minimum number of owners. - /// @param numOwners The number of owners. - /// @return A boolean indicating if the number of owners is greater than or equal to the minimum number of owners. - function _isAboveMinOwners(uint256 numOwners) internal view returns (bool) { - return numOwners >= MIN_OWNERS; - } - /// @notice Getter function for the Safe contract instance /// @return safe_ The Safe contract instance function safe() public view returns (Safe safe_) { From 42d4f5e54d9bb513d2b02d0190d4f601ab9e590d Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 22:21:17 -0400 Subject: [PATCH 171/374] refactor(ctb): Move pre-removal check to outer function --- .../src/Safe/LivenessModule.sol | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 8f9026d22038..e330c06f2e4b 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -63,15 +63,18 @@ contract LivenessModule is ISemver { require(_previousOwners.length == _ownersToRemove.length, "LivenessModule: arrays must be the same length"); // We will remove at least one owner, so we'll initialize the newOwners count to the current number of owners - // minus one. - uint256 newOwnersCount = SAFE.getOwners().length; + uint256 ownersCount = SAFE.getOwners().length; for (uint256 i = 0; i < _previousOwners.length; i++) { - newOwnersCount--; + ownersCount--; + require( + ownersCount < MIN_OWNERS || _canRemove(_ownersToRemove[i]), + "LivenessModule: the safe still has sufficient owners, or the owner to remove has signed recently" + ); _removeOwner({ _prevOwner: _previousOwners[i], _ownerToRemove: _ownersToRemove[i], - _newOwnersCount: newOwnersCount, - _newThreshold: get75PercentThreshold(newOwnersCount) + _newOwnersCount: ownersCount, + _newThreshold: get75PercentThreshold(ownersCount) }); } _verifyFinalState(); @@ -88,10 +91,6 @@ contract LivenessModule is ISemver { ) internal { - require( - _newOwnersCount < MIN_OWNERS || _canRemove(_ownerToRemove), - "LivenessModule: the safe still has sufficient owners, or the owner to remove has signed recently" - ); if (_newOwnersCount > 0) { // Remove the owner and update the threshold _removeOwnerSafeCall({ _prevOwner: _prevOwner, _owner: _ownerToRemove, _threshold: _newThreshold }); From 199cb31d4e32a5bb6203e117093649deb5f6700b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 23:03:57 -0400 Subject: [PATCH 172/374] test(ctb): Extract owner prevOwners generation into helper function --- .../src/Safe/LivenessModule.sol | 16 +++++++++--- .../test/LivenessModule.t.sol | 26 ++++++++++++++----- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index e330c06f2e4b..603a56a30745 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -59,6 +59,11 @@ contract LivenessModule is ISemver { ); } + /// @notice This function can be called by anyone to remove a set of owners that have not signed a transaction + /// during the liveness interval. If the number of owners drops below the minimum, then all owners + /// must be removed. + /// @param _previousOwners The previous owners in the linked list of owners + /// @param _ownersToRemove The owners to remove function removeOwners(address[] memory _previousOwners, address[] memory _ownersToRemove) external { require(_previousOwners.length == _ownersToRemove.length, "LivenessModule: arrays must be the same length"); @@ -80,9 +85,11 @@ contract LivenessModule is ISemver { _verifyFinalState(); } - /// @notice This function can be called by anyone to remove an owner that has not signed a transaction - /// during the liveness interval. If the number of owners drops below the minimum, then the - /// ownership of the Safe is transferred to the fallback owner. + /// @notice Removes an owner from the Safe and updates the threshold. + /// @param _prevOwner Owner that pointed to the owner to be removed in the linked list + /// @param _ownerToRemove Owner address to be removed. + /// @param _newOwnersCount New number of owners after removal. + /// @param _newThreshold New threshold. function _removeOwner( address _prevOwner, address _ownerToRemove, @@ -95,7 +102,8 @@ contract LivenessModule is ISemver { // Remove the owner and update the threshold _removeOwnerSafeCall({ _prevOwner: _prevOwner, _owner: _ownerToRemove, _threshold: _newThreshold }); } else { - // Add the fallback owner as the sole owner of the Safe + // There is only one owner left. The Safe will not allow a safe with no owners, so we will + // need to swap owners instead. _swapToFallbackOwnerSafeCall({ _prevOwner: _prevOwner, _oldOwner: _ownerToRemove }); } } diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 4aeae7ca9809..fa85646bf201 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -50,6 +50,23 @@ contract LivenessModule_TestInit is Test, SafeTestTools { } } + /// @notice Given an arrary of owners to remove, this function will return an array of the previous owners + /// in the order that they must be provided to the LivenessMoules's removeOwners() function. + /// Because owners are removed one at a time, and not necessarily in order, we need to simulate + /// the owners list after each removal, in order to identify the correct previous owner. + /// @param _ownersToRemove The owners to remove + /// @return prevOwners_ The previous owners in the linked list + function _getPrevOwners(address[] memory _ownersToRemove) internal returns (address[] memory prevOwners_) { + prevOwners_ = new address[](_ownersToRemove.length); + address[] memory currentOwners; + for (uint256 i = 0; i < _ownersToRemove.length; i++) { + currentOwners = ownerSimulator.getOwners(); + prevOwners_[i] = _getPrevOwner(safeInstance.owners[i], currentOwners); + if (currentOwners.length == 1) break; + ownerSimulator.removeOwnerWrapped(prevOwners_[i], _ownersToRemove[i], 1); + } + } + function setUp() public { // Create a Safe with 10 owners (, uint256[] memory keys) = makeAddrsAndKeys(10); @@ -122,20 +139,15 @@ contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { } function test_removeOwner_allOwners_succeeds() external { - vm.warp(block.timestamp + 30 days); uint256 numOwners = safeInstance.owners.length; - address[] memory prevOwners = new address[](numOwners); address[] memory ownersToRemove = new address[](numOwners); - address[] memory currentOwners; for (uint256 i = 0; i < numOwners; i++) { - currentOwners = ownerSimulator.getOwners(); ownersToRemove[i] = safeInstance.owners[i]; - prevOwners[i] = _getPrevOwner(safeInstance.owners[i], currentOwners); - if (currentOwners.length == 1) break; - ownerSimulator.removeOwnerWrapped(prevOwners[i], ownersToRemove[i], 1); } + address[] memory prevOwners = _getPrevOwners(ownersToRemove); + vm.warp(block.timestamp + 30 days); livenessModule.removeOwners(prevOwners, ownersToRemove); assertEq(safeInstance.safe.getOwners().length, 1); assertEq(safeInstance.safe.getOwners()[0], fallbackOwner); From 3f6470e710346ca2483593ecad62fe06c1352d80 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 23:18:20 -0400 Subject: [PATCH 173/374] test(ctb): Add natspec to test functions --- .../test/LivenessGuard.t.sol | 22 ++++++++++++------- .../test/LivenessModule.t.sol | 11 ++++++++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 206f27df8e5d..73833f8f6fef 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -10,14 +10,6 @@ import "test/safe-tools/SafeTestTools.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; -// Todo(Maurelian): -// Other tests needed: -// - EIP1271 signatures -// - Signatures from contracts -// - Signatures from non-owners -// - Signers may call directly to prove liveness (must be an owner). -// - Unexpected length of signature data - contract LivenessGuard_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; @@ -26,6 +18,7 @@ contract LivenessGuard_TestInit is Test, SafeTestTools { LivenessGuard livenessGuard; SafeInstance safeInstance; + /// @dev Sets up the test environment function setUp() public { safeInstance = _setupSafe(); livenessGuard = new LivenessGuard(safeInstance.safe); @@ -34,6 +27,7 @@ contract LivenessGuard_TestInit is Test, SafeTestTools { } contract LivenessGuard_Getters_Test is LivenessGuard_TestInit { + /// @dev Tests that the getters return the correct values function test_getters_works() external { assertEq(address(livenessGuard.safe()), address(safeInstance.safe)); assertEq(livenessGuard.lastLive(address(0)), 0); @@ -41,6 +35,7 @@ contract LivenessGuard_Getters_Test is LivenessGuard_TestInit { } contract LivenessGuard_CheckTx_TestFails is LivenessGuard_TestInit { + /// @dev Tests that the checkTransaction function reverts if the caller is not the Safe function test_checkTransaction_callerIsNotSafe_revert() external { vm.expectRevert("LivenessGuard: only Safe can call this function"); livenessGuard.checkTransaction({ @@ -62,6 +57,7 @@ contract LivenessGuard_CheckTx_TestFails is LivenessGuard_TestInit { contract LivenessGuard_CheckTx_Test is LivenessGuard_TestInit { using SafeTestLib for SafeInstance; + /// @dev Tests that the checkTransaction function succeeds function test_checkTransaction_succeeds() external { // Create an array of the addresses who will sign the transaction. SafeTestTools // will generate these signatures up to the threshold by iterating over the owners array. @@ -85,6 +81,7 @@ contract LivenessGuard_CheckTx_Test is LivenessGuard_TestInit { } contract LivenessGuard_CheckAfterExecution_TestFails is LivenessGuard_TestInit { + /// @dev Tests that the checkAfterExecution function reverts if the caller is not the Safe function test_checkAfterExecution_callerIsNotSafe_revert() external { vm.expectRevert("LivenessGuard: only Safe can call this function"); livenessGuard.checkAfterExecution(bytes32(0), false); @@ -93,7 +90,16 @@ contract LivenessGuard_CheckAfterExecution_TestFails is LivenessGuard_TestInit { contract LivenessGuard_CheckAfterExecution_Test is LivenessGuard_TestInit { } +contract LivenessGuard_ShowLiveness_TestFail is LivenessGuard_TestInit { + /// @dev Tests that the showLiveness function reverts if the caller is not an owner + function test_showLiveness_callIsNotSafeOwner_reverts() external { + vm.expectRevert("LivenessGuard: only Safe owners can call this function"); + livenessGuard.showLiveness(); + } +} + contract LivenessGuard_ShowLiveness_Test is LivenessGuard_TestInit { + /// @dev Tests that the showLiveness function succeeds function test_showLiveness_succeeds() external { // Cache the caller address caller = safeInstance.owners[0]; diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index fa85646bf201..5dd4e5811c67 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -12,6 +12,9 @@ import "test/safe-tools/SafeTestTools.sol"; import { LivenessModule } from "src/Safe/LivenessModule.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; +/// @dev A minimal wrapper around the OwnerManager contract. This contract is meant to be initialized with +/// the same owners as a Safe instance, and then used to simulate the resulting owners list +/// after an owner is removed. contract OwnerSimulator is OwnerManager { constructor(address[] memory _owners, uint256 _threshold) { setupOwners(_owners, _threshold); @@ -25,7 +28,7 @@ contract OwnerSimulator is OwnerManager { contract LivenessModule_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; - /// @notice The address of the first owner in the linked list of owners + /// @dev The address of the first owner in the linked list of owners address internal constant SENTINEL_OWNERS = address(0x1); event SignersRecorded(bytes32 indexed txHash, address[] signers); @@ -50,7 +53,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { } } - /// @notice Given an arrary of owners to remove, this function will return an array of the previous owners + /// @dev Given an array of owners to remove, this function will return an array of the previous owners /// in the order that they must be provided to the LivenessMoules's removeOwners() function. /// Because owners are removed one at a time, and not necessarily in order, we need to simulate /// the owners list after each removal, in order to identify the correct previous owner. @@ -67,6 +70,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { } } + /// @dev Sets up the test environment function setUp() public { // Create a Safe with 10 owners (, uint256[] memory keys) = makeAddrsAndKeys(10); @@ -88,6 +92,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { } contract LivenessModule_Getters_Test is LivenessModule_TestInit { + /// @dev Tests if the getters work correctly function test_getters_works() external { assertEq(address(livenessModule.safe()), address(safeInstance.safe)); assertEq(address(livenessModule.livenessGuard()), address(livenessGuard)); @@ -125,6 +130,7 @@ contract LivenessModule_Get75PercentThreshold_Test is LivenessModule_TestInit { } contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { + /// @dev Tests if removing one owner works correctly function test_removeOwner_oneOwner_succeeds() external { uint256 ownersBefore = safeInstance.owners.length; address[] memory prevOwners = new address[](1); @@ -138,6 +144,7 @@ contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { assertEq(safeInstance.safe.getOwners().length, ownersBefore - 1); } + /// @dev Tests if removing all owners works correctly function test_removeOwner_allOwners_succeeds() external { uint256 numOwners = safeInstance.owners.length; From 69f3cce1faa3048cd7d1b48daff5e8921a6e4688 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 23:27:32 -0400 Subject: [PATCH 174/374] refactor(ctb): Add _onlySafe function --- .../contracts-bedrock/src/Safe/LivenessGuard.sol | 12 ++++++++---- packages/contracts-bedrock/test/LivenessGuard.t.sol | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 2e257697b55c..30825b8c1191 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -47,6 +47,11 @@ contract LivenessGuard is ISemver, BaseGuard { SAFE = _safe; } + /// @notice Internal function to ensure that only the Safe can call certain functions. + function _onlySafe() internal view { + require(msg.sender == address(SAFE), "LivenessGuard: only Safe can call this function"); + } + /// @notice Records the most recent time which any owner has signed a transaction. /// @dev Called by the Safe contract before execution of a transaction. function checkTransaction( @@ -65,7 +70,7 @@ contract LivenessGuard is ISemver, BaseGuard { external { msgSender; // silence unused variable warning - require(msg.sender == address(SAFE), "LivenessGuard: only Safe can call this function"); + _onlySafe(); // Cache the set of owners prior to execution. // This will be used in the checkAfterExecution method. @@ -106,8 +111,7 @@ contract LivenessGuard is ISemver, BaseGuard { /// 1. Add new owners to the lastLive mapping /// 2. Delete removed owners from the lastLive mapping function checkAfterExecution(bytes32, bool) external { - require(msg.sender == address(SAFE), "LivenessGuard: only Safe can call this function"); - + _onlySafe(); // Get the current set of owners address[] memory ownersAfter = SAFE.getOwners(); @@ -132,7 +136,7 @@ contract LivenessGuard is ISemver, BaseGuard { /// @notice Enables an owner to demonstrate liveness by calling this method directly. /// This is useful for owners who have not recently signed a transaction via the Safe. function showLiveness() external { - require(SAFE.isOwner(msg.sender), "LivenessGuard: only Safe owners may demontstrate liveness"); + require(SAFE.isOwner(msg.sender), "LivenessGuard: only Safe owners may demonstrate liveness"); lastLive[msg.sender] = block.timestamp; emit OwnerRecorded(0x0, msg.sender); diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 73833f8f6fef..89531ba42dd1 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -93,7 +93,7 @@ contract LivenessGuard_CheckAfterExecution_Test is LivenessGuard_TestInit { } contract LivenessGuard_ShowLiveness_TestFail is LivenessGuard_TestInit { /// @dev Tests that the showLiveness function reverts if the caller is not an owner function test_showLiveness_callIsNotSafeOwner_reverts() external { - vm.expectRevert("LivenessGuard: only Safe owners can call this function"); + vm.expectRevert("LivenessGuard: only Safe owners may demonstrate liveness"); livenessGuard.showLiveness(); } } From ade16503198d84109dc09395e52b2023bcf57ffb Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 25 Oct 2023 23:28:04 -0400 Subject: [PATCH 175/374] test(ctb): Additional Liveness Module Testing --- .../test/LivenessModule.t.sol | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 5dd4e5811c67..67579c0a7209 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -33,6 +33,8 @@ contract LivenessModule_TestInit is Test, SafeTestTools { event SignersRecorded(bytes32 indexed txHash, address[] signers); + uint256 livenessInterval = 30 days; + uint256 minOwners = 6; LivenessModule livenessModule; LivenessGuard livenessGuard; SafeInstance safeInstance; @@ -82,8 +84,8 @@ contract LivenessModule_TestInit is Test, SafeTestTools { livenessModule = new LivenessModule({ _safe: safeInstance.safe, _livenessGuard: livenessGuard, - _livenessInterval: 30 days, - _minOwners: 6, + _livenessInterval: livenessInterval, + _minOwners: minOwners, _fallbackOwner: fallbackOwner }); safeInstance.enableModule(address(livenessModule)); @@ -91,6 +93,20 @@ contract LivenessModule_TestInit is Test, SafeTestTools { } } +contract LivenessModule_Constructor_Test is LivenessModule_TestInit { + /// @dev Tests that the constructor fails if the minOwners is greater than the number of owners + function test_constructor_minOwnersGreaterThanOwners_revert() external { + vm.expectRevert("LivenessModule: minOwners must be less than the number of owners"); + new LivenessModule({ + _safe: safeInstance.safe, + _livenessGuard: livenessGuard, + _livenessInterval: livenessInterval, + _minOwners: 11, + _fallbackOwner: address(0) + }); + } +} + contract LivenessModule_Getters_Test is LivenessModule_TestInit { /// @dev Tests if the getters work correctly function test_getters_works() external { From 10a256ff328f75bd410fe3c92f4049a93827abd8 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 00:10:26 -0400 Subject: [PATCH 176/374] test(ctb): Guard changed --- .../test/LivenessModule.t.sol | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 67579c0a7209..ac1bdb444738 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -67,11 +67,23 @@ contract LivenessModule_TestInit is Test, SafeTestTools { for (uint256 i = 0; i < _ownersToRemove.length; i++) { currentOwners = ownerSimulator.getOwners(); prevOwners_[i] = _getPrevOwner(safeInstance.owners[i], currentOwners); + + // Don't try to remove the last owner if (currentOwners.length == 1) break; ownerSimulator.removeOwnerWrapped(prevOwners_[i], _ownersToRemove[i], 1); } } + /// @dev Removes an owner from the safe + function _removeAnOwner(address _ownerToRemove) internal { + address[] memory prevOwners = new address[](1); + address[] memory ownersToRemove = new address[](1); + ownersToRemove[0] = _ownerToRemove; + prevOwners[0] = _getPrevOwner(_ownerToRemove, safeInstance.owners); + + livenessModule.removeOwners(prevOwners, ownersToRemove); + } + /// @dev Sets up the test environment function setUp() public { // Create a Safe with 10 owners @@ -145,18 +157,35 @@ contract LivenessModule_Get75PercentThreshold_Test is LivenessModule_TestInit { } } +contract LivenessModule_RemoveOwner_TestFail is LivenessModule_TestInit { + using SafeTestLib for SafeInstance; + // "LivenessModule: guard has been changed" + + function test_removeOwner_guardChanged_revert() external { + address[] memory ownersToRemove = new address[](1); + ownersToRemove[0] = safeInstance.owners[0]; + address[] memory prevOwners = _getPrevOwners(ownersToRemove); + + // Change the guard + livenessGuard = new LivenessGuard(safeInstance.safe); + safeInstance.setGuard(address(livenessGuard)); + + vm.warp(block.timestamp + livenessInterval + 1); + vm.expectRevert("LivenessModule: guard has been changed"); + livenessModule.removeOwners(prevOwners, ownersToRemove); + } +} + contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { /// @dev Tests if removing one owner works correctly function test_removeOwner_oneOwner_succeeds() external { uint256 ownersBefore = safeInstance.owners.length; - address[] memory prevOwners = new address[](1); - address[] memory ownersToRemove = new address[](1); - ownersToRemove[0] = safeInstance.owners[0]; - prevOwners[0] = _getPrevOwner(safeInstance.owners[0], safeInstance.owners); + address ownerToRemove = safeInstance.owners[0]; - vm.warp(block.timestamp + 30 days); + // vm.warp(block.timestamp + 30 days); + _removeAnOwner(ownerToRemove); - livenessModule.removeOwners(prevOwners, ownersToRemove); + assertFalse(safeInstance.safe.isOwner(ownerToRemove)); assertEq(safeInstance.safe.getOwners().length, ownersBefore - 1); } From 63fceb3908d4aee997cdff7e6222b104b105d0c1 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 00:48:47 -0400 Subject: [PATCH 177/374] refactor(ctb): Remove _requireGuard It was only used once. --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 603a56a30745..859e2aa178f1 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -150,6 +150,7 @@ contract LivenessModule is ISemver { function _verifyFinalState() internal view { address[] memory owners = SAFE.getOwners(); uint256 numOwners = owners.length; + // Ensure that the safe is not being left in an unsafe state with too few owners. require( numOwners >= MIN_OWNERS || (numOwners == 1 && owners[0] == FALLBACK_OWNER), "LivenessModule: Safe must have the minimum number of owners or be owned solely by the fallback owner" @@ -163,12 +164,7 @@ contract LivenessModule is ISemver { "LivenessModule: threshold must be 75% of the number of owners" ); - // Check that the guard has not been changed. - _requireCorrectGuard(); - } - - /// @notice Reverts if the guard address does not match the expected value. - function _requireCorrectGuard() internal view { + // Check that the guard has not been changed require( address(LIVENESS_GUARD) == address(uint160(uint256(bytes32(SAFE.getStorageAt(GUARD_STORAGE_SLOT, 1))))), "LivenessModule: guard has been changed" From 7fe44b99827d4c3dacfd0eab785074ef4a8d1d32 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 00:57:38 -0400 Subject: [PATCH 178/374] test(ctb): Add tests for all reverts in Liveness Module --- .../test/LivenessModule.t.sol | 133 ++++++++++++++++-- 1 file changed, 124 insertions(+), 9 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index ac1bdb444738..e4205f0796ce 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -33,6 +33,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { event SignersRecorded(bytes32 indexed txHash, address[] signers); + uint256 initTime = 10; uint256 livenessInterval = 30 days; uint256 minOwners = 6; LivenessModule livenessModule; @@ -86,6 +87,10 @@ contract LivenessModule_TestInit is Test, SafeTestTools { /// @dev Sets up the test environment function setUp() public { + // Set the block timestamp to the initTime, so that signatures recorded in the first block + // are non-zero. + vm.warp(initTime); + // Create a Safe with 10 owners (, uint256[] memory keys) = makeAddrsAndKeys(10); safeInstance = _setupSafe(keys, 8); @@ -107,7 +112,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { contract LivenessModule_Constructor_Test is LivenessModule_TestInit { /// @dev Tests that the constructor fails if the minOwners is greater than the number of owners - function test_constructor_minOwnersGreaterThanOwners_revert() external { + function test_constructor_minOwnersGreaterThanOwners_reverts() external { vm.expectRevert("LivenessModule: minOwners must be less than the number of owners"); new LivenessModule({ _safe: safeInstance.safe, @@ -117,6 +122,22 @@ contract LivenessModule_Constructor_Test is LivenessModule_TestInit { _fallbackOwner: address(0) }); } + + /// @dev Tests that the constructor fails if the minOwners is greater than the number of owners + function test_constructor_wrongThreshold_reverts() external { + uint256 wrongThreshold = livenessModule.get75PercentThreshold(safeInstance.owners.length) + 1; + vm.mockCall( + address(safeInstance.safe), abi.encodeCall(OwnerManager.getThreshold, ()), abi.encode(wrongThreshold) + ); + vm.expectRevert("LivenessModule: Safe must have a threshold of 75% of the number of owners"); + new LivenessModule({ + _safe: safeInstance.safe, + _livenessGuard: livenessGuard, + _livenessInterval: livenessInterval, + _minOwners: minOwners, + _fallbackOwner: address(0) + }); + } } contract LivenessModule_Getters_Test is LivenessModule_TestInit { @@ -157,11 +178,91 @@ contract LivenessModule_Get75PercentThreshold_Test is LivenessModule_TestInit { } } -contract LivenessModule_RemoveOwner_TestFail is LivenessModule_TestInit { +contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { using SafeTestLib for SafeInstance; - // "LivenessModule: guard has been changed" - function test_removeOwner_guardChanged_revert() external { + /// @dev Tests with different length owner arrays + function test_removeOwners_differentArrayLengths_reverts() external { + address[] memory ownersToRemove = new address[](1); + address[] memory prevOwners = new address[](2); + vm.expectRevert("LivenessModule: arrays must be the same length"); + livenessModule.removeOwners(prevOwners, ownersToRemove); + } + + /// @dev Test removing an owner which has recently signed a transaction + function test_removeOwners_ownerHasSignedRecently_reverts() external { + /// Will sign a transaction with the first M owners in the owners list + vm.warp(block.timestamp + livenessInterval); + safeInstance.execTransaction({ to: address(1111), value: 0, data: hex"abba" }); + vm.expectRevert( + "LivenessModule: the safe still has sufficient owners, or the owner to remove has signed recently" + ); + _removeAnOwner(safeInstance.owners[0]); + } + + /// @dev Test removing an owner which has recently called showLiveness + function test_removeOwners_ownerHasShownLivenessRecently_reverts() external { + /// Will sign a transaction with the first M owners in the owners list + vm.warp(block.timestamp + livenessInterval); + vm.prank(safeInstance.owners[0]); + livenessGuard.showLiveness(); + vm.expectRevert( + "LivenessModule: the safe still has sufficient owners, or the owner to remove has signed recently" + ); + _removeAnOwner(safeInstance.owners[0]); + } + + /// @dev Test removing an owner with an incorrect previous owner + function test_removeOwners_wrongPreviousOwner_reverts() external { + address[] memory prevOwners = new address[](1); + address[] memory ownersToRemove = new address[](1); + ownersToRemove[0] = safeInstance.owners[0]; + prevOwners[0] = ownersToRemove[0]; // incorrect. + + vm.warp(block.timestamp + livenessInterval); + vm.expectRevert("LivenessModule: failed to remove owner"); + livenessModule.removeOwners(prevOwners, ownersToRemove); + } + + /// @dev Tests if removing all owners works correctly + function test_removeOwners_swapToFallBackOwner_reverts() external { + uint256 numOwners = safeInstance.owners.length; + + address[] memory ownersToRemove = new address[](numOwners); + for (uint256 i = 0; i < numOwners; i++) { + ownersToRemove[i] = safeInstance.owners[i]; + } + address[] memory prevOwners = _getPrevOwners(ownersToRemove); + + // Incorrectly set the final owner to address(0) + ownersToRemove[ownersToRemove.length - 1] = address(0); + + vm.warp(block.timestamp + livenessInterval); + vm.expectRevert("LivenessModule: failed to swap to fallback owner"); + livenessModule.removeOwners(prevOwners, ownersToRemove); + } + + /// @dev Tests if remove owners reverts if it removes too many owners without swapping to the fallback owner + function test_removeOwners_belowMinButNotToFallbackOwner_reverts() external { + // Remove all but one owner + uint256 numOwners = safeInstance.owners.length - 1; + + address[] memory ownersToRemove = new address[](numOwners); + for (uint256 i = 0; i < numOwners; i++) { + ownersToRemove[i] = safeInstance.owners[i]; + } + address[] memory prevOwners = _getPrevOwners(ownersToRemove); + + vm.warp(block.timestamp + livenessInterval); + vm.expectRevert( + "LivenessModule: Safe must have the minimum number of owners or be owned solely by the fallback owner" + ); + livenessModule.removeOwners(prevOwners, ownersToRemove); + } + + /// @dev Tests if remove owners reverts if the current Safe.guard does note match the expected + /// livenessGuard address. + function test_removeOwners_guardChanged_reverts() external { address[] memory ownersToRemove = new address[](1); ownersToRemove[0] = safeInstance.owners[0]; address[] memory prevOwners = _getPrevOwners(ownersToRemove); @@ -174,15 +275,29 @@ contract LivenessModule_RemoveOwner_TestFail is LivenessModule_TestInit { vm.expectRevert("LivenessModule: guard has been changed"); livenessModule.removeOwners(prevOwners, ownersToRemove); } + + function test_removeOwners_invalidThreshold_reverts() external { + address[] memory ownersToRemove = new address[](0); + address[] memory prevOwners = new address[](0); + uint256 wrongThreshold = safeInstance.safe.getThreshold() + 1; + + vm.mockCall( + address(safeInstance.safe), abi.encodeCall(OwnerManager.getThreshold, ()), abi.encode(wrongThreshold) + ); + + vm.warp(block.timestamp + livenessInterval + 1); + vm.expectRevert("LivenessModule: Safe must have a threshold of 75% of the number of owners"); + livenessModule.removeOwners(prevOwners, ownersToRemove); + } } -contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { +contract LivenessModule_RemoveOwners_Test is LivenessModule_TestInit { /// @dev Tests if removing one owner works correctly - function test_removeOwner_oneOwner_succeeds() external { + function test_removeOwners_oneOwner_succeeds() external { uint256 ownersBefore = safeInstance.owners.length; address ownerToRemove = safeInstance.owners[0]; - // vm.warp(block.timestamp + 30 days); + vm.warp(block.timestamp + livenessInterval + 1); _removeAnOwner(ownerToRemove); assertFalse(safeInstance.safe.isOwner(ownerToRemove)); @@ -190,7 +305,7 @@ contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { } /// @dev Tests if removing all owners works correctly - function test_removeOwner_allOwners_succeeds() external { + function test_removeOwners_allOwners_succeeds() external { uint256 numOwners = safeInstance.owners.length; address[] memory ownersToRemove = new address[](numOwners); @@ -199,7 +314,7 @@ contract LivenessModule_RemoveOwner_Test is LivenessModule_TestInit { } address[] memory prevOwners = _getPrevOwners(ownersToRemove); - vm.warp(block.timestamp + 30 days); + vm.warp(block.timestamp + livenessInterval + 1); livenessModule.removeOwners(prevOwners, ownersToRemove); assertEq(safeInstance.safe.getOwners().length, 1); assertEq(safeInstance.safe.getOwners()[0], fallbackOwner); From a51e82f39657f3eeb01ffdbced3af6f759797402 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 01:17:59 -0400 Subject: [PATCH 179/374] feat(ctb): Add constructor check on threshold --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 7 +++++-- packages/contracts-bedrock/test/LivenessModule.t.sol | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 859e2aa178f1..ed4f5d579de5 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -54,8 +54,11 @@ contract LivenessModule is ISemver { LIVENESS_INTERVAL = _livenessInterval; FALLBACK_OWNER = _fallbackOwner; MIN_OWNERS = _minOwners; + address[] memory owners = _safe.getOwners(); + require(_minOwners < owners.length, "LivenessModule: minOwners must be less than the number of owners"); require( - _minOwners < _safe.getOwners().length, "LivenessModule: minOwners must be less than the number of owners" + _safe.getThreshold() == get75PercentThreshold(owners.length), + "LivenessModule: Safe must have a threshold of 75% of the number of owners" ); } @@ -161,7 +164,7 @@ contract LivenessModule is ISemver { uint256 threshold = SAFE.getThreshold(); require( threshold == get75PercentThreshold(numOwners), - "LivenessModule: threshold must be 75% of the number of owners" + "LivenessModule: Safe must have a threshold of 75% of the number of owners" ); // Check that the guard has not been changed diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index e4205f0796ce..eeef3734d046 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -219,7 +219,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { ownersToRemove[0] = safeInstance.owners[0]; prevOwners[0] = ownersToRemove[0]; // incorrect. - vm.warp(block.timestamp + livenessInterval); + vm.warp(block.timestamp + livenessInterval + 1); vm.expectRevert("LivenessModule: failed to remove owner"); livenessModule.removeOwners(prevOwners, ownersToRemove); } @@ -237,7 +237,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { // Incorrectly set the final owner to address(0) ownersToRemove[ownersToRemove.length - 1] = address(0); - vm.warp(block.timestamp + livenessInterval); + vm.warp(block.timestamp + livenessInterval + 1); vm.expectRevert("LivenessModule: failed to swap to fallback owner"); livenessModule.removeOwners(prevOwners, ownersToRemove); } @@ -253,7 +253,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { } address[] memory prevOwners = _getPrevOwners(ownersToRemove); - vm.warp(block.timestamp + livenessInterval); + vm.warp(block.timestamp + livenessInterval + 1); vm.expectRevert( "LivenessModule: Safe must have the minimum number of owners or be owned solely by the fallback owner" ); From 854db4392313f28417bedd4b5fd02e015a6dd82d Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 01:52:15 -0400 Subject: [PATCH 180/374] feat(ctb): LivenessGuard record current owners in constructor --- .../contracts-bedrock/src/Safe/LivenessGuard.sol | 6 ++++++ packages/contracts-bedrock/test/LivenessGuard.t.sol | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 30825b8c1191..802c98dfed0f 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -45,6 +45,12 @@ contract LivenessGuard is ISemver, BaseGuard { /// @param _safe The safe account for which this contract will be the guard. constructor(Safe _safe) { SAFE = _safe; + address[] memory owners = _safe.getOwners(); + for (uint256 i = 0; i < owners.length; i++) { + address owner = owners[i]; + lastLive[owner] = block.timestamp; + emit OwnerRecorded(0x0, owner); + } } /// @notice Internal function to ensure that only the Safe can call certain functions. diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 89531ba42dd1..6dc9b06393be 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -15,17 +15,29 @@ contract LivenessGuard_TestInit is Test, SafeTestTools { event OwnerRecorded(bytes32 indexed txHash, address signer); + uint256 initTime = 10; LivenessGuard livenessGuard; SafeInstance safeInstance; /// @dev Sets up the test environment function setUp() public { + vm.warp(initTime); safeInstance = _setupSafe(); livenessGuard = new LivenessGuard(safeInstance.safe); safeInstance.setGuard(address(livenessGuard)); } } +contract LivenessGuard_Constructor_Test is LivenessGuard_TestInit { + function test_constructor_works() external { + address[] memory owners = safeInstance.owners; + livenessGuard = new LivenessGuard(safeInstance.safe); + for (uint256 i = 0; i < owners.length; i++) { + assertEq(livenessGuard.lastLive(owners[i]), initTime); + } + } +} + contract LivenessGuard_Getters_Test is LivenessGuard_TestInit { /// @dev Tests that the getters return the correct values function test_getters_works() external { From 57cfa4d351b50abd73e11c5946db0d8104587b78 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 02:18:43 -0400 Subject: [PATCH 181/374] feat(ctb): Address feedback --- .../src/Safe/LivenessGuard.sol | 8 +++++--- .../contracts-bedrock/test/LivenessGuard.t.sol | 1 + .../contracts-bedrock/test/LivenessModule.t.sol | 17 ++++++----------- .../contracts-bedrock/test/SafeSigners.t.sol | 1 + 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 802c98dfed0f..97ced936b42f 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -81,7 +81,8 @@ contract LivenessGuard is ISemver, BaseGuard { // Cache the set of owners prior to execution. // This will be used in the checkAfterExecution method. address[] memory owners = SAFE.getOwners(); - for (uint256 i = 0; i < owners.length; i++) { + uint256 ownersLength = owners.length; + for (uint256 i = 0; i < ownersLength; i++) { ownersBefore.add(owners[i]); } @@ -133,8 +134,9 @@ contract LivenessGuard is ISemver, BaseGuard { } // Now iterate over the remaining ownersBefore entries. Any remaining addresses are no longer an owner, so we // delete them from the lastLive mapping. - for (uint256 j = 0; j < ownersBefore.length(); j++) { - address ownerBefore = ownersBefore.at(j); + uint256 ownersBeforeLength = ownersBefore.length(); + for (uint256 i = 0; i < ownersBeforeLength; i++) { + address ownerBefore = ownersBefore.at(i); delete lastLive[ownerBefore]; } } diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 6dc9b06393be..671a12bcb7ba 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -29,6 +29,7 @@ contract LivenessGuard_TestInit is Test, SafeTestTools { } contract LivenessGuard_Constructor_Test is LivenessGuard_TestInit { + /// @dev Tests that the constructor correctly sets the current time as the lastLive time for each owner function test_constructor_works() external { address[] memory owners = safeInstance.owners; livenessGuard = new LivenessGuard(safeInstance.safe); diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index eeef3734d046..7a39c774bf37 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -20,6 +20,7 @@ contract OwnerSimulator is OwnerManager { setupOwners(_owners, _threshold); } + /// @dev Exposes the OwnerManager's removeOwner function so that anyone may call without needing auth function removeOwnerWrapped(address prevOwner, address owner, uint256 _threshold) public { OwnerManager(address(this)).removeOwner(prevOwner, owner, _threshold); } @@ -194,9 +195,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { /// Will sign a transaction with the first M owners in the owners list vm.warp(block.timestamp + livenessInterval); safeInstance.execTransaction({ to: address(1111), value: 0, data: hex"abba" }); - vm.expectRevert( - "LivenessModule: the safe still has sufficient owners, or the owner to remove has signed recently" - ); + vm.expectRevert("LivenessModule: the owner to remove has signed recently"); _removeAnOwner(safeInstance.owners[0]); } @@ -206,9 +205,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { vm.warp(block.timestamp + livenessInterval); vm.prank(safeInstance.owners[0]); livenessGuard.showLiveness(); - vm.expectRevert( - "LivenessModule: the safe still has sufficient owners, or the owner to remove has signed recently" - ); + vm.expectRevert("LivenessModule: the owner to remove has signed recently"); _removeAnOwner(safeInstance.owners[0]); } @@ -242,8 +239,8 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { livenessModule.removeOwners(prevOwners, ownersToRemove); } - /// @dev Tests if remove owners reverts if it removes too many owners without swapping to the fallback owner - function test_removeOwners_belowMinButNotToFallbackOwner_reverts() external { + /// @dev Tests if remove owners reverts if it removes too many owners without removing all of them + function test_removeOwners_belowMinButNotEmptied_reverts() external { // Remove all but one owner uint256 numOwners = safeInstance.owners.length - 1; @@ -254,9 +251,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { address[] memory prevOwners = _getPrevOwners(ownersToRemove); vm.warp(block.timestamp + livenessInterval + 1); - vm.expectRevert( - "LivenessModule: Safe must have the minimum number of owners or be owned solely by the fallback owner" - ); + vm.expectRevert("LivenessModule: must transfer ownership to fallback owner"); livenessModule.removeOwners(prevOwners, ownersToRemove); } diff --git a/packages/contracts-bedrock/test/SafeSigners.t.sol b/packages/contracts-bedrock/test/SafeSigners.t.sol index a9edbb1ca52e..8ad92d09af65 100644 --- a/packages/contracts-bedrock/test/SafeSigners.t.sol +++ b/packages/contracts-bedrock/test/SafeSigners.t.sol @@ -21,6 +21,7 @@ contract SafeSigners_Test is Test, SafeTestTools { /// @dev Maps every key to one of the 4 signatures types. /// This is used in the tests below as a pseudorandom mechanism for determining which /// signature type to use for each key. + /// @param _key The key to map to a signature type. function sigType(uint256 _key) internal pure returns (SigTypes sigType_) { uint256 t = _key % 4; sigType_ = SigTypes(t); From 0cd44702819182121a029f5301e721f8744054d8 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 02:46:28 -0400 Subject: [PATCH 182/374] specs: Define deployment order for liveness contracts --- packages/contracts-bedrock/test/LivenessModule.t.sol | 2 +- specs/safe-liveness-checking.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 7a39c774bf37..a872b52e4c17 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -106,8 +106,8 @@ contract LivenessModule_TestInit is Test, SafeTestTools { _minOwners: minOwners, _fallbackOwner: fallbackOwner }); - safeInstance.enableModule(address(livenessModule)); safeInstance.setGuard(address(livenessGuard)); + safeInstance.enableModule(address(livenessModule)); } } diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md index 86cb4054a9d0..69ec6462dc64 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/safe-liveness-checking.md @@ -86,3 +86,14 @@ The following security properties must be upheld: 5. The module implements the correct checks prior to removing a signer. 6. The module sets the correct threshold upon removing a signer. 7. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1. +### Deployment + +The module are guard are intended to be deployed and installed on the safe in the following sequence: + +1. Deploy the guard contract, this will set a timestamp for each existing owner on the Safe. +1. Deploy the module. +1. Enable the module on the safe. +1. Set the guard on the safe. + +This order of operations is necessary to satisfy the constructor checks in the module, and is +intended to prevent owners from being immediately removable. From 7b82cba7147f0fe02e2fe8c4842c8a40ab2f6c7f Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 02:50:21 -0400 Subject: [PATCH 183/374] specs: Add diagram and other details --- packages/contracts-bedrock/.gas-snapshot | 24 ++++++++++--- specs/safe-liveness-checking.md | 46 +++++++++++++++++------- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 67e01fb5ddb4..3c874406e284 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -305,11 +305,27 @@ LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12957) LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10755) LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34524) LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689) -LivenessGuard_ShowLiveness_Test:test_showLiveness_succeeds() (gas: 51339) +LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8553) +LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 234784) +LivenessGuard_CheckTx_TestFails:test_checkTransaction_callerIsNotSafe_revert() (gas: 10343) +LivenessGuard_Constructor_Test:test_constructor_works() (gas: 1163577) +LivenessGuard_Getters_Test:test_getters_works() (gas: 10662) +LivenessGuard_ShowLiveness_Test:test_showLiveness_succeeds() (gas: 29584) +LivenessGuard_ShowLiveness_TestFail:test_showLiveness_callIsNotSafeOwner_reverts() (gas: 18770) +LivenessModule_Constructor_Test:test_constructor_minOwnersGreaterThanOwners_reverts() (gas: 83531) +LivenessModule_Constructor_Test:test_constructor_wrongThreshold_reverts() (gas: 92808) LivenessModule_Get75PercentThreshold_Test:test_get75PercentThreshold_Works() (gas: 26339) -LivenessModule_RemoveOwner_Test:test_removeOwner_allOwners_succeeds() (gas: 159764) -LivenessModule_RemoveOwner_Test:test_removeOwner_oneOwner_succeeds() (gas: 109028) -LivnessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 160454) +LivenessModule_Getters_Test:test_getters_works() (gas: 14807) +LivenessModule_RemoveOwners_Test:test_removeOwners_allOwners_succeeds() (gas: 346743) +LivenessModule_RemoveOwners_Test:test_removeOwners_oneOwner_succeeds() (gas: 127161) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowMinButNotEmptied_reverts() (gas: 301067) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_differentArrayLengths_reverts() (gas: 10536) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_guardChanged_reverts() (gas: 1741747) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_invalidThreshold_reverts() (gas: 67238) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRecently_reverts() (gas: 91661) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 638440) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallBackOwner_reverts() (gas: 310105) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 70465) MIPS_Test:test_add_succeeds() (gas: 122932) MIPS_Test:test_addiSign_succeeds() (gas: 122923) MIPS_Test:test_addi_succeeds() (gas: 123120) diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md index 69ec6462dc64..aa28ea2d10d1 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/safe-liveness-checking.md @@ -8,8 +8,11 @@ - [Liveness checking methodology](#liveness-checking-methodology) - [The Liveness Guard](#the-liveness-guard) - [The Liveness Module](#the-liveness-module) + - [Owner removal call flow](#owner-removal-call-flow) - [Shutdown](#shutdown) - [Security Properties](#security-properties) + - [Interdependency between the Guard and Module](#interdependency-between-the-guard-and-module) + - [Deployment](#deployment) @@ -19,6 +22,11 @@ The Security Security Council uses a specially extended Safe multisig contract t any loss of access to a signer's keys is identified and addressed within a predictable period of time. +This mechanism is intended only to be used to remove signers who have lost access to their keys, or +are otherwise inactive. It is not intended to be used to remove signers who are acting in bad faith, +or any other subjective criteria, such cases should be addressed by governance, and the removal +handled via the standard Safe ownership management functionality. + ## Liveness checking methodology This is achieved using two types of contracts which the Safe contract has built-in support for: @@ -51,7 +59,8 @@ A `LivenessModule` is also created which does the following: ### Owner removal call flow -The following diagram illustrates the flow for removing a single owner. +The following diagram illustrates the flow for removing a single owner. The `verifyFinalState` +box indicates calls to the Safe which ensure the final state is valid. ```mermaid sequenceDiagram @@ -59,18 +68,21 @@ sequenceDiagram participant LivenessModule participant LivenessGuard participant Safe - User->>LivenessModule: removeOwner(owner) + User->>LivenessModule: removeOwners([previousOwner], [owner]) LivenessModule->>LivenessGuard: lastLive(owner) LivenessModule->>Safe: getOwners() - LivenessModule->>LivenessModule: get75PercentThreshold(numOwnersAfter) - LivenessModule->>LivenessModule: _getPrevOwner(owner, owners) - LivenessModule->>LivenessModule: _removeOwner(prevOwner, owner, thresholdAfter) - LivenessModule->>LivenessModule: _verifyFinalState() + LivenessModule->>Safe: removeOwner(previousOwner, owner) + + alt verifyFinalState + LivenessModule->>Safe: getOwners() + LivenessModule->>Safe: getThreshold() + LivenessModule->>Safe: getGuard() + end ``` ### Shutdown -In the unlikely event that the signer set (`N`) is reduced below 8, then (and only then) is a +In the unlikely event that the signer set (`N`) is reduced below the allowed threshold, then (and only then) is a shutdown mechanism activated which removes the existing signers, and hands control of the multisig over to a predetermined entity. @@ -79,13 +91,21 @@ In the unlikely event that the signer set (`N`) is reduced below 8, then (and on The following security properties must be upheld: 1. Signatures are assigned to the correct signer. -2. Non-signers are unable to create a record of having signed. -3. A signer cannot be censored or griefed such that their signing is not recorded. -4. Signers may demonstrate liveness either by signing a transaction or by calling directly to the +1. Non-signers are unable to create a record of having signed. +1. A signer cannot be censored or grieffed such that their signing is not recorded. +1. Signers may demonstrate liveness either by signing a transaction or by calling directly to the guard. -5. The module implements the correct checks prior to removing a signer. -6. The module sets the correct threshold upon removing a signer. -7. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1. +1. The module only removes a signer if they have demonstrated liveness during the interval, or + if necessary to convert the safe to a 1 of 1. +1. The module sets the correct 75% threshold upon removing a signer. +1. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1. + +### Interdependency between the Guard and Module + +The Guard has no dependency on the Module, and can be used independently to track liveness of +Safe owners. The Module however does have a dependency on the Guard, only one guard contract can +be set on the Safe, and the Module will be unable to function if the Guard is removed. + ### Deployment The module are guard are intended to be deployed and installed on the safe in the following sequence: From f7ecd62be397ccd4283a5f14bf0c73c8670ef8e2 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 09:54:25 -0400 Subject: [PATCH 184/374] codecov: Ignore all files in contracts-bedrock/test --- codecov.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/codecov.yml b/codecov.yml index 953756f48752..f64112c9cf1c 100644 --- a/codecov.yml +++ b/codecov.yml @@ -9,8 +9,9 @@ comment: ignore: - "op-e2e" - - "**/*.t.sol" - "op-bindings/bindings/*.go" + - "**/*.t.sol" + - "packages/contracts-bedrock/test/**/*.sol" - "packages/contracts-bedrock/contracts/vendor/WETH9.sol" - 'packages/contracts-bedrock/contracts/EAS/**/*.sol' coverage: From d52cc302125259a7676cc07d22dee25ccfa06029 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 11:01:49 -0400 Subject: [PATCH 185/374] test(ctb): Add Guard owner management tests --- .../test/LivenessGuard.t.sol | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 671a12bcb7ba..cf21c0f2f2ac 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -101,8 +101,6 @@ contract LivenessGuard_CheckAfterExecution_TestFails is LivenessGuard_TestInit { } } -contract LivenessGuard_CheckAfterExecution_Test is LivenessGuard_TestInit { } - contract LivenessGuard_ShowLiveness_TestFail is LivenessGuard_TestInit { /// @dev Tests that the showLiveness function reverts if the caller is not an owner function test_showLiveness_callIsNotSafeOwner_reverts() external { @@ -126,3 +124,39 @@ contract LivenessGuard_ShowLiveness_Test is LivenessGuard_TestInit { assertEq(livenessGuard.lastLive(caller), block.timestamp); } } + +contract LivenessGuard_OwnerManagement_Test is LivenessGuard_TestInit { + using SafeTestLib for SafeInstance; + + /// @dev Tests that the guard correctly deletes the owner from the lastLive mapping when it is removed + function test_removeOwner_succeeds() external { + address ownerToRemove = safeInstance.owners[0]; + assertGe(livenessGuard.lastLive(ownerToRemove), 0); + assertTrue(safeInstance.safe.isOwner(ownerToRemove)); + + safeInstance.execTransaction({ + to: address(safeInstance.safe), + value: 0, + data: abi.encodeWithSelector(OwnerManager.removeOwner.selector, SENTINEL_OWNERS, ownerToRemove, 1) + }); + + assertFalse(safeInstance.safe.isOwner(ownerToRemove)); + assertEq(livenessGuard.lastLive(ownerToRemove), 0); + } + + /// @dev Tests that the guard correctly adds an owner to the lastLive mapping when it is added + function test_addOwner_succeeds() external { + address ownerToAdd = makeAddr("new owner"); + assertEq(livenessGuard.lastLive(ownerToAdd), 0); + assertFalse(safeInstance.safe.isOwner(ownerToAdd)); + + safeInstance.execTransaction({ + to: address(safeInstance.safe), + value: 0, + data: abi.encodeWithSelector(OwnerManager.addOwnerWithThreshold.selector, ownerToAdd, 1) + }); + + assertTrue(safeInstance.safe.isOwner(ownerToAdd)); + assertEq(livenessGuard.lastLive(ownerToAdd), block.timestamp); + } +} From 30a444092c5905aebe512c2993b92a08103d30b3 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 11:17:12 -0400 Subject: [PATCH 186/374] safe-tools: Refactor getPrevOwner() into lib Also make lib functions internal which removes the deploy and linking with solidity libs. --- .../test/LivenessModule.t.sol | 21 +---------- .../test/safe-tools/SafeTestTools.sol | 37 ++++++++++++++----- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index a872b52e4c17..f4783dbb41d1 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -29,9 +29,6 @@ contract OwnerSimulator is OwnerManager { contract LivenessModule_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; - /// @dev The address of the first owner in the linked list of owners - address internal constant SENTINEL_OWNERS = address(0x1); - event SignersRecorded(bytes32 indexed txHash, address[] signers); uint256 initTime = 10; @@ -43,20 +40,6 @@ contract LivenessModule_TestInit is Test, SafeTestTools { OwnerSimulator ownerSimulator; address fallbackOwner; - /// @notice Get the previous owner in the linked list of owners - /// @param _owner The owner whose previous owner we want to find - /// @param _owners The list of owners - function _getPrevOwner(address _owner, address[] memory _owners) internal pure returns (address prevOwner_) { - for (uint256 i = 0; i < _owners.length; i++) { - if (_owners[i] != _owner) continue; - if (i == 0) { - prevOwner_ = SENTINEL_OWNERS; - break; - } - prevOwner_ = _owners[i - 1]; - } - } - /// @dev Given an array of owners to remove, this function will return an array of the previous owners /// in the order that they must be provided to the LivenessMoules's removeOwners() function. /// Because owners are removed one at a time, and not necessarily in order, we need to simulate @@ -68,7 +51,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { address[] memory currentOwners; for (uint256 i = 0; i < _ownersToRemove.length; i++) { currentOwners = ownerSimulator.getOwners(); - prevOwners_[i] = _getPrevOwner(safeInstance.owners[i], currentOwners); + prevOwners_[i] = SafeTestLib.getPrevOwner(safeInstance.owners[i], currentOwners); // Don't try to remove the last owner if (currentOwners.length == 1) break; @@ -81,7 +64,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { address[] memory prevOwners = new address[](1); address[] memory ownersToRemove = new address[](1); ownersToRemove[0] = _ownerToRemove; - prevOwners[0] = _getPrevOwner(_ownerToRemove, safeInstance.owners); + prevOwners[0] = SafeTestLib.getPrevOwner(_ownerToRemove, safeInstance.owners); livenessModule.removeOwners(prevOwners, ownersToRemove); } diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index acd5cacb0eef..0573a0a3f01f 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -15,6 +15,9 @@ import "./CompatibilityFallbackHandler_1_3_0.sol"; address constant VM_ADDR = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; bytes12 constant ADDR_MASK = 0xffffffffffffffffffffffff; +/// @dev The address of the first owner in the linked list of owners +address constant SENTINEL_OWNERS = address(0x1); + /// @dev Get the address from a private key function getAddr(uint256 pk) pure returns (address) { return Vm(VM_ADDR).addr(pk); @@ -145,7 +148,7 @@ library SafeTestLib { address refundReceiver, bytes memory signatures ) - public + internal returns (bool) { if (instance.owners.length == 0) { @@ -207,7 +210,7 @@ library SafeTestLib { bytes memory data, Enum.Operation operation ) - public + internal returns (bool) { return execTransaction(instance, to, value, data, operation, 0, 0, 0, address(0), address(0), ""); @@ -220,14 +223,14 @@ library SafeTestLib { uint256 value, bytes memory data ) - public + internal returns (bool) { return execTransaction(instance, to, value, data, Enum.Operation.Call, 0, 0, 0, address(0), address(0), ""); } /// @dev Enables a module on the Safe. - function enableModule(SafeInstance memory instance, address module) public { + function enableModule(SafeInstance memory instance, address module) internal { execTransaction( instance, address(instance.safe), @@ -244,7 +247,7 @@ library SafeTestLib { } /// @dev Disables a module on the Safe. - function disableModule(SafeInstance memory instance, address module) public { + function disableModule(SafeInstance memory instance, address module) internal { (address[] memory modules,) = instance.safe.getModulesPaginated(SENTINEL_MODULES, 1000); address prevModule = SENTINEL_MODULES; bool moduleFound; @@ -275,7 +278,7 @@ library SafeTestLib { /// @dev Sets the guard address on the Safe. Unlike modules there can only be one guard, so /// this method will remove the previous guard. If the guard is set to the 0 address, the /// guard will be disabled. - function setGuard(SafeInstance memory instance, address guard) public { + function setGuard(SafeInstance memory instance, address guard) internal { execTransaction( instance, address(instance.safe), @@ -292,7 +295,7 @@ library SafeTestLib { } /// @dev Signs message data using EIP1271: Standard Signature Validation Method for Contracts - function EIP1271Sign(SafeInstance memory instance, bytes memory data) public { + function EIP1271Sign(SafeInstance memory instance, bytes memory data) internal { address signMessageLib = address(new SignMessageLib()); execTransaction({ instance: instance, @@ -310,7 +313,7 @@ library SafeTestLib { } /// @dev Signs a data hash using EIP1271: Standard Signature Validation Method for Contracts - function EIP1271Sign(SafeInstance memory instance, bytes32 digest) public { + function EIP1271Sign(SafeInstance memory instance, bytes32 digest) internal { EIP1271Sign(instance, abi.encodePacked(digest)); } @@ -328,7 +331,7 @@ library SafeTestLib { address gasToken, address refundReceiver ) - public + internal view returns (uint8 v, bytes32 r, bytes32 s) { @@ -353,10 +356,24 @@ library SafeTestLib { } /// @dev Increments the nonce of the Safe by sending an empty transaction. - function incrementNonce(SafeInstance memory instance) public returns (uint256 newNonce) { + function incrementNonce(SafeInstance memory instance) internal returns (uint256 newNonce) { execTransaction(instance, address(0), 0, "", Enum.Operation.Call, 0, 0, 0, address(0), address(0), ""); return instance.safe.nonce(); } + + /// @notice Get the previous owner in the linked list of owners + /// @param _owner The owner whose previous owner we want to find + /// @param _owners The list of owners + function getPrevOwner(address _owner, address[] memory _owners) internal pure returns (address prevOwner_) { + for (uint256 i = 0; i < _owners.length; i++) { + if (_owners[i] != _owner) continue; + if (i == 0) { + prevOwner_ = SENTINEL_OWNERS; + break; + } + prevOwner_ = _owners[i - 1]; + } + } } /// @dev SafeTestTools implements a set of helper functions for testing Safe contracts. From 3787e706ef293ff21ef9094a9c8d511738331724 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 11:29:40 -0400 Subject: [PATCH 187/374] safe-tools: Refactor getPrevOwners (plural) into lib This also move the OwnerSimulator into the lib, which nicely abstracts that away. --- .../test/LivenessModule.t.sol | 45 +++---------------- .../test/safe-tools/SafeTestTools.sol | 44 +++++++++++++++++- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index f4783dbb41d1..0558bec70803 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -12,20 +12,6 @@ import "test/safe-tools/SafeTestTools.sol"; import { LivenessModule } from "src/Safe/LivenessModule.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; -/// @dev A minimal wrapper around the OwnerManager contract. This contract is meant to be initialized with -/// the same owners as a Safe instance, and then used to simulate the resulting owners list -/// after an owner is removed. -contract OwnerSimulator is OwnerManager { - constructor(address[] memory _owners, uint256 _threshold) { - setupOwners(_owners, _threshold); - } - - /// @dev Exposes the OwnerManager's removeOwner function so that anyone may call without needing auth - function removeOwnerWrapped(address prevOwner, address owner, uint256 _threshold) public { - OwnerManager(address(this)).removeOwner(prevOwner, owner, _threshold); - } -} - contract LivenessModule_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; @@ -37,28 +23,8 @@ contract LivenessModule_TestInit is Test, SafeTestTools { LivenessModule livenessModule; LivenessGuard livenessGuard; SafeInstance safeInstance; - OwnerSimulator ownerSimulator; address fallbackOwner; - /// @dev Given an array of owners to remove, this function will return an array of the previous owners - /// in the order that they must be provided to the LivenessMoules's removeOwners() function. - /// Because owners are removed one at a time, and not necessarily in order, we need to simulate - /// the owners list after each removal, in order to identify the correct previous owner. - /// @param _ownersToRemove The owners to remove - /// @return prevOwners_ The previous owners in the linked list - function _getPrevOwners(address[] memory _ownersToRemove) internal returns (address[] memory prevOwners_) { - prevOwners_ = new address[](_ownersToRemove.length); - address[] memory currentOwners; - for (uint256 i = 0; i < _ownersToRemove.length; i++) { - currentOwners = ownerSimulator.getOwners(); - prevOwners_[i] = SafeTestLib.getPrevOwner(safeInstance.owners[i], currentOwners); - - // Don't try to remove the last owner - if (currentOwners.length == 1) break; - ownerSimulator.removeOwnerWrapped(prevOwners_[i], _ownersToRemove[i], 1); - } - } - /// @dev Removes an owner from the safe function _removeAnOwner(address _ownerToRemove) internal { address[] memory prevOwners = new address[](1); @@ -78,7 +44,6 @@ contract LivenessModule_TestInit is Test, SafeTestTools { // Create a Safe with 10 owners (, uint256[] memory keys) = makeAddrsAndKeys(10); safeInstance = _setupSafe(keys, 8); - ownerSimulator = new OwnerSimulator(safeInstance.owners, 1); livenessGuard = new LivenessGuard(safeInstance.safe); fallbackOwner = makeAddr("fallbackOwner"); @@ -212,7 +177,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { for (uint256 i = 0; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } - address[] memory prevOwners = _getPrevOwners(ownersToRemove); + address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); // Incorrectly set the final owner to address(0) ownersToRemove[ownersToRemove.length - 1] = address(0); @@ -231,7 +196,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { for (uint256 i = 0; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } - address[] memory prevOwners = _getPrevOwners(ownersToRemove); + address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); vm.warp(block.timestamp + livenessInterval + 1); vm.expectRevert("LivenessModule: must transfer ownership to fallback owner"); @@ -243,7 +208,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { function test_removeOwners_guardChanged_reverts() external { address[] memory ownersToRemove = new address[](1); ownersToRemove[0] = safeInstance.owners[0]; - address[] memory prevOwners = _getPrevOwners(ownersToRemove); + address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); // Change the guard livenessGuard = new LivenessGuard(safeInstance.safe); @@ -270,7 +235,9 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { } contract LivenessModule_RemoveOwners_Test is LivenessModule_TestInit { + using SafeTestLib for SafeInstance; /// @dev Tests if removing one owner works correctly + function test_removeOwners_oneOwner_succeeds() external { uint256 ownersBefore = safeInstance.owners.length; address ownerToRemove = safeInstance.owners[0]; @@ -290,7 +257,7 @@ contract LivenessModule_RemoveOwners_Test is LivenessModule_TestInit { for (uint256 i = 0; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } - address[] memory prevOwners = _getPrevOwners(ownersToRemove); + address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); vm.warp(block.timestamp + livenessInterval + 1); livenessModule.removeOwners(prevOwners, ownersToRemove); diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 0573a0a3f01f..9b78ff7843d1 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -3,7 +3,7 @@ pragma solidity >=0.7.0 <0.9.0; import "forge-std/Test.sol"; import "scripts/libraries/LibSort.sol"; -import { ModuleManager, GuardManager, Safe as GnosisSafe } from "safe-contracts/Safe.sol"; +import { Safe as GnosisSafe, OwnerManager, ModuleManager, GuardManager } from "safe-contracts/Safe.sol"; import { SafeProxyFactory as GnosisSafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import { SignMessageLib } from "safe-contracts/libraries/SignMessageLib.sol"; @@ -110,7 +110,21 @@ function sortPKsByComputedAddress(uint256[] memory _pks) pure returns (uint256[] return sortedPKs; } -// collapsed interface that includes comapatibilityfallback handler calls +/// @dev A minimal wrapper around the OwnerManager contract. This contract is meant to be initialized with +/// the same owners as a Safe instance, and then used to simulate the resulting owners list +/// after an owner is removed. +contract OwnerSimulator is OwnerManager { + constructor(address[] memory _owners, uint256 _threshold) { + setupOwners(_owners, _threshold); + } + + /// @dev Exposes the OwnerManager's removeOwner function so that anyone may call without needing auth + function removeOwnerWrapped(address prevOwner, address owner, uint256 _threshold) public { + OwnerManager(address(this)).removeOwner(prevOwner, owner, _threshold); + } +} + +/// @dev collapsed interface that includes comapatibilityfallback handler calls abstract contract DeployedSafe is GnosisSafe, CompatibilityFallbackHandler { } struct AdvancedSafeInitParams { @@ -374,6 +388,32 @@ library SafeTestLib { prevOwner_ = _owners[i - 1]; } } + + /// @dev Given an array of owners to remove, this function will return an array of the previous owners + /// in the order that they must be provided to the LivenessMoules's removeOwners() function. + /// Because owners are removed one at a time, and not necessarily in order, we need to simulate + /// the owners list after each removal, in order to identify the correct previous owner. + /// @param _ownersToRemove The owners to remove + /// @return prevOwners_ The previous owners in the linked list + function getPrevOwners( + SafeInstance memory instance, + address[] memory _ownersToRemove + ) + internal + returns (address[] memory prevOwners_) + { + OwnerSimulator ownerSimulator = new OwnerSimulator(instance.owners, 1); + prevOwners_ = new address[](_ownersToRemove.length); + address[] memory currentOwners; + for (uint256 i = 0; i < _ownersToRemove.length; i++) { + currentOwners = ownerSimulator.getOwners(); + prevOwners_[i] = SafeTestLib.getPrevOwner(instance.owners[i], currentOwners); + + // Don't try to remove the last owner + if (currentOwners.length == 1) break; + ownerSimulator.removeOwnerWrapped(prevOwners_[i], _ownersToRemove[i], 1); + } + } } /// @dev SafeTestTools implements a set of helper functions for testing Safe contracts. From ab4a40cc8e12edeae68e32b7d641b13cc4681558 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 11:46:31 -0400 Subject: [PATCH 188/374] safe-tools: Refactor to move free functions into SafeTestLib --- .../test/LivenessGuard.t.sol | 2 +- .../test/LivenessModule.t.sol | 2 +- .../contracts-bedrock/test/SafeSigners.t.sol | 11 +- .../test/safe-tools/SafeTestTools.sol | 212 +++++++++--------- 4 files changed, 116 insertions(+), 111 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index cf21c0f2f2ac..679604b0db2f 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -137,7 +137,7 @@ contract LivenessGuard_OwnerManagement_Test is LivenessGuard_TestInit { safeInstance.execTransaction({ to: address(safeInstance.safe), value: 0, - data: abi.encodeWithSelector(OwnerManager.removeOwner.selector, SENTINEL_OWNERS, ownerToRemove, 1) + data: abi.encodeWithSelector(OwnerManager.removeOwner.selector, SafeTestLib.SENTINEL_OWNERS, ownerToRemove, 1) }); assertFalse(safeInstance.safe.isOwner(ownerToRemove)); diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 0558bec70803..718dffff06f3 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -42,7 +42,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { vm.warp(initTime); // Create a Safe with 10 owners - (, uint256[] memory keys) = makeAddrsAndKeys(10); + (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys(10); safeInstance = _setupSafe(keys, 8); livenessGuard = new LivenessGuard(safeInstance.safe); diff --git a/packages/contracts-bedrock/test/SafeSigners.t.sol b/packages/contracts-bedrock/test/SafeSigners.t.sol index 8ad92d09af65..ffada6c96e09 100644 --- a/packages/contracts-bedrock/test/SafeSigners.t.sol +++ b/packages/contracts-bedrock/test/SafeSigners.t.sol @@ -39,10 +39,11 @@ contract SafeSigners_Test is Test, SafeTestTools { // Limit the number of signatures to 25 uint256 numSigs = bound(_numSigs, 1, 25); - (, uint256[] memory keys) = makeAddrsAndKeys(numSigs); + (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys(numSigs); for (uint256 i = 0; i < keys.length; i++) { if (sigType(keys[i]) == SigTypes.Contract) { - keys[i] = encodeSmartContractWalletAsPK(decodeSmartContractWalletAsAddress(keys[i])); + keys[i] = + SafeTestLib.encodeSmartContractWalletAsPK(SafeTestLib.decodeSmartContractWalletAsAddress(keys[i])); } } @@ -66,15 +67,15 @@ contract SafeSigners_Test is Test, SafeTestTools { v += 4; signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); } else if (sigType(pks[i]) == SigTypes.ApprovedHash) { - vm.prank(getAddr(pks[i])); + vm.prank(SafeTestLib.getAddr(pks[i])); safeInstance.safe.approveHash(digest); v = 1; // s is not checked on approved hash signatures, so we can leave it as zero. - r = bytes32(uint256(uint160(getAddr(pks[i])))); + r = bytes32(uint256(uint160(SafeTestLib.getAddr(pks[i])))); signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); } else if (sigType(pks[i]) == SigTypes.Contract) { contractSigs++; - address addr = decodeSmartContractWalletAsAddress(pks[i]); + address addr = SafeTestLib.decodeSmartContractWalletAsAddress(pks[i]); r = bytes32(uint256(uint160(addr))); vm.mockCall( addr, abi.encodeWithSignature("isValidSignature(bytes,bytes)"), abi.encode(EIP1271_MAGIC_VALUE) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 9b78ff7843d1..c6935afe6d9c 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -11,104 +11,7 @@ import "./CompatibilityFallbackHandler_1_3_0.sol"; // Tools to simplify testing Safe contracts // Author: Colin Nielsen (https://github.com/colinnielsen/safe-tools) - -address constant VM_ADDR = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; -bytes12 constant ADDR_MASK = 0xffffffffffffffffffffffff; - -/// @dev The address of the first owner in the linked list of owners -address constant SENTINEL_OWNERS = address(0x1); - -/// @dev Get the address from a private key -function getAddr(uint256 pk) pure returns (address) { - return Vm(VM_ADDR).addr(pk); -} - -/// @dev Get arrays of addresses and private keys. The arrays are sorted by address, and the addresses are labelled -function makeAddrsAndKeys(uint256 num) returns (address[] memory addrs, uint256[] memory keys) { - keys = new uint256[](num); - addrs = new address[](num); - for (uint256 i; i < num; i++) { - uint256 key = uint256(keccak256(abi.encodePacked(i))); - keys[i] = key; - } - - for (uint256 i; i < num; i++) { - addrs[i] = Vm(VM_ADDR).addr(keys[i]); - Vm(VM_ADDR).label(getAddr(keys[i]), string.concat("SAFETEST: Signer ", string(abi.encodePacked(bytes32(i))))); - } -} - -/// @dev Encode a smart contract wallet as a private key -function encodeSmartContractWalletAsPK(address addr) pure returns (uint256 encodedPK) { - assembly { - let addr_b32 := addr - encodedPK := or(addr, ADDR_MASK) - } -} - -/// @dev Decode a smart contract wallet as an address from a private key -function decodeSmartContractWalletAsAddress(uint256 pk) pure returns (address decodedAddr) { - assembly { - let addr := shl(96, pk) - decodedAddr := shr(96, addr) - } -} - -/// @dev Checks if a private key is an encoded smart contract address -function isSmartContractPK(uint256 pk) pure returns (bool isEncoded) { - assembly { - isEncoded := eq(shr(160, pk), shr(160, ADDR_MASK)) - } -} - -library Sort { - /// @dev Sorts an array of addresses in place - function sort(address[] memory arr) public pure returns (address[] memory) { - LibSort.sort(arr); - return arr; - } -} - -/// @dev Sorts an array of private keys by the computed address -/// If the private key is a smart contract wallet, it will be decoded and sorted by the address -function sortPKsByComputedAddress(uint256[] memory _pks) pure returns (uint256[] memory) { - uint256[] memory sortedPKs = new uint256[](_pks.length); - - address[] memory addresses = new address[](_pks.length); - bytes32[2][] memory accounts = new bytes32[2][](_pks.length); - - for (uint256 i; i < _pks.length; i++) { - uint256 pk = _pks[i]; - address signer = getAddr(pk); - if (isSmartContractPK(pk)) { - signer = decodeSmartContractWalletAsAddress(pk); - } - addresses[i] = signer; - accounts[i][0] = bytes32(abi.encode(signer)); - accounts[i][1] = bytes32(pk); - } - - addresses = Sort.sort(addresses); - - uint256 found; - for (uint256 j; j < addresses.length; j++) { - address signer = addresses[j]; - uint256 pk; - for (uint256 k; k < accounts.length; k++) { - if (address(uint160(uint256(accounts[k][0]))) == signer) { - pk = uint256(accounts[k][1]); - found++; - } - } - - sortedPKs[j] = pk; - } - - if (found < _pks.length) { - revert("SAFETESTTOOLS: issue with private key sorting, please open a ticket on github"); - } - return sortedPKs; -} +// With expanded and improved functionality by OP Labs /// @dev A minimal wrapper around the OwnerManager contract. This contract is meant to be initialized with /// the same owners as a Safe instance, and then used to simulate the resulting owners list @@ -146,7 +49,108 @@ struct SafeInstance { DeployedSafe safe; } +library Sort { + /// @dev Sorts an array of addresses in place + function sort(address[] memory arr) public pure returns (address[] memory) { + LibSort.sort(arr); + return arr; + } +} + library SafeTestLib { + /// @dev The address of foundry's VM contract + address constant VM_ADDR = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; + /// @dev The address of the first owner in the linked list of owners + address constant SENTINEL_OWNERS = address(0x1); + + /// @dev Get the address from a private key + function getAddr(uint256 pk) internal pure returns (address) { + return Vm(VM_ADDR).addr(pk); + } + + /// @dev Get arrays of addresses and private keys. The arrays are sorted by address, and the addresses are labelled + function makeAddrsAndKeys(uint256 num) internal returns (address[] memory addrs, uint256[] memory keys) { + keys = new uint256[](num); + addrs = new address[](num); + for (uint256 i; i < num; i++) { + uint256 key = uint256(keccak256(abi.encodePacked(i))); + keys[i] = key; + } + + for (uint256 i; i < num; i++) { + addrs[i] = Vm(VM_ADDR).addr(keys[i]); + Vm(VM_ADDR).label( + getAddr(keys[i]), string.concat("SAFETEST: Signer ", string(abi.encodePacked(bytes32(i)))) + ); + } + } + + bytes12 constant ADDR_MASK = 0xffffffffffffffffffffffff; + + /// @dev Encode a smart contract wallet as a private key + function encodeSmartContractWalletAsPK(address addr) internal pure returns (uint256 encodedPK) { + assembly { + let addr_b32 := addr + encodedPK := or(addr, ADDR_MASK) + } + } + + /// @dev Decode a smart contract wallet as an address from a private key + function decodeSmartContractWalletAsAddress(uint256 pk) internal pure returns (address decodedAddr) { + assembly { + let addr := shl(96, pk) + decodedAddr := shr(96, addr) + } + } + + /// @dev Checks if a private key is an encoded smart contract address + function isSmartContractPK(uint256 pk) internal pure returns (bool isEncoded) { + assembly { + isEncoded := eq(shr(160, pk), shr(160, ADDR_MASK)) + } + } + + /// @dev Sorts an array of private keys by the computed address + /// If the private key is a smart contract wallet, it will be decoded and sorted by the address + function sortPKsByComputedAddress(uint256[] memory _pks) internal pure returns (uint256[] memory) { + uint256[] memory sortedPKs = new uint256[](_pks.length); + + address[] memory addresses = new address[](_pks.length); + bytes32[2][] memory accounts = new bytes32[2][](_pks.length); + + for (uint256 i; i < _pks.length; i++) { + uint256 pk = _pks[i]; + address signer = SafeTestLib.getAddr(pk); + if (isSmartContractPK(pk)) { + signer = decodeSmartContractWalletAsAddress(pk); + } + addresses[i] = signer; + accounts[i][0] = bytes32(abi.encode(signer)); + accounts[i][1] = bytes32(pk); + } + + addresses = Sort.sort(addresses); + + uint256 found; + for (uint256 j; j < addresses.length; j++) { + address signer = addresses[j]; + uint256 pk; + for (uint256 k; k < accounts.length; k++) { + if (address(uint160(uint256(accounts[k][0]))) == signer) { + pk = uint256(accounts[k][1]); + found++; + } + } + + sortedPKs[j] = pk; + } + + if (found < _pks.length) { + revert("SAFETESTTOOLS: issue with private key sorting, please open a ticket on github"); + } + return sortedPKs; + } + /// @dev A wrapper for the full execTransaction method, if no signatures are provided it will /// generate them for all owners. function execTransaction( @@ -442,14 +446,14 @@ contract SafeTestTools { public returns (SafeInstance memory) { - uint256[] memory sortedPKs = sortPKsByComputedAddress(ownerPKs); + uint256[] memory sortedPKs = SafeTestLib.sortPKsByComputedAddress(ownerPKs); address[] memory owners = new address[](sortedPKs.length); for (uint256 i; i < sortedPKs.length; i++) { - if (isSmartContractPK(sortedPKs[i])) { - owners[i] = decodeSmartContractWalletAsAddress(sortedPKs[i]); + if (SafeTestLib.isSmartContractPK(sortedPKs[i])) { + owners[i] = SafeTestLib.decodeSmartContractWalletAsAddress(sortedPKs[i]); } else { - owners[i] = getAddr(sortedPKs[i]); + owners[i] = SafeTestLib.getAddr(sortedPKs[i]); } } // store the initialization parameters @@ -482,7 +486,7 @@ contract SafeTestTools { }); instances.push(instance0); - Vm(VM_ADDR).deal(address(safe0), initialBalance); + Vm(SafeTestLib.VM_ADDR).deal(address(safe0), initialBalance); return instance0; } @@ -531,7 +535,7 @@ contract SafeTestTools { } function _setupSafe() public returns (SafeInstance memory) { - (, uint256[] memory defaultPKs) = makeAddrsAndKeys(3); + (, uint256[] memory defaultPKs) = SafeTestLib.makeAddrsAndKeys(3); return _setupSafe( defaultPKs, From beba38d5a77b738bb4ff531a48426db19589bb8c Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 12:11:09 -0400 Subject: [PATCH 189/374] safe-tools: Reorder functions in SafeTestLib Moving the multiple overriden execTransaction calls to the end is more readable. The other write operations are also now grouped together. --- .../test/safe-tools/SafeTestTools.sol | 208 +++++++++--------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index c6935afe6d9c..9a5196f5791c 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -151,10 +151,10 @@ library SafeTestLib { return sortedPKs; } - /// @dev A wrapper for the full execTransaction method, if no signatures are provided it will - /// generate them for all owners. - function execTransaction( + /// @dev Sign a transaction as a safe owner with a private key. + function signTransaction( SafeInstance memory instance, + uint256 pk, address to, uint256 value, bytes memory data, @@ -163,20 +163,16 @@ library SafeTestLib { uint256 baseGas, uint256 gasPrice, address gasToken, - address refundReceiver, - bytes memory signatures + address refundReceiver ) internal - returns (bool) + view + returns (uint8 v, bytes32 r, bytes32 s) { - if (instance.owners.length == 0) { - revert("SAFETEST: Instance not initialized. Call _setupSafe() to initialize a test safe"); - } - - bytes32 safeTxHash; + bytes32 txDataHash; { uint256 _nonce = instance.safe.nonce(); - safeTxHash = instance.safe.getTransactionHash({ + txDataHash = instance.safe.getTransactionHash({ to: to, value: value, data: data, @@ -190,61 +186,47 @@ library SafeTestLib { }); } - if (signatures.length == 0) { - for (uint256 i; i < instance.ownerPKs.length; ++i) { - uint256 pk = instance.ownerPKs[i]; - (uint8 v, bytes32 r, bytes32 s) = Vm(VM_ADDR).sign(pk, safeTxHash); - if (isSmartContractPK(pk)) { - v = 0; - address addr = decodeSmartContractWalletAsAddress(pk); - assembly { - r := addr - } - console.logBytes32(r); - } - signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); + (v, r, s) = Vm(VM_ADDR).sign(pk, txDataHash); + } + + /// @notice Get the previous owner in the linked list of owners + /// @param _owner The owner whose previous owner we want to find + /// @param _owners The list of owners + function getPrevOwner(address _owner, address[] memory _owners) internal pure returns (address prevOwner_) { + for (uint256 i = 0; i < _owners.length; i++) { + if (_owners[i] != _owner) continue; + if (i == 0) { + prevOwner_ = SENTINEL_OWNERS; + break; } + prevOwner_ = _owners[i - 1]; } - - return instance.safe.execTransaction({ - to: to, - value: value, - data: data, - operation: operation, - safeTxGas: safeTxGas, - baseGas: baseGas, - gasPrice: gasPrice, - gasToken: gasToken, - refundReceiver: payable(refundReceiver), - signatures: signatures - }); } - /// @dev Executes either a CALL or DELEGATECALL transaction. - function execTransaction( + /// @dev Given an array of owners to remove, this function will return an array of the previous owners + /// in the order that they must be provided to the LivenessMoules's removeOwners() function. + /// Because owners are removed one at a time, and not necessarily in order, we need to simulate + /// the owners list after each removal, in order to identify the correct previous owner. + /// @param _ownersToRemove The owners to remove + /// @return prevOwners_ The previous owners in the linked list + function getPrevOwners( SafeInstance memory instance, - address to, - uint256 value, - bytes memory data, - Enum.Operation operation + address[] memory _ownersToRemove ) internal - returns (bool) + returns (address[] memory prevOwners_) { - return execTransaction(instance, to, value, data, operation, 0, 0, 0, address(0), address(0), ""); - } + OwnerSimulator ownerSimulator = new OwnerSimulator(instance.owners, 1); + prevOwners_ = new address[](_ownersToRemove.length); + address[] memory currentOwners; + for (uint256 i = 0; i < _ownersToRemove.length; i++) { + currentOwners = ownerSimulator.getOwners(); + prevOwners_[i] = SafeTestLib.getPrevOwner(instance.owners[i], currentOwners); - /// @dev Executes a CALL transaction. - function execTransaction( - SafeInstance memory instance, - address to, - uint256 value, - bytes memory data - ) - internal - returns (bool) - { - return execTransaction(instance, to, value, data, Enum.Operation.Call, 0, 0, 0, address(0), address(0), ""); + // Don't try to remove the last owner + if (currentOwners.length == 1) break; + ownerSimulator.removeOwnerWrapped(prevOwners_[i], _ownersToRemove[i], 1); + } } /// @dev Enables a module on the Safe. @@ -335,10 +317,16 @@ library SafeTestLib { EIP1271Sign(instance, abi.encodePacked(digest)); } - /// @dev Sign a transaction as a safe owner with a private key. - function signTransaction( + /// @dev Increments the nonce of the Safe by sending an empty transaction. + function incrementNonce(SafeInstance memory instance) internal returns (uint256 newNonce) { + execTransaction(instance, address(0), 0, "", Enum.Operation.Call, 0, 0, 0, address(0), address(0), ""); + return instance.safe.nonce(); + } + + /// @dev A wrapper for the full execTransaction method, if no signatures are provided it will + /// generate them for all owners. + function execTransaction( SafeInstance memory instance, - uint256 pk, address to, uint256 value, bytes memory data, @@ -347,16 +335,20 @@ library SafeTestLib { uint256 baseGas, uint256 gasPrice, address gasToken, - address refundReceiver + address refundReceiver, + bytes memory signatures ) internal - view - returns (uint8 v, bytes32 r, bytes32 s) + returns (bool) { - bytes32 txDataHash; + if (instance.owners.length == 0) { + revert("SAFETEST: Instance not initialized. Call _setupSafe() to initialize a test safe"); + } + + bytes32 safeTxHash; { uint256 _nonce = instance.safe.nonce(); - txDataHash = instance.safe.getTransactionHash({ + safeTxHash = instance.safe.getTransactionHash({ to: to, value: value, data: data, @@ -370,53 +362,61 @@ library SafeTestLib { }); } - (v, r, s) = Vm(VM_ADDR).sign(pk, txDataHash); - } - - /// @dev Increments the nonce of the Safe by sending an empty transaction. - function incrementNonce(SafeInstance memory instance) internal returns (uint256 newNonce) { - execTransaction(instance, address(0), 0, "", Enum.Operation.Call, 0, 0, 0, address(0), address(0), ""); - return instance.safe.nonce(); - } - - /// @notice Get the previous owner in the linked list of owners - /// @param _owner The owner whose previous owner we want to find - /// @param _owners The list of owners - function getPrevOwner(address _owner, address[] memory _owners) internal pure returns (address prevOwner_) { - for (uint256 i = 0; i < _owners.length; i++) { - if (_owners[i] != _owner) continue; - if (i == 0) { - prevOwner_ = SENTINEL_OWNERS; - break; + if (signatures.length == 0) { + for (uint256 i; i < instance.ownerPKs.length; ++i) { + uint256 pk = instance.ownerPKs[i]; + (uint8 v, bytes32 r, bytes32 s) = Vm(VM_ADDR).sign(pk, safeTxHash); + if (isSmartContractPK(pk)) { + v = 0; + address addr = decodeSmartContractWalletAsAddress(pk); + assembly { + r := addr + } + console.logBytes32(r); + } + signatures = bytes.concat(signatures, abi.encodePacked(r, s, v)); } - prevOwner_ = _owners[i - 1]; } + + return instance.safe.execTransaction({ + to: to, + value: value, + data: data, + operation: operation, + safeTxGas: safeTxGas, + baseGas: baseGas, + gasPrice: gasPrice, + gasToken: gasToken, + refundReceiver: payable(refundReceiver), + signatures: signatures + }); } - /// @dev Given an array of owners to remove, this function will return an array of the previous owners - /// in the order that they must be provided to the LivenessMoules's removeOwners() function. - /// Because owners are removed one at a time, and not necessarily in order, we need to simulate - /// the owners list after each removal, in order to identify the correct previous owner. - /// @param _ownersToRemove The owners to remove - /// @return prevOwners_ The previous owners in the linked list - function getPrevOwners( + /// @dev Executes either a CALL or DELEGATECALL transaction. + function execTransaction( SafeInstance memory instance, - address[] memory _ownersToRemove + address to, + uint256 value, + bytes memory data, + Enum.Operation operation ) internal - returns (address[] memory prevOwners_) + returns (bool) { - OwnerSimulator ownerSimulator = new OwnerSimulator(instance.owners, 1); - prevOwners_ = new address[](_ownersToRemove.length); - address[] memory currentOwners; - for (uint256 i = 0; i < _ownersToRemove.length; i++) { - currentOwners = ownerSimulator.getOwners(); - prevOwners_[i] = SafeTestLib.getPrevOwner(instance.owners[i], currentOwners); + return execTransaction(instance, to, value, data, operation, 0, 0, 0, address(0), address(0), ""); + } - // Don't try to remove the last owner - if (currentOwners.length == 1) break; - ownerSimulator.removeOwnerWrapped(prevOwners_[i], _ownersToRemove[i], 1); - } + /// @dev Executes a CALL transaction. + function execTransaction( + SafeInstance memory instance, + address to, + uint256 value, + bytes memory data + ) + internal + returns (bool) + { + return execTransaction(instance, to, value, data, Enum.Operation.Call, 0, 0, 0, address(0), address(0), ""); } } From e3ac8519d18dce177a961587e0365422bc943b4c Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 12:30:19 -0400 Subject: [PATCH 190/374] safe-tools: Add owner management methods to SafeTestLib Can now easily add, remove and swap owners. Previous owner identification is handled automatically if not specified. This allows for testing errors by specifying an incorrect prevOwner. --- .../test/safe-tools/SafeTestTools.sol | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 9a5196f5791c..a2dd7bde841c 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -323,6 +323,40 @@ library SafeTestLib { return instance.safe.nonce(); } + /// @dev Adds a new owner to the safe + function addOwnerWithThreshold(SafeInstance memory instance, address owner, uint256 threshold) internal { + execTransaction( + instance, + address(instance.safe), + 0, + abi.encodeWithSelector(OwnerManager.addOwnerWithThreshold.selector, owner, threshold) + ); + } + + /// @dev Removes an owner from the safe. If not provided explictly, the identification of the prevOwner is handled + /// automatically. + function removeOwner(SafeInstance memory instance, address prevOwner, address owner, uint256 threshold) internal { + prevOwner = prevOwner > address(0) ? prevOwner : SafeTestLib.getPrevOwner(owner, instance.owners); + execTransaction( + instance, + address(instance.safe), + 0, + abi.encodeWithSelector(OwnerManager.removeOwner.selector, prevOwner, owner, threshold) + ); + } + + /// @dev Replaces an old owner with a new owner. If not provided explictly, the identification of the prevOwner is + /// handled automatically. + function swapOwner(SafeInstance memory instance, address prevOwner, address oldOwner, address newOwner) internal { + prevOwner = prevOwner > address(0) ? prevOwner : SafeTestLib.getPrevOwner(oldOwner, instance.owners); + execTransaction( + instance, + address(instance.safe), + 0, + abi.encodeWithSelector(OwnerManager.swapOwner.selector, prevOwner, oldOwner, newOwner) + ); + } + /// @dev A wrapper for the full execTransaction method, if no signatures are provided it will /// generate them for all owners. function execTransaction( From 2f3965fcb8f36d984aacc1ef5f819c4478fff3c4 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 12:33:18 -0400 Subject: [PATCH 191/374] test(ctb): Refactor tests to use owner management lib utils --- .../test/LivenessGuard.t.sol | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 679604b0db2f..66cdc4189774 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -134,11 +134,7 @@ contract LivenessGuard_OwnerManagement_Test is LivenessGuard_TestInit { assertGe(livenessGuard.lastLive(ownerToRemove), 0); assertTrue(safeInstance.safe.isOwner(ownerToRemove)); - safeInstance.execTransaction({ - to: address(safeInstance.safe), - value: 0, - data: abi.encodeWithSelector(OwnerManager.removeOwner.selector, SafeTestLib.SENTINEL_OWNERS, ownerToRemove, 1) - }); + safeInstance.removeOwner({ prevOwner: address(0), owner: ownerToRemove, threshold: 1 }); assertFalse(safeInstance.safe.isOwner(ownerToRemove)); assertEq(livenessGuard.lastLive(ownerToRemove), 0); @@ -150,11 +146,26 @@ contract LivenessGuard_OwnerManagement_Test is LivenessGuard_TestInit { assertEq(livenessGuard.lastLive(ownerToAdd), 0); assertFalse(safeInstance.safe.isOwner(ownerToAdd)); - safeInstance.execTransaction({ - to: address(safeInstance.safe), - value: 0, - data: abi.encodeWithSelector(OwnerManager.addOwnerWithThreshold.selector, ownerToAdd, 1) - }); + safeInstance.addOwnerWithThreshold({ owner: ownerToAdd, threshold: 1 }); + + assertTrue(safeInstance.safe.isOwner(ownerToAdd)); + assertEq(livenessGuard.lastLive(ownerToAdd), block.timestamp); + } + + /// @dev Tests that the guard correctly adds an owner to the lastLive mapping when it is added + function test_swapOwner_succeeds() external { + address ownerToRemove = safeInstance.owners[0]; + assertGe(livenessGuard.lastLive(ownerToRemove), 0); + assertTrue(safeInstance.safe.isOwner(ownerToRemove)); + + address ownerToAdd = makeAddr("new owner"); + assertEq(livenessGuard.lastLive(ownerToAdd), 0); + assertFalse(safeInstance.safe.isOwner(ownerToAdd)); + + safeInstance.swapOwner({ prevOwner: address(0), oldOwner: ownerToRemove, newOwner: ownerToAdd }); + + assertFalse(safeInstance.safe.isOwner(ownerToRemove)); + assertEq(livenessGuard.lastLive(ownerToRemove), 0); assertTrue(safeInstance.safe.isOwner(ownerToAdd)); assertEq(livenessGuard.lastLive(ownerToAdd), block.timestamp); From 41c9a3d4b768fc306ffe9c24355c512c91457679 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 13:56:32 -0400 Subject: [PATCH 192/374] refactor(ctb): Simplify require statements by nesting in an if() Rather than using an OR clause we put them inside an if statement. This allows us to clarify the error message and is more testable. --- .../src/Safe/LivenessModule.sol | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index ed4f5d579de5..1f5857f63861 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -74,10 +74,10 @@ contract LivenessModule is ISemver { uint256 ownersCount = SAFE.getOwners().length; for (uint256 i = 0; i < _previousOwners.length; i++) { ownersCount--; - require( - ownersCount < MIN_OWNERS || _canRemove(_ownersToRemove[i]), - "LivenessModule: the safe still has sufficient owners, or the owner to remove has signed recently" - ); + if (ownersCount >= MIN_OWNERS) { + require(_canRemove(_ownersToRemove[i]), "LivenessModule: the owner to remove has signed recently"); + } + _removeOwner({ _prevOwner: _previousOwners[i], _ownerToRemove: _ownersToRemove[i], @@ -154,10 +154,14 @@ contract LivenessModule is ISemver { address[] memory owners = SAFE.getOwners(); uint256 numOwners = owners.length; // Ensure that the safe is not being left in an unsafe state with too few owners. - require( - numOwners >= MIN_OWNERS || (numOwners == 1 && owners[0] == FALLBACK_OWNER), - "LivenessModule: Safe must have the minimum number of owners or be owned solely by the fallback owner" - ); + if (numOwners == 1) { + require(owners[0] == FALLBACK_OWNER, "LivenessModule: must transfer ownership to fallback owner"); + } else { + require( + numOwners >= MIN_OWNERS, + "LivenessModule: must remove all owners and transfer to fallback owner if numOwners < minOwners" + ); + } // Check that the threshold is correct. This check is also correct when there is a single // owner, because get75PercentThreshold(1) returns 1. From 71bb67b5b6c772acea4ed90ddd1677df2446519a Mon Sep 17 00:00:00 2001 From: Maurelian Date: Thu, 26 Oct 2023 21:33:21 -0400 Subject: [PATCH 193/374] feat: Address feedback --- .../src/Safe/LivenessGuard.sol | 31 ++++++++++--------- .../src/Safe/LivenessModule.sol | 20 ++++-------- .../test/LivenessGuard.t.sol | 6 ++-- specs/safe-liveness-checking.md | 5 +-- 4 files changed, 28 insertions(+), 34 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index 97ced936b42f..a39c80551a81 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -23,7 +23,7 @@ contract LivenessGuard is ISemver, BaseGuard { /// @notice Emitted when an owner is recorded. /// @param owner The owner's address. - event OwnerRecorded(bytes32 indexed txHash, address owner); + event OwnerRecorded(address owner); /// @notice Semantic version. /// @custom:semver 1.0.0 @@ -49,12 +49,18 @@ contract LivenessGuard is ISemver, BaseGuard { for (uint256 i = 0; i < owners.length; i++) { address owner = owners[i]; lastLive[owner] = block.timestamp; - emit OwnerRecorded(0x0, owner); + emit OwnerRecorded(owner); } } + /// @notice Getter function for the Safe contract instance + /// @return safe_ The Safe contract instance + function safe() public view returns (Safe safe_) { + safe_ = SAFE; + } + /// @notice Internal function to ensure that only the Safe can call certain functions. - function _onlySafe() internal view { + function _requireOnlySafe() internal view { require(msg.sender == address(SAFE), "LivenessGuard: only Safe can call this function"); } @@ -76,7 +82,7 @@ contract LivenessGuard is ISemver, BaseGuard { external { msgSender; // silence unused variable warning - _onlySafe(); + _requireOnlySafe(); // Cache the set of owners prior to execution. // This will be used in the checkAfterExecution method. @@ -88,7 +94,7 @@ contract LivenessGuard is ISemver, BaseGuard { // This call will reenter to the Safe which is calling it. This is OK because it is only reading the // nonce, and using the getTransactionHash() method. - bytes32 txHash = Safe(payable(msg.sender)).getTransactionHash({ + bytes32 txHash = SAFE.getTransactionHash({ to: to, value: value, data: data, @@ -98,7 +104,7 @@ contract LivenessGuard is ISemver, BaseGuard { gasPrice: gasPrice, gasToken: gasToken, refundReceiver: refundReceiver, - _nonce: Safe(payable(msg.sender)).nonce() - 1 + _nonce: SAFE.nonce() - 1 }); uint256 threshold = SAFE.getThreshold(); @@ -107,7 +113,7 @@ contract LivenessGuard is ISemver, BaseGuard { for (uint256 i = 0; i < signers.length; i++) { lastLive[signers[i]] = block.timestamp; - emit OwnerRecorded(txHash, signers[i]); + emit OwnerRecorded(signers[i]); } } @@ -118,7 +124,7 @@ contract LivenessGuard is ISemver, BaseGuard { /// 1. Add new owners to the lastLive mapping /// 2. Delete removed owners from the lastLive mapping function checkAfterExecution(bytes32, bool) external { - _onlySafe(); + _requireOnlySafe(); // Get the current set of owners address[] memory ownersAfter = SAFE.getOwners(); @@ -132,6 +138,7 @@ contract LivenessGuard is ISemver, BaseGuard { lastLive[ownerAfter] = block.timestamp; } } + // Now iterate over the remaining ownersBefore entries. Any remaining addresses are no longer an owner, so we // delete them from the lastLive mapping. uint256 ownersBeforeLength = ownersBefore.length(); @@ -147,12 +154,6 @@ contract LivenessGuard is ISemver, BaseGuard { require(SAFE.isOwner(msg.sender), "LivenessGuard: only Safe owners may demonstrate liveness"); lastLive[msg.sender] = block.timestamp; - emit OwnerRecorded(0x0, msg.sender); - } - - /// @notice Getter function for the Safe contract instance - /// @return safe_ The Safe contract instance - function safe() public view returns (Safe safe_) { - safe_ = SAFE; + emit OwnerRecorded(msg.sender); } } diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 1f5857f63861..225d306250f5 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -55,7 +55,7 @@ contract LivenessModule is ISemver { FALLBACK_OWNER = _fallbackOwner; MIN_OWNERS = _minOwners; address[] memory owners = _safe.getOwners(); - require(_minOwners < owners.length, "LivenessModule: minOwners must be less than the number of owners"); + require(_minOwners <= owners.length, "LivenessModule: minOwners must be less than the number of owners"); require( _safe.getThreshold() == get75PercentThreshold(owners.length), "LivenessModule: Safe must have a threshold of 75% of the number of owners" @@ -70,7 +70,7 @@ contract LivenessModule is ISemver { function removeOwners(address[] memory _previousOwners, address[] memory _ownersToRemove) external { require(_previousOwners.length == _ownersToRemove.length, "LivenessModule: arrays must be the same length"); - // We will remove at least one owner, so we'll initialize the newOwners count to the current number of owners + // We will remove at least one owner, so we'll initialize the ownersCount count to the current number of owners uint256 ownersCount = SAFE.getOwners().length; for (uint256 i = 0; i < _previousOwners.length; i++) { ownersCount--; @@ -81,8 +81,7 @@ contract LivenessModule is ISemver { _removeOwner({ _prevOwner: _previousOwners[i], _ownerToRemove: _ownersToRemove[i], - _newOwnersCount: ownersCount, - _newThreshold: get75PercentThreshold(ownersCount) + _newOwnersCount: ownersCount }); } _verifyFinalState(); @@ -92,18 +91,11 @@ contract LivenessModule is ISemver { /// @param _prevOwner Owner that pointed to the owner to be removed in the linked list /// @param _ownerToRemove Owner address to be removed. /// @param _newOwnersCount New number of owners after removal. - /// @param _newThreshold New threshold. - function _removeOwner( - address _prevOwner, - address _ownerToRemove, - uint256 _newOwnersCount, - uint256 _newThreshold - ) - internal - { + function _removeOwner(address _prevOwner, address _ownerToRemove, uint256 _newOwnersCount) internal { if (_newOwnersCount > 0) { + uint256 newThreshold = get75PercentThreshold(_newOwnersCount); // Remove the owner and update the threshold - _removeOwnerSafeCall({ _prevOwner: _prevOwner, _owner: _ownerToRemove, _threshold: _newThreshold }); + _removeOwnerSafeCall({ _prevOwner: _prevOwner, _owner: _ownerToRemove, _threshold: newThreshold }); } else { // There is only one owner left. The Safe will not allow a safe with no owners, so we will // need to swap owners instead. diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 66cdc4189774..191efc144013 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -13,7 +13,7 @@ import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; contract LivenessGuard_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; - event OwnerRecorded(bytes32 indexed txHash, address signer); + event OwnerRecorded(address owner); uint256 initTime = 10; LivenessGuard livenessGuard; @@ -81,7 +81,7 @@ contract LivenessGuard_CheckTx_Test is LivenessGuard_TestInit { for (uint256 i; i < signers.length; i++) { // Don't check topic1 so that we can avoid the ugly txHash calculation. vm.expectEmit(false, true, true, true, address(livenessGuard)); - emit OwnerRecorded(0x0, signers[i]); + emit OwnerRecorded(signers[i]); } vm.expectCall(address(safeInstance.safe), abi.encodeWithSignature("nonce()")); vm.expectCall(address(safeInstance.safe), abi.encodeCall(OwnerManager.getThreshold, ())); @@ -116,7 +116,7 @@ contract LivenessGuard_ShowLiveness_Test is LivenessGuard_TestInit { address caller = safeInstance.owners[0]; vm.expectEmit(address(livenessGuard)); - emit OwnerRecorded(0x0, caller); + emit OwnerRecorded(caller); vm.prank(caller); livenessGuard.showLiveness(); diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md index aa28ea2d10d1..604df07bc678 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/safe-liveness-checking.md @@ -92,13 +92,14 @@ The following security properties must be upheld: 1. Signatures are assigned to the correct signer. 1. Non-signers are unable to create a record of having signed. -1. A signer cannot be censored or grieffed such that their signing is not recorded. +1. A signer cannot be censored or griefed such that their signing is not recorded. 1. Signers may demonstrate liveness either by signing a transaction or by calling directly to the guard. 1. The module only removes a signer if they have demonstrated liveness during the interval, or if necessary to convert the safe to a 1 of 1. 1. The module sets the correct 75% threshold upon removing a signer. 1. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1. +1. It must be impossible for the guard's checkTransaction or checkAfterExecution to permanently revert given any calldata and the current state. ### Interdependency between the Guard and Module @@ -108,7 +109,7 @@ be set on the Safe, and the Module will be unable to function if the Guard is re ### Deployment -The module are guard are intended to be deployed and installed on the safe in the following sequence: +The module and guard are intended to be deployed and installed on the safe in the following sequence: 1. Deploy the guard contract, this will set a timestamp for each existing owner on the Safe. 1. Deploy the module. From d925a353f5f7e3691fd94e4b97cfb739384b7ef3 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 00:40:03 -0400 Subject: [PATCH 194/374] safe-tools: Fix address label string concatenation --- packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index a2dd7bde841c..cb8c82137d10 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -79,9 +79,7 @@ library SafeTestLib { for (uint256 i; i < num; i++) { addrs[i] = Vm(VM_ADDR).addr(keys[i]); - Vm(VM_ADDR).label( - getAddr(keys[i]), string.concat("SAFETEST: Signer ", string(abi.encodePacked(bytes32(i)))) - ); + Vm(VM_ADDR).label(getAddr(keys[i]), string.concat("SAFETEST: Signer ", Vm(VM_ADDR).toString(i))); } } From 2469eb3a52b85f1c8889f35c6af592e0157e8a92 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 00:44:01 -0400 Subject: [PATCH 195/374] safe-tools: Break up getPrevOwner() into multiple functions A new pure function getPrevOwnerFromList() accepts a list to search in, this avoids making an extra call which breaks expectRevert tests. --- .../test/LivenessModule.t.sol | 16 ++++--- .../test/safe-tools/SafeTestTools.sol | 43 +++++++++++++++---- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 718dffff06f3..9cac377a5188 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -26,11 +26,11 @@ contract LivenessModule_TestInit is Test, SafeTestTools { address fallbackOwner; /// @dev Removes an owner from the safe - function _removeAnOwner(address _ownerToRemove) internal { + function _removeAnOwner(address _ownerToRemove, address[] memory _owners) internal { address[] memory prevOwners = new address[](1); address[] memory ownersToRemove = new address[](1); ownersToRemove[0] = _ownerToRemove; - prevOwners[0] = SafeTestLib.getPrevOwner(_ownerToRemove, safeInstance.owners); + prevOwners[0] = SafeTestLib.getPrevOwnerFromList(_ownerToRemove, _owners); livenessModule.removeOwners(prevOwners, ownersToRemove); } @@ -141,20 +141,22 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { /// @dev Test removing an owner which has recently signed a transaction function test_removeOwners_ownerHasSignedRecently_reverts() external { /// Will sign a transaction with the first M owners in the owners list - vm.warp(block.timestamp + livenessInterval); safeInstance.execTransaction({ to: address(1111), value: 0, data: hex"abba" }); + + address[] memory owners = safeInstance.safe.getOwners(); + vm.expectRevert("LivenessModule: the owner to remove has signed recently"); - _removeAnOwner(safeInstance.owners[0]); + _removeAnOwner(safeInstance.owners[0], owners); } /// @dev Test removing an owner which has recently called showLiveness function test_removeOwners_ownerHasShownLivenessRecently_reverts() external { /// Will sign a transaction with the first M owners in the owners list - vm.warp(block.timestamp + livenessInterval); vm.prank(safeInstance.owners[0]); livenessGuard.showLiveness(); + address[] memory owners = safeInstance.safe.getOwners(); vm.expectRevert("LivenessModule: the owner to remove has signed recently"); - _removeAnOwner(safeInstance.owners[0]); + _removeAnOwner(safeInstance.owners[0], owners); } /// @dev Test removing an owner with an incorrect previous owner @@ -243,7 +245,7 @@ contract LivenessModule_RemoveOwners_Test is LivenessModule_TestInit { address ownerToRemove = safeInstance.owners[0]; vm.warp(block.timestamp + livenessInterval + 1); - _removeAnOwner(ownerToRemove); + _removeAnOwner(ownerToRemove, safeInstance.owners); assertFalse(safeInstance.safe.isOwner(ownerToRemove)); assertEq(safeInstance.safe.getOwners().length, ownersBefore - 1); diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index cb8c82137d10..76af3b6c6dc1 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -187,17 +187,42 @@ library SafeTestLib { (v, r, s) = Vm(VM_ADDR).sign(pk, txDataHash); } - /// @notice Get the previous owner in the linked list of owners + /// @dev Get the previous owner in the linked list of owners. + /// This version of getPrevOwner will call to the Safe contract to get the current list of owners. + /// Note that this will break vm.expectRevert() tests by making a call which does not revert.. /// @param _owner The owner whose previous owner we want to find - /// @param _owners The list of owners - function getPrevOwner(address _owner, address[] memory _owners) internal pure returns (address prevOwner_) { - for (uint256 i = 0; i < _owners.length; i++) { - if (_owners[i] != _owner) continue; + function getPrevOwner(SafeInstance memory instance, address _owner) internal view returns (address prevOwner_) { + address[] memory owners = instance.safe.getOwners(); + for (uint256 i = 0; i < owners.length; i++) { + if (owners[i] != _owner) continue; if (i == 0) { prevOwner_ = SENTINEL_OWNERS; break; } - prevOwner_ = _owners[i - 1]; + prevOwner_ = owners[i - 1]; + } + } + + /// @dev Get the previous owner in the provided list of owners. + /// This version of getPrevOwner accepts a list of owners, and will return the previous owner. + /// It is useful when testing for a revert, as it avoids the need to call to the Safe contract. + /// @param _owner The owner whose previous owner we want to find + /// @param _ownersList The list of owners to search in + function getPrevOwnerFromList( + address _owner, + address[] memory _ownersList + ) + internal + pure + returns (address prevOwner_) + { + for (uint256 i = 0; i < _ownersList.length; i++) { + if (_ownersList[i] != _owner) continue; + if (i == 0) { + prevOwner_ = SENTINEL_OWNERS; + break; + } + prevOwner_ = _ownersList[i - 1]; } } @@ -219,7 +244,7 @@ library SafeTestLib { address[] memory currentOwners; for (uint256 i = 0; i < _ownersToRemove.length; i++) { currentOwners = ownerSimulator.getOwners(); - prevOwners_[i] = SafeTestLib.getPrevOwner(instance.owners[i], currentOwners); + prevOwners_[i] = SafeTestLib.getPrevOwnerFromList(instance.owners[i], currentOwners); // Don't try to remove the last owner if (currentOwners.length == 1) break; @@ -334,7 +359,7 @@ library SafeTestLib { /// @dev Removes an owner from the safe. If not provided explictly, the identification of the prevOwner is handled /// automatically. function removeOwner(SafeInstance memory instance, address prevOwner, address owner, uint256 threshold) internal { - prevOwner = prevOwner > address(0) ? prevOwner : SafeTestLib.getPrevOwner(owner, instance.owners); + prevOwner = prevOwner > address(0) ? prevOwner : SafeTestLib.getPrevOwner(instance, owner); execTransaction( instance, address(instance.safe), @@ -346,7 +371,7 @@ library SafeTestLib { /// @dev Replaces an old owner with a new owner. If not provided explictly, the identification of the prevOwner is /// handled automatically. function swapOwner(SafeInstance memory instance, address prevOwner, address oldOwner, address newOwner) internal { - prevOwner = prevOwner > address(0) ? prevOwner : SafeTestLib.getPrevOwner(oldOwner, instance.owners); + prevOwner = prevOwner > address(0) ? prevOwner : SafeTestLib.getPrevOwner(instance, oldOwner); execTransaction( instance, address(instance.safe), From 30377e223d609520e0a668e5971ae72a6cb9cff9 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 09:12:38 -0400 Subject: [PATCH 196/374] refactor(ctb): Move getters to just after constructor --- .../src/Safe/LivenessModule.sol | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 225d306250f5..a8c4f136d0c8 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -62,6 +62,42 @@ contract LivenessModule is ISemver { ); } + /// @notice For a given number of owners, return the lowest threshold which is greater than 75. + /// Note: this function returns 1 for numOwners == 1. + function get75PercentThreshold(uint256 _numOwners) public pure returns (uint256 threshold_) { + threshold_ = (_numOwners * 75 + 99) / 100; + } + + /// @notice Getter function for the Safe contract instance + /// @return safe_ The Safe contract instance + function safe() public view returns (Safe safe_) { + safe_ = SAFE; + } + + /// @notice Getter function for the LivenessGuard contract instance + /// @return livenessGuard_ The LivenessGuard contract instance + function livenessGuard() public view returns (LivenessGuard livenessGuard_) { + livenessGuard_ = LIVENESS_GUARD; + } + + /// @notice Getter function for the liveness interval + /// @return livenessInterval_ The liveness interval, in seconds + function livenessInterval() public view returns (uint256 livenessInterval_) { + livenessInterval_ = LIVENESS_INTERVAL; + } + + /// @notice Getter function for the minimum number of owners + /// @return minOwners_ The minimum number of owners + function minOwners() public view returns (uint256 minOwners_) { + minOwners_ = MIN_OWNERS; + } + + /// @notice Getter function for the fallback owner + /// @return fallbackOwner_ The fallback owner of the Safe + function fallbackOwner() public view returns (address fallbackOwner_) { + fallbackOwner_ = FALLBACK_OWNER; + } + /// @notice This function can be called by anyone to remove a set of owners that have not signed a transaction /// during the liveness interval. If the number of owners drops below the minimum, then all owners /// must be removed. @@ -169,40 +205,4 @@ contract LivenessModule is ISemver { "LivenessModule: guard has been changed" ); } - - /// @notice For a given number of owners, return the lowest threshold which is greater than 75. - /// Note: this function returns 1 for numOwners == 1. - function get75PercentThreshold(uint256 _numOwners) public pure returns (uint256 threshold_) { - threshold_ = (_numOwners * 75 + 99) / 100; - } - - /// @notice Getter function for the Safe contract instance - /// @return safe_ The Safe contract instance - function safe() public view returns (Safe safe_) { - safe_ = SAFE; - } - - /// @notice Getter function for the LivenessGuard contract instance - /// @return livenessGuard_ The LivenessGuard contract instance - function livenessGuard() public view returns (LivenessGuard livenessGuard_) { - livenessGuard_ = LIVENESS_GUARD; - } - - /// @notice Getter function for the liveness interval - /// @return livenessInterval_ The liveness interval, in seconds - function livenessInterval() public view returns (uint256 livenessInterval_) { - livenessInterval_ = LIVENESS_INTERVAL; - } - - /// @notice Getter function for the minimum number of owners - /// @return minOwners_ The minimum number of owners - function minOwners() public view returns (uint256 minOwners_) { - minOwners_ = MIN_OWNERS; - } - - /// @notice Getter function for the fallback owner - /// @return fallbackOwner_ The fallback owner of the Safe - function fallbackOwner() public view returns (address fallbackOwner_) { - fallbackOwner_ = FALLBACK_OWNER; - } } From 7b5dfee97f2e791d40a37a6b481de8e25a7e2249 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 09:24:49 -0400 Subject: [PATCH 197/374] docs(ctb): Improved comments in SafeSigners.sol --- packages/contracts-bedrock/src/Safe/SafeSigners.sol | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/SafeSigners.sol b/packages/contracts-bedrock/src/Safe/SafeSigners.sol index f0ad74fc67ed..32e65913dda5 100644 --- a/packages/contracts-bedrock/src/Safe/SafeSigners.sol +++ b/packages/contracts-bedrock/src/Safe/SafeSigners.sol @@ -38,10 +38,11 @@ library SafeSigners { } /// @notice Extract the signers from a set of signatures. - /// @param dataHash Hash of the data. - /// @param signatures Signature data for identifying signers. - /// @param requiredSignatures Amount of required valid signatures. - /// @return _owners List of unique signers. + /// This method is based closely on the code in the Safe.checkNSignatures() method. + /// https://github.com/safe-global/safe-contracts/blob/e870f514ad34cd9654c72174d6d4a839e3c6639f/contracts/Safe.sol#L274 + /// It has been modified by removing all signature _validation_ code. We trust the Safe to properly validate + /// the signatures. + /// This method therefore simply extracts the addresses from the signatures. function getNSigners( bytes32 dataHash, bytes memory signatures, @@ -53,10 +54,6 @@ library SafeSigners { { _owners = new address[](requiredSignatures); - // The following code is extracted from the Safe.checkNSignatures() method. It removes the signature - // validation code, and keeps only the parsing code necessary to extract the owner addresses from the - // signatures. We do not double check if the owner derived from a signature is valid. As this is handled - // in the final require statement of Safe.checkNSignatures(). address currentOwner; uint8 v; bytes32 r; From a2b4bae02b8190efd6f1ef68aac4df3d83151d5b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 09:39:01 -0400 Subject: [PATCH 198/374] specs: Document deployment and updating of the liveness checking system --- specs/safe-liveness-checking.md | 50 +++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md index 604df07bc678..f1313fa7ccca 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/safe-liveness-checking.md @@ -11,7 +11,7 @@ - [Owner removal call flow](#owner-removal-call-flow) - [Shutdown](#shutdown) - [Security Properties](#security-properties) - - [Interdependency between the Guard and Module](#interdependency-between-the-guard-and-module) + - [Interdependency between the guard and module](#interdependency-between-the-guard-and-module) - [Deployment](#deployment) @@ -48,7 +48,7 @@ Signers may also call the contract's `showLiveness()()` method directly in order A `LivenessModule` is also created which does the following: -1. Has a function `removeOwner()` that anyone may call to specify an owner to be removed from the +1. Has a function `removeOwners()` that anyone may call to specify one or more owners to be removed from the Safe. 1. The Module would then check the `LivenessGuard.lastLive()` to determine if the signer is eligible for removal. @@ -99,22 +99,50 @@ The following security properties must be upheld: if necessary to convert the safe to a 1 of 1. 1. The module sets the correct 75% threshold upon removing a signer. 1. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1. -1. It must be impossible for the guard's checkTransaction or checkAfterExecution to permanently revert given any calldata and the current state. +1. It must be impossible for the guard's checkTransaction or checkAfterExecution to permanently + revert given any calldata and the current state. -### Interdependency between the Guard and Module +### Interdependency between the guard and module -The Guard has no dependency on the Module, and can be used independently to track liveness of -Safe owners. The Module however does have a dependency on the Guard, only one guard contract can -be set on the Safe, and the Module will be unable to function if the Guard is removed. +The guard has no dependency on the module, and can be used independently to track liveness of +Safe owners. -### Deployment +This means that the module can be removed or replaced without any affect on the guard. -The module and guard are intended to be deployed and installed on the safe in the following sequence: +The module however does have a dependency on the guard; if the guard is removed from the Safe, then +the module will no longer be functional and calls to its `removeOwners` function will revert. -1. Deploy the guard contract, this will set a timestamp for each existing owner on the Safe. +### Deploying the liveness checking system + +[deploying]: #deploying-the-liveness-checking-system + +The module and guard are intended to be deployed and installed on the safe in the following +sequence: + +1. Deploy the guard contract + 2. The guard's constructor will read the Safe's owners and set a timestamp 1. Deploy the module. -1. Enable the module on the safe. 1. Set the guard on the safe. +1. Enable the module on the safe. This order of operations is necessary to satisfy the constructor checks in the module, and is intended to prevent owners from being immediately removable. + +### Modify the liveness checking system + +Changes to the liveness checking system should be done in the following manner: + +#### Replacing the module + +The module can safely be removed without affecting the operation of the guard. A new module can then +be added. + +#### Replacing the guard + +The safe can only have one guard contract at a time, and if the guard is removed the module will +cease to function. This does not affect the ability of the Safe to operate normally, however the +module should be removed as a best practice. + +If a new guard is added, eg. as a means of upgrading it, then a new module will also need to be +deployed and enabled. Once both the guard and module have been removed, they can be replaced +according to the steps in the [Deployment][deploying] section above. From f2cf018e6504ed2214a7c15bbfee9782f78dcaac Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 11:06:27 -0400 Subject: [PATCH 199/374] refactor(ctb): Extract module tests vm.warp into _warpPastLivenesInterval --- .../test/LivenessModule.t.sol | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 9cac377a5188..71734cd9a80d 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -35,6 +35,11 @@ contract LivenessModule_TestInit is Test, SafeTestTools { livenessModule.removeOwners(prevOwners, ownersToRemove); } + /// @dev Set the current time to after the liveness interval + function _warpPastLivenessInterval() internal { + vm.warp(initTime + livenessInterval + 1); + } + /// @dev Sets up the test environment function setUp() public { // Set the block timestamp to the initTime, so that signatures recorded in the first block @@ -166,7 +171,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { ownersToRemove[0] = safeInstance.owners[0]; prevOwners[0] = ownersToRemove[0]; // incorrect. - vm.warp(block.timestamp + livenessInterval + 1); + _warpPastLivenessInterval(); vm.expectRevert("LivenessModule: failed to remove owner"); livenessModule.removeOwners(prevOwners, ownersToRemove); } @@ -184,7 +189,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { // Incorrectly set the final owner to address(0) ownersToRemove[ownersToRemove.length - 1] = address(0); - vm.warp(block.timestamp + livenessInterval + 1); + _warpPastLivenessInterval(); vm.expectRevert("LivenessModule: failed to swap to fallback owner"); livenessModule.removeOwners(prevOwners, ownersToRemove); } @@ -200,7 +205,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { } address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); - vm.warp(block.timestamp + livenessInterval + 1); + _warpPastLivenessInterval(); vm.expectRevert("LivenessModule: must transfer ownership to fallback owner"); livenessModule.removeOwners(prevOwners, ownersToRemove); } @@ -216,7 +221,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { livenessGuard = new LivenessGuard(safeInstance.safe); safeInstance.setGuard(address(livenessGuard)); - vm.warp(block.timestamp + livenessInterval + 1); + _warpPastLivenessInterval(); vm.expectRevert("LivenessModule: guard has been changed"); livenessModule.removeOwners(prevOwners, ownersToRemove); } @@ -230,7 +235,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { address(safeInstance.safe), abi.encodeCall(OwnerManager.getThreshold, ()), abi.encode(wrongThreshold) ); - vm.warp(block.timestamp + livenessInterval + 1); + _warpPastLivenessInterval(); vm.expectRevert("LivenessModule: Safe must have a threshold of 75% of the number of owners"); livenessModule.removeOwners(prevOwners, ownersToRemove); } @@ -244,7 +249,7 @@ contract LivenessModule_RemoveOwners_Test is LivenessModule_TestInit { uint256 ownersBefore = safeInstance.owners.length; address ownerToRemove = safeInstance.owners[0]; - vm.warp(block.timestamp + livenessInterval + 1); + _warpPastLivenessInterval(); _removeAnOwner(ownerToRemove, safeInstance.owners); assertFalse(safeInstance.safe.isOwner(ownerToRemove)); @@ -261,7 +266,7 @@ contract LivenessModule_RemoveOwners_Test is LivenessModule_TestInit { } address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); - vm.warp(block.timestamp + livenessInterval + 1); + _warpPastLivenessInterval(); livenessModule.removeOwners(prevOwners, ownersToRemove); assertEq(safeInstance.safe.getOwners().length, 1); assertEq(safeInstance.safe.getOwners()[0], fallbackOwner); From 24e9a030224f6c7c23a50fb2d2f61c84125a46a3 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 11:07:03 -0400 Subject: [PATCH 200/374] refactor(ctb): Make canRemove a public function --- .../src/Safe/LivenessModule.sol | 17 +++++++++-------- .../test/LivenessModule.t.sol | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index a8c4f136d0c8..66d802306adb 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -98,6 +98,14 @@ contract LivenessModule is ISemver { fallbackOwner_ = FALLBACK_OWNER; } + /// @notice Checks if the owner can be removed + /// @param _owner The owner to be removed + /// @return canRemove_ bool indicating if the owner can be removed + function canRemove(address _owner) public view returns (bool canRemove_) { + require(SAFE.isOwner(_owner), "LivenessModule: the owner to remove must be an owner of the Safe"); + canRemove_ = LIVENESS_GUARD.lastLive(_owner) + LIVENESS_INTERVAL < block.timestamp; + } + /// @notice This function can be called by anyone to remove a set of owners that have not signed a transaction /// during the liveness interval. If the number of owners drops below the minimum, then all owners /// must be removed. @@ -111,7 +119,7 @@ contract LivenessModule is ISemver { for (uint256 i = 0; i < _previousOwners.length; i++) { ownersCount--; if (ownersCount >= MIN_OWNERS) { - require(_canRemove(_ownersToRemove[i]), "LivenessModule: the owner to remove has signed recently"); + require(canRemove(_ownersToRemove[i]), "LivenessModule: the owner to remove has signed recently"); } _removeOwner({ @@ -170,13 +178,6 @@ contract LivenessModule is ISemver { ); } - /// @notice Checks if the owner can be removed - /// @param _owner The owner to be removed - /// @return canRemove_ bool indicating if the owner can be removed - function _canRemove(address _owner) internal view returns (bool canRemove_) { - canRemove_ = LIVENESS_GUARD.lastLive(_owner) + LIVENESS_INTERVAL < block.timestamp; - } - /// @notice A FREI-PI invariant check enforcing requirements on number of owners and threshold. function _verifyFinalState() internal view { address[] memory owners = SAFE.getOwners(); diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 71734cd9a80d..de0cb36d85c5 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -105,6 +105,24 @@ contract LivenessModule_Getters_Test is LivenessModule_TestInit { } } +contract LivenessModule_CanRemove_TestFail is LivenessModule_TestInit { + /// @dev Tests if canRemove work correctly + function test_canRemove_notSafeOwner_reverts() external { + address nonOwner = makeAddr("nonOwner"); + vm.expectRevert("LivenessModule: the owner to remove must be an owner of the Safe"); + livenessModule.canRemove(nonOwner); + } +} + +contract LivenessModule_CanRemove_Test is LivenessModule_TestInit { + /// @dev Tests if canRemove work correctly + function test_canRemove_works() external { + _warpPastLivenessInterval(); + bool canRemove = livenessModule.canRemove(safeInstance.owners[0]); + assertTrue(canRemove); + } +} + contract LivenessModule_Get75PercentThreshold_Test is LivenessModule_TestInit { /// @dev check the return values of the get75PercentThreshold function against manually /// calculated values. From 81a8c1042e23014fedfb850e8a2dbd17e5b5cd4f Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 11:26:08 -0400 Subject: [PATCH 201/374] refactor(ctb): Standardize on not caching the length in a for-loop --- packages/contracts-bedrock/.gas-snapshot | 39 +++++++++++-------- .../src/Safe/LivenessGuard.sol | 7 ++-- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 3c874406e284..c5315d9f1633 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -306,26 +306,31 @@ LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10755) LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34524) LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689) LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8553) -LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 234784) -LivenessGuard_CheckTx_TestFails:test_checkTransaction_callerIsNotSafe_revert() (gas: 10343) -LivenessGuard_Constructor_Test:test_constructor_works() (gas: 1163577) +LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 228306) +LivenessGuard_CheckTx_TestFails:test_checkTransaction_callerIsNotSafe_revert() (gas: 10380) +LivenessGuard_Constructor_Test:test_constructor_works() (gas: 1174506) LivenessGuard_Getters_Test:test_getters_works() (gas: 10662) -LivenessGuard_ShowLiveness_Test:test_showLiveness_succeeds() (gas: 29584) +LivenessGuard_OwnerManagement_Test:test_addOwner_succeeds() (gas: 272723) +LivenessGuard_OwnerManagement_Test:test_removeOwner_succeeds() (gas: 241108) +LivenessGuard_OwnerManagement_Test:test_swapOwner_succeeds() (gas: 279720) +LivenessGuard_ShowLiveness_Test:test_showLiveness_succeeds() (gas: 28831) LivenessGuard_ShowLiveness_TestFail:test_showLiveness_callIsNotSafeOwner_reverts() (gas: 18770) -LivenessModule_Constructor_Test:test_constructor_minOwnersGreaterThanOwners_reverts() (gas: 83531) -LivenessModule_Constructor_Test:test_constructor_wrongThreshold_reverts() (gas: 92808) +LivenessModule_CanRemove_Test:test_canRemove_works() (gas: 33026) +LivenessModule_CanRemove_TestFail:test_canRemove_notSafeOwner_reverts() (gas: 20489) +LivenessModule_Constructor_Test:test_constructor_minOwnersGreaterThanOwners_reverts() (gas: 83623) +LivenessModule_Constructor_Test:test_constructor_wrongThreshold_reverts() (gas: 92901) LivenessModule_Get75PercentThreshold_Test:test_get75PercentThreshold_Works() (gas: 26339) -LivenessModule_Getters_Test:test_getters_works() (gas: 14807) -LivenessModule_RemoveOwners_Test:test_removeOwners_allOwners_succeeds() (gas: 346743) -LivenessModule_RemoveOwners_Test:test_removeOwners_oneOwner_succeeds() (gas: 127161) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowMinButNotEmptied_reverts() (gas: 301067) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_differentArrayLengths_reverts() (gas: 10536) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_guardChanged_reverts() (gas: 1741747) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_invalidThreshold_reverts() (gas: 67238) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRecently_reverts() (gas: 91661) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 638440) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallBackOwner_reverts() (gas: 310105) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 70465) +LivenessModule_Getters_Test:test_getters_works() (gas: 14853) +LivenessModule_RemoveOwners_Test:test_removeOwners_allOwners_succeeds() (gas: 1311942) +LivenessModule_RemoveOwners_Test:test_removeOwners_oneOwner_succeeds() (gas: 130731) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowMinButNotEmptied_reverts() (gas: 1265044) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_differentArrayLengths_reverts() (gas: 10547) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_guardChanged_reverts() (gas: 2820629) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_invalidThreshold_reverts() (gas: 69358) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRecently_reverts() (gas: 77817) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 614867) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallBackOwner_reverts() (gas: 1273705) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954) MIPS_Test:test_add_succeeds() (gas: 122932) MIPS_Test:test_addiSign_succeeds() (gas: 122923) MIPS_Test:test_addi_succeeds() (gas: 123120) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index a39c80551a81..ce77c33982d5 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -87,8 +87,7 @@ contract LivenessGuard is ISemver, BaseGuard { // Cache the set of owners prior to execution. // This will be used in the checkAfterExecution method. address[] memory owners = SAFE.getOwners(); - uint256 ownersLength = owners.length; - for (uint256 i = 0; i < ownersLength; i++) { + for (uint256 i = 0; i < owners.length; i++) { ownersBefore.add(owners[i]); } @@ -141,8 +140,8 @@ contract LivenessGuard is ISemver, BaseGuard { // Now iterate over the remaining ownersBefore entries. Any remaining addresses are no longer an owner, so we // delete them from the lastLive mapping. - uint256 ownersBeforeLength = ownersBefore.length(); - for (uint256 i = 0; i < ownersBeforeLength; i++) { + // uint256 ownersBeforeLength = ownersBefore.length(); + for (uint256 i = 0; i < ownersBefore.length(); i++) { address ownerBefore = ownersBefore.at(i); delete lastLive[ownerBefore]; } From ec882b185f12ab76ed2444faf3515cab6d49d44e Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 11:48:33 -0400 Subject: [PATCH 202/374] refactor(ctb): Fix placement of ownersCount Also adds comments to clarify the logic. --- .../src/Safe/LivenessModule.sol | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 66d802306adb..44c2f1c63d35 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -114,19 +114,37 @@ contract LivenessModule is ISemver { function removeOwners(address[] memory _previousOwners, address[] memory _ownersToRemove) external { require(_previousOwners.length == _ownersToRemove.length, "LivenessModule: arrays must be the same length"); - // We will remove at least one owner, so we'll initialize the ownersCount count to the current number of owners + // Initialize the ownersCount count to the current number of owners, so that we can track the number of + // owners in the Safe after each removal. The Safe will revert if an owner cannot be removed, so it is safe + // keep a local count of the number of owners this way. uint256 ownersCount = SAFE.getOwners().length; for (uint256 i = 0; i < _previousOwners.length; i++) { - ownersCount--; + // Validate that the owner can be removed, which means that either: + // 1. the ownersCount is now less than MIN_OWNERS, in which case all owners should be removed regardless + // of liveness, + // 2. the owner has not signed a transaction during the liveness interval. if (ownersCount >= MIN_OWNERS) { require(canRemove(_ownersToRemove[i]), "LivenessModule: the owner to remove has signed recently"); } + // Pre-emptively update our local count of the number of owners. + // This is safe because _removeOwner will bubble up any revert from the Safe if the owner cannot be removed. + ownersCount--; + + // We now attempt remove the owner from the safe. _removeOwner({ _prevOwner: _previousOwners[i], _ownerToRemove: _ownersToRemove[i], _newOwnersCount: ownersCount }); + + // when all owners are removed and the sole owner is the fallback owner, the + // ownersCount variable will be incorrectly set to zero. + // This reflects the fact that all prior owners have been removed. The loop should naturally exit at this + // point, but for safety we detect this condition and force the loop to terminate. + if (ownersCount == 0) { + break; + } } _verifyFinalState(); } @@ -182,7 +200,10 @@ contract LivenessModule is ISemver { function _verifyFinalState() internal view { address[] memory owners = SAFE.getOwners(); uint256 numOwners = owners.length; - // Ensure that the safe is not being left in an unsafe state with too few owners. + + // Ensure that the safe is not being left in a safe state such that either: + // 1. there are at least the minimum number of owners, or + // 2. there is a single owner and that owner is the fallback owner. if (numOwners == 1) { require(owners[0] == FALLBACK_OWNER, "LivenessModule: must transfer ownership to fallback owner"); } else { From d1f965f9738cfb148941979ebd258ae858618bef Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 12:15:27 -0400 Subject: [PATCH 203/374] fix(ctb): Remove remaining entries from ownersBefore --- packages/contracts-bedrock/src/Safe/LivenessGuard.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index ce77c33982d5..b6a0bd3d6fd2 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -144,6 +144,7 @@ contract LivenessGuard is ISemver, BaseGuard { for (uint256 i = 0; i < ownersBefore.length(); i++) { address ownerBefore = ownersBefore.at(i); delete lastLive[ownerBefore]; + ownersBefore.remove(ownerBefore); } } From d759e6ff7c000b50cd96513ef485eefc8968041e Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 12:18:40 -0400 Subject: [PATCH 204/374] fix(ctb): Module constructor allows higher than minimum threshold in Safe Loosening this requirement should provide added flexibility when setting up the liveness system --- packages/contracts-bedrock/src/Safe/LivenessModule.sol | 4 ++-- packages/contracts-bedrock/test/LivenessModule.t.sol | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 44c2f1c63d35..6f26b0eb12e9 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -57,8 +57,8 @@ contract LivenessModule is ISemver { address[] memory owners = _safe.getOwners(); require(_minOwners <= owners.length, "LivenessModule: minOwners must be less than the number of owners"); require( - _safe.getThreshold() == get75PercentThreshold(owners.length), - "LivenessModule: Safe must have a threshold of 75% of the number of owners" + _safe.getThreshold() >= get75PercentThreshold(owners.length), + "LivenessModule: Safe must have a threshold of at least 75% of the number of owners" ); } diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index de0cb36d85c5..2c01806f2e31 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -64,7 +64,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { } } -contract LivenessModule_Constructor_Test is LivenessModule_TestInit { +contract LivenessModule_Constructor_TestFail is LivenessModule_TestInit { /// @dev Tests that the constructor fails if the minOwners is greater than the number of owners function test_constructor_minOwnersGreaterThanOwners_reverts() external { vm.expectRevert("LivenessModule: minOwners must be less than the number of owners"); @@ -79,11 +79,11 @@ contract LivenessModule_Constructor_Test is LivenessModule_TestInit { /// @dev Tests that the constructor fails if the minOwners is greater than the number of owners function test_constructor_wrongThreshold_reverts() external { - uint256 wrongThreshold = livenessModule.get75PercentThreshold(safeInstance.owners.length) + 1; + uint256 wrongThreshold = livenessModule.get75PercentThreshold(safeInstance.owners.length) - 1; vm.mockCall( address(safeInstance.safe), abi.encodeCall(OwnerManager.getThreshold, ()), abi.encode(wrongThreshold) ); - vm.expectRevert("LivenessModule: Safe must have a threshold of 75% of the number of owners"); + vm.expectRevert("LivenessModule: Safe must have a threshold of at least 75% of the number of owners"); new LivenessModule({ _safe: safeInstance.safe, _livenessGuard: livenessGuard, From 8fd7b65e0c749055402bb07105f627f45ff393a9 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 12:58:02 -0400 Subject: [PATCH 205/374] specs: Document deployment and updating of liveness module --- specs/safe-liveness-checking.md | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md index f1313fa7ccca..25068268372b 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/safe-liveness-checking.md @@ -4,19 +4,22 @@ **Table of Contents** -- [Liveness Checking Mechanism](#liveness-checking-mechanism) +- [Liveness checking Mechanism](#liveness-checking-mechanism) - [Liveness checking methodology](#liveness-checking-methodology) - - [The Liveness Guard](#the-liveness-guard) - - [The Liveness Module](#the-liveness-module) + - [The liveness guard](#the-liveness-guard) + - [The liveness module](#the-liveness-module) - [Owner removal call flow](#owner-removal-call-flow) - [Shutdown](#shutdown) - [Security Properties](#security-properties) - [Interdependency between the guard and module](#interdependency-between-the-guard-and-module) - - [Deployment](#deployment) + - [Deploying the liveness checking system](#deploying-the-liveness-checking-system) + - [Modify the liveness checking system](#modify-the-liveness-checking-system) + - [Replacing the module](#replacing-the-module) + - [Replacing the guard](#replacing-the-guard) -## Liveness Checking Mechanism +## Liveness checking Mechanism The Security Security Council uses a specially extended Safe multisig contract to ensure that any loss of access to a signer's keys is identified and addressed within a predictable period of @@ -36,7 +39,7 @@ This is achieved using two types of contracts which the Safe contract has built- authorized to execute transactions via the Safe. This means the module must properly implement auth conditions internally. -### The Liveness Guard +### The liveness guard For implementing liveness checks a `LivenessGuard` is created which receives the signatures from each executed transaction, and tracks the latest time at which a transaction was signed by each @@ -44,7 +47,7 @@ signer. This time is made publicly available by calling a `lastLive(address)(Tim Signers may also call the contract's `showLiveness()()` method directly in order to prove liveness. -### The Liveness Module +### The liveness module A `LivenessModule` is also created which does the following: @@ -102,6 +105,10 @@ The following security properties must be upheld: 1. It must be impossible for the guard's checkTransaction or checkAfterExecution to permanently revert given any calldata and the current state. +Note: neither the module nor guard attempt to prevent a quorum of owners from removing either the liveness +module or guard. There are legitimate reasons they might wish to do so. Moreover, if such a quorum +of owners exists, there is no benefit to removing them, as they are defacto 'sufficiently live'. + ### Interdependency between the guard and module The guard has no dependency on the module, and can be used independently to track liveness of @@ -128,6 +135,10 @@ sequence: This order of operations is necessary to satisfy the constructor checks in the module, and is intended to prevent owners from being immediately removable. +Note that changes to the owners set should not be made between the time the module is deployed, and +when it is enabled on the Safe, otherwise the checks made in the module's constructor may be +invalidated. If such changes are made, a new module should be deployed. + ### Modify the liveness checking system Changes to the liveness checking system should be done in the following manner: @@ -137,6 +148,9 @@ Changes to the liveness checking system should be done in the following manner: The module can safely be removed without affecting the operation of the guard. A new module can then be added. +Note: none of the module's parameters are modifiable. In order to update the security properties +enforced by the module, it must be replaced. + #### Replacing the guard The safe can only have one guard contract at a time, and if the guard is removed the module will From ba0c2ac9556e99347a603c1ff54093ca827247e6 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 00:53:04 -0400 Subject: [PATCH 206/374] test(ctb): Add multi-step add/remove/swap test fix guard? temp: add commented out assertions in multistep test test(ctb): Add pre-checks to owner management fuzz test test(ctb): Add WrappedGuard to expose the ownersBefore set --- .../src/Safe/LivenessGuard.sol | 12 +- .../test/LivenessGuard.t.sol | 150 +++++++++++++++++- .../test/LivenessModule.t.sol | 2 +- 3 files changed, 154 insertions(+), 10 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol index b6a0bd3d6fd2..ae2c5145514b 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessGuard.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessGuard.sol @@ -39,7 +39,7 @@ contract LivenessGuard is ISemver, BaseGuard { /// @notice An enumerable set of addresses used to store the list of owners before execution, /// and then to update the lastLive mapping according to changes in the set observed /// after execution. - EnumerableSet.AddressSet private ownersBefore; + EnumerableSet.AddressSet internal ownersBefore; /// @notice Constructor. /// @param _safe The safe account for which this contract will be the guard. @@ -128,8 +128,7 @@ contract LivenessGuard is ISemver, BaseGuard { address[] memory ownersAfter = SAFE.getOwners(); // Iterate over the current owners, and remove one at a time from the ownersBefore set. - uint256 ownersAfterLength = ownersAfter.length; - for (uint256 i = 0; i < ownersAfterLength; i++) { + for (uint256 i = 0; i < ownersAfter.length; i++) { // If the value was present, remove() returns true. address ownerAfter = ownersAfter[i]; if (ownersBefore.remove(ownerAfter) == false) { @@ -140,9 +139,10 @@ contract LivenessGuard is ISemver, BaseGuard { // Now iterate over the remaining ownersBefore entries. Any remaining addresses are no longer an owner, so we // delete them from the lastLive mapping. - // uint256 ownersBeforeLength = ownersBefore.length(); - for (uint256 i = 0; i < ownersBefore.length(); i++) { - address ownerBefore = ownersBefore.at(i); + // We cache the ownersBefore set before iterating over it, because the remove() method mutates the set. + address[] memory ownersBeforeCache = ownersBefore.values(); + for (uint256 i = 0; i < ownersBeforeCache.length; i++) { + address ownerBefore = ownersBeforeCache[i]; delete lastLive[ownerBefore]; ownersBefore.remove(ownerBefore); } diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 191efc144013..7593b6c69b98 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -2,28 +2,42 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; +import { StdUtils } from "forge-std/StdUtils.sol"; +import { StdCheats } from "forge-std/StdCheats.sol"; import { Safe, OwnerManager } from "safe-contracts/Safe.sol"; import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol"; import { ModuleManager } from "safe-contracts/base/ModuleManager.sol"; import { Enum } from "safe-contracts/common/Enum.sol"; import "test/safe-tools/SafeTestTools.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import { LivenessGuard } from "src/Safe/LivenessGuard.sol"; +/// @dev A wrapper contract exposing the length of the ownersBefore set in the LivenessGuard. +contract WrappedGuard is LivenessGuard { + using EnumerableSet for EnumerableSet.AddressSet; + + constructor(Safe safe) LivenessGuard(safe) { } + + function ownersBeforeLength() public view returns (uint256) { + return ownersBefore.length(); + } +} + contract LivenessGuard_TestInit is Test, SafeTestTools { using SafeTestLib for SafeInstance; event OwnerRecorded(address owner); uint256 initTime = 10; - LivenessGuard livenessGuard; + WrappedGuard livenessGuard; SafeInstance safeInstance; /// @dev Sets up the test environment function setUp() public { vm.warp(initTime); safeInstance = _setupSafe(); - livenessGuard = new LivenessGuard(safeInstance.safe); + livenessGuard = new WrappedGuard(safeInstance.safe); safeInstance.setGuard(address(livenessGuard)); } } @@ -32,7 +46,7 @@ contract LivenessGuard_Constructor_Test is LivenessGuard_TestInit { /// @dev Tests that the constructor correctly sets the current time as the lastLive time for each owner function test_constructor_works() external { address[] memory owners = safeInstance.owners; - livenessGuard = new LivenessGuard(safeInstance.safe); + livenessGuard = new WrappedGuard(safeInstance.safe); for (uint256 i = 0; i < owners.length; i++) { assertEq(livenessGuard.lastLive(owners[i]), initTime); } @@ -134,7 +148,9 @@ contract LivenessGuard_OwnerManagement_Test is LivenessGuard_TestInit { assertGe(livenessGuard.lastLive(ownerToRemove), 0); assertTrue(safeInstance.safe.isOwner(ownerToRemove)); + assertEq(livenessGuard.ownersBeforeLength(), 0); safeInstance.removeOwner({ prevOwner: address(0), owner: ownerToRemove, threshold: 1 }); + assertEq(livenessGuard.ownersBeforeLength(), 0); assertFalse(safeInstance.safe.isOwner(ownerToRemove)); assertEq(livenessGuard.lastLive(ownerToRemove), 0); @@ -146,7 +162,9 @@ contract LivenessGuard_OwnerManagement_Test is LivenessGuard_TestInit { assertEq(livenessGuard.lastLive(ownerToAdd), 0); assertFalse(safeInstance.safe.isOwner(ownerToAdd)); + assertEq(livenessGuard.ownersBeforeLength(), 0); safeInstance.addOwnerWithThreshold({ owner: ownerToAdd, threshold: 1 }); + assertEq(livenessGuard.ownersBeforeLength(), 0); assertTrue(safeInstance.safe.isOwner(ownerToAdd)); assertEq(livenessGuard.lastLive(ownerToAdd), block.timestamp); @@ -162,7 +180,9 @@ contract LivenessGuard_OwnerManagement_Test is LivenessGuard_TestInit { assertEq(livenessGuard.lastLive(ownerToAdd), 0); assertFalse(safeInstance.safe.isOwner(ownerToAdd)); + assertEq(livenessGuard.ownersBeforeLength(), 0); safeInstance.swapOwner({ prevOwner: address(0), oldOwner: ownerToRemove, newOwner: ownerToAdd }); + assertEq(livenessGuard.ownersBeforeLength(), 0); assertFalse(safeInstance.safe.isOwner(ownerToRemove)); assertEq(livenessGuard.lastLive(ownerToRemove), 0); @@ -171,3 +191,127 @@ contract LivenessGuard_OwnerManagement_Test is LivenessGuard_TestInit { assertEq(livenessGuard.lastLive(ownerToAdd), block.timestamp); } } + +contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, LivenessGuard_TestInit { + using SafeTestLib for SafeInstance; + + /// @dev Enumerates the possible owner management operations + enum OwnerOp { + Add, + Remove, + Swap + } + + /// @dev Describes a change to be made to the safe + struct OwnerChange { + uint8 operation; // used to choose an OwnerOp + uint256 newThreshold; + uint256 ownerIndex; + } + + /// @dev Maps addresses to private keys + mapping(address => uint256) privateKeys; + + /// @dev Tests that the guard correctly manages the lastLive mapping when owners are added, removed, or swapped + function testFuzz_OwnerManagement_works( + uint256 initialOwners, + uint256 threshold, + OwnerChange[] memory changes + ) + external + { + vm.assume(changes.length < 20); + // Initialize the safe with more owners than changes, to ensure we don't try to remove them all + initialOwners = bound(initialOwners, changes.length, 2 * changes.length); + + // We need at least one owner + initialOwners = initialOwners < 1 ? 1 : initialOwners; + + // Limit the threshold to the number of owners + threshold = bound(threshold, 1, initialOwners); + + // Generate the initial owners and keys and setup the safe + (address[] memory ownerAddrs, uint256[] memory ownerkeys) = SafeTestLib.makeAddrsAndKeys(initialOwners); + // record the private keys for later use + for (uint256 i = 0; i < ownerAddrs.length; i++) { + privateKeys[ownerAddrs[i]] = ownerkeys[i]; + } + + // Create the new safe and register the guard. + SafeInstance memory safeInstance = _setupSafe(ownerkeys, threshold); + livenessGuard = new WrappedGuard(safeInstance.safe); + safeInstance.setGuard(address(livenessGuard)); + + for (uint256 i = 0; i < changes.length; i++) { + OwnerChange memory change = changes[i]; + address[] memory currentOwners = safeInstance.safe.getOwners(); + + // Create a new owner address to add and store the key + (address newOwner, uint256 newKey) = makeAddrAndKey(string.concat("new owner", vm.toString(i))); + privateKeys[newOwner] = newKey; + + OwnerOp op = OwnerOp(bound(change.operation, 0, uint256(type(OwnerOp).max))); + + assertEq(livenessGuard.ownersBeforeLength(), 0); + if (op == OwnerOp.Add) { + assertEq(livenessGuard.lastLive(newOwner), 0); + assertFalse(safeInstance.safe.isOwner(newOwner)); + change.newThreshold = bound(change.newThreshold, 1, currentOwners.length + 1); + + safeInstance.addOwnerWithThreshold(newOwner, change.newThreshold); + + assertTrue(safeInstance.safe.isOwner(newOwner)); + assertEq(livenessGuard.lastLive(newOwner), block.timestamp); + } else { + // Ensure we're removing an owner at an index within bounds + uint256 ownerIndexToRemove = bound(change.ownerIndex, 0, currentOwners.length - 1); + address ownerToRemove = currentOwners[ownerIndexToRemove]; + address prevOwner = safeInstance.getPrevOwner(ownerToRemove); + + if (op == OwnerOp.Remove) { + if (currentOwners.length == 1) continue; + assertGe(livenessGuard.lastLive(ownerToRemove), 0); + assertTrue(safeInstance.safe.isOwner(ownerToRemove)); + change.newThreshold = bound(change.newThreshold, 1, currentOwners.length - 1); + + safeInstance.removeOwner(prevOwner, ownerToRemove, change.newThreshold); + + assertFalse(safeInstance.safe.isOwner(ownerToRemove)); + assertEq(livenessGuard.lastLive(ownerToRemove), 0); + } else if (op == OwnerOp.Swap) { + assertGe(livenessGuard.lastLive(ownerToRemove), 0); + assertTrue(safeInstance.safe.isOwner(ownerToRemove)); + + safeInstance.swapOwner(prevOwner, ownerToRemove, newOwner); + + assertTrue(safeInstance.safe.isOwner(newOwner)); + assertFalse(safeInstance.safe.isOwner(ownerToRemove)); + assertEq(livenessGuard.lastLive(ownerToRemove), 0); + assertEq(livenessGuard.lastLive(newOwner), block.timestamp); + } + } + assertEq(livenessGuard.ownersBeforeLength(), 0); + _refreshOwners(safeInstance); + } + } + + /// @dev Refreshes the owners and ownerPKs arrays in the SafeInstance + function _refreshOwners(SafeInstance memory instance) internal view { + // Get the current owners + instance.owners = instance.safe.getOwners(); + + // Looks up the private key for each owner + uint256[] memory unsortedOwnerPKs = new uint256[](instance.owners.length); + for (uint256 j = 0; j < instance.owners.length; j++) { + unsortedOwnerPKs[j] = privateKeys[instance.owners[j]]; + } + + // Sort the keys by address and store them in the SafeInstance + instance.ownerPKs = SafeTestLib.sortPKsByComputedAddress(unsortedOwnerPKs); + + // Overwrite the SafeInstances owners array with the computed addresses from the ownerPKs array + for (uint256 k; k < instance.owners.length; k++) { + instance.owners[k] = SafeTestLib.getAddr(instance.ownerPKs[k]); + } + } +} diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 2c01806f2e31..59725b1167c8 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -261,8 +261,8 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { contract LivenessModule_RemoveOwners_Test is LivenessModule_TestInit { using SafeTestLib for SafeInstance; - /// @dev Tests if removing one owner works correctly + /// @dev Tests if removing one owner works correctly function test_removeOwners_oneOwner_succeeds() external { uint256 ownersBefore = safeInstance.owners.length; address ownerToRemove = safeInstance.owners[0]; From a1c2987e881fe2657713c4bcfb63a1a6f0282506 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 15:50:11 -0400 Subject: [PATCH 207/374] safe-tools: Make address label prefix configurable --- packages/contracts-bedrock/test/LivenessGuard.t.sol | 3 ++- packages/contracts-bedrock/test/LivenessModule.t.sol | 2 +- packages/contracts-bedrock/test/SafeSigners.t.sol | 2 +- .../test/safe-tools/SafeTestTools.sol | 12 +++++++++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 7593b6c69b98..643872563092 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -231,7 +231,8 @@ contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, Liveness threshold = bound(threshold, 1, initialOwners); // Generate the initial owners and keys and setup the safe - (address[] memory ownerAddrs, uint256[] memory ownerkeys) = SafeTestLib.makeAddrsAndKeys(initialOwners); + (address[] memory ownerAddrs, uint256[] memory ownerkeys) = + SafeTestLib.makeAddrsAndKeys("safeTest", initialOwners); // record the private keys for later use for (uint256 i = 0; i < ownerAddrs.length; i++) { privateKeys[ownerAddrs[i]] = ownerkeys[i]; diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 59725b1167c8..ed93691f0ba8 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -47,7 +47,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { vm.warp(initTime); // Create a Safe with 10 owners - (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys(10); + (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys("moduleTest", 10); safeInstance = _setupSafe(keys, 8); livenessGuard = new LivenessGuard(safeInstance.safe); diff --git a/packages/contracts-bedrock/test/SafeSigners.t.sol b/packages/contracts-bedrock/test/SafeSigners.t.sol index ffada6c96e09..b79386a52238 100644 --- a/packages/contracts-bedrock/test/SafeSigners.t.sol +++ b/packages/contracts-bedrock/test/SafeSigners.t.sol @@ -39,7 +39,7 @@ contract SafeSigners_Test is Test, SafeTestTools { // Limit the number of signatures to 25 uint256 numSigs = bound(_numSigs, 1, 25); - (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys(numSigs); + (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys("getSigsTest", numSigs); for (uint256 i = 0; i < keys.length; i++) { if (sigType(keys[i]) == SigTypes.Contract) { keys[i] = diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 76af3b6c6dc1..bb84c48b4225 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -69,7 +69,13 @@ library SafeTestLib { } /// @dev Get arrays of addresses and private keys. The arrays are sorted by address, and the addresses are labelled - function makeAddrsAndKeys(uint256 num) internal returns (address[] memory addrs, uint256[] memory keys) { + function makeAddrsAndKeys( + string memory prefix, + uint256 num + ) + internal + returns (address[] memory addrs, uint256[] memory keys) + { keys = new uint256[](num); addrs = new address[](num); for (uint256 i; i < num; i++) { @@ -79,7 +85,7 @@ library SafeTestLib { for (uint256 i; i < num; i++) { addrs[i] = Vm(VM_ADDR).addr(keys[i]); - Vm(VM_ADDR).label(getAddr(keys[i]), string.concat("SAFETEST: Signer ", Vm(VM_ADDR).toString(i))); + Vm(VM_ADDR).label(getAddr(keys[i]), string.concat(prefix, Vm(VM_ADDR).toString(i))); } } @@ -592,7 +598,7 @@ contract SafeTestTools { } function _setupSafe() public returns (SafeInstance memory) { - (, uint256[] memory defaultPKs) = SafeTestLib.makeAddrsAndKeys(3); + (, uint256[] memory defaultPKs) = SafeTestLib.makeAddrsAndKeys("default", 3); return _setupSafe( defaultPKs, From 5f56bd2cfd9e5b7160cdc7b83635f305d02faa9b Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 15:50:32 -0400 Subject: [PATCH 208/374] safe-tools: Add changeThreshold method --- .../test/safe-tools/SafeTestTools.sol | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index bb84c48b4225..6e74b3e6ee37 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -352,6 +352,16 @@ library SafeTestLib { return instance.safe.nonce(); } + /// @dev Adds a new owner to the safe + function changeThreshold(SafeInstance memory instance, uint256 threshold) internal { + execTransaction( + instance, + address(instance.safe), + 0, + abi.encodeWithSelector(OwnerManager.changeThreshold.selector, threshold) + ); + } + /// @dev Adds a new owner to the safe function addOwnerWithThreshold(SafeInstance memory instance, address owner, uint256 threshold) internal { execTransaction( From 774dd1b9fe61af0c76e96cf76ebc01de8dabfa0e Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 16:21:57 -0400 Subject: [PATCH 209/374] safe-tools: Fix bug in getPrevOwners --- .../test/safe-tools/SafeTestTools.sol | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 6e74b3e6ee37..1fee1de29ed2 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -199,14 +199,7 @@ library SafeTestLib { /// @param _owner The owner whose previous owner we want to find function getPrevOwner(SafeInstance memory instance, address _owner) internal view returns (address prevOwner_) { address[] memory owners = instance.safe.getOwners(); - for (uint256 i = 0; i < owners.length; i++) { - if (owners[i] != _owner) continue; - if (i == 0) { - prevOwner_ = SENTINEL_OWNERS; - break; - } - prevOwner_ = owners[i - 1]; - } + prevOwner_ = getPrevOwnerFromList(_owner, owners); } /// @dev Get the previous owner in the provided list of owners. @@ -250,7 +243,7 @@ library SafeTestLib { address[] memory currentOwners; for (uint256 i = 0; i < _ownersToRemove.length; i++) { currentOwners = ownerSimulator.getOwners(); - prevOwners_[i] = SafeTestLib.getPrevOwnerFromList(instance.owners[i], currentOwners); + prevOwners_[i] = SafeTestLib.getPrevOwnerFromList(_ownersToRemove[i], currentOwners); // Don't try to remove the last owner if (currentOwners.length == 1) break; From 33c7c8b1f2f68a8e207c63cd85190b76ecc4e194 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 27 Oct 2023 16:24:02 -0400 Subject: [PATCH 210/374] test(ctb): Fuzz test removing an arbitrary number of owners --- .../test/LivenessModule.t.sol | 97 ++++++++++++++++++- .../test/safe-tools/SafeTestTools.sol | 13 ++- 2 files changed, 107 insertions(+), 3 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index ed93691f0ba8..77d33c0d228e 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -41,7 +41,7 @@ contract LivenessModule_TestInit is Test, SafeTestTools { } /// @dev Sets up the test environment - function setUp() public { + function setUp() public virtual { // Set the block timestamp to the initTime, so that signatures recorded in the first block // are non-zero. vm.warp(initTime); @@ -291,3 +291,98 @@ contract LivenessModule_RemoveOwners_Test is LivenessModule_TestInit { assertEq(safeInstance.safe.getThreshold(), 1); } } + +/// @dev A copy of LivenessModule.get75PercentThreshold as a free function to use below. +function get75PercentThreshold(uint256 _numOwners) pure returns (uint256 threshold_) { + threshold_ = (_numOwners * 75 + 99) / 100; +} + +contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { + using SafeTestLib for SafeInstance; + + /// @dev Override the base setUp function, to avoid instantiating an unnecessary Safe + function setUp() public override { + vm.warp(initTime); + fallbackOwner = makeAddr("fallbackOwner"); + } + + /// @dev Tests if removing owners works correctly for various safe configurations and numbeers of live owners + function testFuzz_removeOwners(uint256 _numOwners, uint256 _minOwners, uint256 _numLiveOwners) external { + // _numOwners must be at least 3, so that _minOwners can be set to at least 2 by the following bound() call. + _numOwners = bound(_numOwners, 3, 20); + // _minOwners must be at least 2, otherwise we don't have any range below _minOwners to test the transfer to + // the fallback owner. + _minOwners = bound(_minOwners, _numOwners - 1, _numOwners - 1); + + // Ensure that _numLiveOwners is less than _numOwners so that we can remove at least one owner. + _numLiveOwners = bound(_numLiveOwners, 0, _numOwners - 1); + + // The above bounds are a bit tricky, so we assert that the result is correct + assertTrue(_numOwners > _minOwners && _numOwners > _numLiveOwners && _minOwners >= 2); + + // Create a Safe with _numOwners owners + (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys("rmOwnersTest", _numOwners); + uint256 threshold = get75PercentThreshold(_numOwners); + safeInstance = _setupSafe(keys, threshold); + livenessGuard = new LivenessGuard(safeInstance.safe); + livenessModule = new LivenessModule({ + _safe: safeInstance.safe, + _livenessGuard: livenessGuard, + _livenessInterval: livenessInterval, + _minOwners: _minOwners, + _fallbackOwner: fallbackOwner + }); + safeInstance.setGuard(address(livenessGuard)); + safeInstance.enableModule(address(livenessModule)); + + // Warp ahead so that all owners non-live + _warpPastLivenessInterval(); + + // Create an array of live owners, and call showLiveness for each of them + address[] memory liveOwners = new address[](_numLiveOwners); + for (uint256 i = 0; i < _numLiveOwners; i++) { + liveOwners[i] = safeInstance.owners[i]; + vm.prank(safeInstance.owners[i]); + livenessGuard.showLiveness(); + } + + // Create an array of non-live owners + address[] memory nonLiveOwners = new address[](_numOwners - _numLiveOwners); + for (uint256 i = 0; i < _numOwners - _numLiveOwners; i++) { + nonLiveOwners[i] = safeInstance.owners[i + _numLiveOwners]; + } + + address[] memory prevOwners; + if (_numLiveOwners >= _minOwners) { + // The safe will remain above the minimum number of owners, so we can remove only those owners which are not + // live. + prevOwners = safeInstance.getPrevOwners(nonLiveOwners); + livenessModule.removeOwners(prevOwners, nonLiveOwners); + + // Validate the resulting state of the Safe + assertEq(safeInstance.safe.getOwners().length, _numLiveOwners); + assertEq(safeInstance.safe.getThreshold(), get75PercentThreshold(_numLiveOwners)); + for (uint256 i = 0; i < _numLiveOwners; i++) { + assertTrue(safeInstance.safe.isOwner(liveOwners[i])); + } + for (uint256 i = 0; i < nonLiveOwners.length; i++) { + assertFalse(safeInstance.safe.isOwner(nonLiveOwners[i])); + } + } else { + // The safe is below the minimum number of owners, so we can remove all owners, + // but we need to do remove the non-live owners first, so we reverse the owners array, since + // the first owners have signed recently. + address[] memory ownersToRemove = new address[](_numOwners); + for (uint256 i = 0; i < _numOwners; i++) { + ownersToRemove[_numOwners - i - 1] = safeInstance.owners[i]; + } + prevOwners = safeInstance.getPrevOwners(ownersToRemove); + livenessModule.removeOwners(prevOwners, ownersToRemove); + + // Validate the resulting state of the Safe + assertEq(safeInstance.safe.getOwners().length, 1); + assertEq(safeInstance.safe.getOwners()[0], fallbackOwner); + assertEq(safeInstance.safe.getThreshold(), 1); + } + } +} diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index 1fee1de29ed2..f4ff521ff0c9 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -212,10 +212,17 @@ library SafeTestLib { address[] memory _ownersList ) internal - pure - returns (address prevOwner_) + view + returns ( + // pure + address prevOwner_ + ) { + // console.log("getPrevOwnerFromList"); for (uint256 i = 0; i < _ownersList.length; i++) { + // console.log(i); + // console.log(_owner); + // console.log("_ownersList[i]:", _ownersList[i]); if (_ownersList[i] != _owner) continue; if (i == 0) { prevOwner_ = SENTINEL_OWNERS; @@ -223,6 +230,8 @@ library SafeTestLib { } prevOwner_ = _ownersList[i - 1]; } + + console.log("prevOwner_:", prevOwner_); } /// @dev Given an array of owners to remove, this function will return an array of the previous owners From eb0e133501a4eb39bb516979f211ebab01ff5d5e Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 28 Oct 2023 11:18:10 -0400 Subject: [PATCH 211/374] test(ctb): Add test for incomplete emptying below minOwners --- .../test/LivenessModule.t.sol | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index 77d33c0d228e..c9e72f326134 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -214,6 +214,24 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { /// @dev Tests if remove owners reverts if it removes too many owners without removing all of them function test_removeOwners_belowMinButNotEmptied_reverts() external { + // Remove all but one owner + uint256 numOwners = safeInstance.owners.length - 2; + + address[] memory ownersToRemove = new address[](numOwners); + for (uint256 i = 0; i < numOwners; i++) { + ownersToRemove[i] = safeInstance.owners[i]; + } + address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); + + _warpPastLivenessInterval(); + vm.expectRevert( + "LivenessModule: must remove all owners and transfer to fallback owner if numOwners < minOwners" + ); + livenessModule.removeOwners(prevOwners, ownersToRemove); + } + + /// @dev Tests if remove owners reverts if it removes too many owners transferring to the fallback owner + function test_removeOwners_belowEmptiedButNotFallback_reverts() external { // Remove all but one owner uint256 numOwners = safeInstance.owners.length - 1; From 5c0d3226233cfcaade5a234989228212e4e5e90c Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 28 Oct 2023 15:18:49 -0400 Subject: [PATCH 212/374] test(ctb): Add test for not giving to fallback owner --- .../src/Safe/LivenessModule.sol | 3 +- .../test/LivenessModule.t.sol | 179 ++++++++++++++---- 2 files changed, 141 insertions(+), 41 deletions(-) diff --git a/packages/contracts-bedrock/src/Safe/LivenessModule.sol b/packages/contracts-bedrock/src/Safe/LivenessModule.sol index 6f26b0eb12e9..41f2ed64708e 100644 --- a/packages/contracts-bedrock/src/Safe/LivenessModule.sol +++ b/packages/contracts-bedrock/src/Safe/LivenessModule.sol @@ -213,7 +213,8 @@ contract LivenessModule is ISemver { ); } - // Check that the threshold is correct. This check is also correct when there is a single + // Check that"LivenessModule: must remove all owners and transfer to fallback owner if numOwners < minOwners" + // the threshold is correct. This check is also correct when there is a single // owner, because get75PercentThreshold(1) returns 1. uint256 threshold = SAFE.getThreshold(); require( diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index c9e72f326134..d4e1654c4e31 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -195,7 +195,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { } /// @dev Tests if removing all owners works correctly - function test_removeOwners_swapToFallBackOwner_reverts() external { + function test_removeOwners_swapToFallbackOwner_reverts() external { uint256 numOwners = safeInstance.owners.length; address[] memory ownersToRemove = new address[](numOwners); @@ -230,8 +230,8 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { livenessModule.removeOwners(prevOwners, ownersToRemove); } - /// @dev Tests if remove owners reverts if it removes too many owners transferring to the fallback owner - function test_removeOwners_belowEmptiedButNotFallback_reverts() external { + /// @dev Tests if remove owners reverts if it removes too many owners transferring to the shutDown owner + function test_removeOwners_belowEmptiedButNotShutDown_reverts() external { // Remove all but one owner uint256 numOwners = safeInstance.owners.length - 1; @@ -318,36 +318,66 @@ function get75PercentThreshold(uint256 _numOwners) pure returns (uint256 thresho contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { using SafeTestLib for SafeInstance; - /// @dev Override the base setUp function, to avoid instantiating an unnecessary Safe + address[] ownersToRemove2; + + /// @dev Options for handling the event that the number of owners remaining is less than minOwners + enum ShutDownBehavior { + Correct, // Correctly removes the owners and transfers to the shutDown owner + DoesNotTransferToFallbackOwner, // Removes all but one owner, and does not transfer to the shutDown owner + DoesNotRemoveAllOwners // Leaves more than one owner when below minOwners + } + + /// @dev This contract inherits the storage layout from the LivenessModule_TestInit contract, but we + /// override the base setUp function, to avoid instantiating an unnecessary Safe and liveness checking system. function setUp() public override { vm.warp(initTime); fallbackOwner = makeAddr("fallbackOwner"); } - /// @dev Tests if removing owners works correctly for various safe configurations and numbeers of live owners - function testFuzz_removeOwners(uint256 _numOwners, uint256 _minOwners, uint256 _numLiveOwners) external { - // _numOwners must be at least 3, so that _minOwners can be set to at least 2 by the following bound() call. - _numOwners = bound(_numOwners, 3, 20); - // _minOwners must be at least 2, otherwise we don't have any range below _minOwners to test the transfer to - // the fallback owner. - _minOwners = bound(_minOwners, _numOwners - 1, _numOwners - 1); + /// @dev Extracts the setup of the test environment into a separate function. + function _prepare( + uint256 _numOwners, + uint256 _minOwners, + uint256 _numLiveOwners + ) + internal + returns (uint256 numOwners_, uint256 minOwners_, uint256 numLiveOwners_) + { + // First we modify the test parameters to ensure that they describe a plausible starting point. + // + // _numOwners must be at least 4, so that _minOwners can be set to at least 3 by the following bound() call. + // Limiting the owner set to 20 helps to keep the runtime of the test reasonable. + console.log("bounding numOwners"); + numOwners_ = bound(_numOwners, 4, 20); + // _minOwners must be at least 3, otherwise we don't have any range below _minOwners in which to test all of the + // ShutDownBehavior options. + console.log("bounding minOwners"); + minOwners_ = bound(_minOwners, 3, numOwners_ - 1); // Ensure that _numLiveOwners is less than _numOwners so that we can remove at least one owner. - _numLiveOwners = bound(_numLiveOwners, 0, _numOwners - 1); - - // The above bounds are a bit tricky, so we assert that the result is correct - assertTrue(_numOwners > _minOwners && _numOwners > _numLiveOwners && _minOwners >= 2); + console.log("bounding numLiveOwners"); + numLiveOwners_ = bound(_numLiveOwners, 0, numOwners_ - 1); + + // The above bounds are a bit tricky, so we assert that the resulting parameters enable us to test all possible + // success and revert cases in the removeOwners function. + assertTrue( + numOwners_ > minOwners_ // + && numOwners_ > numLiveOwners_ + // + && minOwners_ >= 3 + ); + // // Create a Safe with _numOwners owners - (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys("rmOwnersTest", _numOwners); - uint256 threshold = get75PercentThreshold(_numOwners); + (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys("rmOwnersTest", numOwners_); + uint256 threshold = get75PercentThreshold(numOwners_); safeInstance = _setupSafe(keys, threshold); livenessGuard = new LivenessGuard(safeInstance.safe); livenessModule = new LivenessModule({ _safe: safeInstance.safe, _livenessGuard: livenessGuard, _livenessInterval: livenessInterval, - _minOwners: _minOwners, + _minOwners: minOwners_, _fallbackOwner: fallbackOwner }); safeInstance.setGuard(address(livenessGuard)); @@ -355,52 +385,121 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // Warp ahead so that all owners non-live _warpPastLivenessInterval(); + } + + /// @dev Tests if removing owners works correctly for various safe configurations and numbeers of live owners + function testFuzz_removeOwners( + uint256 _numOwners, + uint256 _minOwners, + uint256 _numLiveOwners, + uint256 _shutDownBehavior, + uint256 _numOwnersToRemoveinShutDown + ) + external + { + // Prepare the test env and test params + (uint256 numOwners, uint256 minOwners, uint256 numLiveOwners) = _prepare(_numOwners, _minOwners, _numLiveOwners); // Create an array of live owners, and call showLiveness for each of them - address[] memory liveOwners = new address[](_numLiveOwners); - for (uint256 i = 0; i < _numLiveOwners; i++) { + address[] memory liveOwners = new address[](numLiveOwners); + for (uint256 i = 0; i < numLiveOwners; i++) { liveOwners[i] = safeInstance.owners[i]; vm.prank(safeInstance.owners[i]); livenessGuard.showLiveness(); } // Create an array of non-live owners - address[] memory nonLiveOwners = new address[](_numOwners - _numLiveOwners); - for (uint256 i = 0; i < _numOwners - _numLiveOwners; i++) { - nonLiveOwners[i] = safeInstance.owners[i + _numLiveOwners]; + address[] memory nonLiveOwners = new address[](numOwners - numLiveOwners); + for (uint256 i = 0; i < numOwners - numLiveOwners; i++) { + nonLiveOwners[i] = safeInstance.owners[i + numLiveOwners]; } address[] memory prevOwners; - if (_numLiveOwners >= _minOwners) { + if (numLiveOwners >= minOwners) { + console.log("No shutdown"); // The safe will remain above the minimum number of owners, so we can remove only those owners which are not // live. prevOwners = safeInstance.getPrevOwners(nonLiveOwners); livenessModule.removeOwners(prevOwners, nonLiveOwners); // Validate the resulting state of the Safe - assertEq(safeInstance.safe.getOwners().length, _numLiveOwners); - assertEq(safeInstance.safe.getThreshold(), get75PercentThreshold(_numLiveOwners)); - for (uint256 i = 0; i < _numLiveOwners; i++) { + assertEq(safeInstance.safe.getOwners().length, numLiveOwners); + assertEq(safeInstance.safe.getThreshold(), get75PercentThreshold(numLiveOwners)); + for (uint256 i = 0; i < numLiveOwners; i++) { assertTrue(safeInstance.safe.isOwner(liveOwners[i])); } for (uint256 i = 0; i < nonLiveOwners.length; i++) { assertFalse(safeInstance.safe.isOwner(nonLiveOwners[i])); } } else { - // The safe is below the minimum number of owners, so we can remove all owners, - // but we need to do remove the non-live owners first, so we reverse the owners array, since - // the first owners have signed recently. - address[] memory ownersToRemove = new address[](_numOwners); - for (uint256 i = 0; i < _numOwners; i++) { - ownersToRemove[_numOwners - i - 1] = safeInstance.owners[i]; + // The number of non-live owners will push the safe below the minimum number of owners. + // We need to test all of the possible ShutDownBehavior options, so we'll create a ShutDownBehavior enum + // from the _shutDownBehavior input. + ShutDownBehavior shutDownBehavior = + ShutDownBehavior(bound(_shutDownBehavior, 0, uint256(type(ShutDownBehavior).max))); + // The safe is below the minimum number of owners. + // The ShutDownBehavior enum determines how we handle this case. + if (shutDownBehavior == ShutDownBehavior.Correct) { + console.log("Correct Shutdown"); + // We remove all owners, and transfer ownership to the shutDown owner. + // but we need to do remove the non-live owners first, so we reverse the owners array, since + // the first owners have signed recently. + address[] memory ownersToRemove = new address[](numOwners); + for (uint256 i = 0; i < numOwners; i++) { + ownersToRemove[numOwners - i - 1] = safeInstance.owners[i]; + } + prevOwners = safeInstance.getPrevOwners(ownersToRemove); + livenessModule.removeOwners(prevOwners, ownersToRemove); + + // Validate the resulting state of the Safe + assertEq(safeInstance.safe.getOwners().length, 1); + assertEq(safeInstance.safe.getOwners()[0], fallbackOwner); + assertEq(safeInstance.safe.getThreshold(), 1); + } else { + // For both of the incorrect behaviors, we need to calculate the number of owners to remove to + // trigger that behavior. We initialize that value here then set it in the if statements below. + uint256 numOwnersToRemoveinShutDown; + if (shutDownBehavior == ShutDownBehavior.DoesNotRemoveAllOwners) { + console.log("Shutdown DoesNotRemoveAllOwners"); + // In the DoesNotRemoveAllOwners case, we should have more than 1 of the pre-existing owners + // remaining + console.log("bounding numOwnersToRemoveinShutDown"); + numOwnersToRemoveinShutDown = + bound(_numOwnersToRemoveinShutDown, numOwners - minOwners + 1, numOwners - 2); + uint256 i = 0; + for (i; i < numOwnersToRemoveinShutDown; i++) { + // Add non-live owners to remove first + if (i < nonLiveOwners.length) { + ownersToRemove2.push(nonLiveOwners[i]); + } else { + // Then add live owners to remove + ownersToRemove2.push(liveOwners[i - nonLiveOwners.length]); + } + } + prevOwners = safeInstance.getPrevOwners(ownersToRemove2); + vm.expectRevert( + "LivenessModule: must remove all owners and transfer to fallback owner if numOwners < minOwners" + ); + livenessModule.removeOwners(prevOwners, ownersToRemove2); + } else if (shutDownBehavior == ShutDownBehavior.DoesNotTransferToFallbackOwner) { + console.log("Shutdown DoesNotTransferToFallbackOwner"); + // In the DoesNotRemoveAllOwners case, we should have exactly 1 pre-existing owners remaining + numOwnersToRemoveinShutDown = numOwners - 1; + uint256 i = 0; + for (i; i < numOwnersToRemoveinShutDown; i++) { + // Add non-live owners to remove first + if (i < nonLiveOwners.length) { + ownersToRemove2.push(nonLiveOwners[i]); + } else { + // Then add live owners to remove + ownersToRemove2.push(liveOwners[i - nonLiveOwners.length]); + } + } + prevOwners = safeInstance.getPrevOwners(ownersToRemove2); + vm.expectRevert("LivenessModule: must transfer ownership to fallback owner"); + livenessModule.removeOwners(prevOwners, ownersToRemove2); + } } - prevOwners = safeInstance.getPrevOwners(ownersToRemove); - livenessModule.removeOwners(prevOwners, ownersToRemove); - - // Validate the resulting state of the Safe - assertEq(safeInstance.safe.getOwners().length, 1); - assertEq(safeInstance.safe.getOwners()[0], fallbackOwner); - assertEq(safeInstance.safe.getThreshold(), 1); } } } From 2cb544372cad0d06119bd16340a63e347b4d78b7 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 28 Oct 2023 15:28:41 -0400 Subject: [PATCH 213/374] test(ctb): Check all topics in guard.OwnerRecorded --- packages/contracts-bedrock/test/LivenessGuard.t.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 643872563092..3a91e8f79c2d 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -93,8 +93,7 @@ contract LivenessGuard_CheckTx_Test is LivenessGuard_TestInit { signers[1] = safeInstance.owners[1]; for (uint256 i; i < signers.length; i++) { - // Don't check topic1 so that we can avoid the ugly txHash calculation. - vm.expectEmit(false, true, true, true, address(livenessGuard)); + vm.expectEmit(address(livenessGuard)); emit OwnerRecorded(signers[i]); } vm.expectCall(address(safeInstance.safe), abi.encodeWithSignature("nonce()")); From dcd5a0f009fe01b731e5881f5848e4d3f81d2ee8 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 28 Oct 2023 15:46:43 -0400 Subject: [PATCH 214/374] test(ctb): Clean up and add assertions to testFuzz_removeOwners --- .../test/LivenessModule.t.sol | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index d4e1654c4e31..adc1af45666c 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -318,7 +318,8 @@ function get75PercentThreshold(uint256 _numOwners) pure returns (uint256 thresho contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { using SafeTestLib for SafeInstance; - address[] ownersToRemove2; + /// @dev We put this array in storage so that we can more easily populate it using push in the tests below. + address[] ownersToRemove; /// @dev Options for handling the event that the number of owners remaining is less than minOwners enum ShutDownBehavior { @@ -360,13 +361,12 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // The above bounds are a bit tricky, so we assert that the resulting parameters enable us to test all possible // success and revert cases in the removeOwners function. + // This is also necessary to avoid underflows or out of bounds accesses in the test. assertTrue( - numOwners_ > minOwners_ // - && numOwners_ > numLiveOwners_ - // - && minOwners_ >= 3 + numOwners_ > minOwners_ // We need to be able to remove at least one owner + && numOwners_ >= numLiveOwners_ // We can have more live owners than there are owners + && minOwners_ >= 3 // Allows us to test all of the ShutDownBehavior options when removing an owner ); - // // Create a Safe with _numOwners owners (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys("rmOwnersTest", numOwners_); @@ -408,7 +408,6 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { livenessGuard.showLiveness(); } - // Create an array of non-live owners address[] memory nonLiveOwners = new address[](numOwners - numLiveOwners); for (uint256 i = 0; i < numOwners - numLiveOwners; i++) { nonLiveOwners[i] = safeInstance.owners[i + numLiveOwners]; @@ -443,10 +442,12 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { console.log("Correct Shutdown"); // We remove all owners, and transfer ownership to the shutDown owner. // but we need to do remove the non-live owners first, so we reverse the owners array, since - // the first owners have signed recently. - address[] memory ownersToRemove = new address[](numOwners); + // the first owners in the array were the ones to call showLiveness. + // ownersToRemove = new address[](numOwners); for (uint256 i = 0; i < numOwners; i++) { - ownersToRemove[numOwners - i - 1] = safeInstance.owners[i]; + // ownersToRemove[numOwners - i - 1] = safeInstance.owners[i]; + // ownersToRemove[i] = safeInstance.owners[numOwners - i - 1]; + ownersToRemove.push(safeInstance.owners[numOwners - i - 1]); } prevOwners = safeInstance.getPrevOwners(ownersToRemove); livenessModule.removeOwners(prevOwners, ownersToRemove); @@ -470,17 +471,17 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { for (i; i < numOwnersToRemoveinShutDown; i++) { // Add non-live owners to remove first if (i < nonLiveOwners.length) { - ownersToRemove2.push(nonLiveOwners[i]); + ownersToRemove.push(nonLiveOwners[i]); } else { // Then add live owners to remove - ownersToRemove2.push(liveOwners[i - nonLiveOwners.length]); + ownersToRemove.push(liveOwners[i - nonLiveOwners.length]); } } - prevOwners = safeInstance.getPrevOwners(ownersToRemove2); + prevOwners = safeInstance.getPrevOwners(ownersToRemove); vm.expectRevert( "LivenessModule: must remove all owners and transfer to fallback owner if numOwners < minOwners" ); - livenessModule.removeOwners(prevOwners, ownersToRemove2); + livenessModule.removeOwners(prevOwners, ownersToRemove); } else if (shutDownBehavior == ShutDownBehavior.DoesNotTransferToFallbackOwner) { console.log("Shutdown DoesNotTransferToFallbackOwner"); // In the DoesNotRemoveAllOwners case, we should have exactly 1 pre-existing owners remaining @@ -489,15 +490,21 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { for (i; i < numOwnersToRemoveinShutDown; i++) { // Add non-live owners to remove first if (i < nonLiveOwners.length) { - ownersToRemove2.push(nonLiveOwners[i]); + ownersToRemove.push(nonLiveOwners[i]); } else { // Then add live owners to remove - ownersToRemove2.push(liveOwners[i - nonLiveOwners.length]); + ownersToRemove.push(liveOwners[i - nonLiveOwners.length]); } } - prevOwners = safeInstance.getPrevOwners(ownersToRemove2); + prevOwners = safeInstance.getPrevOwners(ownersToRemove); vm.expectRevert("LivenessModule: must transfer ownership to fallback owner"); - livenessModule.removeOwners(prevOwners, ownersToRemove2); + livenessModule.removeOwners(prevOwners, ownersToRemove); + } + // For both of the incorrect behaviors, verify no change to the Safe state + assertEq(safeInstance.safe.getOwners().length, numOwners); + assertEq(safeInstance.safe.getThreshold(), get75PercentThreshold(numOwners)); + for (uint256 j = 0; j < numOwners; j++) { + assertTrue(safeInstance.safe.isOwner(safeInstance.owners[j])); } } } From ae901333b5cad8066870edae952e307a6d9f3b2c Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 28 Oct 2023 15:58:50 -0400 Subject: [PATCH 215/374] test(ctb): Ensure lastLive increments on signing --- packages/contracts-bedrock/test/LivenessGuard.t.sol | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index 3a91e8f79c2d..fd4281ea5170 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -92,6 +92,13 @@ contract LivenessGuard_CheckTx_Test is LivenessGuard_TestInit { signers[0] = safeInstance.owners[0]; signers[1] = safeInstance.owners[1]; + // Record the timestamps before the transaction + uint256[] memory beforeTimestamps = new uint256[](safeInstance.owners.length); + + // Jump ahead + uint256 newTimestamp = block.timestamp + 100; + vm.warp(newTimestamp); + for (uint256 i; i < signers.length; i++) { vm.expectEmit(address(livenessGuard)); emit OwnerRecorded(signers[i]); @@ -99,9 +106,10 @@ contract LivenessGuard_CheckTx_Test is LivenessGuard_TestInit { vm.expectCall(address(safeInstance.safe), abi.encodeWithSignature("nonce()")); vm.expectCall(address(safeInstance.safe), abi.encodeCall(OwnerManager.getThreshold, ())); safeInstance.execTransaction({ to: address(1111), value: 0, data: hex"abba" }); - for (uint256 i; i < safeInstance.threshold; i++) { - assertEq(livenessGuard.lastLive(safeInstance.owners[i]), block.timestamp); + uint256 lastLive = livenessGuard.lastLive(safeInstance.owners[i]); + assertGe(lastLive, beforeTimestamps[i]); + assertEq(lastLive, newTimestamp); } } } From 1873257f868a980bf8980d34af3ad8087f30a9c4 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 28 Oct 2023 16:04:42 -0400 Subject: [PATCH 216/374] test(ctb): testFuzz_OwnerManagement increases timestamp on each action --- packages/contracts-bedrock/test/LivenessGuard.t.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index fd4281ea5170..e1f7cdd761b2 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -211,9 +211,10 @@ contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, Liveness /// @dev Describes a change to be made to the safe struct OwnerChange { + uint8 timeDelta; // used to warp the vm uint8 operation; // used to choose an OwnerOp + uint256 ownerIndex; // used to choose the owner to remove or swap out uint256 newThreshold; - uint256 ownerIndex; } /// @dev Maps addresses to private keys @@ -251,6 +252,7 @@ contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, Liveness safeInstance.setGuard(address(livenessGuard)); for (uint256 i = 0; i < changes.length; i++) { + vm.warp(block.timestamp + changes[i].timeDelta); OwnerChange memory change = changes[i]; address[] memory currentOwners = safeInstance.safe.getOwners(); From 43cb263a7b4d47c25301b3743b8f28c2f62de511 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 28 Oct 2023 16:05:12 -0400 Subject: [PATCH 217/374] bind and lock and snap --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- packages/contracts-bedrock/.gas-snapshot | 35 +++++++++++---------- packages/contracts-bedrock/semver-lock.json | 4 +-- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index 75570153b367..cab2a3b89d8d 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:126:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:285;176:23;;;158:42;;146:2;131:18;1710:45:126;;;;;;;;2448:99;;;412:42:285;2534:6:126;400:55:285;382:74;;370:2;355:18;2448:99:126;211:251:285;26025:6379:126;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:285;;;1743:2;1728:18;26025:6379:126;1609:177:285;26025:6379:126;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:126;;-1:-1:-1;28593:7:126;:20::i;:::-;28579:34;-1:-1:-1;28643:10:126;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:126;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:126;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:126;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:126;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:126;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:126:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:126;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:126;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:126:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:285;19164:28:126;;;2164:21:285;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:126;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:126;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:285;14107:30:126;;;2511:21:285;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:126;2327:344:285;14055:97:126;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:126:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:126;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:126;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:126;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:126;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:126;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:126;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:126;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:126;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:126;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:126;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:126;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:126;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:285;37406:29:126;;;2860:21:285;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:126;2676:343:285;37297:157:126;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:126;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:126;;-1:-1:-1;;38164:8:126;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:126;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:126;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:126;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:126;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:126;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:126;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:126;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:126;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:285;20288:41:126;;;3208:21:285;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:126;3024:338:285;20288:41:126;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:126;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:126;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:126:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:126;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:127;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:126;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:285;;;8234:54:126;3601:23:285;;;3581:18;;;3574:51;8203:11:126;;;;8234:19;:6;:19;;;;3513:18:285;;8234:54:126;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:126;;-1:-1:-1;;;7642:2553:126;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:126;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:126;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:126;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:126;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:126;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:126;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:126;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:126;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:126;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:126;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:126;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:126;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:126;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:126:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:126;25120:9;25084:343;;;-1:-1:-1;;25526:4:126;25519:18;-1:-1:-1;;;;23913:1654:126:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:285;21415:72:126;;;4259:21:285;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:126;4075:399:285;21415:72:126;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:285:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:285;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:285;-1:-1:-1;1349:2:285;1334:18;;1321:32;;-1:-1:-1;1365:16:285;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:285;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:285:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:285;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:285:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:299;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:299;2534:6:135;400:55:299;382:74;;370:2;355:18;2448:99:135;211:251:299;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:299;;;1743:2;1728:18;26025:6379:135;1609:177:299;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:299;19164:28:135;;;2164:21:299;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:299;14107:30:135;;;2511:21:299;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:299;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:299;37406:29:135;;;2860:21:299;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:299;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:299;20288:41:135;;;3208:21:299;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:299;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:299;;;8234:54:135;3601:23:299;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:299;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:299;21415:72:135;;;4259:21:299;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:299;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:299:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:299;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:299;-1:-1:-1;1349:2:299;1334:18;;1321:32;;-1:-1:-1;1365:16:299;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:299;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:299:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:299;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:299:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 87c5194ee3bc..82e64da4c864 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:128:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:285;;;401:2;386:18;537:68:128;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:285;;607:22;589:41;;577:2;562:18;680:66:128;449:187:285;1367:1211:128;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:285;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:128;1100:248:285;2620:1595:128;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:128;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:128:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:285;906:62:128;;;2890:21:285;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:128;;;;;;;;-1:-1:-1;1099:14:128;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:128;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:128:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:128:o;552:449:127:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:127:o;14:248:285:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:285;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:285:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:285;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:285;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:285;1069:19;1056:33;;-1:-1:-1;641:454:285;-1:-1:-1;641:454:285:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:285;;2017:180;-1:-1:-1;2017:180:285:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:285;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:285;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:299;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:299;;607:22;589:41;;577:2;562:18;680:66:137;449:187:299;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:299;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:299;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:299;906:62:137;;;2890:21:299;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:299:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:299;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:299:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:299;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:299;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:299;1069:19;1056:33;;-1:-1:-1;641:454:299;-1:-1:-1;641:454:299:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:299;;2017:180;-1:-1:-1;2017:180:299:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:299;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:299;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index c5315d9f1633..06d5f60a3ad8 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -305,31 +305,32 @@ LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12957) LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10755) LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34524) LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689) -LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8553) -LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 228306) -LivenessGuard_CheckTx_TestFails:test_checkTransaction_callerIsNotSafe_revert() (gas: 10380) -LivenessGuard_Constructor_Test:test_constructor_works() (gas: 1174506) +LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8531) +LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 233535) +LivenessGuard_CheckTx_TestFails:test_checkTransaction_callerIsNotSafe_revert() (gas: 10358) +LivenessGuard_Constructor_Test:test_constructor_works() (gas: 1198965) LivenessGuard_Getters_Test:test_getters_works() (gas: 10662) -LivenessGuard_OwnerManagement_Test:test_addOwner_succeeds() (gas: 272723) -LivenessGuard_OwnerManagement_Test:test_removeOwner_succeeds() (gas: 241108) -LivenessGuard_OwnerManagement_Test:test_swapOwner_succeeds() (gas: 279720) +LivenessGuard_OwnerManagement_Test:test_addOwner_succeeds() (gas: 274366) +LivenessGuard_OwnerManagement_Test:test_removeOwner_succeeds() (gas: 246263) +LivenessGuard_OwnerManagement_Test:test_swapOwner_succeeds() (gas: 284880) LivenessGuard_ShowLiveness_Test:test_showLiveness_succeeds() (gas: 28831) LivenessGuard_ShowLiveness_TestFail:test_showLiveness_callIsNotSafeOwner_reverts() (gas: 18770) LivenessModule_CanRemove_Test:test_canRemove_works() (gas: 33026) LivenessModule_CanRemove_TestFail:test_canRemove_notSafeOwner_reverts() (gas: 20489) -LivenessModule_Constructor_Test:test_constructor_minOwnersGreaterThanOwners_reverts() (gas: 83623) -LivenessModule_Constructor_Test:test_constructor_wrongThreshold_reverts() (gas: 92901) +LivenessModule_Constructor_TestFail:test_constructor_minOwnersGreaterThanOwners_reverts() (gas: 83623) +LivenessModule_Constructor_TestFail:test_constructor_wrongThreshold_reverts() (gas: 92925) LivenessModule_Get75PercentThreshold_Test:test_get75PercentThreshold_Works() (gas: 26339) LivenessModule_Getters_Test:test_getters_works() (gas: 14853) -LivenessModule_RemoveOwners_Test:test_removeOwners_allOwners_succeeds() (gas: 1311942) -LivenessModule_RemoveOwners_Test:test_removeOwners_oneOwner_succeeds() (gas: 130731) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowMinButNotEmptied_reverts() (gas: 1265044) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_differentArrayLengths_reverts() (gas: 10547) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_guardChanged_reverts() (gas: 2820629) +LivenessModule_RemoveOwners_Test:test_removeOwners_allOwners_succeeds() (gas: 1326177) +LivenessModule_RemoveOwners_Test:test_removeOwners_oneOwner_succeeds() (gas: 133975) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowEmptiedButNotShutDown_reverts() (gas: 1278643) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowMinButNotEmptied_reverts() (gas: 1281685) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_differentArrayLengths_reverts() (gas: 10502) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_guardChanged_reverts() (gas: 2839358) LivenessModule_RemoveOwners_TestFail:test_removeOwners_invalidThreshold_reverts() (gas: 69358) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRecently_reverts() (gas: 77817) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 614867) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallBackOwner_reverts() (gas: 1273705) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRecently_reverts() (gas: 80971) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 617629) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1288036) LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954) MIPS_Test:test_add_succeeds() (gas: 122932) MIPS_Test:test_addiSign_succeeds() (gas: 122923) diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 07382eba2e82..baf78554fc45 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -18,8 +18,8 @@ "src/L2/L2StandardBridge.sol": "0x284ebf5569c75d98f2d1920a276d1116524399355708c4a60ea5892283c56719", "src/L2/L2ToL1MessagePasser.sol": "0xafc710b4d320ef450586d96a61cbd58cac814cb3b0c4fdc280eace3efdcdf321", "src/L2/SequencerFeeVault.sol": "0x883e434a69b4789997a4a9a32060dbbd2e12db6f1970927f1310820336119575", - "src/Safe/LivenessGuard.sol": "0x31b4ecc88c982490243ab42914c3de75e5acfa421ffc0ea0d0f0997dcc0341b5", - "src/Safe/LivenessModule.sol": "0xb8c8178c1f4f78eed4777846a40eda6a3a0c1710085822d92267339ae752799b", + "src/Safe/LivenessGuard.sol": "0xa08460138c22a337f8f5d3a17e02beffe8136c4dba58935cc5c9c2d7ffe1222c", + "src/Safe/LivenessModule.sol": "0x45621d74ea464c75064f9194261d29d47552cf4a9c4f4b3a733f5df5803fc0dd", "src/dispute/BlockOracle.sol": "0x7e724b1ee0116dfd744f556e6237af449c2f40c6426d6f1462ae2a47589283bb", "src/dispute/DisputeGameFactory.sol": "0xfdfa141408d7f8de7e230ff4bef088e30d0e4d569ca743d60d292abdd21ff270", "src/dispute/FaultDisputeGame.sol": "0x0766707ab32338a6586c2340ddfbfd4e9023eeb9dfa3ef87e4b404fb0260479f", From 0dab5fcf4af4ffb53ba239b86c46b5e2be318bff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Oct 2023 22:16:13 +0000 Subject: [PATCH 218/374] build(deps): bump viem from 1.17.1 to 1.18.0 Bumps [viem](https://github.com/wagmi-dev/viem) from 1.17.1 to 1.18.0. - [Release notes](https://github.com/wagmi-dev/viem/releases) - [Commits](https://github.com/wagmi-dev/viem/compare/viem@1.17.1...viem@1.18.0) --- updated-dependencies: - dependency-name: viem dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/contracts-ts/package.json | 2 +- packages/fee-estimation/package.json | 2 +- packages/sdk/package.json | 2 +- packages/web3js-plugin/package.json | 2 +- pnpm-lock.yaml | 62 ++++++++++++++-------------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/contracts-ts/package.json b/packages/contracts-ts/package.json index 5fbd9a45925d..9cd089f4c3fe 100644 --- a/packages/contracts-ts/package.json +++ b/packages/contracts-ts/package.json @@ -82,6 +82,6 @@ "change-case": "4.1.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "viem": "^1.17.1" + "viem": "^1.18.0" } } diff --git a/packages/fee-estimation/package.json b/packages/fee-estimation/package.json index 28d611323354..6cbc34b80625 100644 --- a/packages/fee-estimation/package.json +++ b/packages/fee-estimation/package.json @@ -44,7 +44,7 @@ "jsdom": "^22.1.0", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.17.1", + "viem": "^1.18.0", "vite": "^4.5.0", "vitest": "^0.34.2" }, diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 73f75eb6ddb7..8588f45b2590 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -56,7 +56,7 @@ "ts-node": "^10.9.1", "typedoc": "^0.25.2", "typescript": "^5.2.2", - "viem": "^1.17.1", + "viem": "^1.18.0", "vitest": "^0.34.2", "zod": "^3.22.4" }, diff --git a/packages/web3js-plugin/package.json b/packages/web3js-plugin/package.json index 92222f2a37a8..d64bbb6179b0 100644 --- a/packages/web3js-plugin/package.json +++ b/packages/web3js-plugin/package.json @@ -37,7 +37,7 @@ "@vitest/coverage-istanbul": "^0.34.6", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.17.1", + "viem": "^1.18.0", "vite": "^4.5.0", "vitest": "^0.34.1", "zod": "^3.22.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 857684d175c7..8152a3e6c086 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -298,11 +298,11 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) viem: - specifier: ^1.17.1 - version: 1.17.1(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.0 + version: 1.18.0(typescript@5.2.2)(zod@3.22.4) wagmi: specifier: '>1.0.0' - version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.17.1) + version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) devDependencies: '@eth-optimism/contracts-bedrock': specifier: workspace:* @@ -324,7 +324,7 @@ importers: version: 1.5.2(@wagmi/core@1.4.5)(typescript@5.2.2)(wagmi@1.0.1) '@wagmi/core': specifier: ^1.4.5 - version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.17.1) + version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) abitype: specifier: ^0.10.1 version: 0.10.1(typescript@5.2.2) @@ -438,8 +438,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.17.1 - version: 1.17.1(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.0 + version: 1.18.0(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -529,8 +529,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.17.1 - version: 1.17.1(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.0 + version: 1.18.0(typescript@5.2.2)(zod@3.22.4) vitest: specifier: ^0.34.2 version: 0.34.2 @@ -569,8 +569,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.17.1 - version: 1.17.1(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.0 + version: 1.18.0(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -3219,7 +3219,7 @@ packages: resolution: {integrity: sha512-gYw0ki/EAuV1oSyMxpqandHjnthZjYYy+YWpTAzf8BqfXM3ItcZLpjxfg+3+mXW8HIO+3jw6T9iiqEXsqHaMMw==} dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.7.3 - viem: 1.17.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - bufferutil - encoding @@ -4584,7 +4584,7 @@ packages: wagmi: optional: true dependencies: - '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.17.1) + '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) abort-controller: 3.0.0 bundle-require: 3.1.2(esbuild@0.16.17) @@ -4606,15 +4606,15 @@ packages: picocolors: 1.0.0 prettier: 2.8.8 typescript: 5.2.2 - viem: 1.17.1(typescript@5.2.2)(zod@3.22.3) - wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.17.1) + viem: 1.18.0(typescript@5.2.2)(zod@3.22.3) + wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) zod: 3.22.3 transitivePeerDependencies: - bufferutil - utf-8-validate dev: true - /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.17.1): + /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): resolution: {integrity: sha512-fl01vym19DE1uoE+MlASw5zo3Orr/YXlJRjOKLaKYtV+Q7jOLY4TwHgq7sEMs+JYOvFICFBEAlWNNxidr51AqQ==} peerDependencies: '@wagmi/chains': '>=0.2.0' @@ -4637,7 +4637,7 @@ packages: abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.17.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil @@ -4649,7 +4649,7 @@ packages: - utf-8-validate - zod - /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.17.1): + /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): resolution: {integrity: sha512-UgwsQKQDFObJVJMf9pDfFoXTv710o4zrTHyhIWKBTMMkLpCMsMxN5+ZaDhBYt/BgoRinfRYQo8uwuwLhxE6Log==} peerDependencies: typescript: '>=5.0.4' @@ -4669,7 +4669,7 @@ packages: abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.17.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - '@types/react' @@ -4682,7 +4682,7 @@ packages: - zod dev: true - /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.17.1): + /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): resolution: {integrity: sha512-Zzg4Ob92QMF9NsC+z5/8JZjMn3NCCnwVWGJlv79qRX9mp5Ku40OzJNvqDnjcSGjshe6H0L/KtFZAqTlmu8lT7w==} peerDependencies: typescript: '>=4.9.4' @@ -4692,11 +4692,11 @@ packages: optional: true dependencies: '@wagmi/chains': 0.2.22(typescript@5.2.2) - '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.17.1) + '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.17.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -4710,7 +4710,7 @@ packages: - utf-8-validate - zod - /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.17.1): + /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): resolution: {integrity: sha512-N9luRb1Uk4tBN9kaYcQSWKE9AsRt/rvZaFt5IZech4JPzNN2sQlfhKd9GEjOXYRDqEPHdDvos7qyBKiDNTz4GA==} peerDependencies: typescript: '>=5.0.4' @@ -4719,11 +4719,11 @@ packages: typescript: optional: true dependencies: - '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.17.1) + '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.17.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -14318,8 +14318,8 @@ packages: vfile-message: 2.0.4 dev: true - /viem@1.17.1(typescript@5.2.2)(zod@3.22.3): - resolution: {integrity: sha512-MSbrfntjgIMKPUPdNJ1pnwT1pDfnOzJnKSLqpafw1q+1k6k6M/jxn09g3WbKefIKIok122DcbmviMow+4FqkAg==} + /viem@1.18.0(typescript@5.2.2)(zod@3.22.3): + resolution: {integrity: sha512-NeKi5RFj7fHdsnk5pojivHFLkTyBWyehxeSE/gSPTDJKCWnR9i+Ra0W++VwN5ghciEG55O8b4RdpYhzGmhnr7A==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14341,8 +14341,8 @@ packages: - zod dev: true - /viem@1.17.1(typescript@5.2.2)(zod@3.22.4): - resolution: {integrity: sha512-MSbrfntjgIMKPUPdNJ1pnwT1pDfnOzJnKSLqpafw1q+1k6k6M/jxn09g3WbKefIKIok122DcbmviMow+4FqkAg==} + /viem@1.18.0(typescript@5.2.2)(zod@3.22.4): + resolution: {integrity: sha512-NeKi5RFj7fHdsnk5pojivHFLkTyBWyehxeSE/gSPTDJKCWnR9i+Ra0W++VwN5ghciEG55O8b4RdpYhzGmhnr7A==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14835,7 +14835,7 @@ packages: xml-name-validator: 4.0.0 dev: true - /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.17.1): + /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): resolution: {integrity: sha512-+2UkZG9eA3tKqXj1wvlvI8mL0Bcff7Tf5CKfUOyQsdKcY+J5rfwYYya25G+jja57umpHFtfxRaL7xDkNjehrRg==} peerDependencies: react: '>=17.0.0' @@ -14848,12 +14848,12 @@ packages: '@tanstack/query-sync-storage-persister': 4.29.25 '@tanstack/react-query': 4.29.25(react-dom@18.2.0)(react@18.2.0) '@tanstack/react-query-persist-client': 4.29.25(@tanstack/react-query@4.29.25) - '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.17.1) + '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) abitype: 0.8.1(typescript@5.2.2) react: 18.2.0 typescript: 5.2.2 use-sync-external-store: 1.2.0(react@18.2.0) - viem: 1.17.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil From 7a28c35ed5ae1377020be7f0f4398c9867a4d817 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 30 Oct 2023 11:47:30 +1000 Subject: [PATCH 219/374] batching: Give ContractCall more standalone utility. --- op-service/sources/batching/call.go | 10 +++++++--- op-service/sources/batching/multicall.go | 4 +--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/op-service/sources/batching/call.go b/op-service/sources/batching/call.go index 712a4c40070b..658f5ea4c3b5 100644 --- a/op-service/sources/batching/call.go +++ b/op-service/sources/batching/call.go @@ -42,8 +42,12 @@ func NewContractCall(abi *abi.ABI, addr common.Address, method string, args ...i } } +func (c *ContractCall) Pack() ([]byte, error) { + return c.Abi.Pack(c.Method, c.Args...) +} + func (c *ContractCall) ToCallArgs() (interface{}, error) { - data, err := c.Abi.Pack(c.Method, c.Args...) + data, err := c.Pack() if err != nil { return nil, fmt.Errorf("failed to pack arguments: %w", err) } @@ -54,12 +58,12 @@ func (c *ContractCall) ToCallArgs() (interface{}, error) { return toCallArg(msg), nil } -func (c *ContractCall) Unpack(hex hexutil.Bytes) ([]interface{}, error) { +func (c *ContractCall) Unpack(hex hexutil.Bytes) (*CallResult, error) { out, err := c.Abi.Unpack(c.Method, hex) if err != nil { return nil, fmt.Errorf("failed to unpack data: %w", err) } - return out, nil + return &CallResult{out: out}, nil } type CallResult struct { diff --git a/op-service/sources/batching/multicall.go b/op-service/sources/batching/multicall.go index e4ac34d3f7bf..4c5cf76e89a8 100644 --- a/op-service/sources/batching/multicall.go +++ b/op-service/sources/batching/multicall.go @@ -76,9 +76,7 @@ func (m *MultiCaller) CallLatest(ctx context.Context, calls ...*ContractCall) ([ if err != nil { return nil, fmt.Errorf("failed to unpack result: %w", err) } - callResults[i] = &CallResult{ - out: out, - } + callResults[i] = out } return callResults, nil } From 194c739e10274014084f533911f8f5c270632ec0 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 30 Oct 2023 14:22:25 +1000 Subject: [PATCH 220/374] batching: Add more unit tests. --- op-service/sources/batching/call.go | 20 ++++ op-service/sources/batching/call_test.go | 145 +++++++++++++++++++++++ op-service/sources/batching/multicall.go | 21 ---- 3 files changed, 165 insertions(+), 21 deletions(-) create mode 100644 op-service/sources/batching/call_test.go diff --git a/op-service/sources/batching/call.go b/op-service/sources/batching/call.go index 658f5ea4c3b5..6274c6fcd4a0 100644 --- a/op-service/sources/batching/call.go +++ b/op-service/sources/batching/call.go @@ -66,6 +66,26 @@ func (c *ContractCall) Unpack(hex hexutil.Bytes) (*CallResult, error) { return &CallResult{out: out}, nil } +func toCallArg(msg ethereum.CallMsg) interface{} { + arg := map[string]interface{}{ + "from": msg.From, + "to": msg.To, + } + if len(msg.Data) > 0 { + arg["data"] = hexutil.Bytes(msg.Data) + } + if msg.Value != nil { + arg["value"] = (*hexutil.Big)(msg.Value) + } + if msg.Gas != 0 { + arg["gas"] = hexutil.Uint64(msg.Gas) + } + if msg.GasPrice != nil { + arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice) + } + return arg +} + type CallResult struct { out []interface{} } diff --git a/op-service/sources/batching/call_test.go b/op-service/sources/batching/call_test.go new file mode 100644 index 000000000000..4d5fca721d3e --- /dev/null +++ b/op-service/sources/batching/call_test.go @@ -0,0 +1,145 @@ +package batching + +import ( + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/require" +) + +func TestContractCall_ToCallArgs(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + call := NewContractCall(testAbi, addr, "approve", common.Address{0xcc}, big.NewInt(1234444)) + args, err := call.ToCallArgs() + require.NoError(t, err) + argMap, ok := args.(map[string]interface{}) + require.True(t, ok) + require.Equal(t, argMap["from"], common.Address{}) + require.Equal(t, argMap["to"], &addr) + expectedData, err := call.Pack() + require.NoError(t, err) + require.Equal(t, argMap["data"], hexutil.Bytes(expectedData)) + + require.NotContains(t, argMap, "value") + require.NotContains(t, argMap, "gas") + require.NotContains(t, argMap, "gasPrice") +} + +func TestContractCall_Pack(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + sender := common.Address{0xcc} + amount := big.NewInt(1234444) + call := NewContractCall(testAbi, addr, "approve", sender, amount) + actual, err := call.Pack() + require.NoError(t, err) + + expected, err := testAbi.Pack("approve", sender, amount) + require.NoError(t, err) + require.Equal(t, actual, expected) +} + +func TestContractCall_PackInvalid(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + // Second arg should be a *big.Int so packing should fail + call := NewContractCall(testAbi, addr, "approve", common.Address{0xcc}, uint32(123)) + _, err = call.Pack() + require.Error(t, err) +} + +func TestContractCall_Unpack(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + call := NewContractCall(testAbi, addr, "balanceOf", common.Address{0xcc}) + outputs := testAbi.Methods["balanceOf"].Outputs + expected := big.NewInt(1234) + packed, err := outputs.Pack(expected) + require.NoError(t, err) + + unpacked, err := call.Unpack(packed) + require.NoError(t, err) + require.Equal(t, unpacked.GetBigInt(0), expected) +} + +func TestContractCall_UnpackInvalid(t *testing.T) { + addr := common.Address{0xbd} + testAbi, err := bindings.ERC20MetaData.GetAbi() + require.NoError(t, err) + call := NewContractCall(testAbi, addr, "balanceOf", common.Address{0xcc}) + + // Input data is the wrong format and won't unpack successfully + inputPacked, err := call.Pack() + require.NoError(t, err) + + _, err = call.Unpack(inputPacked) + require.Error(t, err) +} + +func TestCallResult_GetValues(t *testing.T) { + tests := []struct { + name string + getter func(result *CallResult, i int) interface{} + expected interface{} + }{ + { + name: "GetUint8", + getter: func(result *CallResult, i int) interface{} { + return result.GetUint8(i) + }, + expected: uint8(12), + }, + { + name: "GetUint32", + getter: func(result *CallResult, i int) interface{} { + return result.GetUint32(i) + }, + expected: uint32(12346), + }, + { + name: "GetUint64", + getter: func(result *CallResult, i int) interface{} { + return result.GetUint64(i) + }, + expected: uint64(12346), + }, + { + name: "GetBool", + getter: func(result *CallResult, i int) interface{} { + return result.GetBool(i) + }, + expected: true, + }, + { + name: "GetHash", + getter: func(result *CallResult, i int) interface{} { + return result.GetHash(i) + }, + expected: ([32]byte)(common.Hash{0xaa, 0xbb, 0xcc}), + }, + { + name: "GetBigInt", + getter: func(result *CallResult, i int) interface{} { + return result.GetBigInt(i) + }, + expected: big.NewInt(2398423), + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + callResult := &CallResult{[]interface{}{nil, 0, "abc", test.expected, "xyz", 3, nil}} + actual := test.getter(callResult, 3) + require.EqualValues(t, test.expected, actual) + }) + } +} diff --git a/op-service/sources/batching/multicall.go b/op-service/sources/batching/multicall.go index 4c5cf76e89a8..0ff035ccf94c 100644 --- a/op-service/sources/batching/multicall.go +++ b/op-service/sources/batching/multicall.go @@ -5,7 +5,6 @@ import ( "fmt" "io" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rpc" ) @@ -80,23 +79,3 @@ func (m *MultiCaller) CallLatest(ctx context.Context, calls ...*ContractCall) ([ } return callResults, nil } - -func toCallArg(msg ethereum.CallMsg) interface{} { - arg := map[string]interface{}{ - "from": msg.From, - "to": msg.To, - } - if len(msg.Data) > 0 { - arg["data"] = hexutil.Bytes(msg.Data) - } - if msg.Value != nil { - arg["value"] = (*hexutil.Big)(msg.Value) - } - if msg.Gas != 0 { - arg["gas"] = hexutil.Uint64(msg.Gas) - } - if msg.GasPrice != nil { - arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice) - } - return arg -} From 53a60cedd3ed79ca1568eb658d4baca1bf032013 Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 30 Oct 2023 01:06:08 -0400 Subject: [PATCH 221/374] Persist Rust toolchain in final `ci-builder` image --- ops/docker/ci-builder/Dockerfile | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/ops/docker/ci-builder/Dockerfile b/ops/docker/ci-builder/Dockerfile index 4f7cf7234978..7dd7a8810dcb 100644 --- a/ops/docker/ci-builder/Dockerfile +++ b/ops/docker/ci-builder/Dockerfile @@ -12,6 +12,9 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup.sh && \ chmod +x ./rustup.sh && \ ./rustup.sh -y +# Install nightly toolchain +RUN source $HOME/.profile && rustup update nightly + RUN source $HOME/.profile && cargo install just RUN source $HOME/.profile && cargo install svm-rs @@ -59,8 +62,12 @@ FROM --platform=linux/amd64 python:3.11.4-slim-bullseye ENV GOPATH=/go ENV PATH=/usr/local/go/bin:$GOPATH/bin:$PATH +ENV PATH=/root/.cargo/bin:$PATH ENV DEBIAN_FRONTEND=noninteractive +# Create rust directories for copying the installation into +RUN mkdir /root/.cargo && mkdir /root/.cargo/bin && mkdir /root/.rustup + # copy the go installation, but not the module cache (cache will get stale, and would add a lot of weight) COPY --from=go-build /usr/local/go /usr/local/go # copy tools @@ -69,11 +76,15 @@ COPY --from=go-build /go/bin/mockery /go/bin/mockery COPY --from=go-build /go/bin/golangci-lint /go/bin/golangci-lint COPY --from=go-build /go/bin/abigen /usr/local/bin/abigen COPY --from=go-build /go/bin/geth /usr/local/bin/geth -COPY --from=rust-build /root/.cargo/bin/svm /usr/local/bin/svm -COPY --from=rust-build /root/.cargo/bin/just /usr/local/bin/just + +# copy the rust installation, alongside the installed toolchains +COPY --from=rust-build /root/.cargo/bin /root/.cargo/bin +COPY --from=rust-build /root/.rustup /root/.rustup +# copy tools COPY --from=rust-build /opt/foundry/target/release/forge /usr/local/bin/forge COPY --from=rust-build /opt/foundry/target/release/cast /usr/local/bin/cast COPY --from=rust-build /opt/foundry/target/release/anvil /usr/local/bin/anvil + COPY --from=echidna-test /usr/local/bin/echidna-test /usr/local/bin/echidna-test COPY .nvmrc .nvmrc @@ -84,7 +95,7 @@ ENV SLITHER_VERSION=0.10.0 # note: python3 package in apt is python 3.9, while base image already has python 3.11 RUN /bin/sh -c set -eux; \ apt-get update; \ - apt-get install -y --no-install-recommends bash curl openssh-client git build-essential ca-certificates jq gnupg binutils-mips-linux-gnu; \ + apt-get install -y --no-install-recommends bash curl openssh-client git build-essential pkg-config libssl-dev clang libclang-dev ca-certificates jq gnupg binutils-mips-linux-gnu; \ mkdir -p /etc/apt/keyrings; \ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg; \ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list; \ From db016e6e0aa73cced5176f41b8f52c28362af3d6 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 30 Oct 2023 17:06:31 +1000 Subject: [PATCH 222/374] op-e2e: Remove manual test code. --- op-e2e/faultproof_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/op-e2e/faultproof_test.go b/op-e2e/faultproof_test.go index 0cfdbbe97dc8..7857fbbee0f7 100644 --- a/op-e2e/faultproof_test.go +++ b/op-e2e/faultproof_test.go @@ -559,9 +559,6 @@ func setupDisputeGameForInvalidOutputRoot(t *testing.T, outputRoot common.Hash) func TestCannonChallengeWithCorrectRoot(t *testing.T) { InitParallel(t, UsesCannon, UseExecutor(0)) - if true { - return - } ctx := context.Background() sys, l1Client := startFaultDisputeSystem(t) t.Cleanup(sys.Close) From 9a6ed52657001a6d66699f7de86902e10632e643 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 30 Oct 2023 14:49:29 +0300 Subject: [PATCH 223/374] ci-builder: include solc 0.8.19 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The other 2 compiler versions are included in `ci-builder` so we should also include `0.8.19`. This will save us from needing to download the compiler in CI many times. The following lines are logged in CI: ``` 3[2K[â †]3[2Ktalling solc version 0.8.19[â °]3[2Ktalling solc version 0.8.19[â ”] Installing solc version 0.8.19 3[2K[â ’]3[2Kcessfully installed solc 0.8.19[â ‘] Successfully installed solc 0.8.19 ``` These lines are not logged for the other 2 solc versions that are included in `ci-builder` because they are already downloaded. --- ops/docker/ci-builder/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ops/docker/ci-builder/Dockerfile b/ops/docker/ci-builder/Dockerfile index ab9f0565c258..b7e2d6a3e3e2 100644 --- a/ops/docker/ci-builder/Dockerfile +++ b/ops/docker/ci-builder/Dockerfile @@ -103,7 +103,8 @@ RUN /bin/sh -c set -eux; \ RUN npm i -g pnpm && npm i -g yarn@1 && pnpm --version && yarn --version RUN svm install 0.5.17 && \ - svm install 0.8.15 + svm install 0.8.15 && \ + svm install 0.8.19 RUN echo "downloading and verifying Codecov uploader" && \ curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import && \ From 381bbb8104437f2e19316824afba03f227a8d226 Mon Sep 17 00:00:00 2001 From: protolambda Date: Mon, 30 Oct 2023 13:25:26 +0100 Subject: [PATCH 224/374] derive: remove outdated channel-out TODOs --- op-node/rollup/derive/channel_out.go | 3 +-- op-node/rollup/derive/span_channel_out.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/op-node/rollup/derive/channel_out.go b/op-node/rollup/derive/channel_out.go index 642c32ac06aa..5eb559678f6a 100644 --- a/op-node/rollup/derive/channel_out.go +++ b/op-node/rollup/derive/channel_out.go @@ -91,7 +91,7 @@ func (co *SingularChannelOut) ID() ChannelID { func NewSingularChannelOut(compress Compressor) (*SingularChannelOut, error) { c := &SingularChannelOut{ - id: ChannelID{}, // TODO: use GUID here instead of fully random data + id: ChannelID{}, frame: 0, rlpLength: 0, compress: compress, @@ -104,7 +104,6 @@ func NewSingularChannelOut(compress Compressor) (*SingularChannelOut, error) { return c, nil } -// TODO: reuse SingularChannelOut for performance func (co *SingularChannelOut) Reset() error { co.frame = 0 co.rlpLength = 0 diff --git a/op-node/rollup/derive/span_channel_out.go b/op-node/rollup/derive/span_channel_out.go index 608257b7bbb3..b509247fb704 100644 --- a/op-node/rollup/derive/span_channel_out.go +++ b/op-node/rollup/derive/span_channel_out.go @@ -34,7 +34,7 @@ func (co *SpanChannelOut) ID() ChannelID { func NewSpanChannelOut(compress Compressor, spanBatchBuilder *SpanBatchBuilder) (*SpanChannelOut, error) { c := &SpanChannelOut{ - id: ChannelID{}, // TODO: use GUID here instead of fully random data + id: ChannelID{}, frame: 0, rlpLength: 0, compress: compress, @@ -49,7 +49,6 @@ func NewSpanChannelOut(compress Compressor, spanBatchBuilder *SpanBatchBuilder) return c, nil } -// TODO: reuse ChannelOut for performance func (co *SpanChannelOut) Reset() error { co.frame = 0 co.rlpLength = 0 From ea8ffecef9a614f912ed9aefda95b1f205da4966 Mon Sep 17 00:00:00 2001 From: protolambda Date: Mon, 30 Oct 2023 13:30:25 +0100 Subject: [PATCH 225/374] op-batcher: remove outdated comment --- op-batcher/batcher/channel_manager.go | 1 - 1 file changed, 1 deletion(-) diff --git a/op-batcher/batcher/channel_manager.go b/op-batcher/batcher/channel_manager.go index 5829e3dc448b..8100a3a2826e 100644 --- a/op-batcher/batcher/channel_manager.go +++ b/op-batcher/batcher/channel_manager.go @@ -59,7 +59,6 @@ func NewChannelManager(log log.Logger, metr metrics.Metricer, cfg ChannelConfig, // Clear clears the entire state of the channel manager. // It is intended to be used before launching op-batcher and after an L2 reorg. -// Must set lastProcessedBlock as current L2 safe head fetched from L2 node. func (s *channelManager) Clear() { s.mu.Lock() defer s.mu.Unlock() From dbdcde31732bdcc2979f3b2eda081855d294236a Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Mon, 16 Oct 2023 16:59:56 +0900 Subject: [PATCH 226/374] Make MaxSpanBatchFieldSize equal to MaxRLPBytesPerChannel --- op-node/rollup/derive/params.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-node/rollup/derive/params.go b/op-node/rollup/derive/params.go index 469899c3aae5..27bac5532318 100644 --- a/op-node/rollup/derive/params.go +++ b/op-node/rollup/derive/params.go @@ -22,7 +22,7 @@ const DerivationVersion0 = 0 // MaxSpanBatchFieldSize is the maximum amount of bytes that will be read from // a span batch to decode span batch field. This value cannot be larger than // MaxRLPBytesPerChannel because single batch cannot be larger than channel size. -const MaxSpanBatchFieldSize = 10_000_000 +const MaxSpanBatchFieldSize = MaxRLPBytesPerChannel // MaxChannelBankSize is the amount of memory space, in number of bytes, // till the bank is pruned by removing channels, From 177b78c5599804fb99135421a78d2b852c4abcf2 Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Mon, 16 Oct 2023 17:01:20 +0900 Subject: [PATCH 227/374] Harden Span batch field size check --- op-node/rollup/derive/span_batch.go | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/op-node/rollup/derive/span_batch.go b/op-node/rollup/derive/span_batch.go index 770eb58b7008..f178b51c3559 100644 --- a/op-node/rollup/derive/span_batch.go +++ b/op-node/rollup/derive/span_batch.go @@ -9,12 +9,14 @@ import ( "math/big" "sort" - "github.com/ethereum-optimism/optimism/op-node/rollup" - "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" ) // Batch format @@ -144,10 +146,14 @@ func (bp *spanBatchPayload) decodeBlockCount(r *bytes.Reader) error { if err != nil { return fmt.Errorf("failed to read block count: %w", err) } - bp.blockCount = blockCount + // number of L2 block in span batch cannot be greater than MaxSpanBatchFieldSize + if blockCount > MaxSpanBatchFieldSize { + return ErrTooBigSpanBatchFieldSize + } if blockCount == 0 { return ErrEmptySpanBatch } + bp.blockCount = blockCount return nil } @@ -160,6 +166,11 @@ func (bp *spanBatchPayload) decodeBlockTxCounts(r *bytes.Reader) error { if err != nil { return fmt.Errorf("failed to read block tx count: %w", err) } + // number of txs in single L2 block cannot be greater than MaxSpanBatchFieldSize + // every tx will take at least single byte + if blockTxCount > MaxSpanBatchFieldSize { + return ErrTooBigSpanBatchFieldSize + } blockTxCounts = append(blockTxCounts, blockTxCount) } bp.blockTxCounts = blockTxCounts @@ -176,7 +187,15 @@ func (bp *spanBatchPayload) decodeTxs(r *bytes.Reader) error { } totalBlockTxCount := uint64(0) for i := 0; i < len(bp.blockTxCounts); i++ { - totalBlockTxCount += bp.blockTxCounts[i] + total, overflow := math.SafeAdd(totalBlockTxCount, bp.blockTxCounts[i]) + if overflow { + return ErrTooBigSpanBatchFieldSize + } + totalBlockTxCount = total + } + // total number of txs in span batch cannot be greater than MaxSpanBatchFieldSize + if totalBlockTxCount > MaxSpanBatchFieldSize { + return ErrTooBigSpanBatchFieldSize } bp.txs.totalBlockTxCount = totalBlockTxCount if err := bp.txs.decode(r); err != nil { From c6d39019b56c743f43394623811a89325545eadb Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Mon, 16 Oct 2023 17:01:39 +0900 Subject: [PATCH 228/374] Add tests for span batch field size check --- op-node/rollup/derive/span_batch_test.go | 62 +++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/op-node/rollup/derive/span_batch_test.go b/op-node/rollup/derive/span_batch_test.go index a4929467ac35..7b3793738e12 100644 --- a/op-node/rollup/derive/span_batch_test.go +++ b/op-node/rollup/derive/span_batch_test.go @@ -2,6 +2,7 @@ package derive import ( "bytes" + "math" "math/big" "math/rand" "testing" @@ -542,9 +543,68 @@ func TestSpanBatchMaxTxData(t *testing.T) { func TestSpanBatchMaxOriginBitsLength(t *testing.T) { var sb RawSpanBatch - sb.blockCount = 0xFFFFFFFFFFFFFFFF + sb.blockCount = math.MaxUint64 r := bytes.NewReader([]byte{}) err := sb.decodeOriginBits(r) assert.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) } + +func TestSpanBatchMaxBlockCount(t *testing.T) { + rng := rand.New(rand.NewSource(0x77556691)) + chainID := big.NewInt(rng.Int63n(1000)) + + rawSpanBatch := RandomRawSpanBatch(rng, chainID) + rawSpanBatch.blockCount = math.MaxUint64 + + var buf bytes.Buffer + err := rawSpanBatch.encodeBlockCount(&buf) + require.NoError(t, err) + + result := buf.Bytes() + r := bytes.NewReader(result) + var sb RawSpanBatch + err = sb.decodeBlockCount(r) + require.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) +} + +func TestSpanBatchMaxBlockTxCount(t *testing.T) { + rng := rand.New(rand.NewSource(0x77556692)) + chainID := big.NewInt(rng.Int63n(1000)) + + rawSpanBatch := RandomRawSpanBatch(rng, chainID) + rawSpanBatch.blockTxCounts[0] = math.MaxUint64 + + var buf bytes.Buffer + err := rawSpanBatch.encodeBlockTxCounts(&buf) + require.NoError(t, err) + + result := buf.Bytes() + r := bytes.NewReader(result) + var sb RawSpanBatch + sb.blockCount = rawSpanBatch.blockCount + err = sb.decodeBlockTxCounts(r) + require.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) +} + +func TestSpanBatchTotalBlockTxCountNotOverflow(t *testing.T) { + rng := rand.New(rand.NewSource(0x77556693)) + chainID := big.NewInt(rng.Int63n(1000)) + + rawSpanBatch := RandomRawSpanBatch(rng, chainID) + rawSpanBatch.blockTxCounts[0] = MaxSpanBatchFieldSize - 1 + rawSpanBatch.blockTxCounts[1] = MaxSpanBatchFieldSize - 1 + // we are sure that totalBlockTxCount will overflow on uint64 + + var buf bytes.Buffer + err := rawSpanBatch.encodeBlockTxCounts(&buf) + require.NoError(t, err) + + result := buf.Bytes() + r := bytes.NewReader(result) + var sb RawSpanBatch + sb.blockTxCounts = rawSpanBatch.blockTxCounts + err = sb.decodeTxs(r) + + require.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) +} From c0d92e6646456d76fc779845e18ca6ee23611a40 Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Mon, 16 Oct 2023 18:52:53 +0900 Subject: [PATCH 229/374] Add comments for l1Blocks field of batch queue --- op-node/rollup/derive/batch_queue.go | 6 ++++++ op-node/rollup/derive/batches.go | 1 + 2 files changed, 7 insertions(+) diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index b12f08c54fbd..420e0ce928e5 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -45,6 +45,12 @@ type BatchQueue struct { prev NextBatchProvider origin eth.L1BlockRef + // l1Blocks contains consecutive eth.L1BlockRef sorted by time. + // Every L1 origin of unsafe L2 blocks must be eventually included in l1Blocks. + // Batch queue's job is to ensure below two rules: + // If every L2 block corresponding to single L1 block becomes safe, it will be popped from l1Blocks. + // If new L2 block's L1 origin is not included in l1Blocks, fetch and push to l1Blocks. + // length of l1Blocks never exceeds SequencerWindowSize l1Blocks []eth.L1BlockRef // batches in order of when we've first seen them diff --git a/op-node/rollup/derive/batches.go b/op-node/rollup/derive/batches.go index e618fcc7433a..ee64eda4519c 100644 --- a/op-node/rollup/derive/batches.go +++ b/op-node/rollup/derive/batches.go @@ -236,6 +236,7 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B endEpochNum := batch.GetBlockEpochNum(batch.GetBlockCount() - 1) originChecked := false + // l1Blocks is supplied from batch queue and its length is limited to SequencerWindowSize. for _, l1Block := range l1Blocks { if l1Block.Number == endEpochNum { if !batch.CheckOriginHash(l1Block.Hash) { From 51866cdba16d275fa834d5d0537c07ae3c09a955 Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Mon, 16 Oct 2023 22:31:54 +0900 Subject: [PATCH 230/374] Update spec for span batch field limit --- specs/span-batches.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/specs/span-batches.md b/specs/span-batches.md index 3314a19aa457..c28026e7104a 100644 --- a/specs/span-batches.md +++ b/specs/span-batches.md @@ -144,6 +144,14 @@ Where: [EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559 +Every field size of span batch is limited to `MAX_SPAN_BATCH_FIELD_SIZE` (currently 10,000,000 bytes, +equal to `MAX_RLP_BYTES_PER_CHANNEL`). There can be at least single span batch per channel, and channel size is limited +to `MAX_RLP_BYTES_PER_CHANNEL` and you may think that there is already an implicit limit. However, having an explicit +limit for each field is helpful for several reasons. We may save computation costs by avoiding malicious input while +decoding. For example, lets say bad batcher wrote span batch which `block_count = max.Uint64`. We may early return using +the explicit limit, not trying to consume data until EOF is reached. We can also safely preallocate memory for decoding +because we know the upper limit of memory usage. + ## Optimization Strategies ### Truncating information and storing only necessary data From f4e24507dfc2feac7a7dd0b9374f4c5c2c9277c2 Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Tue, 17 Oct 2023 16:23:31 +0900 Subject: [PATCH 231/374] Rename variable and explanations span batch limit --- op-node/rollup/derive/params.go | 6 ++-- op-node/rollup/derive/span_batch.go | 38 ++++++++++++-------- op-node/rollup/derive/span_batch_test.go | 16 ++++----- op-node/rollup/derive/span_batch_txs.go | 8 ++--- op-node/rollup/derive/span_batch_txs_test.go | 4 +-- specs/span-batches.md | 7 ++-- 6 files changed, 44 insertions(+), 35 deletions(-) diff --git a/op-node/rollup/derive/params.go b/op-node/rollup/derive/params.go index 27bac5532318..bba78cc2dfee 100644 --- a/op-node/rollup/derive/params.go +++ b/op-node/rollup/derive/params.go @@ -19,10 +19,10 @@ func frameSize(frame Frame) uint64 { const DerivationVersion0 = 0 -// MaxSpanBatchFieldSize is the maximum amount of bytes that will be read from -// a span batch to decode span batch field. This value cannot be larger than +// MaxSpanBatchSize is the maximum amount of bytes that will be needed +// to decode every span batch field. This value cannot be larger than // MaxRLPBytesPerChannel because single batch cannot be larger than channel size. -const MaxSpanBatchFieldSize = MaxRLPBytesPerChannel +const MaxSpanBatchSize = MaxRLPBytesPerChannel // MaxChannelBankSize is the amount of memory space, in number of bytes, // till the bank is pruned by removing channels, diff --git a/op-node/rollup/derive/span_batch.go b/op-node/rollup/derive/span_batch.go index f178b51c3559..fc516f5a76ca 100644 --- a/op-node/rollup/derive/span_batch.go +++ b/op-node/rollup/derive/span_batch.go @@ -27,7 +27,7 @@ import ( // payload := block_count ++ origin_bits ++ block_tx_counts ++ txs // txs := contract_creation_bits ++ y_parity_bits ++ tx_sigs ++ tx_tos ++ tx_datas ++ tx_nonces ++ tx_gases -var ErrTooBigSpanBatchFieldSize = errors.New("batch would cause field bytes to go over limit") +var ErrTooBigSpanBatchSize = errors.New("span batch size limit reached") var ErrEmptySpanBatch = errors.New("span-batch must not be empty") @@ -59,8 +59,8 @@ func (bp *spanBatchPayload) decodeOriginBits(r *bytes.Reader) error { originBitBufferLen++ } // avoid out of memory before allocation - if originBitBufferLen > MaxSpanBatchFieldSize { - return ErrTooBigSpanBatchFieldSize + if originBitBufferLen > MaxSpanBatchSize { + return ErrTooBigSpanBatchSize } originBitBuffer := make([]byte, originBitBufferLen) _, err := io.ReadFull(r, originBitBuffer) @@ -146,9 +146,9 @@ func (bp *spanBatchPayload) decodeBlockCount(r *bytes.Reader) error { if err != nil { return fmt.Errorf("failed to read block count: %w", err) } - // number of L2 block in span batch cannot be greater than MaxSpanBatchFieldSize - if blockCount > MaxSpanBatchFieldSize { - return ErrTooBigSpanBatchFieldSize + // number of L2 block in span batch cannot be greater than MaxSpanBatchSize + if blockCount > MaxSpanBatchSize { + return ErrTooBigSpanBatchSize } if blockCount == 0 { return ErrEmptySpanBatch @@ -166,10 +166,10 @@ func (bp *spanBatchPayload) decodeBlockTxCounts(r *bytes.Reader) error { if err != nil { return fmt.Errorf("failed to read block tx count: %w", err) } - // number of txs in single L2 block cannot be greater than MaxSpanBatchFieldSize + // number of txs in single L2 block cannot be greater than MaxSpanBatchSize // every tx will take at least single byte - if blockTxCount > MaxSpanBatchFieldSize { - return ErrTooBigSpanBatchFieldSize + if blockTxCount > MaxSpanBatchSize { + return ErrTooBigSpanBatchSize } blockTxCounts = append(blockTxCounts, blockTxCount) } @@ -189,13 +189,13 @@ func (bp *spanBatchPayload) decodeTxs(r *bytes.Reader) error { for i := 0; i < len(bp.blockTxCounts); i++ { total, overflow := math.SafeAdd(totalBlockTxCount, bp.blockTxCounts[i]) if overflow { - return ErrTooBigSpanBatchFieldSize + return ErrTooBigSpanBatchSize } totalBlockTxCount = total } - // total number of txs in span batch cannot be greater than MaxSpanBatchFieldSize - if totalBlockTxCount > MaxSpanBatchFieldSize { - return ErrTooBigSpanBatchFieldSize + // total number of txs in span batch cannot be greater than MaxSpanBatchSize + if totalBlockTxCount > MaxSpanBatchSize { + return ErrTooBigSpanBatchSize } bp.txs.totalBlockTxCount = totalBlockTxCount if err := bp.txs.decode(r); err != nil { @@ -224,6 +224,14 @@ func (bp *spanBatchPayload) decodePayload(r *bytes.Reader) error { // decodeBytes parses data into b from data func (b *RawSpanBatch) decodeBytes(data []byte) error { r := bytes.NewReader(data) + return b.decode(r) +} + +// decode reads the byte encoding of SpanBatch from Reader stream +func (b *RawSpanBatch) decode(r *bytes.Reader) error { + if r.Len() > MaxSpanBatchSize { + return ErrTooBigSpanBatchSize + } if err := b.decodePrefix(r); err != nil { return err } @@ -680,13 +688,13 @@ func ReadTxData(r *bytes.Reader) ([]byte, int, error) { } } // avoid out of memory before allocation - s := rlp.NewStream(r, MaxSpanBatchFieldSize) + s := rlp.NewStream(r, MaxSpanBatchSize) var txPayload []byte kind, _, err := s.Kind() switch { case err != nil: if errors.Is(err, rlp.ErrValueTooLarge) { - return nil, 0, ErrTooBigSpanBatchFieldSize + return nil, 0, ErrTooBigSpanBatchSize } return nil, 0, fmt.Errorf("failed to read tx RLP prefix: %w", err) case kind == rlp.List: diff --git a/op-node/rollup/derive/span_batch_test.go b/op-node/rollup/derive/span_batch_test.go index 7b3793738e12..0795b2062434 100644 --- a/op-node/rollup/derive/span_batch_test.go +++ b/op-node/rollup/derive/span_batch_test.go @@ -529,7 +529,7 @@ func TestSpanBatchMaxTxData(t *testing.T) { rng := rand.New(rand.NewSource(0x177288)) invalidTx := types.NewTx(&types.DynamicFeeTx{ - Data: testutils.RandomData(rng, MaxSpanBatchFieldSize+1), + Data: testutils.RandomData(rng, MaxSpanBatchSize+1), }) txEncoded, err := invalidTx.MarshalBinary() @@ -538,7 +538,7 @@ func TestSpanBatchMaxTxData(t *testing.T) { r := bytes.NewReader(txEncoded) _, _, err = ReadTxData(r) - assert.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) + require.ErrorIs(t, err, ErrTooBigSpanBatchSize) } func TestSpanBatchMaxOriginBitsLength(t *testing.T) { @@ -547,7 +547,7 @@ func TestSpanBatchMaxOriginBitsLength(t *testing.T) { r := bytes.NewReader([]byte{}) err := sb.decodeOriginBits(r) - assert.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) + require.ErrorIs(t, err, ErrTooBigSpanBatchSize) } func TestSpanBatchMaxBlockCount(t *testing.T) { @@ -565,7 +565,7 @@ func TestSpanBatchMaxBlockCount(t *testing.T) { r := bytes.NewReader(result) var sb RawSpanBatch err = sb.decodeBlockCount(r) - require.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) + require.ErrorIs(t, err, ErrTooBigSpanBatchSize) } func TestSpanBatchMaxBlockTxCount(t *testing.T) { @@ -584,7 +584,7 @@ func TestSpanBatchMaxBlockTxCount(t *testing.T) { var sb RawSpanBatch sb.blockCount = rawSpanBatch.blockCount err = sb.decodeBlockTxCounts(r) - require.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) + require.ErrorIs(t, err, ErrTooBigSpanBatchSize) } func TestSpanBatchTotalBlockTxCountNotOverflow(t *testing.T) { @@ -592,8 +592,8 @@ func TestSpanBatchTotalBlockTxCountNotOverflow(t *testing.T) { chainID := big.NewInt(rng.Int63n(1000)) rawSpanBatch := RandomRawSpanBatch(rng, chainID) - rawSpanBatch.blockTxCounts[0] = MaxSpanBatchFieldSize - 1 - rawSpanBatch.blockTxCounts[1] = MaxSpanBatchFieldSize - 1 + rawSpanBatch.blockTxCounts[0] = MaxSpanBatchSize - 1 + rawSpanBatch.blockTxCounts[1] = MaxSpanBatchSize - 1 // we are sure that totalBlockTxCount will overflow on uint64 var buf bytes.Buffer @@ -606,5 +606,5 @@ func TestSpanBatchTotalBlockTxCountNotOverflow(t *testing.T) { sb.blockTxCounts = rawSpanBatch.blockTxCounts err = sb.decodeTxs(r) - require.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) + require.ErrorIs(t, err, ErrTooBigSpanBatchSize) } diff --git a/op-node/rollup/derive/span_batch_txs.go b/op-node/rollup/derive/span_batch_txs.go index 17dd13262346..4f2fe19b58ed 100644 --- a/op-node/rollup/derive/span_batch_txs.go +++ b/op-node/rollup/derive/span_batch_txs.go @@ -67,8 +67,8 @@ func (btx *spanBatchTxs) decodeContractCreationBits(r *bytes.Reader) error { contractCreationBitBufferLen++ } // avoid out of memory before allocation - if contractCreationBitBufferLen > MaxSpanBatchFieldSize { - return ErrTooBigSpanBatchFieldSize + if contractCreationBitBufferLen > MaxSpanBatchSize { + return ErrTooBigSpanBatchSize } contractCreationBitBuffer := make([]byte, contractCreationBitBufferLen) _, err := io.ReadFull(r, contractCreationBitBuffer) @@ -190,8 +190,8 @@ func (btx *spanBatchTxs) decodeYParityBits(r *bytes.Reader) error { yParityBitBufferLen++ } // avoid out of memory before allocation - if yParityBitBufferLen > MaxSpanBatchFieldSize { - return ErrTooBigSpanBatchFieldSize + if yParityBitBufferLen > MaxSpanBatchSize { + return ErrTooBigSpanBatchSize } yParityBitBuffer := make([]byte, yParityBitBufferLen) _, err := io.ReadFull(r, yParityBitBuffer) diff --git a/op-node/rollup/derive/span_batch_txs_test.go b/op-node/rollup/derive/span_batch_txs_test.go index f393c8df70f4..2ef2c353bd54 100644 --- a/op-node/rollup/derive/span_batch_txs_test.go +++ b/op-node/rollup/derive/span_batch_txs_test.go @@ -391,7 +391,7 @@ func TestSpanBatchTxsMaxContractCreationBitsLength(t *testing.T) { r := bytes.NewReader([]byte{}) err := sbt.decodeContractCreationBits(r) - assert.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) + require.ErrorIs(t, err, ErrTooBigSpanBatchSize) } func TestSpanBatchTxsMaxYParityBitsLength(t *testing.T) { @@ -400,5 +400,5 @@ func TestSpanBatchTxsMaxYParityBitsLength(t *testing.T) { r := bytes.NewReader([]byte{}) err := sb.decodeOriginBits(r) - assert.ErrorIs(t, err, ErrTooBigSpanBatchFieldSize) + require.ErrorIs(t, err, ErrTooBigSpanBatchSize) } diff --git a/specs/span-batches.md b/specs/span-batches.md index c28026e7104a..0b0738497e03 100644 --- a/specs/span-batches.md +++ b/specs/span-batches.md @@ -144,10 +144,11 @@ Where: [EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559 -Every field size of span batch is limited to `MAX_SPAN_BATCH_FIELD_SIZE` (currently 10,000,000 bytes, -equal to `MAX_RLP_BYTES_PER_CHANNEL`). There can be at least single span batch per channel, and channel size is limited +Total size of encoded span batch is limited to `MAX_SPAN_BATCH_SIZE` (currently 10,000,000 bytes, +equal to `MAX_RLP_BYTES_PER_CHANNEL`). Therefore every field size of span batch will be implicitly limited to +`MAX_SPAN_BATCH_SIZE` . There can be at least single span batch per channel, and channel size is limited to `MAX_RLP_BYTES_PER_CHANNEL` and you may think that there is already an implicit limit. However, having an explicit -limit for each field is helpful for several reasons. We may save computation costs by avoiding malicious input while +limit for span batch is helpful for several reasons. We may save computation costs by avoiding malicious input while decoding. For example, lets say bad batcher wrote span batch which `block_count = max.Uint64`. We may early return using the explicit limit, not trying to consume data until EOF is reached. We can also safely preallocate memory for decoding because we know the upper limit of memory usage. From 70e060c16dfe52da8875e7e22b3749d9c6d64398 Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Fri, 20 Oct 2023 14:14:13 +0900 Subject: [PATCH 232/374] op-node/derive: use require instead of assert in span-batch tests --- op-node/rollup/derive/span_batch_txs_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/op-node/rollup/derive/span_batch_txs_test.go b/op-node/rollup/derive/span_batch_txs_test.go index 2ef2c353bd54..8f9162e4d35e 100644 --- a/op-node/rollup/derive/span_batch_txs_test.go +++ b/op-node/rollup/derive/span_batch_txs_test.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/holiman/uint256" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSpanBatchTxsContractCreationBits(t *testing.T) { From 72cd648294c929ebf6674ce7b1685cb182d2a501 Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Tue, 10 Oct 2023 16:47:57 +0900 Subject: [PATCH 233/374] op-node: Span Batch type/encoding/decoding refactor Refactor Span batch type Remove unused methods Explicit protocol constant Update type of parentCheck and l1OriginCheck Use require instead of assert in tests Refactor RandomTx Refactor Span batch tx tests Adjust tnf to fix test Update comments Co-authored-by: pcw109550 --- op-batcher/batcher/channel_builder_test.go | 6 +- op-e2e/actions/garbage_channel_out.go | 18 +- .../batch_decoder/reassemble/reassemble.go | 20 +- op-node/rollup/derive/batch.go | 71 +++--- op-node/rollup/derive/batch_test.go | 85 +++---- op-node/rollup/derive/batch_tob_test.go | 8 +- op-node/rollup/derive/channel_in_reader.go | 17 +- op-node/rollup/derive/channel_out.go | 2 +- op-node/rollup/derive/singular_batch.go | 24 ++ op-node/rollup/derive/singular_batch_test.go | 8 +- op-node/rollup/derive/span_batch.go | 56 ++--- op-node/rollup/derive/span_batch_test.go | 210 +++++++++--------- op-node/rollup/derive/span_batch_tx.go | 46 ---- op-node/rollup/derive/span_batch_tx_test.go | 158 ++++++------- op-node/rollup/derive/span_batch_txs_test.go | 89 ++++---- op-node/rollup/derive/span_channel_out.go | 4 +- op-service/testutils/random.go | 96 +++++--- 17 files changed, 461 insertions(+), 457 deletions(-) diff --git a/op-batcher/batcher/channel_builder_test.go b/op-batcher/batcher/channel_builder_test.go index db8e74e2e932..5ee5c5367134 100644 --- a/op-batcher/batcher/channel_builder_test.go +++ b/op-batcher/batcher/channel_builder_test.go @@ -759,7 +759,7 @@ func TestFramePublished(t *testing.T) { } func ChannelBuilder_PendingFrames_TotalFrames(t *testing.T, batchType uint) { - const tnf = 8 + const tnf = 9 rng := rand.New(rand.NewSource(94572314)) require := require.New(t) cfg := defaultTestChannelConfig @@ -828,7 +828,7 @@ func ChannelBuilder_InputBytes(t *testing.T, batchType uint) { spanBatchBuilder.AppendSingularBatch(singularBatch, l1Info.SequenceNumber) rawSpanBatch, err := spanBatchBuilder.GetRawSpanBatch() require.NoError(err) - batch := derive.NewSpanBatchData(*rawSpanBatch) + batch := derive.NewBatchData(rawSpanBatch) var buf bytes.Buffer require.NoError(batch.EncodeRLP(&buf)) l = buf.Len() @@ -878,7 +878,7 @@ func ChannelBuilder_OutputBytes(t *testing.T, batchType uint) { func blockBatchRlpSize(t *testing.T, b *types.Block) int { t.Helper() singularBatch, _, err := derive.BlockToSingularBatch(b) - batch := derive.NewSingularBatchData(*singularBatch) + batch := derive.NewBatchData(singularBatch) require.NoError(t, err) var buf bytes.Buffer require.NoError(t, batch.EncodeRLP(&buf), "RLP-encoding batch") diff --git a/op-e2e/actions/garbage_channel_out.go b/op-e2e/actions/garbage_channel_out.go index d412f80d5566..34056abdf714 100644 --- a/op-e2e/actions/garbage_channel_out.go +++ b/op-e2e/actions/garbage_channel_out.go @@ -255,13 +255,13 @@ func blockToBatch(block *types.Block) (*derive.BatchData, error) { return nil, fmt.Errorf("could not parse the L1 Info deposit: %w", err) } - return &derive.BatchData{ - SingularBatch: derive.SingularBatch{ - ParentHash: block.ParentHash(), - EpochNum: rollup.Epoch(l1Info.Number), - EpochHash: l1Info.BlockHash, - Timestamp: block.Time(), - Transactions: opaqueTxs, - }, - }, nil + singularBatch := &derive.SingularBatch{ + ParentHash: block.ParentHash(), + EpochNum: rollup.Epoch(l1Info.Number), + EpochHash: l1Info.BlockHash, + Timestamp: block.Time(), + Transactions: opaqueTxs, + } + + return derive.NewBatchData(singularBatch), nil } diff --git a/op-node/cmd/batch_decoder/reassemble/reassemble.go b/op-node/cmd/batch_decoder/reassemble/reassemble.go index 8472ba8c03ca..adab7a9cdc8d 100644 --- a/op-node/cmd/batch_decoder/reassemble/reassemble.go +++ b/op-node/cmd/batch_decoder/reassemble/reassemble.go @@ -19,12 +19,12 @@ import ( ) type ChannelWithMetadata struct { - ID derive.ChannelID `json:"id"` - IsReady bool `json:"is_ready"` - InvalidFrames bool `json:"invalid_frames"` - InvalidBatches bool `json:"invalid_batches"` - Frames []FrameWithMetadata `json:"frames"` - Batches []derive.SingularBatch `json:"batches"` + ID derive.ChannelID `json:"id"` + IsReady bool `json:"is_ready"` + InvalidFrames bool `json:"invalid_frames"` + InvalidBatches bool `json:"invalid_batches"` + Frames []FrameWithMetadata `json:"frames"` + Batches []derive.BatchData `json:"batches"` } type FrameWithMetadata struct { @@ -104,7 +104,7 @@ func processFrames(cfg *rollup.Config, id derive.ChannelID, frames []FrameWithMe } } - var batches []derive.SingularBatch + var batches []derive.BatchData invalidBatches := false if ch.IsReady() { br, err := derive.BatchReader(ch.Reader()) @@ -114,11 +114,7 @@ func processFrames(cfg *rollup.Config, id derive.ChannelID, frames []FrameWithMe fmt.Printf("Error reading batch for channel %v. Err: %v\n", id.String(), err) invalidBatches = true } else { - if batch.BatchType != derive.SingularBatchType { - batches = append(batches, batch.SingularBatch) - } else { - fmt.Printf("batch-type %d is not supported", batch.BatchType) - } + batches = append(batches, *batch) } } } else { diff --git a/op-node/rollup/derive/batch.go b/op-node/rollup/derive/batch.go index 88b50bed641d..9f43446dadb6 100644 --- a/op-node/rollup/derive/batch.go +++ b/op-node/rollup/derive/batch.go @@ -25,9 +25,9 @@ var encodeBufferPool = sync.Pool{ const ( // SingularBatchType is the first version of Batch format, representing a single L2 block. - SingularBatchType = iota + SingularBatchType = 0 // SpanBatchType is the Batch version used after SpanBatch hard fork, representing a span of L2 blocks. - SpanBatchType + SpanBatchType = 1 ) // Batch contains information to build one or multiple L2 blocks. @@ -39,12 +39,22 @@ type Batch interface { LogContext(log.Logger) log.Logger } -// BatchData is a composition type that contains raw data of each batch version. -// It has encoding & decoding methods to implement typed encoding. +// BatchData is used to represent the typed encoding & decoding. +// and wraps around a single interface InnerBatchData. +// Further fields such as cache can be added in the future, without embedding each type of InnerBatchData. +// Similar design with op-geth's types.Transaction struct. type BatchData struct { - BatchType int - SingularBatch - RawSpanBatch + inner InnerBatchData +} + +// InnerBatchData is the underlying data of a BatchData. +// This is implemented by SingularBatch and RawSpanBatch. +type InnerBatchData interface { + GetBatchType() int + encode(w io.Writer) error + decode(r *bytes.Reader) error + encodeBytes() ([]byte, error) + decodeBytes(data []byte) error } // EncodeRLP implements rlp.Encoder @@ -58,6 +68,10 @@ func (b *BatchData) EncodeRLP(w io.Writer) error { return rlp.Encode(w, buf.Bytes()) } +func (bd *BatchData) GetBatchType() uint8 { + return uint8(bd.inner.GetBatchType()) +} + // MarshalBinary returns the canonical encoding of the batch. func (b *BatchData) MarshalBinary() ([]byte, error) { var buf bytes.Buffer @@ -67,16 +81,10 @@ func (b *BatchData) MarshalBinary() ([]byte, error) { // encodeTyped encodes batch type and payload for each batch type. func (b *BatchData) encodeTyped(buf *bytes.Buffer) error { - switch b.BatchType { - case SingularBatchType: - buf.WriteByte(SingularBatchType) - return rlp.Encode(buf, &b.SingularBatch) - case SpanBatchType: - buf.WriteByte(SpanBatchType) - return b.RawSpanBatch.encode(buf) - default: - return fmt.Errorf("unrecognized batch type: %d", b.BatchType) + if err := buf.WriteByte(b.GetBatchType()); err != nil { + return err } + return b.inner.encode(buf) } // DecodeRLP implements rlp.Decoder @@ -99,35 +107,28 @@ func (b *BatchData) UnmarshalBinary(data []byte) error { return b.decodeTyped(data) } -// decodeTyped decodes batch type and payload for each batch type. +// decodeTyped decodes a typed batchData func (b *BatchData) decodeTyped(data []byte) error { if len(data) == 0 { - return fmt.Errorf("batch too short") + return errors.New("batch too short") } + var inner InnerBatchData switch data[0] { case SingularBatchType: - b.BatchType = SingularBatchType - return rlp.DecodeBytes(data[1:], &b.SingularBatch) + inner = new(SingularBatch) case SpanBatchType: - b.BatchType = int(data[0]) - return b.RawSpanBatch.decodeBytes(data[1:]) + inner = new(RawSpanBatch) default: return fmt.Errorf("unrecognized batch type: %d", data[0]) } -} - -// NewSingularBatchData creates new BatchData with SingularBatch -func NewSingularBatchData(singularBatch SingularBatch) *BatchData { - return &BatchData{ - BatchType: SingularBatchType, - SingularBatch: singularBatch, + if err := inner.decodeBytes(data[1:]); err != nil { + return err } + b.inner = inner + return nil } -// NewSpanBatchData creates new BatchData with SpanBatch -func NewSpanBatchData(spanBatch RawSpanBatch) *BatchData { - return &BatchData{ - BatchType: SpanBatchType, - RawSpanBatch: spanBatch, - } +// NewBatchData creates a new BatchData +func NewBatchData(inner InnerBatchData) *BatchData { + return &BatchData{inner: inner} } diff --git a/op-node/rollup/derive/batch_test.go b/op-node/rollup/derive/batch_test.go index b7646e7528d7..a5d438ebfec0 100644 --- a/op-node/rollup/derive/batch_test.go +++ b/op-node/rollup/derive/batch_test.go @@ -6,15 +6,16 @@ import ( "math/rand" "testing" - "github.com/ethereum-optimism/optimism/op-node/rollup" - "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum-optimism/optimism/op-service/testutils" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/testutils" ) func RandomRawSpanBatch(rng *rand.Rand, chainId *big.Int) *RawSpanBatch { @@ -52,8 +53,8 @@ func RandomRawSpanBatch(rng *rand.Rand, chainId *big.Int) *RawSpanBatch { spanBatchPrefix: spanBatchPrefix{ relTimestamp: uint64(rng.Uint32()), l1OriginNum: rng.Uint64(), - parentCheck: testutils.RandomData(rng, 20), - l1OriginCheck: testutils.RandomData(rng, 20), + parentCheck: [20]byte(testutils.RandomData(rng, 20)), + l1OriginCheck: [20]byte(testutils.RandomData(rng, 20)), }, spanBatchPayload: spanBatchPayload{ blockCount: blockCount, @@ -141,40 +142,42 @@ func TestBatchRoundTrip(t *testing.T) { chainID := new(big.Int).SetUint64(rng.Uint64()) batches := []*BatchData{ - { - SingularBatch: SingularBatch{ + NewBatchData( + &SingularBatch{ ParentHash: common.Hash{}, EpochNum: 0, Timestamp: 0, Transactions: []hexutil.Bytes{}, }, - }, - { - SingularBatch: SingularBatch{ + ), + NewBatchData( + &SingularBatch{ ParentHash: common.Hash{31: 0x42}, EpochNum: 1, Timestamp: 1647026951, Transactions: []hexutil.Bytes{[]byte{0, 0, 0}, []byte{0x76, 0xfd, 0x7c}}, }, - }, - NewSingularBatchData(*RandomSingularBatch(rng, 5, chainID)), - NewSingularBatchData(*RandomSingularBatch(rng, 7, chainID)), - NewSpanBatchData(*RandomRawSpanBatch(rng, chainID)), - NewSpanBatchData(*RandomRawSpanBatch(rng, chainID)), - NewSpanBatchData(*RandomRawSpanBatch(rng, chainID)), + ), + NewBatchData(RandomSingularBatch(rng, 5, chainID)), + NewBatchData(RandomSingularBatch(rng, 7, chainID)), + NewBatchData(RandomRawSpanBatch(rng, chainID)), + NewBatchData(RandomRawSpanBatch(rng, chainID)), + NewBatchData(RandomRawSpanBatch(rng, chainID)), } for i, batch := range batches { enc, err := batch.MarshalBinary() - assert.NoError(t, err) + require.NoError(t, err) var dec BatchData err = dec.UnmarshalBinary(enc) - assert.NoError(t, err) - if dec.BatchType == SpanBatchType { - _, err := dec.RawSpanBatch.derive(blockTime, genesisTimestamp, chainID) - assert.NoError(t, err) + require.NoError(t, err) + if dec.GetBatchType() == SpanBatchType { + rawSpanBatch, ok := dec.inner.(*RawSpanBatch) + require.True(t, ok) + _, err := rawSpanBatch.derive(blockTime, genesisTimestamp, chainID) + require.NoError(t, err) } - assert.Equal(t, batch, &dec, "Batch not equal test case %v", i) + require.Equal(t, batch, &dec, "Batch not equal test case %v", i) } } @@ -185,43 +188,45 @@ func TestBatchRoundTripRLP(t *testing.T) { chainID := new(big.Int).SetUint64(rng.Uint64()) batches := []*BatchData{ - { - SingularBatch: SingularBatch{ + NewBatchData( + &SingularBatch{ ParentHash: common.Hash{}, EpochNum: 0, Timestamp: 0, Transactions: []hexutil.Bytes{}, }, - }, - { - SingularBatch: SingularBatch{ + ), + NewBatchData( + &SingularBatch{ ParentHash: common.Hash{31: 0x42}, EpochNum: 1, Timestamp: 1647026951, Transactions: []hexutil.Bytes{[]byte{0, 0, 0}, []byte{0x76, 0xfd, 0x7c}}, }, - }, - NewSingularBatchData(*RandomSingularBatch(rng, 5, chainID)), - NewSingularBatchData(*RandomSingularBatch(rng, 7, chainID)), - NewSpanBatchData(*RandomRawSpanBatch(rng, chainID)), - NewSpanBatchData(*RandomRawSpanBatch(rng, chainID)), - NewSpanBatchData(*RandomRawSpanBatch(rng, chainID)), + ), + NewBatchData(RandomSingularBatch(rng, 5, chainID)), + NewBatchData(RandomSingularBatch(rng, 7, chainID)), + NewBatchData(RandomRawSpanBatch(rng, chainID)), + NewBatchData(RandomRawSpanBatch(rng, chainID)), + NewBatchData(RandomRawSpanBatch(rng, chainID)), } for i, batch := range batches { var buf bytes.Buffer err := batch.EncodeRLP(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() var dec BatchData r := bytes.NewReader(result) s := rlp.NewStream(r, 0) err = dec.DecodeRLP(s) - assert.NoError(t, err) - if dec.BatchType == SpanBatchType { - _, err := dec.RawSpanBatch.derive(blockTime, genesisTimestamp, chainID) - assert.NoError(t, err) + require.NoError(t, err) + if dec.GetBatchType() == SpanBatchType { + rawSpanBatch, ok := dec.inner.(*RawSpanBatch) + require.True(t, ok) + _, err := rawSpanBatch.derive(blockTime, genesisTimestamp, chainID) + require.NoError(t, err) } - assert.Equal(t, batch, &dec, "Batch not equal test case %v", i) + require.Equal(t, batch, &dec, "Batch not equal test case %v", i) } } diff --git a/op-node/rollup/derive/batch_tob_test.go b/op-node/rollup/derive/batch_tob_test.go index 6955fdcf5a42..5b62b4b5bb6f 100644 --- a/op-node/rollup/derive/batch_tob_test.go +++ b/op-node/rollup/derive/batch_tob_test.go @@ -17,13 +17,13 @@ func FuzzBatchRoundTrip(f *testing.F) { typeProvider := fuzz.NewFromGoFuzz(fuzzedData).NilChance(0).MaxDepth(10000).NumElements(0, 0x100).AllowUnexportedFields(true) fuzzerutils.AddFuzzerFunctions(typeProvider) + var singularBatch SingularBatch + typeProvider.Fuzz(&singularBatch) + // Create our batch data from fuzzed data var batchData BatchData - typeProvider.Fuzz(&batchData) - // force batchdata to only contain singular batch - batchData.BatchType = SingularBatchType - batchData.RawSpanBatch = RawSpanBatch{} + batchData.inner = &singularBatch // Encode our batch data enc, err := batchData.MarshalBinary() diff --git a/op-node/rollup/derive/channel_in_reader.go b/op-node/rollup/derive/channel_in_reader.go index 1553bd9a6656..24530b903e1f 100644 --- a/op-node/rollup/derive/channel_in_reader.go +++ b/op-node/rollup/derive/channel_in_reader.go @@ -3,6 +3,7 @@ package derive import ( "bytes" "context" + "errors" "fmt" "io" @@ -89,22 +90,30 @@ func (cr *ChannelInReader) NextBatch(ctx context.Context) (Batch, error) { cr.NextChannel() return nil, NotEnoughData } - switch batchData.BatchType { + switch batchData.GetBatchType() { case SingularBatchType: - return &batchData.SingularBatch, nil + singularBatch, ok := batchData.inner.(*SingularBatch) + if !ok { + return nil, NewCriticalError(errors.New("failed type assertion to SingularBatch")) + } + return singularBatch, nil case SpanBatchType: if origin := cr.Origin(); !cr.cfg.IsSpanBatch(origin.Time) { return nil, NewTemporaryError(fmt.Errorf("cannot accept span batch in L1 block %s at time %d", origin, origin.Time)) } + rawSpanBatch, ok := batchData.inner.(*RawSpanBatch) + if !ok { + return nil, NewCriticalError(errors.New("failed type assertion to SpanBatch")) + } // If the batch type is Span batch, derive block inputs from RawSpanBatch. - spanBatch, err := batchData.RawSpanBatch.derive(cr.cfg.BlockTime, cr.cfg.Genesis.L2Time, cr.cfg.L2ChainID) + spanBatch, err := rawSpanBatch.derive(cr.cfg.BlockTime, cr.cfg.Genesis.L2Time, cr.cfg.L2ChainID) if err != nil { return nil, err } return spanBatch, nil default: // error is bubbled up to user, but pipeline can skip the batch and continue after. - return nil, NewTemporaryError(fmt.Errorf("unrecognized batch type: %w", err)) + return nil, NewTemporaryError(fmt.Errorf("unrecognized batch type: %d", batchData.GetBatchType())) } } diff --git a/op-node/rollup/derive/channel_out.go b/op-node/rollup/derive/channel_out.go index 5eb559678f6a..e932b9524ba7 100644 --- a/op-node/rollup/derive/channel_out.go +++ b/op-node/rollup/derive/channel_out.go @@ -145,7 +145,7 @@ func (co *SingularChannelOut) AddSingularBatch(batch *SingularBatch, _ uint64) ( // We encode to a temporary buffer to determine the encoded length to // ensure that the total size of all RLP elements is less than or equal to MAX_RLP_BYTES_PER_CHANNEL var buf bytes.Buffer - if err := rlp.Encode(&buf, NewSingularBatchData(*batch)); err != nil { + if err := rlp.Encode(&buf, NewBatchData(batch)); err != nil { return 0, err } if co.rlpLength+buf.Len() > MaxRLPBytesPerChannel { diff --git a/op-node/rollup/derive/singular_batch.go b/op-node/rollup/derive/singular_batch.go index 3d37325cd35d..47d3eb420696 100644 --- a/op-node/rollup/derive/singular_batch.go +++ b/op-node/rollup/derive/singular_batch.go @@ -1,11 +1,15 @@ package derive import ( + "bytes" + "io" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" ) // Batch format @@ -51,3 +55,23 @@ func (b *SingularBatch) LogContext(log log.Logger) log.Logger { func (b *SingularBatch) Epoch() eth.BlockID { return eth.BlockID{Hash: b.EpochHash, Number: uint64(b.EpochNum)} } + +// encode writes the byte encoding of SingularBatch to Writer stream +func (b *SingularBatch) encode(w io.Writer) error { + return rlp.Encode(w, b) +} + +// decode reads the byte encoding of SingularBatch from Reader stream +func (b *SingularBatch) decode(r *bytes.Reader) error { + return rlp.Decode(r, b) +} + +// encodeBytes returns the byte encoding of SingularBatch +func (b *SingularBatch) encodeBytes() ([]byte, error) { + return rlp.EncodeToBytes(b) +} + +// decodeBytes parses data into b from data +func (b *SingularBatch) decodeBytes(data []byte) error { + return rlp.DecodeBytes(data, b) +} diff --git a/op-node/rollup/derive/singular_batch_test.go b/op-node/rollup/derive/singular_batch_test.go index bd8d2a562d6f..d6922c86d667 100644 --- a/op-node/rollup/derive/singular_batch_test.go +++ b/op-node/rollup/derive/singular_batch_test.go @@ -5,7 +5,7 @@ import ( "math/rand" "testing" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSingularBatchForBatchInterface(t *testing.T) { @@ -15,7 +15,7 @@ func TestSingularBatchForBatchInterface(t *testing.T) { singularBatch := RandomSingularBatch(rng, txCount, chainID) - assert.Equal(t, SingularBatchType, singularBatch.GetBatchType()) - assert.Equal(t, singularBatch.Timestamp, singularBatch.GetTimestamp()) - assert.Equal(t, singularBatch.EpochNum, singularBatch.GetEpochNum()) + require.Equal(t, SingularBatchType, singularBatch.GetBatchType()) + require.Equal(t, singularBatch.Timestamp, singularBatch.GetTimestamp()) + require.Equal(t, singularBatch.EpochNum, singularBatch.GetEpochNum()) } diff --git a/op-node/rollup/derive/span_batch.go b/op-node/rollup/derive/span_batch.go index fc516f5a76ca..37b73ab06faf 100644 --- a/op-node/rollup/derive/span_batch.go +++ b/op-node/rollup/derive/span_batch.go @@ -32,10 +32,10 @@ var ErrTooBigSpanBatchSize = errors.New("span batch size limit reached") var ErrEmptySpanBatch = errors.New("span-batch must not be empty") type spanBatchPrefix struct { - relTimestamp uint64 // Relative timestamp of the first block - l1OriginNum uint64 // L1 origin number - parentCheck []byte // First 20 bytes of the first block's parent hash - l1OriginCheck []byte // First 20 bytes of the last block's L1 origin hash + relTimestamp uint64 // Relative timestamp of the first block + l1OriginNum uint64 // L1 origin number + parentCheck [20]byte // First 20 bytes of the first block's parent hash + l1OriginCheck [20]byte // First 20 bytes of the last block's L1 origin hash } type spanBatchPayload struct { @@ -51,6 +51,11 @@ type RawSpanBatch struct { spanBatchPayload } +// GetBatchType returns its batch type (batch_version) +func (b *RawSpanBatch) GetBatchType() int { + return SpanBatchType +} + // decodeOriginBits parses data into bp.originBits // originBits is bitlist right-padded to a multiple of 8 bits func (bp *spanBatchPayload) decodeOriginBits(r *bytes.Reader) error { @@ -105,8 +110,7 @@ func (bp *spanBatchPrefix) decodeL1OriginNum(r *bytes.Reader) error { // decodeParentCheck parses data into bp.parentCheck func (bp *spanBatchPrefix) decodeParentCheck(r *bytes.Reader) error { - bp.parentCheck = make([]byte, 20) - _, err := io.ReadFull(r, bp.parentCheck) + _, err := io.ReadFull(r, bp.parentCheck[:]) if err != nil { return fmt.Errorf("failed to read parent check: %w", err) } @@ -115,8 +119,7 @@ func (bp *spanBatchPrefix) decodeParentCheck(r *bytes.Reader) error { // decodeL1OriginCheck parses data into bp.decodeL1OriginCheck func (bp *spanBatchPrefix) decodeL1OriginCheck(r *bytes.Reader) error { - bp.l1OriginCheck = make([]byte, 20) - _, err := io.ReadFull(r, bp.l1OriginCheck) + _, err := io.ReadFull(r, bp.l1OriginCheck[:]) if err != nil { return fmt.Errorf("failed to read l1 origin check: %w", err) } @@ -263,7 +266,7 @@ func (bp *spanBatchPrefix) encodeL1OriginNum(w io.Writer) error { // encodeParentCheck encodes bp.parentCheck func (bp *spanBatchPrefix) encodeParentCheck(w io.Writer) error { - if _, err := w.Write(bp.parentCheck); err != nil { + if _, err := w.Write(bp.parentCheck[:]); err != nil { return fmt.Errorf("cannot write parent check: %w", err) } return nil @@ -271,7 +274,7 @@ func (bp *spanBatchPrefix) encodeParentCheck(w io.Writer) error { // encodeL1OriginCheck encodes bp.l1OriginCheck func (bp *spanBatchPrefix) encodeL1OriginCheck(w io.Writer) error { - if _, err := w.Write(bp.l1OriginCheck); err != nil { + if _, err := w.Write(bp.l1OriginCheck[:]); err != nil { return fmt.Errorf("cannot write l1 origin check: %w", err) } return nil @@ -451,8 +454,8 @@ func singularBatchToElement(singularBatch *SingularBatch) *spanBatchElement { // SpanBatch is an implementation of Batch interface, // containing the input to build a span of L2 blocks in derived form (spanBatchElement) type SpanBatch struct { - parentCheck []byte // First 20 bytes of the first block's parent hash - l1OriginCheck []byte // First 20 bytes of the last block's L1 origin hash + parentCheck [20]byte // First 20 bytes of the first block's parent hash + l1OriginCheck [20]byte // First 20 bytes of the last block's L1 origin hash batches []*spanBatchElement // List of block input in derived form } @@ -473,8 +476,8 @@ func (b *SpanBatch) LogContext(log log.Logger) log.Logger { } return log.New( "batch_timestamp", b.batches[0].Timestamp, - "parent_check", hexutil.Encode(b.parentCheck), - "origin_check", hexutil.Encode(b.l1OriginCheck), + "parent_check", hexutil.Encode(b.parentCheck[:]), + "origin_check", hexutil.Encode(b.l1OriginCheck[:]), "start_epoch_number", b.GetStartEpochNum(), "end_epoch_number", b.GetBlockEpochNum(len(b.batches)-1), "block_count", len(b.batches), @@ -488,12 +491,12 @@ func (b *SpanBatch) GetStartEpochNum() rollup.Epoch { // CheckOriginHash checks if the l1OriginCheck matches the first 20 bytes of given hash, probably L1 block hash from the current canonical L1 chain. func (b *SpanBatch) CheckOriginHash(hash common.Hash) bool { - return bytes.Equal(b.l1OriginCheck, hash.Bytes()[:20]) + return bytes.Equal(b.l1OriginCheck[:], hash.Bytes()[:20]) } // CheckParentHash checks if the parentCheck matches the first 20 bytes of given hash, probably the current L2 safe head. func (b *SpanBatch) CheckParentHash(hash common.Hash) bool { - return bytes.Equal(b.parentCheck, hash.Bytes()[:20]) + return bytes.Equal(b.parentCheck[:], hash.Bytes()[:20]) } // GetBlockEpochNum returns the epoch number(L1 origin block number) of the block at the given index in the span. @@ -520,10 +523,10 @@ func (b *SpanBatch) GetBlockCount() int { // updates l1OriginCheck or parentCheck if needed. func (b *SpanBatch) AppendSingularBatch(singularBatch *SingularBatch) { if len(b.batches) == 0 { - b.parentCheck = singularBatch.ParentHash.Bytes()[:20] + copy(b.parentCheck[:], singularBatch.ParentHash.Bytes()[:20]) } b.batches = append(b.batches, singularBatchToElement(singularBatch)) - b.l1OriginCheck = singularBatch.EpochHash.Bytes()[:20] + copy(b.l1OriginCheck[:], singularBatch.EpochHash.Bytes()[:20]) } // ToRawSpanBatch merges SingularBatch List and initialize single RawSpanBatch @@ -541,10 +544,8 @@ func (b *SpanBatch) ToRawSpanBatch(originChangedBit uint, genesisTimestamp uint6 span_end := b.batches[len(b.batches)-1] raw.relTimestamp = span_start.Timestamp - genesisTimestamp raw.l1OriginNum = uint64(span_end.EpochNum) - raw.parentCheck = make([]byte, 20) - copy(raw.parentCheck, b.parentCheck) - raw.l1OriginCheck = make([]byte, 20) - copy(raw.l1OriginCheck, b.l1OriginCheck) + raw.parentCheck = b.parentCheck + raw.l1OriginCheck = b.l1OriginCheck // spanBatchPayload raw.blockCount = uint64(len(b.batches)) raw.originBits = new(big.Int) @@ -608,17 +609,16 @@ func (b *SpanBatch) GetSingularBatches(l1Origins []eth.L1BlockRef, l2SafeHead et // NewSpanBatch converts given singularBatches into spanBatchElements, and creates a new SpanBatch. func NewSpanBatch(singularBatches []*SingularBatch) *SpanBatch { + spanBatch := &SpanBatch{} if len(singularBatches) == 0 { - return &SpanBatch{} - } - spanBatch := SpanBatch{ - parentCheck: singularBatches[0].ParentHash.Bytes()[:20], - l1OriginCheck: singularBatches[len(singularBatches)-1].EpochHash.Bytes()[:20], + return spanBatch } + copy(spanBatch.parentCheck[:], singularBatches[0].ParentHash.Bytes()[:20]) + copy(spanBatch.l1OriginCheck[:], singularBatches[len(singularBatches)-1].EpochHash.Bytes()[:20]) for _, singularBatch := range singularBatches { spanBatch.batches = append(spanBatch.batches, singularBatchToElement(singularBatch)) } - return &spanBatch + return spanBatch } // SpanBatchBuilder is a utility type to build a SpanBatch by adding a SingularBatch one by one. diff --git a/op-node/rollup/derive/span_batch_test.go b/op-node/rollup/derive/span_batch_test.go index 0795b2062434..c8ee658577db 100644 --- a/op-node/rollup/derive/span_batch_test.go +++ b/op-node/rollup/derive/span_batch_test.go @@ -30,11 +30,11 @@ func TestSpanBatchForBatchInterface(t *testing.T) { spanBatch := NewSpanBatch(singularBatches) // check interface method implementations except logging - assert.Equal(t, SpanBatchType, spanBatch.GetBatchType()) - assert.Equal(t, singularBatches[0].Timestamp, spanBatch.GetTimestamp()) - assert.Equal(t, singularBatches[0].EpochNum, spanBatch.GetStartEpochNum()) - assert.True(t, spanBatch.CheckOriginHash(singularBatches[blockCount-1].EpochHash)) - assert.True(t, spanBatch.CheckParentHash(singularBatches[0].ParentHash)) + require.Equal(t, SpanBatchType, spanBatch.GetBatchType()) + require.Equal(t, singularBatches[0].Timestamp, spanBatch.GetTimestamp()) + require.Equal(t, singularBatches[0].EpochNum, spanBatch.GetStartEpochNum()) + require.True(t, spanBatch.CheckOriginHash(singularBatches[blockCount-1].EpochHash)) + require.True(t, spanBatch.CheckParentHash(singularBatches[0].ParentHash)) } func TestEmptySpanBatch(t *testing.T) { @@ -47,8 +47,8 @@ func TestEmptySpanBatch(t *testing.T) { spanBatchPrefix: spanBatchPrefix{ relTimestamp: uint64(rng.Uint32()), l1OriginNum: rng.Uint64(), - parentCheck: testutils.RandomData(rng, 20), - l1OriginCheck: testutils.RandomData(rng, 20), + parentCheck: *(*[20]byte)(testutils.RandomData(rng, 20)), + l1OriginCheck: *(*[20]byte)(testutils.RandomData(rng, 20)), }, spanBatchPayload: spanBatchPayload{ blockCount: 0, @@ -80,23 +80,23 @@ func TestSpanBatchOriginBits(t *testing.T) { var buf bytes.Buffer err := rawSpanBatch.encodeOriginBits(&buf) - assert.NoError(t, err) + require.NoError(t, err) // originBit field is fixed length: single bit originBitBufferLen := blockCount / 8 if blockCount%8 != 0 { originBitBufferLen++ } - assert.Equal(t, buf.Len(), int(originBitBufferLen)) + require.Equal(t, buf.Len(), int(originBitBufferLen)) result := buf.Bytes() var sb RawSpanBatch sb.blockCount = blockCount r := bytes.NewReader(result) err = sb.decodeOriginBits(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, rawSpanBatch.originBits, sb.originBits) + require.Equal(t, rawSpanBatch.originBits, sb.originBits) } func TestSpanBatchPrefix(t *testing.T) { @@ -109,15 +109,15 @@ func TestSpanBatchPrefix(t *testing.T) { var buf bytes.Buffer err := rawSpanBatch.encodePrefix(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() r := bytes.NewReader(result) var sb RawSpanBatch err = sb.decodePrefix(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, rawSpanBatch, &sb) + require.Equal(t, rawSpanBatch, &sb) } func TestSpanBatchRelTimestamp(t *testing.T) { @@ -128,15 +128,15 @@ func TestSpanBatchRelTimestamp(t *testing.T) { var buf bytes.Buffer err := rawSpanBatch.encodeRelTimestamp(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() r := bytes.NewReader(result) var sb RawSpanBatch err = sb.decodeRelTimestamp(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, rawSpanBatch.relTimestamp, sb.relTimestamp) + require.Equal(t, rawSpanBatch.relTimestamp, sb.relTimestamp) } func TestSpanBatchL1OriginNum(t *testing.T) { @@ -147,15 +147,15 @@ func TestSpanBatchL1OriginNum(t *testing.T) { var buf bytes.Buffer err := rawSpanBatch.encodeL1OriginNum(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() r := bytes.NewReader(result) var sb RawSpanBatch err = sb.decodeL1OriginNum(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, rawSpanBatch.l1OriginNum, sb.l1OriginNum) + require.Equal(t, rawSpanBatch.l1OriginNum, sb.l1OriginNum) } func TestSpanBatchParentCheck(t *testing.T) { @@ -166,18 +166,18 @@ func TestSpanBatchParentCheck(t *testing.T) { var buf bytes.Buffer err := rawSpanBatch.encodeParentCheck(&buf) - assert.NoError(t, err) + require.NoError(t, err) // parent check field is fixed length: 20 bytes - assert.Equal(t, buf.Len(), 20) + require.Equal(t, buf.Len(), 20) result := buf.Bytes() r := bytes.NewReader(result) var sb RawSpanBatch err = sb.decodeParentCheck(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, rawSpanBatch.parentCheck, sb.parentCheck) + require.Equal(t, rawSpanBatch.parentCheck, sb.parentCheck) } func TestSpanBatchL1OriginCheck(t *testing.T) { @@ -188,18 +188,18 @@ func TestSpanBatchL1OriginCheck(t *testing.T) { var buf bytes.Buffer err := rawSpanBatch.encodeL1OriginCheck(&buf) - assert.NoError(t, err) + require.NoError(t, err) // l1 origin check field is fixed length: 20 bytes - assert.Equal(t, buf.Len(), 20) + require.Equal(t, buf.Len(), 20) result := buf.Bytes() r := bytes.NewReader(result) var sb RawSpanBatch err = sb.decodeL1OriginCheck(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, rawSpanBatch.l1OriginCheck, sb.l1OriginCheck) + require.Equal(t, rawSpanBatch.l1OriginCheck, sb.l1OriginCheck) } func TestSpanBatchPayload(t *testing.T) { @@ -210,18 +210,18 @@ func TestSpanBatchPayload(t *testing.T) { var buf bytes.Buffer err := rawSpanBatch.encodePayload(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() r := bytes.NewReader(result) var sb RawSpanBatch err = sb.decodePayload(r) - assert.NoError(t, err) + require.NoError(t, err) sb.txs.recoverV(chainID) - assert.Equal(t, rawSpanBatch.spanBatchPayload, sb.spanBatchPayload) + require.Equal(t, rawSpanBatch.spanBatchPayload, sb.spanBatchPayload) } func TestSpanBatchBlockCount(t *testing.T) { @@ -232,16 +232,16 @@ func TestSpanBatchBlockCount(t *testing.T) { var buf bytes.Buffer err := rawSpanBatch.encodeBlockCount(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() r := bytes.NewReader(result) var sb RawSpanBatch err = sb.decodeBlockCount(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, rawSpanBatch.blockCount, sb.blockCount) + require.Equal(t, rawSpanBatch.blockCount, sb.blockCount) } func TestSpanBatchBlockTxCounts(t *testing.T) { @@ -252,7 +252,7 @@ func TestSpanBatchBlockTxCounts(t *testing.T) { var buf bytes.Buffer err := rawSpanBatch.encodeBlockTxCounts(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() r := bytes.NewReader(result) @@ -260,9 +260,9 @@ func TestSpanBatchBlockTxCounts(t *testing.T) { sb.blockCount = rawSpanBatch.blockCount err = sb.decodeBlockTxCounts(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, rawSpanBatch.blockTxCounts, sb.blockTxCounts) + require.Equal(t, rawSpanBatch.blockTxCounts, sb.blockTxCounts) } func TestSpanBatchTxs(t *testing.T) { @@ -273,7 +273,7 @@ func TestSpanBatchTxs(t *testing.T) { var buf bytes.Buffer err := rawSpanBatch.encodeTxs(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() r := bytes.NewReader(result) @@ -281,11 +281,11 @@ func TestSpanBatchTxs(t *testing.T) { sb.blockTxCounts = rawSpanBatch.blockTxCounts err = sb.decodeTxs(r) - assert.NoError(t, err) + require.NoError(t, err) sb.txs.recoverV(chainID) - assert.Equal(t, rawSpanBatch.txs, sb.txs) + require.Equal(t, rawSpanBatch.txs, sb.txs) } func TestSpanBatchRoundTrip(t *testing.T) { @@ -295,15 +295,15 @@ func TestSpanBatchRoundTrip(t *testing.T) { rawSpanBatch := RandomRawSpanBatch(rng, chainID) result, err := rawSpanBatch.encodeBytes() - assert.NoError(t, err) + require.NoError(t, err) var sb RawSpanBatch err = sb.decodeBytes(result) - assert.NoError(t, err) + require.NoError(t, err) sb.txs.recoverV(chainID) - assert.Equal(t, rawSpanBatch, &sb) + require.Equal(t, rawSpanBatch, &sb) } func TestSpanBatchDerive(t *testing.T) { @@ -321,24 +321,24 @@ func TestSpanBatchDerive(t *testing.T) { spanBatch := NewSpanBatch(singularBatches) originChangedBit := uint(originChangedBit) rawSpanBatch, err := spanBatch.ToRawSpanBatch(originChangedBit, genesisTimeStamp, chainID) - assert.NoError(t, err) + require.NoError(t, err) spanBatchDerived, err := rawSpanBatch.derive(l2BlockTime, genesisTimeStamp, chainID) - assert.NoError(t, err) + require.NoError(t, err) blockCount := len(singularBatches) - assert.Equal(t, safeL2Head.Hash.Bytes()[:20], spanBatchDerived.parentCheck) - assert.Equal(t, singularBatches[blockCount-1].Epoch().Hash.Bytes()[:20], spanBatchDerived.l1OriginCheck) - assert.Equal(t, len(singularBatches), int(rawSpanBatch.blockCount)) + require.Equal(t, safeL2Head.Hash.Bytes()[:20], spanBatchDerived.parentCheck[:]) + require.Equal(t, singularBatches[blockCount-1].Epoch().Hash.Bytes()[:20], spanBatchDerived.l1OriginCheck[:]) + require.Equal(t, len(singularBatches), int(rawSpanBatch.blockCount)) for i := 1; i < len(singularBatches); i++ { - assert.Equal(t, spanBatchDerived.batches[i].Timestamp, spanBatchDerived.batches[i-1].Timestamp+l2BlockTime) + require.Equal(t, spanBatchDerived.batches[i].Timestamp, spanBatchDerived.batches[i-1].Timestamp+l2BlockTime) } for i := 0; i < len(singularBatches); i++ { - assert.Equal(t, singularBatches[i].EpochNum, spanBatchDerived.batches[i].EpochNum) - assert.Equal(t, singularBatches[i].Timestamp, spanBatchDerived.batches[i].Timestamp) - assert.Equal(t, singularBatches[i].Transactions, spanBatchDerived.batches[i].Transactions) + require.Equal(t, singularBatches[i].EpochNum, spanBatchDerived.batches[i].EpochNum) + require.Equal(t, singularBatches[i].Timestamp, spanBatchDerived.batches[i].Timestamp) + require.Equal(t, singularBatches[i].Transactions, spanBatchDerived.batches[i].Transactions) } } } @@ -359,7 +359,7 @@ func TestSpanBatchAppend(t *testing.T) { // initialize with two singular batches spanBatch2 := NewSpanBatch(singularBatches[:L]) - assert.Equal(t, spanBatch, spanBatch2) + require.Equal(t, spanBatch, spanBatch2) } func TestSpanBatchMerge(t *testing.T) { @@ -375,32 +375,32 @@ func TestSpanBatchMerge(t *testing.T) { spanBatch := NewSpanBatch(singularBatches) originChangedBit := uint(originChangedBit) rawSpanBatch, err := spanBatch.ToRawSpanBatch(originChangedBit, genesisTimeStamp, chainID) - assert.NoError(t, err) + require.NoError(t, err) // check span batch prefix - assert.Equal(t, rawSpanBatch.relTimestamp, singularBatches[0].Timestamp-genesisTimeStamp, "invalid relative timestamp") - assert.Equal(t, rollup.Epoch(rawSpanBatch.l1OriginNum), singularBatches[blockCount-1].EpochNum) - assert.Equal(t, rawSpanBatch.parentCheck, singularBatches[0].ParentHash.Bytes()[:20], "invalid parent check") - assert.Equal(t, rawSpanBatch.l1OriginCheck, singularBatches[blockCount-1].EpochHash.Bytes()[:20], "invalid l1 origin check") + require.Equal(t, rawSpanBatch.relTimestamp, singularBatches[0].Timestamp-genesisTimeStamp, "invalid relative timestamp") + require.Equal(t, rollup.Epoch(rawSpanBatch.l1OriginNum), singularBatches[blockCount-1].EpochNum) + require.Equal(t, rawSpanBatch.parentCheck[:], singularBatches[0].ParentHash.Bytes()[:20], "invalid parent check") + require.Equal(t, rawSpanBatch.l1OriginCheck[:], singularBatches[blockCount-1].EpochHash.Bytes()[:20], "invalid l1 origin check") // check span batch payload - assert.Equal(t, int(rawSpanBatch.blockCount), len(singularBatches)) - assert.Equal(t, rawSpanBatch.originBits.Bit(0), originChangedBit) + require.Equal(t, int(rawSpanBatch.blockCount), len(singularBatches)) + require.Equal(t, rawSpanBatch.originBits.Bit(0), originChangedBit) for i := 1; i < blockCount; i++ { if rawSpanBatch.originBits.Bit(i) == 1 { - assert.Equal(t, singularBatches[i].EpochNum, singularBatches[i-1].EpochNum+1) + require.Equal(t, singularBatches[i].EpochNum, singularBatches[i-1].EpochNum+1) } else { - assert.Equal(t, singularBatches[i].EpochNum, singularBatches[i-1].EpochNum) + require.Equal(t, singularBatches[i].EpochNum, singularBatches[i-1].EpochNum) } } for i := 0; i < len(singularBatches); i++ { txCount := len(singularBatches[i].Transactions) - assert.Equal(t, txCount, int(rawSpanBatch.blockTxCounts[i])) + require.Equal(t, txCount, int(rawSpanBatch.blockTxCounts[i])) } // check invariants endEpochNum := rawSpanBatch.l1OriginNum - assert.Equal(t, endEpochNum, uint64(singularBatches[blockCount-1].EpochNum)) + require.Equal(t, endEpochNum, uint64(singularBatches[blockCount-1].EpochNum)) // we do not check txs field because it has to be derived to be compared } @@ -420,12 +420,12 @@ func TestSpanBatchToSingularBatch(t *testing.T) { spanBatch := NewSpanBatch(singularBatches) originChangedBit := uint(originChangedBit) rawSpanBatch, err := spanBatch.ToRawSpanBatch(originChangedBit, genesisTimeStamp, chainID) - assert.NoError(t, err) + require.NoError(t, err) l1Origins := mockL1Origin(rng, rawSpanBatch, singularBatches) singularBatches2, err := spanBatch.GetSingularBatches(l1Origins, safeL2Head) - assert.NoError(t, err) + require.NoError(t, err) // GetSingularBatches does not fill in parent hash of singular batches // empty out parent hash for comparison @@ -434,52 +434,54 @@ func TestSpanBatchToSingularBatch(t *testing.T) { } // check parent hash is empty for i := 0; i < len(singularBatches2); i++ { - assert.Equal(t, singularBatches2[i].ParentHash, common.Hash{}) + require.Equal(t, singularBatches2[i].ParentHash, common.Hash{}) } - assert.Equal(t, singularBatches, singularBatches2) + require.Equal(t, singularBatches, singularBatches2) } } func TestSpanBatchReadTxData(t *testing.T) { - rng := rand.New(rand.NewSource(0x109550)) - chainID := new(big.Int).SetUint64(rng.Uint64()) - - txCount := 64 - - signer := types.NewLondonSigner(chainID) - var rawTxs [][]byte - var txs []*types.Transaction - m := make(map[byte]int) - for i := 0; i < txCount; i++ { - tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - m[tx.Type()] += 1 - rawTx, err := tx.MarshalBinary() - assert.NoError(t, err) - rawTxs = append(rawTxs, rawTx) - txs = append(txs, tx) + cases := []spanBatchTxTest{ + {"legacy tx", 32, testutils.RandomLegacyTx}, + {"access list tx", 32, testutils.RandomAccessListTx}, + {"dynamic fee tx", 32, testutils.RandomDynamicFeeTx}, } - for i := 0; i < txCount; i++ { - r := bytes.NewReader(rawTxs[i]) - _, txType, err := ReadTxData(r) - assert.NoError(t, err) - assert.Equal(t, int(txs[i].Type()), txType) + for i, testCase := range cases { + t.Run(testCase.name, func(t *testing.T) { + rng := rand.New(rand.NewSource(int64(0x109550 + i))) + chainID := new(big.Int).SetUint64(rng.Uint64()) + signer := types.NewLondonSigner(chainID) + + var rawTxs [][]byte + var txs []*types.Transaction + for txIdx := 0; txIdx < testCase.trials; txIdx++ { + tx := testCase.mkTx(rng, signer) + rawTx, err := tx.MarshalBinary() + require.NoError(t, err) + rawTxs = append(rawTxs, rawTx) + txs = append(txs, tx) + } + + for txIdx := 0; txIdx < testCase.trials; txIdx++ { + r := bytes.NewReader(rawTxs[i]) + _, txType, err := ReadTxData(r) + require.NoError(t, err) + assert.Equal(t, int(txs[i].Type()), txType) + } + }) } - // make sure every tx type is tested - assert.Positive(t, m[types.LegacyTxType]) - assert.Positive(t, m[types.AccessListTxType]) - assert.Positive(t, m[types.DynamicFeeTxType]) } func TestSpanBatchReadTxDataInvalid(t *testing.T) { dummy, err := rlp.EncodeToBytes("dummy") - assert.NoError(t, err) + require.NoError(t, err) // test non list rlp decoding r := bytes.NewReader(dummy) _, _, err = ReadTxData(r) - assert.ErrorContains(t, err, "tx RLP prefix type must be list") + require.ErrorContains(t, err, "tx RLP prefix type must be list") } func TestSpanBatchBuilder(t *testing.T) { @@ -500,28 +502,28 @@ func TestSpanBatchBuilder(t *testing.T) { } spanBatchBuilder := NewSpanBatchBuilder(genesisTimeStamp, chainID) - assert.Equal(t, 0, spanBatchBuilder.GetBlockCount()) + require.Equal(t, 0, spanBatchBuilder.GetBlockCount()) for i := 0; i < len(singularBatches); i++ { spanBatchBuilder.AppendSingularBatch(singularBatches[i], seqNum) - assert.Equal(t, i+1, spanBatchBuilder.GetBlockCount()) - assert.Equal(t, singularBatches[0].ParentHash.Bytes()[:20], spanBatchBuilder.spanBatch.parentCheck) - assert.Equal(t, singularBatches[i].EpochHash.Bytes()[:20], spanBatchBuilder.spanBatch.l1OriginCheck) + require.Equal(t, i+1, spanBatchBuilder.GetBlockCount()) + require.Equal(t, singularBatches[0].ParentHash.Bytes()[:20], spanBatchBuilder.spanBatch.parentCheck[:]) + require.Equal(t, singularBatches[i].EpochHash.Bytes()[:20], spanBatchBuilder.spanBatch.l1OriginCheck[:]) } rawSpanBatch, err := spanBatchBuilder.GetRawSpanBatch() - assert.NoError(t, err) + require.NoError(t, err) // compare with rawSpanBatch not using spanBatchBuilder spanBatch := NewSpanBatch(singularBatches) originChangedBit := uint(originChangedBit) rawSpanBatch2, err := spanBatch.ToRawSpanBatch(originChangedBit, genesisTimeStamp, chainID) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, rawSpanBatch2, rawSpanBatch) + require.Equal(t, rawSpanBatch2, rawSpanBatch) spanBatchBuilder.Reset() - assert.Equal(t, 0, spanBatchBuilder.GetBlockCount()) + require.Equal(t, 0, spanBatchBuilder.GetBlockCount()) } } @@ -533,7 +535,7 @@ func TestSpanBatchMaxTxData(t *testing.T) { }) txEncoded, err := invalidTx.MarshalBinary() - assert.NoError(t, err) + require.NoError(t, err) r := bytes.NewReader(txEncoded) _, _, err = ReadTxData(r) diff --git a/op-node/rollup/derive/span_batch_tx.go b/op-node/rollup/derive/span_batch_tx.go index c35a95fbc3a6..12628097a3f5 100644 --- a/op-node/rollup/derive/span_batch_tx.go +++ b/op-node/rollup/derive/span_batch_tx.go @@ -4,7 +4,6 @@ import ( "bytes" "errors" "fmt" - "io" "math/big" "github.com/ethereum/go-ethereum/common" @@ -70,21 +69,6 @@ func (tx *spanBatchTx) MarshalBinary() ([]byte, error) { return buf.Bytes(), err } -// EncodeRLP implements rlp.Encoder -func (tx *spanBatchTx) EncodeRLP(w io.Writer) error { - if tx.Type() == types.LegacyTxType { - return rlp.Encode(w, tx.inner) - } - // It's an EIP-2718 typed TX envelope. - buf := encodeBufferPool.Get().(*bytes.Buffer) - defer encodeBufferPool.Put(buf) - buf.Reset() - if err := tx.encodeTyped(buf); err != nil { - return err - } - return rlp.Encode(w, buf.Bytes()) -} - // setDecoded sets the inner transaction after decoding. func (tx *spanBatchTx) setDecoded(inner spanBatchTxData, size uint64) { tx.inner = inner @@ -115,36 +99,6 @@ func (tx *spanBatchTx) decodeTyped(b []byte) (spanBatchTxData, error) { } } -// DecodeRLP implements rlp.Decoder -func (tx *spanBatchTx) DecodeRLP(s *rlp.Stream) error { - kind, size, err := s.Kind() - switch { - case err != nil: - return err - case kind == rlp.List: - // It's a legacy transaction. - var inner spanBatchLegacyTxData - err = s.Decode(&inner) - if err != nil { - return fmt.Errorf("failed to decode spanBatchLegacyTxData: %w", err) - } - tx.setDecoded(&inner, rlp.ListSize(size)) - return nil - default: - // It's an EIP-2718 typed TX envelope. - var b []byte - if b, err = s.Bytes(); err != nil { - return err - } - inner, err := tx.decodeTyped(b) - if err != nil { - return err - } - tx.setDecoded(inner, uint64(len(b))) - return nil - } -} - // UnmarshalBinary decodes the canonical encoding of transactions. // It supports legacy RLP transactions and EIP2718 typed transactions. func (tx *spanBatchTx) UnmarshalBinary(b []byte) error { diff --git a/op-node/rollup/derive/span_batch_tx_test.go b/op-node/rollup/derive/span_batch_tx_test.go index d995e9fb015a..dd50cb6bbbfa 100644 --- a/op-node/rollup/derive/span_batch_tx_test.go +++ b/op-node/rollup/derive/span_batch_tx_test.go @@ -1,103 +1,87 @@ package derive import ( - "bytes" "math/big" "math/rand" "testing" "github.com/ethereum-optimism/optimism/op-service/testutils" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) +type spanBatchTxTest struct { + name string + trials int + mkTx func(rng *rand.Rand, signer types.Signer) *types.Transaction +} + func TestSpanBatchTxConvert(t *testing.T) { - rng := rand.New(rand.NewSource(0x1331)) - chainID := big.NewInt(rng.Int63n(1000)) - signer := types.NewLondonSigner(chainID) - - m := make(map[byte]int) - for i := 0; i < 32; i++ { - tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - m[tx.Type()] += 1 - v, r, s := tx.RawSignatureValues() - sbtx, err := newSpanBatchTx(*tx) - assert.NoError(t, err) - - tx2, err := sbtx.convertToFullTx(tx.Nonce(), tx.Gas(), tx.To(), chainID, v, r, s) - assert.NoError(t, err) - - // compare after marshal because we only need inner field of transaction - txEncoded, err := tx.MarshalBinary() - assert.NoError(t, err) - tx2Encoded, err := tx2.MarshalBinary() - assert.NoError(t, err) - - assert.Equal(t, txEncoded, tx2Encoded) + cases := []spanBatchTxTest{ + {"legacy tx", 32, testutils.RandomLegacyTx}, + {"access list tx", 32, testutils.RandomAccessListTx}, + {"dynamic fee tx", 32, testutils.RandomDynamicFeeTx}, } - // make sure every tx type is tested - assert.Positive(t, m[types.LegacyTxType]) - assert.Positive(t, m[types.AccessListTxType]) - assert.Positive(t, m[types.DynamicFeeTxType]) -} -func TestSpanBatchTxRoundTrip(t *testing.T) { - rng := rand.New(rand.NewSource(0x1332)) - chainID := big.NewInt(rng.Int63n(1000)) - signer := types.NewLondonSigner(chainID) + for i, testCase := range cases { + t.Run(testCase.name, func(t *testing.T) { + rng := rand.New(rand.NewSource(int64(0x1331 + i))) + chainID := big.NewInt(rng.Int63n(1000)) + signer := types.NewLondonSigner(chainID) - m := make(map[byte]int) - for i := 0; i < 32; i++ { - tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - m[tx.Type()] += 1 - sbtx, err := newSpanBatchTx(*tx) - assert.NoError(t, err) + for txIdx := 0; txIdx < testCase.trials; txIdx++ { + tx := testCase.mkTx(rng, signer) - sbtxEncoded, err := sbtx.MarshalBinary() - assert.NoError(t, err) + v, r, s := tx.RawSignatureValues() + sbtx, err := newSpanBatchTx(*tx) + require.NoError(t, err) - var sbtx2 spanBatchTx - err = sbtx2.UnmarshalBinary(sbtxEncoded) - assert.NoError(t, err) + tx2, err := sbtx.convertToFullTx(tx.Nonce(), tx.Gas(), tx.To(), chainID, v, r, s) + require.NoError(t, err) - assert.Equal(t, sbtx, &sbtx2) + // compare after marshal because we only need inner field of transaction + txEncoded, err := tx.MarshalBinary() + require.NoError(t, err) + tx2Encoded, err := tx2.MarshalBinary() + require.NoError(t, err) + + assert.Equal(t, txEncoded, tx2Encoded) + } + }) } - // make sure every tx type is tested - assert.Positive(t, m[types.LegacyTxType]) - assert.Positive(t, m[types.AccessListTxType]) - assert.Positive(t, m[types.DynamicFeeTxType]) } -func TestSpanBatchTxRoundTripRLP(t *testing.T) { - rng := rand.New(rand.NewSource(0x1333)) - chainID := big.NewInt(rng.Int63n(1000)) - signer := types.NewLondonSigner(chainID) - - m := make(map[byte]int) - for i := 0; i < 32; i++ { - tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - m[tx.Type()] += 1 - sbtx, err := newSpanBatchTx(*tx) - assert.NoError(t, err) - - var buf bytes.Buffer - err = sbtx.EncodeRLP(&buf) - assert.NoError(t, err) - - result := buf.Bytes() - var sbtx2 spanBatchTx - r := bytes.NewReader(result) - rlpReader := rlp.NewStream(r, 0) - err = sbtx2.DecodeRLP(rlpReader) - assert.NoError(t, err) - - assert.Equal(t, sbtx, &sbtx2) +func TestSpanBatchTxRoundTrip(t *testing.T) { + cases := []spanBatchTxTest{ + {"legacy tx", 32, testutils.RandomLegacyTx}, + {"access list tx", 32, testutils.RandomAccessListTx}, + {"dynamic fee tx", 32, testutils.RandomDynamicFeeTx}, + } + + for i, testCase := range cases { + t.Run(testCase.name, func(t *testing.T) { + rng := rand.New(rand.NewSource(int64(0x1332 + i))) + chainID := big.NewInt(rng.Int63n(1000)) + signer := types.NewLondonSigner(chainID) + + for txIdx := 0; txIdx < testCase.trials; txIdx++ { + tx := testCase.mkTx(rng, signer) + + sbtx, err := newSpanBatchTx(*tx) + require.NoError(t, err) + + sbtxEncoded, err := sbtx.MarshalBinary() + require.NoError(t, err) + + var sbtx2 spanBatchTx + err = sbtx2.UnmarshalBinary(sbtxEncoded) + require.NoError(t, err) + + assert.Equal(t, sbtx, &sbtx2) + } + }) } - // make sure every tx type is tested - assert.Positive(t, m[types.LegacyTxType]) - assert.Positive(t, m[types.AccessListTxType]) - assert.Positive(t, m[types.DynamicFeeTxType]) } type spanBatchDummyTxData struct{} @@ -107,44 +91,44 @@ func TestSpanBatchTxInvalidTxType(t *testing.T) { // span batch never contain deposit tx depositTx := types.NewTx(&types.DepositTx{}) _, err := newSpanBatchTx(*depositTx) - assert.ErrorContains(t, err, "invalid tx type") + require.ErrorContains(t, err, "invalid tx type") var sbtx spanBatchTx sbtx.inner = &spanBatchDummyTxData{} _, err = sbtx.convertToFullTx(0, 0, nil, nil, nil, nil, nil) - assert.ErrorContains(t, err, "invalid tx type") + require.ErrorContains(t, err, "invalid tx type") } func TestSpanBatchTxDecodeInvalid(t *testing.T) { var sbtx spanBatchTx _, err := sbtx.decodeTyped([]byte{}) - assert.EqualError(t, err, "typed transaction too short") + require.EqualError(t, err, "typed transaction too short") tx := types.NewTx(&types.LegacyTx{}) txEncoded, err := tx.MarshalBinary() - assert.NoError(t, err) + require.NoError(t, err) // legacy tx is not typed tx _, err = sbtx.decodeTyped(txEncoded) - assert.EqualError(t, err, types.ErrTxTypeNotSupported.Error()) + require.EqualError(t, err, types.ErrTxTypeNotSupported.Error()) tx2 := types.NewTx(&types.AccessListTx{}) tx2Encoded, err := tx2.MarshalBinary() - assert.NoError(t, err) + require.NoError(t, err) tx2Encoded[0] = types.DynamicFeeTxType _, err = sbtx.decodeTyped(tx2Encoded) - assert.ErrorContains(t, err, "failed to decode spanBatchDynamicFeeTxData") + require.ErrorContains(t, err, "failed to decode spanBatchDynamicFeeTxData") tx3 := types.NewTx(&types.DynamicFeeTx{}) tx3Encoded, err := tx3.MarshalBinary() - assert.NoError(t, err) + require.NoError(t, err) tx3Encoded[0] = types.AccessListTxType _, err = sbtx.decodeTyped(tx3Encoded) - assert.ErrorContains(t, err, "failed to decode spanBatchAccessListTxData") + require.ErrorContains(t, err, "failed to decode spanBatchAccessListTxData") invalidLegacyTxDecoded := []byte{0xFF, 0xFF} err = sbtx.UnmarshalBinary(invalidLegacyTxDecoded) - assert.ErrorContains(t, err, "failed to decode spanBatchLegacyTxData") + require.ErrorContains(t, err, "failed to decode spanBatchLegacyTxData") } diff --git a/op-node/rollup/derive/span_batch_txs_test.go b/op-node/rollup/derive/span_batch_txs_test.go index 8f9162e4d35e..1fda8b5ffbf3 100644 --- a/op-node/rollup/derive/span_batch_txs_test.go +++ b/op-node/rollup/derive/span_batch_txs_test.go @@ -6,11 +6,12 @@ import ( "math/rand" "testing" - "github.com/ethereum-optimism/optimism/op-service/testutils" - "github.com/ethereum/go-ethereum/core/types" "github.com/holiman/uint256" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/core/types" + + "github.com/ethereum-optimism/optimism/op-service/testutils" ) func TestSpanBatchTxsContractCreationBits(t *testing.T) { @@ -27,23 +28,23 @@ func TestSpanBatchTxsContractCreationBits(t *testing.T) { var buf bytes.Buffer err := sbt.encodeContractCreationBits(&buf) - assert.NoError(t, err) + require.NoError(t, err) // contractCreationBit field is fixed length: single bit contractCreationBitBufferLen := totalBlockTxCount / 8 if totalBlockTxCount%8 != 0 { contractCreationBitBufferLen++ } - assert.Equal(t, buf.Len(), int(contractCreationBitBufferLen)) + require.Equal(t, buf.Len(), int(contractCreationBitBufferLen)) result := buf.Bytes() sbt.contractCreationBits = nil r := bytes.NewReader(result) err = sbt.decodeContractCreationBits(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, contractCreationBits, sbt.contractCreationBits) + require.Equal(t, contractCreationBits, sbt.contractCreationBits) } func TestSpanBatchTxsContractCreationCount(t *testing.T) { @@ -62,16 +63,16 @@ func TestSpanBatchTxsContractCreationCount(t *testing.T) { var buf bytes.Buffer err := sbt.encodeContractCreationBits(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() sbt.contractCreationBits = nil r := bytes.NewReader(result) err = sbt.decodeContractCreationBits(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, contractCreationCount, sbt.contractCreationCount()) + require.Equal(t, contractCreationCount, sbt.contractCreationCount()) } func TestSpanBatchTxsYParityBits(t *testing.T) { @@ -88,23 +89,23 @@ func TestSpanBatchTxsYParityBits(t *testing.T) { var buf bytes.Buffer err := sbt.encodeYParityBits(&buf) - assert.NoError(t, err) + require.NoError(t, err) // yParityBit field is fixed length: single bit yParityBitBufferLen := totalBlockTxCount / 8 if totalBlockTxCount%8 != 0 { yParityBitBufferLen++ } - assert.Equal(t, buf.Len(), int(yParityBitBufferLen)) + require.Equal(t, buf.Len(), int(yParityBitBufferLen)) result := buf.Bytes() sbt.yParityBits = nil r := bytes.NewReader(result) err = sbt.decodeYParityBits(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, yParityBits, sbt.yParityBits) + require.Equal(t, yParityBits, sbt.yParityBits) } func TestSpanBatchTxsTxSigs(t *testing.T) { @@ -121,22 +122,22 @@ func TestSpanBatchTxsTxSigs(t *testing.T) { var buf bytes.Buffer err := sbt.encodeTxSigsRS(&buf) - assert.NoError(t, err) + require.NoError(t, err) // txSig field is fixed length: 32 byte + 32 byte = 64 byte - assert.Equal(t, buf.Len(), 64*int(totalBlockTxCount)) + require.Equal(t, buf.Len(), 64*int(totalBlockTxCount)) result := buf.Bytes() sbt.txSigs = nil r := bytes.NewReader(result) err = sbt.decodeTxSigsRS(r) - assert.NoError(t, err) + require.NoError(t, err) // v field is not set for i := 0; i < int(totalBlockTxCount); i++ { - assert.Equal(t, txSigs[i].r, sbt.txSigs[i].r) - assert.Equal(t, txSigs[i].s, sbt.txSigs[i].s) + require.Equal(t, txSigs[i].r, sbt.txSigs[i].r) + require.Equal(t, txSigs[i].s, sbt.txSigs[i].s) } } @@ -154,16 +155,16 @@ func TestSpanBatchTxsTxNonces(t *testing.T) { var buf bytes.Buffer err := sbt.encodeTxNonces(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() sbt.txNonces = nil r := bytes.NewReader(result) err = sbt.decodeTxNonces(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, txNonces, sbt.txNonces) + require.Equal(t, txNonces, sbt.txNonces) } func TestSpanBatchTxsTxGases(t *testing.T) { @@ -180,16 +181,16 @@ func TestSpanBatchTxsTxGases(t *testing.T) { var buf bytes.Buffer err := sbt.encodeTxGases(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() sbt.txGases = nil r := bytes.NewReader(result) err = sbt.decodeTxGases(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, txGases, sbt.txGases) + require.Equal(t, txGases, sbt.txGases) } func TestSpanBatchTxsTxTos(t *testing.T) { @@ -209,19 +210,19 @@ func TestSpanBatchTxsTxTos(t *testing.T) { var buf bytes.Buffer err := sbt.encodeTxTos(&buf) - assert.NoError(t, err) + require.NoError(t, err) // to field is fixed length: 20 bytes - assert.Equal(t, buf.Len(), 20*len(txTos)) + require.Equal(t, buf.Len(), 20*len(txTos)) result := buf.Bytes() sbt.txTos = nil r := bytes.NewReader(result) err = sbt.decodeTxTos(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, txTos, sbt.txTos) + require.Equal(t, txTos, sbt.txTos) } func TestSpanBatchTxsTxDatas(t *testing.T) { @@ -240,7 +241,7 @@ func TestSpanBatchTxsTxDatas(t *testing.T) { var buf bytes.Buffer err := sbt.encodeTxDatas(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() sbt.txDatas = nil @@ -248,10 +249,10 @@ func TestSpanBatchTxsTxDatas(t *testing.T) { r := bytes.NewReader(result) err = sbt.decodeTxDatas(r) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, txDatas, sbt.txDatas) - assert.Equal(t, txTypes, sbt.txTypes) + require.Equal(t, txDatas, sbt.txDatas) + require.Equal(t, txTypes, sbt.txTypes) } func TestSpanBatchTxsRecoverV(t *testing.T) { @@ -291,7 +292,7 @@ func TestSpanBatchTxsRecoverV(t *testing.T) { recoveredVs = append(recoveredVs, txSig.v) } - assert.Equal(t, originalVs, recoveredVs, "recovered v mismatch") + require.Equal(t, originalVs, recoveredVs, "recovered v mismatch") } func TestSpanBatchTxsRoundTrip(t *testing.T) { @@ -305,7 +306,7 @@ func TestSpanBatchTxsRoundTrip(t *testing.T) { var buf bytes.Buffer err := sbt.encode(&buf) - assert.NoError(t, err) + require.NoError(t, err) result := buf.Bytes() r := bytes.NewReader(result) @@ -313,10 +314,10 @@ func TestSpanBatchTxsRoundTrip(t *testing.T) { var sbt2 spanBatchTxs sbt2.totalBlockTxCount = totalBlockTxCount err = sbt2.decode(r) - assert.NoError(t, err) + require.NoError(t, err) sbt2.recoverV(chainID) - assert.Equal(t, sbt, &sbt2) + require.Equal(t, sbt, &sbt2) } } @@ -331,16 +332,16 @@ func TestSpanBatchTxsRoundTripFullTxs(t *testing.T) { for i := 0; i < int(totalblockTxCounts); i++ { tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) rawTx, err := tx.MarshalBinary() - assert.NoError(t, err) + require.NoError(t, err) txs = append(txs, rawTx) } sbt, err := newSpanBatchTxs(txs, chainID) - assert.NoError(t, err) + require.NoError(t, err) txs2, err := sbt.fullTxs(chainID) - assert.NoError(t, err) + require.NoError(t, err) - assert.Equal(t, txs, txs2) + require.Equal(t, txs, txs2) } } @@ -373,17 +374,17 @@ func TestSpanBatchTxsFullTxNotEnoughTxTos(t *testing.T) { for i := 0; i < int(totalblockTxCounts); i++ { tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) rawTx, err := tx.MarshalBinary() - assert.NoError(t, err) + require.NoError(t, err) txs = append(txs, rawTx) } sbt, err := newSpanBatchTxs(txs, chainID) - assert.NoError(t, err) + require.NoError(t, err) // drop single to field sbt.txTos = sbt.txTos[:len(sbt.txTos)-2] _, err = sbt.fullTxs(chainID) - assert.EqualError(t, err, "tx to not enough") + require.EqualError(t, err, "tx to not enough") } func TestSpanBatchTxsMaxContractCreationBitsLength(t *testing.T) { diff --git a/op-node/rollup/derive/span_channel_out.go b/op-node/rollup/derive/span_channel_out.go index b509247fb704..a272dfaf5225 100644 --- a/op-node/rollup/derive/span_channel_out.go +++ b/op-node/rollup/derive/span_channel_out.go @@ -106,12 +106,12 @@ func (co *SpanChannelOut) AddSingularBatch(batch *SingularBatch, seqNum uint64) return 0, fmt.Errorf("failed to convert SpanBatch into RawSpanBatch: %w", err) } // Encode RawSpanBatch into bytes - if err = rlp.Encode(&buf, NewSpanBatchData(*rawSpanBatch)); err != nil { + if err = rlp.Encode(&buf, NewBatchData(rawSpanBatch)); err != nil { return 0, fmt.Errorf("failed to encode RawSpanBatch into bytes: %w", err) } // Ensure that the total size of all RLP elements is less than or equal to MAX_RLP_BYTES_PER_CHANNEL if buf.Len() > MaxRLPBytesPerChannel { - return 0, fmt.Errorf("could not add %d bytes to channel of %d bytes, max is %d. err: %w", + return 0, fmt.Errorf("could not take %d bytes as replacement of channel of %d bytes, max is %d. err: %w", buf.Len(), co.rlpLength, MaxRLPBytesPerChannel, ErrTooManyRLPBytes) } co.rlpLength = buf.Len() diff --git a/op-service/testutils/random.go b/op-service/testutils/random.go index f2d074aad9a2..d1363ecf3f5d 100644 --- a/op-service/testutils/random.go +++ b/op-service/testutils/random.go @@ -141,49 +141,72 @@ func RandomTo(rng *rand.Rand) *common.Address { } func RandomTx(rng *rand.Rand, baseFee *big.Int, signer types.Signer) *types.Transaction { - gas := params.TxGas + uint64(rng.Int63n(2_000_000)) - key := InsecureRandomKey(rng) - tip := big.NewInt(rng.Int63n(10 * params.GWei)) - txTypeList := []int{types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType} txType := txTypeList[rng.Intn(len(txTypeList))] - var txData types.TxData + var tx *types.Transaction switch txType { case types.LegacyTxType: - txData = &types.LegacyTx{ - Nonce: rng.Uint64(), - GasPrice: new(big.Int).SetUint64(rng.Uint64()), - Gas: gas, - To: RandomTo(rng), - Value: RandomETH(rng, 10), - Data: RandomData(rng, rng.Intn(1000)), - } + tx = RandomLegacyTx(rng, signer) case types.AccessListTxType: - txData = &types.AccessListTx{ - ChainID: signer.ChainID(), - Nonce: rng.Uint64(), - GasPrice: new(big.Int).SetUint64(rng.Uint64()), - Gas: gas, - To: RandomTo(rng), - Value: RandomETH(rng, 10), - Data: RandomData(rng, rng.Intn(1000)), - AccessList: nil, - } + tx = RandomAccessListTx(rng, signer) case types.DynamicFeeTxType: - txData = &types.DynamicFeeTx{ - ChainID: signer.ChainID(), - Nonce: rng.Uint64(), - GasTipCap: tip, - GasFeeCap: new(big.Int).Add(baseFee, tip), - Gas: gas, - To: RandomTo(rng), - Value: RandomETH(rng, 10), - Data: RandomData(rng, rng.Intn(1000)), - AccessList: nil, - } + tx = RandomDynamicFeeTxWithBaseFee(rng, baseFee, signer) default: panic("invalid tx type") } + return tx +} + +func RandomLegacyTx(rng *rand.Rand, signer types.Signer) *types.Transaction { + key := InsecureRandomKey(rng) + txData := &types.LegacyTx{ + Nonce: rng.Uint64(), + GasPrice: new(big.Int).SetUint64(rng.Uint64()), + Gas: params.TxGas + uint64(rng.Int63n(2_000_000)), + To: RandomTo(rng), + Value: RandomETH(rng, 10), + Data: RandomData(rng, rng.Intn(1000)), + } + tx, err := types.SignNewTx(key, signer, txData) + if err != nil { + panic(err) + } + return tx +} + +func RandomAccessListTx(rng *rand.Rand, signer types.Signer) *types.Transaction { + key := InsecureRandomKey(rng) + txData := &types.AccessListTx{ + ChainID: signer.ChainID(), + Nonce: rng.Uint64(), + GasPrice: new(big.Int).SetUint64(rng.Uint64()), + Gas: params.TxGas + uint64(rng.Int63n(2_000_000)), + To: RandomTo(rng), + Value: RandomETH(rng, 10), + Data: RandomData(rng, rng.Intn(1000)), + AccessList: nil, + } + tx, err := types.SignNewTx(key, signer, txData) + if err != nil { + panic(err) + } + return tx +} + +func RandomDynamicFeeTxWithBaseFee(rng *rand.Rand, baseFee *big.Int, signer types.Signer) *types.Transaction { + key := InsecureRandomKey(rng) + tip := big.NewInt(rng.Int63n(10 * params.GWei)) + txData := &types.DynamicFeeTx{ + ChainID: signer.ChainID(), + Nonce: rng.Uint64(), + GasTipCap: tip, + GasFeeCap: new(big.Int).Add(baseFee, tip), + Gas: params.TxGas + uint64(rng.Int63n(2_000_000)), + To: RandomTo(rng), + Value: RandomETH(rng, 10), + Data: RandomData(rng, rng.Intn(1000)), + AccessList: nil, + } tx, err := types.SignNewTx(key, signer, txData) if err != nil { panic(err) @@ -191,6 +214,11 @@ func RandomTx(rng *rand.Rand, baseFee *big.Int, signer types.Signer) *types.Tran return tx } +func RandomDynamicFeeTx(rng *rand.Rand, signer types.Signer) *types.Transaction { + baseFee := new(big.Int).SetUint64(rng.Uint64()) + return RandomDynamicFeeTxWithBaseFee(rng, baseFee, signer) +} + func RandomReceipt(rng *rand.Rand, signer types.Signer, tx *types.Transaction, txIndex uint64, cumulativeGasUsed uint64) *types.Receipt { gasUsed := params.TxGas + uint64(rng.Int63n(int64(tx.Gas()-params.TxGas+1))) logs := make([]*types.Log, rng.Intn(10)) From 9f9cf6180a09cc2026bc0d5d96e52b30b13f0b6a Mon Sep 17 00:00:00 2001 From: protolambda Date: Mon, 30 Oct 2023 16:06:39 +0100 Subject: [PATCH 234/374] op-node: reduce batch inner type encode/decode methods to just one way Signed-off-by: protolambda --- op-node/rollup/derive/batch.go | 4 +--- op-node/rollup/derive/singular_batch.go | 10 ---------- op-node/rollup/derive/span_batch.go | 17 ----------------- op-node/rollup/derive/span_batch_test.go | 5 +++-- 4 files changed, 4 insertions(+), 32 deletions(-) diff --git a/op-node/rollup/derive/batch.go b/op-node/rollup/derive/batch.go index 9f43446dadb6..9f3563e79080 100644 --- a/op-node/rollup/derive/batch.go +++ b/op-node/rollup/derive/batch.go @@ -53,8 +53,6 @@ type InnerBatchData interface { GetBatchType() int encode(w io.Writer) error decode(r *bytes.Reader) error - encodeBytes() ([]byte, error) - decodeBytes(data []byte) error } // EncodeRLP implements rlp.Encoder @@ -121,7 +119,7 @@ func (b *BatchData) decodeTyped(data []byte) error { default: return fmt.Errorf("unrecognized batch type: %d", data[0]) } - if err := inner.decodeBytes(data[1:]); err != nil { + if err := inner.decode(bytes.NewReader(data[1:])); err != nil { return err } b.inner = inner diff --git a/op-node/rollup/derive/singular_batch.go b/op-node/rollup/derive/singular_batch.go index 47d3eb420696..6354dc46ee53 100644 --- a/op-node/rollup/derive/singular_batch.go +++ b/op-node/rollup/derive/singular_batch.go @@ -65,13 +65,3 @@ func (b *SingularBatch) encode(w io.Writer) error { func (b *SingularBatch) decode(r *bytes.Reader) error { return rlp.Decode(r, b) } - -// encodeBytes returns the byte encoding of SingularBatch -func (b *SingularBatch) encodeBytes() ([]byte, error) { - return rlp.EncodeToBytes(b) -} - -// decodeBytes parses data into b from data -func (b *SingularBatch) decodeBytes(data []byte) error { - return rlp.DecodeBytes(data, b) -} diff --git a/op-node/rollup/derive/span_batch.go b/op-node/rollup/derive/span_batch.go index 37b73ab06faf..e71dd05a5b18 100644 --- a/op-node/rollup/derive/span_batch.go +++ b/op-node/rollup/derive/span_batch.go @@ -224,12 +224,6 @@ func (bp *spanBatchPayload) decodePayload(r *bytes.Reader) error { return nil } -// decodeBytes parses data into b from data -func (b *RawSpanBatch) decodeBytes(data []byte) error { - r := bytes.NewReader(data) - return b.decode(r) -} - // decode reads the byte encoding of SpanBatch from Reader stream func (b *RawSpanBatch) decode(r *bytes.Reader) error { if r.Len() > MaxSpanBatchSize { @@ -383,17 +377,6 @@ func (b *RawSpanBatch) encode(w io.Writer) error { return nil } -// encodeBytes returns the byte encoding of SpanBatch -func (b *RawSpanBatch) encodeBytes() ([]byte, error) { - buf := encodeBufferPool.Get().(*bytes.Buffer) - defer encodeBufferPool.Put(buf) - buf.Reset() - if err := b.encode(buf); err != nil { - return []byte{}, err - } - return buf.Bytes(), nil -} - // derive converts RawSpanBatch into SpanBatch, which has a list of spanBatchElement. // We need chain config constants to derive values for making payload attributes. func (b *RawSpanBatch) derive(blockTime, genesisTimestamp uint64, chainID *big.Int) (*SpanBatch, error) { diff --git a/op-node/rollup/derive/span_batch_test.go b/op-node/rollup/derive/span_batch_test.go index c8ee658577db..eaa03a8a53d7 100644 --- a/op-node/rollup/derive/span_batch_test.go +++ b/op-node/rollup/derive/span_batch_test.go @@ -294,11 +294,12 @@ func TestSpanBatchRoundTrip(t *testing.T) { rawSpanBatch := RandomRawSpanBatch(rng, chainID) - result, err := rawSpanBatch.encodeBytes() + var result bytes.Buffer + err := rawSpanBatch.encode(&result) require.NoError(t, err) var sb RawSpanBatch - err = sb.decodeBytes(result) + err = sb.decode(bytes.NewReader(result.Bytes())) require.NoError(t, err) sb.txs.recoverV(chainID) From 4cc340aef1fb6003272c4308c99bdacd3893264a Mon Sep 17 00:00:00 2001 From: inphi Date: Mon, 30 Oct 2023 10:03:08 -0400 Subject: [PATCH 235/374] ci: disable codecov comments on zero diff Also disables Go codecov to avoid spurious diffs due to non-deterministic codecov reports --- .circleci/config.yml | 7 ++++--- codecov.yml | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5d885f87c6ed..260dd8e14f57 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -770,9 +770,10 @@ jobs: key: golang-build-cache-<> paths: - "/root/.cache/go-build" - - run: - name: upload coverage - command: codecov --verbose --clean --flags bedrock-go-tests + # TODO(CLI-148): Fix codecov + #- run: + #name: upload coverage + #command: codecov --verbose --clean --flags bedrock-go-tests - store_test_results: path: /tmp/test-results diff --git a/codecov.yml b/codecov.yml index f64112c9cf1c..6edb2f3e455c 100644 --- a/codecov.yml +++ b/codecov.yml @@ -3,7 +3,7 @@ codecov: comment: layout: "diff, flags, files" behavior: default - require_changes: false + require_changes: true flags: - contracts-bedrock-tests From 6600e979d092a2f7cc726e6f9471710902fc93ce Mon Sep 17 00:00:00 2001 From: Hamdi Allam Date: Mon, 30 Oct 2023 13:15:37 -0400 Subject: [PATCH 236/374] header traversal nits --- indexer/etl/etl.go | 10 +++-- indexer/etl/l1_etl_test.go | 4 +- indexer/node/header_traversal.go | 40 +++++++++-------- indexer/node/header_traversal_test.go | 63 +++++++++++++++++---------- 4 files changed, 72 insertions(+), 45 deletions(-) diff --git a/indexer/etl/etl.go b/indexer/etl/etl.go index be262565dfed..501bc795ae93 100644 --- a/indexer/etl/etl.go +++ b/indexer/etl/etl.go @@ -67,15 +67,19 @@ func (etl *ETL) Start(ctx context.Context) error { if len(headers) > 0 { etl.log.Info("retrying previous batch") } else { - newHeaders, err := etl.headerTraversal.NextFinalizedHeaders(etl.headerBufferSize) + newHeaders, err := etl.headerTraversal.NextHeaders(etl.headerBufferSize) if err != nil { etl.log.Error("error querying for headers", "err", err) } else if len(newHeaders) == 0 { - etl.log.Warn("no new headers. processor unexpectedly at head...") + etl.log.Warn("no new headers. etl at head?") } else { - etl.metrics.RecordLatestHeight(etl.headerTraversal.LatestHeader().Number) headers = newHeaders } + + latestHeader := etl.headerTraversal.LatestHeader() + if latestHeader != nil { + etl.metrics.RecordLatestHeight(latestHeader.Number) + } } // only clear the reference if we were able to process this batch diff --git a/indexer/etl/l1_etl_test.go b/indexer/etl/l1_etl_test.go index c64167f173ca..0c6b49dbac9a 100644 --- a/indexer/etl/l1_etl_test.go +++ b/indexer/etl/l1_etl_test.go @@ -62,7 +62,7 @@ func TestL1ETLConstruction(t *testing.T) { }, assertion: func(etl *L1ETL, err error) { require.NoError(t, err) - require.Equal(t, etl.headerTraversal.LastHeader().ParentHash, common.HexToHash("0x69")) + require.Equal(t, etl.headerTraversal.LastTraversedHeader().ParentHash, common.HexToHash("0x69")) }, }, { @@ -94,7 +94,7 @@ func TestL1ETLConstruction(t *testing.T) { }, assertion: func(etl *L1ETL, err error) { require.NoError(t, err) - header := etl.headerTraversal.LastHeader() + header := etl.headerTraversal.LastTraversedHeader() require.True(t, header.Number.Cmp(big.NewInt(69)) == 0) }, diff --git a/indexer/node/header_traversal.go b/indexer/node/header_traversal.go index 437d64ddeca2..3546aa8d1e46 100644 --- a/indexer/node/header_traversal.go +++ b/indexer/node/header_traversal.go @@ -17,8 +17,8 @@ var ( type HeaderTraversal struct { ethClient EthClient - lastHeader *types.Header - latestHeader *types.Header + latestHeader *types.Header + lastTraversedHeader *types.Header blockConfirmationDepth *big.Int } @@ -26,30 +26,37 @@ type HeaderTraversal struct { // NewHeaderTraversal instantiates a new instance of HeaderTraversal against the supplied rpc client. // The HeaderTraversal will start fetching blocks starting from the supplied header unless nil, indicating genesis. func NewHeaderTraversal(ethClient EthClient, fromHeader *types.Header, confDepth *big.Int) *HeaderTraversal { - return &HeaderTraversal{ethClient: ethClient, lastHeader: fromHeader, blockConfirmationDepth: confDepth} + return &HeaderTraversal{ + ethClient: ethClient, + lastTraversedHeader: fromHeader, + blockConfirmationDepth: confDepth, + } } // LatestHeader returns the latest header reported by underlying eth client +// as headers are traversed via `NextHeaders`. func (f *HeaderTraversal) LatestHeader() *types.Header { return f.latestHeader } -// LastHeader returns the last header traversed. +// LastTraversedHeader returns the last header traversed. // - This is useful for testing the state of the HeaderTraversal -// - NOTE: LastHeader may be << LatestHeader depending on the number -// headers traversed via `NextFinalizedHeaders`. -func (f *HeaderTraversal) LastHeader() *types.Header { - return f.lastHeader +// - LastTraversedHeader may be << LatestHeader depending on the number +// headers traversed via `NextHeaders`. +func (f *HeaderTraversal) LastTraversedHeader() *types.Header { + return f.lastTraversedHeader } -// NextFinalizedHeaders retrieves the next set of headers that have been +// NextHeaders retrieves the next set of headers that have been // marked as finalized by the connected client, bounded by the supplied size -func (f *HeaderTraversal) NextFinalizedHeaders(maxSize uint64) ([]types.Header, error) { +func (f *HeaderTraversal) NextHeaders(maxSize uint64) ([]types.Header, error) { latestHeader, err := f.ethClient.BlockHeaderByNumber(nil) if err != nil { return nil, fmt.Errorf("unable to query latest block: %w", err) } else if latestHeader == nil { return nil, fmt.Errorf("latest header unreported") + } else { + f.latestHeader = latestHeader } endHeight := new(big.Int).Sub(latestHeader.Number, f.blockConfirmationDepth) @@ -58,8 +65,8 @@ func (f *HeaderTraversal) NextFinalizedHeaders(maxSize uint64) ([]types.Header, return nil, nil } - if f.lastHeader != nil { - cmp := f.lastHeader.Number.Cmp(endHeight) + if f.lastTraversedHeader != nil { + cmp := f.lastTraversedHeader.Number.Cmp(endHeight) if cmp == 0 { // We're synced to head and there are no new headers return nil, nil } else if cmp > 0 { @@ -68,8 +75,8 @@ func (f *HeaderTraversal) NextFinalizedHeaders(maxSize uint64) ([]types.Header, } nextHeight := bigint.Zero - if f.lastHeader != nil { - nextHeight = new(big.Int).Add(f.lastHeader.Number, bigint.One) + if f.lastTraversedHeader != nil { + nextHeight = new(big.Int).Add(f.lastTraversedHeader.Number, bigint.One) } // endHeight = (nextHeight - endHeight) <= maxSize @@ -82,13 +89,12 @@ func (f *HeaderTraversal) NextFinalizedHeaders(maxSize uint64) ([]types.Header, numHeaders := len(headers) if numHeaders == 0 { return nil, nil - } else if f.lastHeader != nil && headers[0].ParentHash != f.lastHeader.Hash() { + } else if f.lastTraversedHeader != nil && headers[0].ParentHash != f.lastTraversedHeader.Hash() { // The indexer's state is in an irrecoverable state relative to the provider. This // should never happen since the indexer is dealing with only finalized blocks. return nil, ErrHeaderTraversalAndProviderMismatchedState } - f.lastHeader = &headers[numHeaders-1] - f.latestHeader = latestHeader + f.lastTraversedHeader = &headers[numHeaders-1] return headers, nil } diff --git a/indexer/node/header_traversal_test.go b/indexer/node/header_traversal_test.go index 6358fc7c8eb0..603b8fdd3a97 100644 --- a/indexer/node/header_traversal_test.go +++ b/indexer/node/header_traversal_test.go @@ -33,44 +33,55 @@ func makeHeaders(numHeaders uint64, prevHeader *types.Header) []types.Header { return headers } -func TestHeaderTraversalNextFinalizedHeadersNoOp(t *testing.T) { +func TestHeaderTraversalNextHeadersNoOp(t *testing.T) { client := new(MockEthClient) // start from block 10 as the latest fetched block - lastHeader := &types.Header{Number: big.NewInt(10)} - headerTraversal := NewHeaderTraversal(client, lastHeader, bigint.Zero) + LastTraversedHeader := &types.Header{Number: big.NewInt(10)} + headerTraversal := NewHeaderTraversal(client, LastTraversedHeader, bigint.Zero) + + require.Nil(t, headerTraversal.LatestHeader()) + require.NotNil(t, headerTraversal.LastTraversedHeader()) // no new headers when matched with head - client.On("BlockHeaderByNumber", (*big.Int)(nil)).Return(lastHeader, nil) - headers, err := headerTraversal.NextFinalizedHeaders(100) + client.On("BlockHeaderByNumber", (*big.Int)(nil)).Return(LastTraversedHeader, nil) + headers, err := headerTraversal.NextHeaders(100) require.NoError(t, err) require.Empty(t, headers) + + require.NotNil(t, headerTraversal.LatestHeader()) + require.NotNil(t, headerTraversal.LastTraversedHeader()) + require.Equal(t, LastTraversedHeader.Number.Uint64(), headerTraversal.LatestHeader().Number.Uint64()) } -func TestHeaderTraversalNextFinalizedHeadersCursored(t *testing.T) { +func TestHeaderTraversalNextHeadersCursored(t *testing.T) { client := new(MockEthClient) // start from genesis headerTraversal := NewHeaderTraversal(client, nil, bigint.Zero) - // blocks [0..4] - headers := makeHeaders(5, nil) - client.On("BlockHeaderByNumber", (*big.Int)(nil)).Return(&headers[4], nil).Times(1) // Times so that we can override next - client.On("BlockHeadersByRange", mock.MatchedBy(bigint.Matcher(0)), mock.MatchedBy(bigint.Matcher(4))).Return(headers, nil) - headers, err := headerTraversal.NextFinalizedHeaders(5) + headers := makeHeaders(10, nil) + + // blocks [0..4]. Latest reported is 7 + client.On("BlockHeaderByNumber", (*big.Int)(nil)).Return(&headers[7], nil).Times(1) // Times so that we can override next + client.On("BlockHeadersByRange", mock.MatchedBy(bigint.Matcher(0)), mock.MatchedBy(bigint.Matcher(4))).Return(headers[:5], nil) + _, err := headerTraversal.NextHeaders(5) require.NoError(t, err) - require.Len(t, headers, 5) - // blocks [5..9] - headers = makeHeaders(5, &headers[len(headers)-1]) - client.On("BlockHeaderByNumber", (*big.Int)(nil)).Return(&headers[4], nil) - client.On("BlockHeadersByRange", mock.MatchedBy(bigint.Matcher(5)), mock.MatchedBy(bigint.Matcher(9))).Return(headers, nil) - headers, err = headerTraversal.NextFinalizedHeaders(5) + require.Equal(t, uint64(7), headerTraversal.LatestHeader().Number.Uint64()) + require.Equal(t, uint64(4), headerTraversal.LastTraversedHeader().Number.Uint64()) + + // blocks [5..9]. Latest Reported is 9 + client.On("BlockHeaderByNumber", (*big.Int)(nil)).Return(&headers[9], nil) + client.On("BlockHeadersByRange", mock.MatchedBy(bigint.Matcher(5)), mock.MatchedBy(bigint.Matcher(9))).Return(headers[5:], nil) + _, err = headerTraversal.NextHeaders(5) require.NoError(t, err) - require.Len(t, headers, 5) + + require.Equal(t, uint64(9), headerTraversal.LatestHeader().Number.Uint64()) + require.Equal(t, uint64(9), headerTraversal.LastTraversedHeader().Number.Uint64()) } -func TestHeaderTraversalNextFinalizedHeadersMaxSize(t *testing.T) { +func TestHeaderTraversalNextHeadersMaxSize(t *testing.T) { client := new(MockEthClient) // start from genesis @@ -82,16 +93,22 @@ func TestHeaderTraversalNextFinalizedHeadersMaxSize(t *testing.T) { // clamped by the supplied size headers := makeHeaders(5, nil) client.On("BlockHeadersByRange", mock.MatchedBy(bigint.Matcher(0)), mock.MatchedBy(bigint.Matcher(4))).Return(headers, nil) - headers, err := headerTraversal.NextFinalizedHeaders(5) + headers, err := headerTraversal.NextHeaders(5) require.NoError(t, err) require.Len(t, headers, 5) + require.Equal(t, uint64(100), headerTraversal.LatestHeader().Number.Uint64()) + require.Equal(t, uint64(4), headerTraversal.LastTraversedHeader().Number.Uint64()) + // clamped by the supplied size. FinalizedHeight == 100 headers = makeHeaders(10, &headers[len(headers)-1]) client.On("BlockHeadersByRange", mock.MatchedBy(bigint.Matcher(5)), mock.MatchedBy(bigint.Matcher(14))).Return(headers, nil) - headers, err = headerTraversal.NextFinalizedHeaders(10) + headers, err = headerTraversal.NextHeaders(10) require.NoError(t, err) require.Len(t, headers, 10) + + require.Equal(t, uint64(100), headerTraversal.LatestHeader().Number.Uint64()) + require.Equal(t, uint64(14), headerTraversal.LastTraversedHeader().Number.Uint64()) } func TestHeaderTraversalMismatchedProviderStateError(t *testing.T) { @@ -104,7 +121,7 @@ func TestHeaderTraversalMismatchedProviderStateError(t *testing.T) { headers := makeHeaders(5, nil) client.On("BlockHeaderByNumber", (*big.Int)(nil)).Return(&headers[4], nil).Times(1) // Times so that we can override next client.On("BlockHeadersByRange", mock.MatchedBy(bigint.Matcher(0)), mock.MatchedBy(bigint.Matcher(4))).Return(headers, nil) - headers, err := headerTraversal.NextFinalizedHeaders(5) + headers, err := headerTraversal.NextHeaders(5) require.NoError(t, err) require.Len(t, headers, 5) @@ -112,7 +129,7 @@ func TestHeaderTraversalMismatchedProviderStateError(t *testing.T) { headers = makeHeaders(5, nil) client.On("BlockHeaderByNumber", (*big.Int)(nil)).Return(&types.Header{Number: big.NewInt(9)}, nil) client.On("BlockHeadersByRange", mock.MatchedBy(bigint.Matcher(5)), mock.MatchedBy(bigint.Matcher(9))).Return(headers, nil) - headers, err = headerTraversal.NextFinalizedHeaders(5) + headers, err = headerTraversal.NextHeaders(5) require.Nil(t, headers) require.Equal(t, ErrHeaderTraversalAndProviderMismatchedState, err) } From 3f3ad34ec4d185e4428f6ed8daef89e081b6557c Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Mon, 30 Oct 2023 12:13:55 -0700 Subject: [PATCH 237/374] op-node: Hide rethDB option If the rethDB option is used without the proper build configuration, the op-node will panic. Note that we do not have this build configuration in our releases. This hides the option to use it, but does not fully remove it. There was some duplication required to easily hide the command line flag while still being able to use it for testing purposes. This commit should be reverted when rethDB is stable. --- op-node/flags/flags.go | 1 + op-service/sources/receipts.go | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go index fa6fcd066db6..fef9f7b1582d 100644 --- a/op-node/flags/flags.go +++ b/op-node/flags/flags.go @@ -87,6 +87,7 @@ var ( Usage: "The L1 RethDB path, used to fetch receipts for L1 blocks. Only applicable when using the `reth_db` RPC kind with `l1.rpckind`.", EnvVars: prefixEnvVars("L1_RETHDB"), Required: false, + Hidden: true, } L1RPCRateLimit = &cli.Float64Flag{ Name: "l1.rpc-rate-limit", diff --git a/op-service/sources/receipts.go b/op-service/sources/receipts.go index f5520624a7f7..f3f5205ee457 100644 --- a/op-service/sources/receipts.go +++ b/op-service/sources/receipts.go @@ -138,9 +138,13 @@ var RPCProviderKinds = []RPCProviderKind{ RPCKindBasic, RPCKindAny, RPCKindStandard, - RPCKindRethDB, } +// Copy of RPCProviderKinds with RethDB added to all RethDB to be used but to hide it from the flags +var validRPCProviderKinds = func() []RPCProviderKind { + return append(RPCProviderKinds, RPCKindRethDB) +}() + func (kind RPCProviderKind) String() string { return string(kind) } @@ -159,7 +163,7 @@ func (kind *RPCProviderKind) Clone() any { } func ValidRPCProviderKind(value RPCProviderKind) bool { - for _, k := range RPCProviderKinds { + for _, k := range validRPCProviderKinds { if k == value { return true } From 895ccc9b06d18b04ebdc6157c58b88c4d04000ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 20:43:39 +0000 Subject: [PATCH 238/374] build(deps-dev): bump eslint-plugin-unicorn from 48.0.1 to 49.0.0 Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 48.0.1 to 49.0.0. - [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases) - [Commits](https://github.com/sindresorhus/eslint-plugin-unicorn/compare/v48.0.1...v49.0.0) --- updated-dependencies: - dependency-name: eslint-plugin-unicorn dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package.json | 2 +- pnpm-lock.yaml | 64 +++++++++++++++----------------------------------- 2 files changed, 20 insertions(+), 46 deletions(-) diff --git a/package.json b/package.json index 9a94eb9d18ff..ea043beb1343 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-promise": "^5.1.0", "eslint-plugin-react": "^7.24.0", - "eslint-plugin-unicorn": "^48.0.1", + "eslint-plugin-unicorn": "^49.0.0", "husky": "^8.0.3", "lint-staged": "15.0.2", "markdownlint": "^0.31.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8152a3e6c086..3a9ad046405e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -79,8 +79,8 @@ importers: specifier: ^7.24.0 version: 7.33.2(eslint@8.52.0) eslint-plugin-unicorn: - specifier: ^48.0.1 - version: 48.0.1(eslint@8.52.0) + specifier: ^49.0.0 + version: 49.0.0(eslint@8.52.0) husky: specifier: ^8.0.3 version: 8.0.3 @@ -603,20 +603,12 @@ packages: '@jridgewell/trace-mapping': 0.3.19 dev: true - /@babel/code-frame@7.22.10: - resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.22.10 - chalk: 2.4.2 - /@babel/code-frame@7.22.13: resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.22.20 chalk: 2.4.2 - dev: true /@babel/compat-data@7.22.9: resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} @@ -628,7 +620,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.22.13 '@babel/generator': 7.22.10 '@babel/helper-compilation-targets': 7.22.10 '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) @@ -742,7 +734,7 @@ packages: '@babel/helper-module-imports': 7.22.5 '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 dev: true /@babel/helper-simple-access@7.22.5: @@ -767,11 +759,6 @@ packages: /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier@7.22.5: - resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} - engines: {node: '>=6.9.0'} /@babel/helper-validator-option@7.22.5: resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} @@ -789,14 +776,6 @@ packages: - supports-color dev: true - /@babel/highlight@7.22.10: - resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.22.5 - chalk: 2.4.2 - js-tokens: 4.0.0 - /@babel/highlight@7.22.20: resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} engines: {node: '>=6.9.0'} @@ -804,7 +783,6 @@ packages: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 - dev: true /@babel/parser@7.22.10: resolution: {integrity: sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==} @@ -848,7 +826,7 @@ packages: resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.22.13 '@babel/parser': 7.22.10 '@babel/types': 7.22.10 dev: true @@ -857,7 +835,7 @@ packages: resolution: {integrity: sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.22.13 '@babel/generator': 7.22.10 '@babel/helper-environment-visitor': 7.22.5 '@babel/helper-function-name': 7.22.5 @@ -894,7 +872,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 dev: true @@ -3700,7 +3678,7 @@ packages: resolution: {integrity: sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==} engines: {node: '>=14'} dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.22.13 '@babel/runtime': 7.22.6 '@types/aria-query': 5.0.1 aria-query: 5.1.3 @@ -6164,7 +6142,7 @@ packages: /call-bind@1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 get-intrinsic: 1.2.1 /callsite@1.0.0: @@ -7328,7 +7306,7 @@ packages: define-properties: 1.2.0 es-abstract: 1.22.1 es-set-tostringtag: 2.0.1 - function-bind: 1.1.1 + function-bind: 1.1.2 get-intrinsic: 1.2.1 globalthis: 1.0.3 has-property-descriptors: 1.0.0 @@ -7681,13 +7659,13 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-unicorn@48.0.1(eslint@8.52.0): - resolution: {integrity: sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==} + /eslint-plugin-unicorn@49.0.0(eslint@8.52.0): + resolution: {integrity: sha512-0fHEa/8Pih5cmzFW5L7xMEfUTvI9WKeQtjmKpTUmY+BiFCDxkxrTdnURJOHKykhtwIeyYsxnecbGvDCml++z4Q==} engines: {node: '>=16'} peerDependencies: - eslint: '>=8.44.0' + eslint: '>=8.52.0' dependencies: - '@babel/helper-validator-identifier': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) ci-info: 3.8.0 clean-regexp: 1.0.0 @@ -7696,7 +7674,6 @@ packages: indent-string: 4.0.0 is-builtin-module: 3.2.1 jsesc: 3.0.2 - lodash: 4.17.21 pluralize: 8.0.0 read-pkg-up: 7.0.1 regexp-tree: 0.1.27 @@ -8588,9 +8565,6 @@ packages: dev: true optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -8667,7 +8641,7 @@ packages: /get-intrinsic@1.2.1: resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 has: 1.0.3 has-proto: 1.0.1 has-symbols: 1.0.3 @@ -9036,7 +9010,7 @@ packages: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 /hash-base@3.1.0: resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} @@ -11736,7 +11710,7 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.22.13 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -12652,7 +12626,7 @@ packages: resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} hasBin: true dependencies: - is-core-module: 2.13.0 + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: true @@ -12669,7 +12643,7 @@ packages: resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} hasBin: true dependencies: - is-core-module: 2.13.0 + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: true From 89ef8cde974eeaff0becf5a81181e5cedc0a0fa5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 20:47:00 +0000 Subject: [PATCH 239/374] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.9.0 to 6.9.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- packages/contracts-bedrock/package.json | 2 +- pnpm-lock.yaml | 80 +++++++++++++++++++------ 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 9a94eb9d18ff..c0c820415caf 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@types/chai-as-promised": "^7.1.4", "@types/mocha": "^10.0.3", "@types/node": "^20.8.9", - "@typescript-eslint/eslint-plugin": "^6.9.0", + "@typescript-eslint/eslint-plugin": "^6.9.1", "@typescript-eslint/parser": "^6.9.0", "chai": "^4.3.10", "depcheck": "^1.4.7", diff --git a/packages/contracts-bedrock/package.json b/packages/contracts-bedrock/package.json index 88f7e05e4700..18a7c09db2ca 100644 --- a/packages/contracts-bedrock/package.json +++ b/packages/contracts-bedrock/package.json @@ -44,7 +44,7 @@ "lint": "pnpm lint:fix && pnpm lint:check" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^6.9.0", + "@typescript-eslint/eslint-plugin": "^6.9.1", "@typescript-eslint/parser": "^6.9.0", "tsx": "^3.14.0", "typescript": "^5.2.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8152a3e6c086..5d9d4c88e4d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,8 +34,8 @@ importers: specifier: ^20.8.9 version: 20.8.9 '@typescript-eslint/eslint-plugin': - specifier: ^6.9.0 - version: 6.9.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2) + specifier: ^6.9.1 + version: 6.9.1(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2) '@typescript-eslint/parser': specifier: ^6.9.0 version: 6.9.0(eslint@8.52.0)(typescript@5.2.2) @@ -268,8 +268,8 @@ importers: packages/contracts-bedrock: devDependencies: '@typescript-eslint/eslint-plugin': - specifier: ^6.9.0 - version: 6.9.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2) + specifier: ^6.9.1 + version: 6.9.1(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2) '@typescript-eslint/parser': specifier: ^6.9.0 version: 6.9.0(eslint@8.52.0)(typescript@5.2.2) @@ -4223,8 +4223,8 @@ packages: '@types/node': 20.8.9 dev: false - /@typescript-eslint/eslint-plugin@6.9.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==} + /@typescript-eslint/eslint-plugin@6.9.1(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2): + resolution: {integrity: sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -4236,10 +4236,10 @@ packages: dependencies: '@eslint-community/regexpp': 4.6.2 '@typescript-eslint/parser': 6.9.0(eslint@8.52.0)(typescript@5.2.2) - '@typescript-eslint/scope-manager': 6.9.0 - '@typescript-eslint/type-utils': 6.9.0(eslint@8.52.0)(typescript@5.2.2) - '@typescript-eslint/utils': 6.9.0(eslint@8.52.0)(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.9.0 + '@typescript-eslint/scope-manager': 6.9.1 + '@typescript-eslint/type-utils': 6.9.1(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.9.1(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.9.1 debug: 4.3.4(supports-color@8.1.1) eslint: 8.52.0 graphemer: 1.4.0 @@ -4281,8 +4281,16 @@ packages: '@typescript-eslint/visitor-keys': 6.9.0 dev: true - /@typescript-eslint/type-utils@6.9.0(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==} + /@typescript-eslint/scope-manager@6.9.1: + resolution: {integrity: sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.9.1 + '@typescript-eslint/visitor-keys': 6.9.1 + dev: true + + /@typescript-eslint/type-utils@6.9.1(eslint@8.52.0)(typescript@5.2.2): + resolution: {integrity: sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -4291,8 +4299,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.9.0(typescript@5.2.2) - '@typescript-eslint/utils': 6.9.0(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.2.2) + '@typescript-eslint/utils': 6.9.1(eslint@8.52.0)(typescript@5.2.2) debug: 4.3.4(supports-color@8.1.1) eslint: 8.52.0 ts-api-utils: 1.0.1(typescript@5.2.2) @@ -4306,6 +4314,11 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dev: true + /@typescript-eslint/types@6.9.1: + resolution: {integrity: sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + /@typescript-eslint/typescript-estree@6.9.0(typescript@5.2.2): resolution: {integrity: sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4327,8 +4340,29 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@6.9.0(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==} + /@typescript-eslint/typescript-estree@6.9.1(typescript@5.2.2): + resolution: {integrity: sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.9.1 + '@typescript-eslint/visitor-keys': 6.9.1 + debug: 4.3.4(supports-color@8.1.1) + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.4 + ts-api-utils: 1.0.1(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@6.9.1(eslint@8.52.0)(typescript@5.2.2): + resolution: {integrity: sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -4336,9 +4370,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 6.9.0 - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/typescript-estree': 6.9.0(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.9.1 + '@typescript-eslint/types': 6.9.1 + '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.2.2) eslint: 8.52.0 semver: 7.5.4 transitivePeerDependencies: @@ -4354,6 +4388,14 @@ packages: eslint-visitor-keys: 3.4.3 dev: true + /@typescript-eslint/visitor-keys@6.9.1: + resolution: {integrity: sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.9.1 + eslint-visitor-keys: 3.4.3 + dev: true + /@ungap/structured-clone@1.2.0: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true From 32d0a4906fdd3d7e8b4f2d3fa81d89adb5475fcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 20:56:49 +0000 Subject: [PATCH 240/374] build(deps): bump viem from 1.18.0 to 1.18.1 Bumps [viem](https://github.com/wagmi-dev/viem) from 1.18.0 to 1.18.1. - [Release notes](https://github.com/wagmi-dev/viem/releases) - [Commits](https://github.com/wagmi-dev/viem/compare/viem@1.18.0...viem@1.18.1) --- updated-dependencies: - dependency-name: viem dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/contracts-ts/package.json | 2 +- packages/fee-estimation/package.json | 2 +- packages/sdk/package.json | 2 +- packages/web3js-plugin/package.json | 2 +- pnpm-lock.yaml | 62 ++++++++++++++-------------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/contracts-ts/package.json b/packages/contracts-ts/package.json index 9cd089f4c3fe..25ca19ea07a4 100644 --- a/packages/contracts-ts/package.json +++ b/packages/contracts-ts/package.json @@ -82,6 +82,6 @@ "change-case": "4.1.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "viem": "^1.18.0" + "viem": "^1.18.1" } } diff --git a/packages/fee-estimation/package.json b/packages/fee-estimation/package.json index 6cbc34b80625..6acb6bbe246a 100644 --- a/packages/fee-estimation/package.json +++ b/packages/fee-estimation/package.json @@ -44,7 +44,7 @@ "jsdom": "^22.1.0", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.18.0", + "viem": "^1.18.1", "vite": "^4.5.0", "vitest": "^0.34.2" }, diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 8588f45b2590..8a8bdcf4d882 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -56,7 +56,7 @@ "ts-node": "^10.9.1", "typedoc": "^0.25.2", "typescript": "^5.2.2", - "viem": "^1.18.0", + "viem": "^1.18.1", "vitest": "^0.34.2", "zod": "^3.22.4" }, diff --git a/packages/web3js-plugin/package.json b/packages/web3js-plugin/package.json index d64bbb6179b0..5656c5b68390 100644 --- a/packages/web3js-plugin/package.json +++ b/packages/web3js-plugin/package.json @@ -37,7 +37,7 @@ "@vitest/coverage-istanbul": "^0.34.6", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.18.0", + "viem": "^1.18.1", "vite": "^4.5.0", "vitest": "^0.34.1", "zod": "^3.22.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8152a3e6c086..e7362be6898f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -298,11 +298,11 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) viem: - specifier: ^1.18.0 - version: 1.18.0(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.1 + version: 1.18.1(typescript@5.2.2)(zod@3.22.4) wagmi: specifier: '>1.0.0' - version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) + version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) devDependencies: '@eth-optimism/contracts-bedrock': specifier: workspace:* @@ -324,7 +324,7 @@ importers: version: 1.5.2(@wagmi/core@1.4.5)(typescript@5.2.2)(wagmi@1.0.1) '@wagmi/core': specifier: ^1.4.5 - version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) + version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) abitype: specifier: ^0.10.1 version: 0.10.1(typescript@5.2.2) @@ -438,8 +438,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.0 - version: 1.18.0(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.1 + version: 1.18.1(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -529,8 +529,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.0 - version: 1.18.0(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.1 + version: 1.18.1(typescript@5.2.2)(zod@3.22.4) vitest: specifier: ^0.34.2 version: 0.34.2 @@ -569,8 +569,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.0 - version: 1.18.0(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.1 + version: 1.18.1(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -3219,7 +3219,7 @@ packages: resolution: {integrity: sha512-gYw0ki/EAuV1oSyMxpqandHjnthZjYYy+YWpTAzf8BqfXM3ItcZLpjxfg+3+mXW8HIO+3jw6T9iiqEXsqHaMMw==} dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.7.3 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - bufferutil - encoding @@ -4584,7 +4584,7 @@ packages: wagmi: optional: true dependencies: - '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) + '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) abort-controller: 3.0.0 bundle-require: 3.1.2(esbuild@0.16.17) @@ -4606,15 +4606,15 @@ packages: picocolors: 1.0.0 prettier: 2.8.8 typescript: 5.2.2 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.3) - wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) + viem: 1.18.1(typescript@5.2.2)(zod@3.22.3) + wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) zod: 3.22.3 transitivePeerDependencies: - bufferutil - utf-8-validate dev: true - /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): + /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.1): resolution: {integrity: sha512-fl01vym19DE1uoE+MlASw5zo3Orr/YXlJRjOKLaKYtV+Q7jOLY4TwHgq7sEMs+JYOvFICFBEAlWNNxidr51AqQ==} peerDependencies: '@wagmi/chains': '>=0.2.0' @@ -4637,7 +4637,7 @@ packages: abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil @@ -4649,7 +4649,7 @@ packages: - utf-8-validate - zod - /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): + /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.1): resolution: {integrity: sha512-UgwsQKQDFObJVJMf9pDfFoXTv710o4zrTHyhIWKBTMMkLpCMsMxN5+ZaDhBYt/BgoRinfRYQo8uwuwLhxE6Log==} peerDependencies: typescript: '>=5.0.4' @@ -4669,7 +4669,7 @@ packages: abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - '@types/react' @@ -4682,7 +4682,7 @@ packages: - zod dev: true - /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): + /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.1): resolution: {integrity: sha512-Zzg4Ob92QMF9NsC+z5/8JZjMn3NCCnwVWGJlv79qRX9mp5Ku40OzJNvqDnjcSGjshe6H0L/KtFZAqTlmu8lT7w==} peerDependencies: typescript: '>=4.9.4' @@ -4692,11 +4692,11 @@ packages: optional: true dependencies: '@wagmi/chains': 0.2.22(typescript@5.2.2) - '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) + '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -4710,7 +4710,7 @@ packages: - utf-8-validate - zod - /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): + /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.1): resolution: {integrity: sha512-N9luRb1Uk4tBN9kaYcQSWKE9AsRt/rvZaFt5IZech4JPzNN2sQlfhKd9GEjOXYRDqEPHdDvos7qyBKiDNTz4GA==} peerDependencies: typescript: '>=5.0.4' @@ -4719,11 +4719,11 @@ packages: typescript: optional: true dependencies: - '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) + '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -14318,8 +14318,8 @@ packages: vfile-message: 2.0.4 dev: true - /viem@1.18.0(typescript@5.2.2)(zod@3.22.3): - resolution: {integrity: sha512-NeKi5RFj7fHdsnk5pojivHFLkTyBWyehxeSE/gSPTDJKCWnR9i+Ra0W++VwN5ghciEG55O8b4RdpYhzGmhnr7A==} + /viem@1.18.1(typescript@5.2.2)(zod@3.22.3): + resolution: {integrity: sha512-dkZG1jI8iL7G0+KZ8ZKHCXbzZxzu8Iib7OLCxkdaqdrlNrWTEMIZSp/2AHpbjpPeAg3VFD1CUayKPTJv2ZMXCg==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14341,8 +14341,8 @@ packages: - zod dev: true - /viem@1.18.0(typescript@5.2.2)(zod@3.22.4): - resolution: {integrity: sha512-NeKi5RFj7fHdsnk5pojivHFLkTyBWyehxeSE/gSPTDJKCWnR9i+Ra0W++VwN5ghciEG55O8b4RdpYhzGmhnr7A==} + /viem@1.18.1(typescript@5.2.2)(zod@3.22.4): + resolution: {integrity: sha512-dkZG1jI8iL7G0+KZ8ZKHCXbzZxzu8Iib7OLCxkdaqdrlNrWTEMIZSp/2AHpbjpPeAg3VFD1CUayKPTJv2ZMXCg==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14835,7 +14835,7 @@ packages: xml-name-validator: 4.0.0 dev: true - /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.0): + /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.1): resolution: {integrity: sha512-+2UkZG9eA3tKqXj1wvlvI8mL0Bcff7Tf5CKfUOyQsdKcY+J5rfwYYya25G+jja57umpHFtfxRaL7xDkNjehrRg==} peerDependencies: react: '>=17.0.0' @@ -14848,12 +14848,12 @@ packages: '@tanstack/query-sync-storage-persister': 4.29.25 '@tanstack/react-query': 4.29.25(react-dom@18.2.0)(react@18.2.0) '@tanstack/react-query-persist-client': 4.29.25(@tanstack/react-query@4.29.25) - '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) + '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) abitype: 0.8.1(typescript@5.2.2) react: 18.2.0 typescript: 5.2.2 use-sync-external-store: 1.2.0(react@18.2.0) - viem: 1.18.0(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil From b428230f11ab0365001d871d4b2861a170ab5f91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 20:59:45 +0000 Subject: [PATCH 241/374] build(deps-dev): bump abitype from 0.10.1 to 0.10.2 Bumps [abitype](https://github.com/wagmi-dev/abitype) from 0.10.1 to 0.10.2. - [Release notes](https://github.com/wagmi-dev/abitype/releases) - [Commits](https://github.com/wagmi-dev/abitype/compare/abitype@0.10.1...abitype@0.10.2) --- updated-dependencies: - dependency-name: abitype dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/contracts-ts/package.json | 2 +- packages/fee-estimation/package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/contracts-ts/package.json b/packages/contracts-ts/package.json index 9cd089f4c3fe..f33e1c57c1d5 100644 --- a/packages/contracts-ts/package.json +++ b/packages/contracts-ts/package.json @@ -54,7 +54,7 @@ "@vitest/coverage-istanbul": "^0.34.6", "@wagmi/cli": "^1.5.2", "@wagmi/core": "^1.4.5", - "abitype": "^0.10.1", + "abitype": "^0.10.2", "glob": "^10.3.10", "isomorphic-fetch": "^3.0.0", "jest-dom": "link:@types/@testing-library/jest-dom", diff --git a/packages/fee-estimation/package.json b/packages/fee-estimation/package.json index 6cbc34b80625..01ade2c36001 100644 --- a/packages/fee-estimation/package.json +++ b/packages/fee-estimation/package.json @@ -38,7 +38,7 @@ "@testing-library/jest-dom": "^6.1.4", "@testing-library/react-hooks": "^8.0.1", "@vitest/coverage-istanbul": "^0.34.6", - "abitype": "^0.10.1", + "abitype": "^0.10.2", "isomorphic-fetch": "^3.0.0", "jest-dom": "link:@types/@testing-library/jest-dom", "jsdom": "^22.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8152a3e6c086..5bd283da3662 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -326,8 +326,8 @@ importers: specifier: ^1.4.5 version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.0) abitype: - specifier: ^0.10.1 - version: 0.10.1(typescript@5.2.2) + specifier: ^0.10.2 + version: 0.10.2(typescript@5.2.2) glob: specifier: ^10.3.10 version: 10.3.10 @@ -420,8 +420,8 @@ importers: specifier: ^0.34.6 version: 0.34.6(vitest@0.34.2) abitype: - specifier: ^0.10.1 - version: 0.10.1(typescript@5.2.2) + specifier: ^0.10.2 + version: 0.10.2(typescript@5.2.2) isomorphic-fetch: specifier: ^3.0.0 version: 3.0.0 @@ -5271,8 +5271,8 @@ packages: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} dev: true - /abitype@0.10.1(typescript@5.2.2): - resolution: {integrity: sha512-nFx5F2RniXGXw2Ci1uu6iDGnP/z3hW+H65G7cxrs5JDF3Ot9GuYkBJCRAB9EZ5QIi3dNByZaCrGFUn8LLkLQbw==} + /abitype@0.10.2(typescript@5.2.2): + resolution: {integrity: sha512-1XndI+RKFWK4+TXCNv1683MRyX5NGmlHXCvqzjOqhSS3PQrxT2QYRZq1bMPPRNjn89B3eVaM2w7y3jVj/OIUzA==} peerDependencies: typescript: '>=5.0.4' zod: ^3 >=3.22.0 From 22207974f00a723903742315466d69940b349782 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 21:01:49 +0000 Subject: [PATCH 242/374] build(deps): bump merkletreejs from 0.3.10 to 0.3.11 Bumps [merkletreejs](https://github.com/miguelmota/merkletreejs) from 0.3.10 to 0.3.11. - [Commits](https://github.com/miguelmota/merkletreejs/commits) --- updated-dependencies: - dependency-name: merkletreejs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/sdk/package.json | 2 +- pnpm-lock.yaml | 41 +++++++++++++++++---------------------- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 8588f45b2590..77fac0215730 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -65,7 +65,7 @@ "@eth-optimism/contracts-bedrock": "workspace:*", "@eth-optimism/core-utils": "workspace:*", "lodash": "^4.17.21", - "merkletreejs": "^0.3.10", + "merkletreejs": "^0.3.11", "rlp": "^2.2.7" }, "peerDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8152a3e6c086..a3df7525b224 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -462,8 +462,8 @@ importers: specifier: ^4.17.21 version: 4.17.21 merkletreejs: - specifier: ^0.3.10 - version: 0.3.10 + specifier: ^0.3.11 + version: 0.3.11 rlp: specifier: ^2.2.7 version: 2.2.7 @@ -6720,8 +6720,8 @@ packages: which: 2.0.2 dev: true - /crypto-js@3.3.0: - resolution: {integrity: sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==} + /crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} dev: false /css.escape@1.5.1: @@ -10770,13 +10770,13 @@ packages: semaphore-async-await: 1.5.1 dev: true - /merkletreejs@0.3.10: - resolution: {integrity: sha512-lin42tKfRdkW+6iE5pjtQ9BnH+1Hk3sJ5Fn9hUUSjcXRcJbSISHgPCfYvMNEXiNqZPhz/TyRPEV30qgnujsQ7A==} + /merkletreejs@0.3.11: + resolution: {integrity: sha512-LJKTl4iVNTndhL+3Uz/tfkjD0klIWsHlUzgtuNnNrsf7bAlXR30m+xYB7lHr5Z/l6e/yAIsr26Dabx6Buo4VGQ==} engines: {node: '>= 7.6.0'} dependencies: bignumber.js: 9.0.1 buffer-reverse: 1.0.1 - crypto-js: 3.3.0 + crypto-js: 4.2.0 treeify: 1.1.0 web3-utils: 1.10.1 dev: false @@ -14886,7 +14886,7 @@ packages: web3-providers-http: 4.0.4 web3-providers-ws: 4.0.4 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 optionalDependencies: web3-providers-ipc: 4.0.5 @@ -14910,7 +14910,6 @@ packages: dependencies: web3-types: 1.1.1 dev: false - optional: true /web3-eth-abi@4.1.0: resolution: {integrity: sha512-qd+zCGKi2YsL2KkbM5M8Qztles/WPOvFpw6Lg3a904DRIVxkIvWdQfoK0JbA6Vbt8DSVKCc4rpZ15D6I/wfBKQ==} @@ -14920,7 +14919,7 @@ packages: '@ethersproject/bignumber': 5.7.0 web3-errors: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 dev: false /web3-eth-accounts@4.0.3: @@ -14945,7 +14944,7 @@ packages: ethereum-cryptography: 2.1.2 web3-errors: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 dev: false @@ -14958,7 +14957,7 @@ packages: web3-eth: 4.1.0 web3-eth-abi: 4.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 transitivePeerDependencies: - bufferutil @@ -14977,7 +14976,7 @@ packages: web3-eth-contract: 4.0.4 web3-net: 4.0.4 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 transitivePeerDependencies: - bufferutil @@ -14991,7 +14990,7 @@ packages: dependencies: web3-errors: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 dev: false @@ -15003,7 +15002,7 @@ packages: web3-eth: 4.1.0 web3-rpc-methods: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 transitivePeerDependencies: - bufferutil @@ -15045,7 +15044,7 @@ packages: web3-providers-ws: 4.0.4 web3-rpc-methods: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 web3-validator: 2.0.0 transitivePeerDependencies: - bufferutil @@ -15060,7 +15059,7 @@ packages: web3-core: 4.1.0 web3-rpc-methods: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 transitivePeerDependencies: - bufferutil - encoding @@ -15074,7 +15073,7 @@ packages: cross-fetch: 3.1.8 web3-errors: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 transitivePeerDependencies: - encoding dev: false @@ -15098,7 +15097,7 @@ packages: isomorphic-ws: 5.0.0(ws@8.13.0) web3-errors: 1.1.0 web3-types: 1.1.0 - web3-utils: 4.0.4 + web3-utils: 4.0.5 ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil @@ -15128,7 +15127,6 @@ packages: engines: {node: '>=14', npm: '>=6.12.0'} requiresBuild: true dev: false - optional: true /web3-utils@1.10.1: resolution: {integrity: sha512-r6iUUw/uMnNcWXjhRv33Nyrhxq3VGOPBXeSzxhOXIci4SvC/LPTpROY0uTrMX7ztKyODYrHp8WhTkEf+ZnHssw==} @@ -15156,14 +15154,12 @@ packages: /web3-utils@4.0.5: resolution: {integrity: sha512-43xIM7rr3htYNzliVQLpWLQmEf4XX8IXgjvqLcEuC/xje14O5UQM4kamRCtz8v3JZN3X6QTfsV6Zgby67mVmCg==} engines: {node: '>=14', npm: '>=6.12.0'} - requiresBuild: true dependencies: ethereum-cryptography: 2.1.2 web3-errors: 1.1.1 web3-types: 1.1.1 web3-validator: 2.0.1 dev: false - optional: true /web3-validator@1.0.2: resolution: {integrity: sha512-orx1CQAEnwJUnl/8iF2II2zSA4wiooNJvFmVE0Dbmt/kE370SugIDViQP76snhxtouG2AXzz4GyKbPCMlLGh/A==} @@ -15198,7 +15194,6 @@ packages: web3-types: 1.1.1 zod: 3.22.4 dev: false - optional: true /web3@4.0.3: resolution: {integrity: sha512-rUMxui5f52yPWjiMRQV6xqIrTQSovYM2CNhl57y+xj/fGXNLbI1D5FsLPnUMZjMaFHJBTteaBxq/sTEaw/1jNA==} From a51fd20853a073b40b38680e34be4ed5859e8bf3 Mon Sep 17 00:00:00 2001 From: protolambda Date: Mon, 30 Oct 2023 22:21:05 +0100 Subject: [PATCH 243/374] op-batcher: fix test RNG data flake --- op-batcher/batcher/channel_manager_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/op-batcher/batcher/channel_manager_test.go b/op-batcher/batcher/channel_manager_test.go index eac3cff44d11..852961c75b9a 100644 --- a/op-batcher/batcher/channel_manager_test.go +++ b/op-batcher/batcher/channel_manager_test.go @@ -318,7 +318,9 @@ func ChannelManagerCloseNoPendingChannel(t *testing.T, batchType uint) { // new channel frames after this point. func ChannelManagerClosePendingChannel(t *testing.T, batchType uint) { require := require.New(t) - rng := rand.New(rand.NewSource(time.Now().UnixNano())) + // The number of batch txs depends on compression of the random data, hence the static test RNG seed. + // Example of different RNG seed that creates less than 2 frames: 1698700588902821588 + rng := rand.New(rand.NewSource(123)) log := testlog.Logger(t, log.LvlCrit) m := NewChannelManager(log, metrics.NoopMetrics, ChannelConfig{ From cfcb147f58ec3264adabf85252606f85772e9c85 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Mon, 18 Sep 2023 16:48:55 +0900 Subject: [PATCH 244/374] Add span batch e2e tests --- .circleci/config.yml | 4 + op-e2e/Makefile | 6 +- op-e2e/actions/l2_batcher.go | 52 ++-- op-e2e/actions/l2_batcher_test.go | 14 +- op-e2e/actions/l2_proposer_test.go | 2 +- op-e2e/actions/reorg_test.go | 124 +++++++++- op-e2e/actions/span_batch_test.go | 342 +++++++++++++++++++++++++++ op-e2e/actions/system_config_test.go | 8 +- op-e2e/actions/user_test.go | 2 +- op-e2e/setup.go | 4 +- 10 files changed, 517 insertions(+), 41 deletions(-) create mode 100644 op-e2e/actions/span_batch_test.go diff --git a/.circleci/config.yml b/.circleci/config.yml index 9804389292ee..e9191803f39d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1418,6 +1418,10 @@ workflows: - op-stack-go-lint - devnet-allocs - l1-geth-version-check + - go-e2e-test: + name: op-e2e-span-batch-tests + module: op-e2e + target: test-span-batch - op-program-compat: requires: - op-program-tests diff --git a/op-e2e/Makefile b/op-e2e/Makefile index 5f92b5e458c0..8f53508e9ffd 100644 --- a/op-e2e/Makefile +++ b/op-e2e/Makefile @@ -21,7 +21,11 @@ test-ws: pre-test test-http: pre-test OP_E2E_USE_HTTP=true $(go_test) $(go_test_flags) ./... -.PHONY: test-ws +.PHONY: test-http + +test-span-batch: pre-test + OP_E2E_USE_SPAN_BATCH=true $(go_test) $(go_test_flags) ./... +.PHONY: test-span-batch cannon-prestate: make -C .. cannon-prestate diff --git a/op-e2e/actions/l2_batcher.go b/op-e2e/actions/l2_batcher.go index 7431e7985bda..8818a42c4194 100644 --- a/op-e2e/actions/l2_batcher.go +++ b/op-e2e/actions/l2_batcher.go @@ -20,6 +20,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources" ) type SyncStatusAPI interface { @@ -59,24 +60,26 @@ type L2Batcher struct { syncStatusAPI SyncStatusAPI l2 BlocksAPI l1 L1TxAPI + engCl *sources.EngineClient l1Signer types.Signer l2ChannelOut ChannelOutIface l2Submitting bool // when the channel out is being submitted, and not safe to write to without resetting - l2BufferedBlock eth.BlockID - l2SubmittedBlock eth.BlockID + l2BufferedBlock eth.L2BlockRef + l2SubmittedBlock eth.L2BlockRef l2BatcherCfg *BatcherCfg batcherAddr common.Address } -func NewL2Batcher(log log.Logger, rollupCfg *rollup.Config, batcherCfg *BatcherCfg, api SyncStatusAPI, l1 L1TxAPI, l2 BlocksAPI) *L2Batcher { +func NewL2Batcher(log log.Logger, rollupCfg *rollup.Config, batcherCfg *BatcherCfg, api SyncStatusAPI, l1 L1TxAPI, l2 BlocksAPI, engCl *sources.EngineClient) *L2Batcher { return &L2Batcher{ log: log, rollupCfg: rollupCfg, syncStatusAPI: api, l1: l1, l2: l2, + engCl: engCl, l2BatcherCfg: batcherCfg, l1Signer: types.LatestSignerForChainID(rollupCfg.L1ChainID), batcherAddr: crypto.PubkeyToAddress(batcherCfg.BatcherKey.PublicKey), @@ -103,31 +106,39 @@ func (s *L2Batcher) Buffer(t Testing) error { syncStatus, err := s.syncStatusAPI.SyncStatus(t.Ctx()) require.NoError(t, err, "no sync status error") // If we just started, start at safe-head - if s.l2SubmittedBlock == (eth.BlockID{}) { + if s.l2SubmittedBlock == (eth.L2BlockRef{}) { s.log.Info("Starting batch-submitter work at safe-head", "safe", syncStatus.SafeL2) - s.l2SubmittedBlock = syncStatus.SafeL2.ID() - s.l2BufferedBlock = syncStatus.SafeL2.ID() + s.l2SubmittedBlock = syncStatus.SafeL2 + s.l2BufferedBlock = syncStatus.SafeL2 s.l2ChannelOut = nil } // If it's lagging behind, catch it up. if s.l2SubmittedBlock.Number < syncStatus.SafeL2.Number { s.log.Warn("last submitted block lagged behind L2 safe head: batch submission will continue from the safe head now", "last", s.l2SubmittedBlock, "safe", syncStatus.SafeL2) - s.l2SubmittedBlock = syncStatus.SafeL2.ID() - s.l2BufferedBlock = syncStatus.SafeL2.ID() + s.l2SubmittedBlock = syncStatus.SafeL2 + s.l2BufferedBlock = syncStatus.SafeL2 s.l2ChannelOut = nil } // Add the next unsafe block to the channel if s.l2BufferedBlock.Number >= syncStatus.UnsafeL2.Number { if s.l2BufferedBlock.Number > syncStatus.UnsafeL2.Number || s.l2BufferedBlock.Hash != syncStatus.UnsafeL2.Hash { s.log.Error("detected a reorg in L2 chain vs previous buffered information, resetting to safe head now", "safe_head", syncStatus.SafeL2) - s.l2SubmittedBlock = syncStatus.SafeL2.ID() - s.l2BufferedBlock = syncStatus.SafeL2.ID() + s.l2SubmittedBlock = syncStatus.SafeL2 + s.l2BufferedBlock = syncStatus.SafeL2 s.l2ChannelOut = nil } else { s.log.Info("nothing left to submit") return nil } } + block, err := s.l2.BlockByNumber(t.Ctx(), big.NewInt(int64(s.l2BufferedBlock.Number+1))) + require.NoError(t, err, "need l2 block %d from sync status", s.l2SubmittedBlock.Number+1) + if block.ParentHash() != s.l2BufferedBlock.Hash { + s.log.Error("detected a reorg in L2 chain vs previous submitted information, resetting to safe head now", "safe_head", syncStatus.SafeL2) + s.l2SubmittedBlock = syncStatus.SafeL2 + s.l2BufferedBlock = syncStatus.SafeL2 + s.l2ChannelOut = nil + } // Create channel if we don't have one yet if s.l2ChannelOut == nil { var ch ChannelOutIface @@ -140,23 +151,24 @@ func (s *L2Batcher) Buffer(t Testing) error { ApproxComprRatio: 1, }) require.NoError(t, e, "failed to create compressor") - ch, err = derive.NewChannelOut(derive.SingularBatchType, c, nil) + + var batchType uint = derive.SingularBatchType + var spanBatchBuilder *derive.SpanBatchBuilder = nil + if s.rollupCfg.IsSpanBatch(block.Time()) { + batchType = derive.SpanBatchType + spanBatchBuilder = derive.NewSpanBatchBuilder(s.rollupCfg.Genesis.L2Time, s.rollupCfg.L2ChainID) + } + ch, err = derive.NewChannelOut(batchType, c, spanBatchBuilder) } require.NoError(t, err, "failed to create channel") s.l2ChannelOut = ch } - block, err := s.l2.BlockByNumber(t.Ctx(), big.NewInt(int64(s.l2BufferedBlock.Number+1))) - require.NoError(t, err, "need l2 block %d from sync status", s.l2SubmittedBlock.Number+1) - if block.ParentHash() != s.l2BufferedBlock.Hash { - s.log.Error("detected a reorg in L2 chain vs previous submitted information, resetting to safe head now", "safe_head", syncStatus.SafeL2) - s.l2SubmittedBlock = syncStatus.SafeL2.ID() - s.l2BufferedBlock = syncStatus.SafeL2.ID() - s.l2ChannelOut = nil - } if _, err := s.l2ChannelOut.AddBlock(block); err != nil { // should always succeed return err } - s.l2BufferedBlock = eth.ToBlockID(block) + ref, err := s.engCl.L2BlockRefByHash(t.Ctx(), block.Hash()) + require.NoError(t, err, "failed to get L2BlockRef") + s.l2BufferedBlock = ref return nil } diff --git a/op-e2e/actions/l2_batcher_test.go b/op-e2e/actions/l2_batcher_test.go index aa986dcd80cc..bc467f0f7b1d 100644 --- a/op-e2e/actions/l2_batcher_test.go +++ b/op-e2e/actions/l2_batcher_test.go @@ -39,7 +39,7 @@ func TestBatcher(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient()) + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) // Alice makes a L2 tx cl := seqEngine.EthClient() @@ -137,7 +137,7 @@ func TestL2Finalization(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient()) + }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) heightToSubmit := sequencer.SyncStatus().UnsafeL2.Number @@ -223,7 +223,7 @@ func TestL2FinalizationWithSparseL1(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient()) + }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) batcher.ActSubmitAll(t) // include in L1 @@ -287,7 +287,7 @@ func TestGarbageBatch(gt *testing.T) { } } - batcher := NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient()) + batcher := NewL2Batcher(log, sd.RollupCfg, batcherCfg, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) @@ -359,7 +359,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient()) + }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) @@ -417,7 +417,7 @@ func TestBigL2Txs(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 40_000, // try a small batch size, to force the data to be split between more frames BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient()) + }, sequencer.RollupClient(), miner.EthClient(), engine.EthClient(), engine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) @@ -470,7 +470,7 @@ func TestBigL2Txs(gt *testing.T) { sequencer.ActL2EndBlock(t) for batcher.l2BufferedBlock.Number < sequencer.SyncStatus().UnsafeL2.Number { // if we run out of space, close the channel and submit all the txs - if err := batcher.Buffer(t); errors.Is(err, derive.ErrTooManyRLPBytes) { + if err := batcher.Buffer(t); errors.Is(err, derive.ErrTooManyRLPBytes) || errors.Is(err, derive.CompressorFullErr) { log.Info("flushing filled channel to batch txs", "id", batcher.l2ChannelOut.ID()) batcher.ActL2ChannelClose(t) for batcher.l2ChannelOut != nil { diff --git a/op-e2e/actions/l2_proposer_test.go b/op-e2e/actions/l2_proposer_test.go index 5e1f51a33db5..d16d610978ed 100644 --- a/op-e2e/actions/l2_proposer_test.go +++ b/op-e2e/actions/l2_proposer_test.go @@ -26,7 +26,7 @@ func TestProposer(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient()) + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) proposer := NewL2Proposer(t, log, &ProposerCfg{ OutputOracleAddr: sd.DeploymentsL1.L2OutputOracleProxy, diff --git a/op-e2e/actions/reorg_test.go b/op-e2e/actions/reorg_test.go index bf8cf8a92ba5..a50dacc17f8e 100644 --- a/op-e2e/actions/reorg_test.go +++ b/op-e2e/actions/reorg_test.go @@ -40,7 +40,7 @@ func setupReorgTestActors(t Testing, dp *e2eutils.DeployParams, sd *e2eutils.Set MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient()) + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) return sd, dp, miner, sequencer, seqEngine, verifier, verifEngine, batcher } @@ -189,8 +189,16 @@ func TestReorgFlipFlop(gt *testing.T) { verifier.ActL2PipelineFull(t) require.Equal(t, sd.RollupCfg.Genesis.L1, verifier.L2Safe().L1Origin, "expected to be back at genesis origin after losing A0 and A1") - require.NotZero(t, verifier.L2Safe().Number, "still preserving old L2 blocks that did not reference reorged L1 chain (assuming more than one L2 block per L1 block)") - require.Equal(t, verifier.L2Safe(), verifier.L2Unsafe(), "head is at safe block after L1 reorg") + if sd.RollupCfg.SpanBatchTime == nil { + // before span batch hard fork + require.NotZero(t, verifier.L2Safe().Number, "still preserving old L2 blocks that did not reference reorged L1 chain (assuming more than one L2 block per L1 block)") + require.Equal(t, verifier.L2Safe(), verifier.L2Unsafe(), "head is at safe block after L1 reorg") + } else { + // after span batch hard fork + require.Zero(t, verifier.L2Safe().Number, "safe head is at genesis block because span batch referenced reorged L1 chain is not accepted") + require.Equal(t, verifier.L2Unsafe().ID(), sequencer.L2Unsafe().ParentID(), "head is at the highest unsafe block that references canonical L1 chain(genesis block)") + batcher.l2BufferedBlock = eth.L2BlockRef{} // must reset batcher to resubmit blocks included in the last batch + } checkVerifEngine() // and sync the sequencer, then build some new L2 blocks, up to and including with L1 origin B2 @@ -210,6 +218,7 @@ func TestReorgFlipFlop(gt *testing.T) { verifier.ActL1HeadSignal(t) verifier.ActL2PipelineFull(t) require.Equal(t, verifier.L2Safe().L1Origin, blockB2.ID(), "B2 is the L1 origin of verifier now") + require.Equal(t, verifier.L2Unsafe(), sequencer.L2Unsafe(), "verifier unsafe head is reorged along sequencer") checkVerifEngine() // Flop back to chain A! @@ -585,7 +594,7 @@ func TestRestartOpGeth(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient()) + }, sequencer.RollupClient(), miner.EthClient(), seqEng.EthClient(), seqEng.EngineClient(t, sd.RollupCfg)) // start sequencer.ActL2PipelineFull(t) @@ -674,7 +683,7 @@ func TestConflictingL2Blocks(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, altSequencer.RollupClient(), miner.EthClient(), altSeqEng.EthClient()) + }, altSequencer.RollupClient(), miner.EthClient(), altSeqEng.EthClient(), altSeqEng.EngineClient(t, sd.RollupCfg)) // And set up user Alice, using the alternative sequencer endpoint l2Cl := altSeqEng.EthClient() @@ -762,3 +771,108 @@ func TestConflictingL2Blocks(gt *testing.T) { require.Equal(t, verifier.L2Unsafe(), altSequencer.L2Unsafe(), "alt-sequencer gets back in harmony with verifier by reorging out its conflicting data") require.Equal(t, sequencer.L2Unsafe(), altSequencer.L2Unsafe(), "and gets back in harmony with original sequencer") } + +func TestSyncAfterReorg(gt *testing.T) { + t := NewDefaultTesting(gt) + testingParams := e2eutils.TestParams{ + MaxSequencerDrift: 60, + SequencerWindowSize: 4, + ChannelTimeout: 2, + L1BlockTime: 12, + } + sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := setupReorgTest(t, &testingParams) + l2Client := seqEngine.EthClient() + log := testlog.Logger(t, log.LvlDebug) + addresses := e2eutils.CollectAddresses(sd, dp) + l2UserEnv := &BasicUserEnv[*L2Bindings]{ + EthCl: l2Client, + Signer: types.LatestSigner(sd.L2Cfg.Config), + AddressCorpora: addresses, + Bindings: NewL2Bindings(t, l2Client, seqEngine.GethClient()), + } + alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b))) + alice.L2.SetUserEnv(l2UserEnv) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // build empty L1 block: A0 + miner.ActL1SetFeeRecipient(common.Address{'A', 0}) + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + for sequencer.derivation.UnsafeL2Head().L1Origin.Number < sequencer.l1State.L1Head().Number { + // build L2 blocks until the L1 origin is the current L1 head(A0) + sequencer.ActL2PipelineFull(t) + sequencer.ActL2StartBlock(t) + if sequencer.derivation.UnsafeL2Head().Number == 11 { + // include a user tx at L2 block #12 to make a state transition + alice.L2.ActResetTxOpts(t) + alice.L2.ActSetTxToAddr(&dp.Addresses.Bob)(t) + alice.L2.ActMakeTx(t) + // Include the tx in the block we're making + seqEngine.ActL2IncludeTx(alice.Address())(t) + } + sequencer.ActL2EndBlock(t) + } + // submit all new L2 blocks: #1 ~ #12 + batcher.ActSubmitAll(t) + + // build an L1 block included batch TX: A1 + miner.ActL1SetFeeRecipient(common.Address{'A', 1}) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) + miner.ActL1EndBlock(t) + + for i := 2; i < 6; i++ { + // build L2 blocks until the L1 origin is the current L1 head + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + // submt all new L2 blocks + batcher.ActSubmitAll(t) + + // build an L1 block included batch TX: A2 ~ A5 + miner.ActL1SetFeeRecipient(common.Address{'A', byte(i)}) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) + miner.ActL1EndBlock(t) + } + + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + // capture current L2 safe head + submittedSafeHead := sequencer.L2Safe().ID() + + // build L2 blocks until the L1 origin is the current L1 head(A5) + sequencer.ActBuildToL1Head(t) + batcher.ActSubmitAll(t) + + // build an L1 block included batch TX: A6 + miner.ActL1SetFeeRecipient(common.Address{'A', 6}) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(sd.RollupCfg.Genesis.SystemConfig.BatcherAddr)(t) + miner.ActL1EndBlock(t) + + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + // reorg L1 + miner.ActL1RewindToParent(t) // undo A6 + miner.ActL1SetFeeRecipient(common.Address{'B', 6}) // build B6 + miner.ActEmptyBlock(t) + miner.ActL1SetFeeRecipient(common.Address{'B', 7}) // build B7 + miner.ActEmptyBlock(t) + + // sequencer and verifier detect L1 reorg + // derivation pipeline is reset + // safe head may be reset to block #11 + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + // sequencer and verifier must derive all submitted batches and reach to the captured block + require.Equal(t, sequencer.L2Safe().ID(), submittedSafeHead) + require.Equal(t, verifier.L2Safe().ID(), submittedSafeHead) +} diff --git a/op-e2e/actions/span_batch_test.go b/op-e2e/actions/span_batch_test.go new file mode 100644 index 000000000000..226abd3fe1a0 --- /dev/null +++ b/op-e2e/actions/span_batch_test.go @@ -0,0 +1,342 @@ +package actions + +import ( + crand "crypto/rand" + "math/big" + "math/rand" + "testing" + + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/rollup/sync" + "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" +) + +// TestDropSpanBatchBeforeHardfork tests behavior of op-node before SpanBatch hardfork. +// op-node must drop SpanBatch before SpanBatch hardfork. +func TestDropSpanBatchBeforeHardfork(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + dp := e2eutils.MakeDeployParams(t, p) + // do not activate SpanBatch hardfork for verifier + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = nil + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LvlError) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + + rollupSeqCl := sequencer.RollupClient() + dp2 := e2eutils.MakeDeployParams(t, p) + minTs := hexutil.Uint64(0) + // activate SpanBatch hardfork for batcher. so batcher will submit SpanBatches to L1. + dp2.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs + sd2 := e2eutils.Setup(t, dp2, defaultAlloc) + batcher := NewL2Batcher(log, sd2.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + + // Alice makes a L2 tx + cl := seqEngine.EthClient() + n, err := cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + signer := types.LatestSigner(sd.L2Cfg.Config) + tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: n, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + Gas: params.TxGas, + To: &dp.Addresses.Bob, + Value: e2eutils.Ether(2), + }) + require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Make L2 block + sequencer.ActL2StartBlock(t) + seqEngine.ActL2IncludeTx(dp.Addresses.Alice)(t) + sequencer.ActL2EndBlock(t) + + // batch submit to L1. batcher should submit span batches. + batcher.ActL2BatchBuffer(t) + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + // confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + bl := miner.l1Chain.CurrentBlock() + log.Info("bl", "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + + // Now make enough L1 blocks that the verifier will have to derive a L2 block + // It will also eagerly derive the block from the batcher + for i := uint64(0); i < sd.RollupCfg.SeqWindowSize; i++ { + miner.ActL1StartBlock(12)(t) + miner.ActL1EndBlock(t) + } + + // try to sync verifier from L1 batch. but verifier should drop every span batch. + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, uint64(1), verifier.SyncStatus().SafeL2.L1Origin.Number) + + verifCl := verifEngine.EthClient() + for i := int64(1); i < int64(verifier.L2Safe().Number); i++ { + block, _ := verifCl.BlockByNumber(t.Ctx(), big.NewInt(i)) + require.NoError(t, err) + // because verifier drops every span batch, it should generate empty blocks. + // so every block has only L1 attribute deposit transaction. + require.Equal(t, block.Transactions().Len(), 1) + } + // check that the tx from alice is not included in verifier's chain + _, _, err = verifCl.TransactionByHash(t.Ctx(), tx.Hash()) + require.ErrorIs(t, err, ethereum.NotFound) +} + +// TestAcceptSingularBatchAfterHardfork tests behavior of op-node after SpanBatch hardfork. +// op-node must accept SingularBatch after SpanBatch hardfork. +func TestAcceptSingularBatchAfterHardfork(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + minTs := hexutil.Uint64(0) + dp := e2eutils.MakeDeployParams(t, p) + + // activate SpanBatch hardfork for verifier. + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LvlError) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + verifEngine, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + + rollupSeqCl := sequencer.RollupClient() + dp2 := e2eutils.MakeDeployParams(t, p) + + // not activate SpanBatch hardfork for batcher + dp2.DeployConfig.L2GenesisSpanBatchTimeOffset = nil + sd2 := e2eutils.Setup(t, dp2, defaultAlloc) + batcher := NewL2Batcher(log, sd2.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + + // Alice makes a L2 tx + cl := seqEngine.EthClient() + n, err := cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + signer := types.LatestSigner(sd.L2Cfg.Config) + tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: n, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(miner.l1Chain.CurrentBlock().BaseFee, big.NewInt(2*params.GWei)), + Gas: params.TxGas, + To: &dp.Addresses.Bob, + Value: e2eutils.Ether(2), + }) + require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Make L2 block + sequencer.ActL2StartBlock(t) + seqEngine.ActL2IncludeTx(dp.Addresses.Alice)(t) + sequencer.ActL2EndBlock(t) + + // batch submit to L1. batcher should submit singular batches. + batcher.ActL2BatchBuffer(t) + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + // confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + bl := miner.l1Chain.CurrentBlock() + log.Info("bl", "txs", len(miner.l1Chain.GetBlockByHash(bl.Hash()).Transactions())) + + // Now make enough L1 blocks that the verifier will have to derive a L2 block + // It will also eagerly derive the block from the batcher + for i := uint64(0); i < sd.RollupCfg.SeqWindowSize; i++ { + miner.ActL1StartBlock(12)(t) + miner.ActL1EndBlock(t) + } + + // sync verifier from L1 batch in otherwise empty sequence window + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, uint64(1), verifier.SyncStatus().SafeL2.L1Origin.Number) + + // check that the tx from alice made it into the L2 chain + verifCl := verifEngine.EthClient() + vTx, isPending, err := verifCl.TransactionByHash(t.Ctx(), tx.Hash()) + require.NoError(t, err) + require.False(t, isPending) + require.NotNil(t, vTx) +} + +// TestSpanBatchEmptyChain tests derivation of empty chain using SpanBatch. +func TestSpanBatchEmptyChain(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + dp := e2eutils.MakeDeployParams(t, p) + minTs := hexutil.Uint64(0) + // Activate SpanBatch hardfork + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LvlError) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + + rollupSeqCl := sequencer.RollupClient() + batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + miner.ActEmptyBlock(t) + // Make 1200 empty L2 blocks (L1BlockTime / L2BlockTime * 100) + for i := 0; i < 100; i++ { + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1Head(t) + + if i%10 == 9 { + // batch submit to L1 + batcher.ActSubmitAll(t) + + // confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + } else { + miner.ActEmptyBlock(t) + } + } + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + require.Equal(t, sequencer.L2Unsafe(), sequencer.L2Safe()) + require.Equal(t, verifier.L2Unsafe(), verifier.L2Safe()) + require.Equal(t, sequencer.L2Safe(), verifier.L2Safe()) +} + +// TestSpanBatchLowThroughputChain tests derivation of low-throughput chain using SpanBatch. +func TestSpanBatchLowThroughputChain(gt *testing.T) { + t := NewDefaultTesting(gt) + p := &e2eutils.TestParams{ + MaxSequencerDrift: 20, + SequencerWindowSize: 24, + ChannelTimeout: 20, + L1BlockTime: 12, + } + dp := e2eutils.MakeDeployParams(t, p) + minTs := hexutil.Uint64(0) + // Activate SpanBatch hardfork + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LvlError) + miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) + _, verifier := setupVerifier(t, sd, log, miner.L1Client(t, sd.RollupCfg), &sync.Config{}) + + rollupSeqCl := sequencer.RollupClient() + batcher := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ + MinL1TxSize: 0, + MaxL1TxSize: 128_000, + BatcherKey: dp.Secrets.Batcher, + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) + cl := seqEngine.EthClient() + aliceNonce, err := cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + miner.ActEmptyBlock(t) + // Make 600 L2 blocks (L1BlockTime / L2BlockTime * 50) including 1~3 txs + for i := 0; i < 50; i++ { + sequencer.ActL1HeadSignal(t) + for sequencer.derivation.UnsafeL2Head().L1Origin.Number < sequencer.l1State.L1Head().Number { + sequencer.ActL2PipelineFull(t) + sequencer.ActL2StartBlock(t) + // fill the block with random number of L2 txs from alice + for j := 0; j < rand.Intn(3); j++ { + signer := types.LatestSigner(sd.L2Cfg.Config) + data := make([]byte, rand.Intn(100)) + _, err := crand.Read(data[:]) // fill with random bytes + require.NoError(t, err) + gas, err := core.IntrinsicGas(data, nil, false, true, true, false) + require.NoError(t, err) + baseFee := seqEngine.l2Chain.CurrentBlock().BaseFee + tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: aliceNonce, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(new(big.Int).Mul(baseFee, big.NewInt(2)), big.NewInt(2*params.GWei)), + Gas: gas, + To: &dp.Addresses.Bob, + Value: big.NewInt(0), + Data: data, + }) + require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + seqEngine.ActL2IncludeTx(dp.Addresses.Alice)(t) + aliceNonce++ + } + sequencer.ActL2EndBlock(t) + } + + if i%10 == 9 { + // batch submit to L1 + batcher.ActSubmitAll(t) + + // confirm batch on L1 + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + } else { + miner.ActEmptyBlock(t) + } + } + sequencer.ActL1HeadSignal(t) + sequencer.ActL2PipelineFull(t) + + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + require.Equal(t, sequencer.L2Unsafe(), sequencer.L2Safe()) + require.Equal(t, verifier.L2Unsafe(), verifier.L2Safe()) + require.Equal(t, sequencer.L2Safe(), verifier.L2Safe()) +} diff --git a/op-e2e/actions/system_config_test.go b/op-e2e/actions/system_config_test.go index 68fca336ad15..59cbc57729ba 100644 --- a/op-e2e/actions/system_config_test.go +++ b/op-e2e/actions/system_config_test.go @@ -39,14 +39,14 @@ func TestBatcherKeyRotation(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient()) + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) // a batcher with a new key batcherB := NewL2Batcher(log, sd.RollupCfg, &BatcherCfg{ MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Bob, - }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient()) + }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) @@ -210,7 +210,7 @@ func TestGPOParamsChange(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), seqEngine.EthClient()) + }, sequencer.RollupClient(), miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) alice := NewBasicUser[any](log, dp.Secrets.Alice, rand.New(rand.NewSource(1234))) alice.SetUserEnv(&BasicUserEnv[any]{ @@ -339,7 +339,7 @@ func TestGasLimitChange(gt *testing.T) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, sequencer.RollupClient(), miner.EthClient(), seqEngine.EthClient()) + }, sequencer.RollupClient(), miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) sequencer.ActL2PipelineFull(t) miner.ActEmptyBlock(t) diff --git a/op-e2e/actions/user_test.go b/op-e2e/actions/user_test.go index c63918cdaec1..5e0a88eb683c 100644 --- a/op-e2e/actions/user_test.go +++ b/op-e2e/actions/user_test.go @@ -60,7 +60,7 @@ func runCrossLayerUserTest(gt *testing.T, test regolithScheduledTest) { MinL1TxSize: 0, MaxL1TxSize: 128_000, BatcherKey: dp.Secrets.Batcher, - }, seq.RollupClient(), miner.EthClient(), seqEngine.EthClient()) + }, seq.RollupClient(), miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) proposer := NewL2Proposer(t, log, &ProposerCfg{ OutputOracleAddr: sd.DeploymentsL1.L2OutputOracleProxy, ProposerKey: dp.Secrets.Proposer, diff --git a/op-e2e/setup.go b/op-e2e/setup.go index dc6b0e2e9627..e1fd1ae011e6 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -680,7 +680,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste return nil, fmt.Errorf("unable to start l2 output submitter: %w", err) } - batchType := derive.SingularBatchType + var batchType uint = derive.SingularBatchType if os.Getenv("OP_E2E_USE_SPAN_BATCH") == "true" { batchType = derive.SpanBatchType } @@ -704,7 +704,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste Format: oplog.FormatText, }, Stopped: sys.cfg.DisableBatcher, // Batch submitter may be enabled later - BatchType: uint(batchType), + BatchType: batchType, } // Batch Submitter batcher, err := bss.BatcherServiceFromCLIConfig(context.Background(), "0.0.1", batcherCLIConfig, sys.cfg.Loggers["batcher"]) From aec1466fa24aea690f54d885679501e1c845ac57 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Fri, 27 Oct 2023 19:03:10 +0900 Subject: [PATCH 245/374] Fix flaky e2e test --- op-e2e/actions/span_batch_test.go | 37 +++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/op-e2e/actions/span_batch_test.go b/op-e2e/actions/span_batch_test.go index 226abd3fe1a0..65b20cf04306 100644 --- a/op-e2e/actions/span_batch_test.go +++ b/op-e2e/actions/span_batch_test.go @@ -1,7 +1,9 @@ package actions import ( + "crypto/ecdsa" crand "crypto/rand" + "fmt" "math/big" "math/rand" "testing" @@ -10,9 +12,12 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" @@ -279,21 +284,37 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) { BatcherKey: dp.Secrets.Batcher, }, rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg)) cl := seqEngine.EthClient() - aliceNonce, err := cl.PendingNonceAt(t.Ctx(), dp.Addresses.Alice) - require.NoError(t, err) + + const numTestUsers = 5 + var privKeys [numTestUsers]*ecdsa.PrivateKey + var addrs [numTestUsers]common.Address + for i := 0; i < numTestUsers; i++ { + // Create a new test account + privateKey, err := dp.Secrets.Wallet.PrivateKey(accounts.Account{ + URL: accounts.URL{ + Path: fmt.Sprintf("m/44'/60'/0'/0/%d", 10+i), + }, + }) + privKeys[i] = privateKey + addr := crypto.PubkeyToAddress(privateKey.PublicKey) + require.NoError(t, err) + addrs[i] = addr + } sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) miner.ActEmptyBlock(t) + totalTxCount := 0 // Make 600 L2 blocks (L1BlockTime / L2BlockTime * 50) including 1~3 txs for i := 0; i < 50; i++ { sequencer.ActL1HeadSignal(t) for sequencer.derivation.UnsafeL2Head().L1Origin.Number < sequencer.l1State.L1Head().Number { sequencer.ActL2PipelineFull(t) sequencer.ActL2StartBlock(t) - // fill the block with random number of L2 txs from alice + // fill the block with random number of L2 txs for j := 0; j < rand.Intn(3); j++ { + userIdx := totalTxCount % numTestUsers signer := types.LatestSigner(sd.L2Cfg.Config) data := make([]byte, rand.Intn(100)) _, err := crand.Read(data[:]) // fill with random bytes @@ -301,9 +322,11 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) { gas, err := core.IntrinsicGas(data, nil, false, true, true, false) require.NoError(t, err) baseFee := seqEngine.l2Chain.CurrentBlock().BaseFee - tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + nonce, err := cl.PendingNonceAt(t.Ctx(), addrs[userIdx]) + require.NoError(t, err) + tx := types.MustSignNewTx(privKeys[userIdx], signer, &types.DynamicFeeTx{ ChainID: sd.L2Cfg.Config.ChainID, - Nonce: aliceNonce, + Nonce: nonce, GasTipCap: big.NewInt(2 * params.GWei), GasFeeCap: new(big.Int).Add(new(big.Int).Mul(baseFee, big.NewInt(2)), big.NewInt(2*params.GWei)), Gas: gas, @@ -312,8 +335,8 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) { Data: data, }) require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) - seqEngine.ActL2IncludeTx(dp.Addresses.Alice)(t) - aliceNonce++ + seqEngine.ActL2IncludeTx(addrs[userIdx])(t) + totalTxCount += 1 } sequencer.ActL2EndBlock(t) } From 210492cdcb122af75aeae384c850f088ff728ece Mon Sep 17 00:00:00 2001 From: Tei Im Date: Thu, 26 Oct 2023 12:36:22 +0900 Subject: [PATCH 246/374] Implement span batch atomicity during chain derivation Add pendingSafeHead to engine queue Engine queue advances node's safe head once the span batch is fully processed Batch queue resets cached batches derived from span batch when detecting processing error --- op-e2e/actions/l2_verifier.go | 4 + op-e2e/actions/sync_test.go | 238 +++++++++++++++++++++ op-node/rollup/derive/attributes_queue.go | 20 +- op-node/rollup/derive/batch_queue.go | 56 ++--- op-node/rollup/derive/batch_queue_test.go | 114 +++++++--- op-node/rollup/derive/engine_queue.go | 92 ++++---- op-node/rollup/derive/engine_queue_test.go | 13 +- op-node/rollup/derive/pipeline.go | 5 + 8 files changed, 441 insertions(+), 101 deletions(-) diff --git a/op-e2e/actions/l2_verifier.go b/op-e2e/actions/l2_verifier.go index 1340210d197e..8a99b593a866 100644 --- a/op-e2e/actions/l2_verifier.go +++ b/op-e2e/actions/l2_verifier.go @@ -135,6 +135,10 @@ func (s *L2Verifier) L2Safe() eth.L2BlockRef { return s.derivation.SafeL2Head() } +func (s *L2Verifier) L2PendingSafe() eth.L2BlockRef { + return s.derivation.PendingSafeL2Head() +} + func (s *L2Verifier) L2Unsafe() eth.L2BlockRef { return s.derivation.UnsafeL2Head() } diff --git a/op-e2e/actions/sync_test.go b/op-e2e/actions/sync_test.go index 07321859579f..57f8564f7a98 100644 --- a/op-e2e/actions/sync_test.go +++ b/op-e2e/actions/sync_test.go @@ -2,15 +2,24 @@ package actions import ( "errors" + "math/big" "math/rand" "testing" + "github.com/ethereum-optimism/optimism/op-batcher/compressor" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum-optimism/optimism/op-service/testutils" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" ) @@ -166,3 +175,232 @@ func TestEngineP2PSync(gt *testing.T) { require.Equal(t, sequencer.L2Unsafe().Hash, verifier.EngineSyncTarget().Hash) } } + +func TestInvalidPayloadInSpanBatch(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + minTs := hexutil.Uint64(0) + // Activate SpanBatch hardfork + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs + dp.DeployConfig.L2BlockTime = 2 + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LvlInfo) + _, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + l2Cl := seqEng.EthClient() + rng := rand.New(rand.NewSource(1234)) + signer := types.LatestSigner(sd.L2Cfg.Config) + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + c, e := compressor.NewRatioCompressor(compressor.Config{ + TargetFrameSize: 128_000, + TargetNumFrames: 1, + ApproxComprRatio: 1, + }) + require.NoError(t, e) + spanBatchBuilder := derive.NewSpanBatchBuilder(sd.RollupCfg.Genesis.L2Time, sd.RollupCfg.L2ChainID) + // Create new span batch channel + channelOut, err := derive.NewChannelOut(derive.SpanBatchType, c, spanBatchBuilder) + require.NoError(t, err) + + // Create block A1 ~ A12 for L1 block #0 ~ #2 + miner.ActEmptyBlock(t) + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1HeadUnsafe(t) + + for i := uint64(1); i <= sequencer.L2Unsafe().Number; i++ { + block, err := l2Cl.BlockByNumber(t.Ctx(), new(big.Int).SetUint64(i)) + require.NoError(t, err) + if i == 8 { + // Make block A8 as an invalid block + invalidTx := testutils.RandomTx(rng, big.NewInt(100), signer) + block = block.WithBody([]*types.Transaction{block.Transactions()[0], invalidTx}, []*types.Header{}) + } + // Add A1 ~ A12 into the channel + _, err = channelOut.AddBlock(block) + require.NoError(t, err) + } + + // Submit span batch(A1, ..., A7, invalid A8, A9, ..., A12) + batcher.l2ChannelOut = channelOut + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + miner.ActL1SafeNext(t) + miner.ActL1FinalizeNext(t) + + // After the verifier processed the span batch, only unsafe head should be advanced to A7. + // Safe head is not updated because the span batch is not fully processed. + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Unsafe().Number, uint64(7)) + require.Equal(t, verifier.L2Safe().Number, uint64(0)) + + // Create new span batch channel + c, e = compressor.NewRatioCompressor(compressor.Config{ + TargetFrameSize: 128_000, + TargetNumFrames: 1, + ApproxComprRatio: 1, + }) + require.NoError(t, e) + spanBatchBuilder = derive.NewSpanBatchBuilder(sd.RollupCfg.Genesis.L2Time, sd.RollupCfg.L2ChainID) + channelOut, err = derive.NewChannelOut(derive.SpanBatchType, c, spanBatchBuilder) + require.NoError(t, err) + + for i := uint64(1); i <= sequencer.L2Unsafe().Number; i++ { + block, err := l2Cl.BlockByNumber(t.Ctx(), new(big.Int).SetUint64(i)) + require.NoError(t, err) + if i == 1 { + // Create valid TX + aliceNonce, err := seqEng.EthClient().PendingNonceAt(t.Ctx(), dp.Addresses.Alice) + require.NoError(t, err) + data := make([]byte, rand.Intn(100)) + gas, err := core.IntrinsicGas(data, nil, false, true, true, false) + require.NoError(t, err) + baseFee := seqEng.l2Chain.CurrentBlock().BaseFee + tx := types.MustSignNewTx(dp.Secrets.Alice, signer, &types.DynamicFeeTx{ + ChainID: sd.L2Cfg.Config.ChainID, + Nonce: aliceNonce, + GasTipCap: big.NewInt(2 * params.GWei), + GasFeeCap: new(big.Int).Add(new(big.Int).Mul(baseFee, big.NewInt(2)), big.NewInt(2*params.GWei)), + Gas: gas, + To: &dp.Addresses.Bob, + Value: big.NewInt(0), + Data: data, + }) + // Create valid new block B1 at the same height as A1 + block = block.WithBody([]*types.Transaction{block.Transactions()[0], tx}, []*types.Header{}) + } + // Add B1, A2 ~ A12 into the channel + _, err = channelOut.AddBlock(block) + require.NoError(t, err) + } + // Submit span batch(B1, A2, ... A12) + batcher.l2ChannelOut = channelOut + batcher.ActL2ChannelClose(t) + batcher.ActL2BatchSubmit(t) + + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + miner.ActL1SafeNext(t) + miner.ActL1FinalizeNext(t) + + verifier.ActL1HeadSignal(t) + verifier.ActL2PipelineFull(t) + + // verifier should advance its unsafe and safe head to the height of A12. + require.Equal(t, verifier.L2Unsafe().Number, uint64(12)) + require.Equal(t, verifier.L2Safe().Number, uint64(12)) +} + +func TestSpanBatchAtomicity_Consolidation(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + minTs := hexutil.Uint64(0) + // Activate SpanBatch hardfork + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs + dp.DeployConfig.L2BlockTime = 2 + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LvlInfo) + _, _, miner, sequencer, seqEng, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + seqEngCl, err := sources.NewEngineClient(seqEng.RPCClient(), log, nil, sources.EngineClientDefaultConfig(sd.RollupCfg)) + require.NoError(t, err) + + targetHeadNumber := uint64(6) // L1 block time / L2 block time + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + + // Create 6 blocks + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1HeadUnsafe(t) + require.Equal(t, sequencer.L2Unsafe().Number, targetHeadNumber) + + // Gossip unsafe blocks to the verifier + for i := uint64(1); i <= sequencer.L2Unsafe().Number; i++ { + seqHead, err := seqEngCl.PayloadByNumber(t.Ctx(), i) + require.NoError(t, err) + verifier.ActL2UnsafeGossipReceive(seqHead)(t) + } + verifier.ActL2PipelineFull(t) + + // Check if the verifier's unsafe sync is done + require.Equal(t, sequencer.L2Unsafe().Hash, verifier.L2Unsafe().Hash) + + // Build and submit a span batch with 6 blocks + batcher.ActSubmitAll(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + // Start verifier safe sync + verifier.ActL1HeadSignal(t) + verifier.l2PipelineIdle = false + for !verifier.l2PipelineIdle { + verifier.ActL2PipelineStep(t) + if verifier.L2PendingSafe().Number < targetHeadNumber { + // If the span batch is not fully processed, the safe head must not advance. + require.Equal(t, verifier.L2Safe().Number, uint64(0)) + } else { + // Once the span batch is fully processed, the safe head must advance to the end of span batch. + require.Equal(t, verifier.L2Safe().Number, targetHeadNumber) + require.Equal(t, verifier.L2Safe(), verifier.L2PendingSafe()) + } + // The unsafe head must not be changed + require.Equal(t, verifier.L2Unsafe(), sequencer.L2Unsafe()) + } +} + +func TestSpanBatchAtomicity_ForceAdvance(gt *testing.T) { + t := NewDefaultTesting(gt) + dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + minTs := hexutil.Uint64(0) + // Activate SpanBatch hardfork + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs + dp.DeployConfig.L2BlockTime = 2 + sd := e2eutils.Setup(t, dp, defaultAlloc) + log := testlog.Logger(t, log.LvlInfo) + _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) + + targetHeadNumber := uint64(6) // L1 block time / L2 block time + + sequencer.ActL2PipelineFull(t) + verifier.ActL2PipelineFull(t) + require.Equal(t, verifier.L2Unsafe().Number, uint64(0)) + + // Create 6 blocks + miner.ActEmptyBlock(t) + sequencer.ActL1HeadSignal(t) + sequencer.ActBuildToL1HeadUnsafe(t) + require.Equal(t, sequencer.L2Unsafe().Number, targetHeadNumber) + + // Build and submit a span batch with 6 blocks + batcher.ActSubmitAll(t) + miner.ActL1StartBlock(12)(t) + miner.ActL1IncludeTx(dp.Addresses.Batcher)(t) + miner.ActL1EndBlock(t) + + // Start verifier safe sync + verifier.ActL1HeadSignal(t) + verifier.l2PipelineIdle = false + for !verifier.l2PipelineIdle { + verifier.ActL2PipelineStep(t) + if verifier.L2PendingSafe().Number < targetHeadNumber { + // If the span batch is not fully processed, the safe head must not advance. + require.Equal(t, verifier.L2Safe().Number, uint64(0)) + } else { + // Once the span batch is fully processed, the safe head must advance to the end of span batch. + require.Equal(t, verifier.L2Safe().Number, targetHeadNumber) + require.Equal(t, verifier.L2Safe(), verifier.L2PendingSafe()) + } + // The unsafe head and the pending safe head must be the same + require.Equal(t, verifier.L2Unsafe(), verifier.L2PendingSafe()) + } +} diff --git a/op-node/rollup/derive/attributes_queue.go b/op-node/rollup/derive/attributes_queue.go index 023fbb3dccda..62b917a82934 100644 --- a/op-node/rollup/derive/attributes_queue.go +++ b/op-node/rollup/derive/attributes_queue.go @@ -28,11 +28,12 @@ type AttributesBuilder interface { } type AttributesQueue struct { - log log.Logger - config *rollup.Config - builder AttributesBuilder - prev *BatchQueue - batch *SingularBatch + log log.Logger + config *rollup.Config + builder AttributesBuilder + prev *BatchQueue + batch *SingularBatch + isLastInSpan bool } func NewAttributesQueue(log log.Logger, cfg *rollup.Config, builder AttributesBuilder, prev *BatchQueue) *AttributesQueue { @@ -48,14 +49,15 @@ func (aq *AttributesQueue) Origin() eth.L1BlockRef { return aq.prev.Origin() } -func (aq *AttributesQueue) NextAttributes(ctx context.Context, l2SafeHead eth.L2BlockRef) (*eth.PayloadAttributes, error) { +func (aq *AttributesQueue) NextAttributes(ctx context.Context, l2SafeHead eth.L2BlockRef) (*AttributesWithParent, error) { // Get a batch if we need it if aq.batch == nil { - batch, err := aq.prev.NextBatch(ctx, l2SafeHead) + batch, isLastInSpan, err := aq.prev.NextBatch(ctx, l2SafeHead) if err != nil { return nil, err } aq.batch = batch + aq.isLastInSpan = isLastInSpan } // Actually generate the next attributes @@ -63,8 +65,10 @@ func (aq *AttributesQueue) NextAttributes(ctx context.Context, l2SafeHead eth.L2 return nil, err } else { // Clear out the local state once we will succeed + attr := AttributesWithParent{attrs, l2SafeHead, aq.isLastInSpan} aq.batch = nil - return attrs, nil + aq.isLastInSpan = false + return &attr, nil } } diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index 420e0ce928e5..babcd2035861 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -89,22 +89,27 @@ func (bq *BatchQueue) popNextBatch(safeL2Head eth.L2BlockRef) *SingularBatch { return nextBatch } -func (bq *BatchQueue) maybeAdvanceEpoch(nextBatch *SingularBatch) { - if len(bq.l1Blocks) == 0 { - return - } - if nextBatch.GetEpochNum() == rollup.Epoch(bq.l1Blocks[0].Number)+1 { - // Advance epoch if necessary - bq.l1Blocks = bq.l1Blocks[1:] +// NextBatch return next valid batch upon the given safe head. +// It also returns the boolean that indicates if the batch is the last block in the batch. +func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) (*SingularBatch, bool, error) { + if len(bq.nextSpan) > 0 { + if bq.nextSpan[0].Timestamp == safeL2Head.Time+bq.config.BlockTime { + // If there are cached singular batches, pop first one and return. + nextBatch := bq.popNextBatch(safeL2Head) + return nextBatch, len(bq.nextSpan) == 0, nil + } else { + bq.nextSpan = bq.nextSpan[:0] + } } -} -func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) (*SingularBatch, error) { - if len(bq.nextSpan) > 0 { - // If there are cached singular batches, pop first one and return. - nextBatch := bq.popNextBatch(safeL2Head) - bq.maybeAdvanceEpoch(nextBatch) - return nextBatch, nil + // If the epoch is advanced, update bq.l1Blocks + if len(bq.l1Blocks) > 0 && safeL2Head.L1Origin.Number > bq.l1Blocks[0].Number { + for i, l1Block := range bq.l1Blocks { + if safeL2Head.L1Origin.Number == l1Block.Number { + bq.l1Blocks = bq.l1Blocks[i:] + break + } + } } // Note: We use the origin that we will have to determine if it's behind. This is important @@ -134,7 +139,7 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) if batch, err := bq.prev.NextBatch(ctx); err == io.EOF { outOfData = true } else if err != nil { - return nil, err + return nil, false, err } else if !originBehind { bq.AddBatch(ctx, batch, safeL2Head) } @@ -143,20 +148,20 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) // empty the previous stages if originBehind { if outOfData { - return nil, io.EOF + return nil, false, io.EOF } else { - return nil, NotEnoughData + return nil, false, NotEnoughData } } // Finally attempt to derive more batches batch, err := bq.deriveNextBatch(ctx, outOfData, safeL2Head) if err == io.EOF && outOfData { - return nil, io.EOF + return nil, false, io.EOF } else if err == io.EOF { - return nil, NotEnoughData + return nil, false, NotEnoughData } else if err != nil { - return nil, err + return nil, false, err } var nextBatch *SingularBatch @@ -164,28 +169,27 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) case SingularBatchType: singularBatch, ok := batch.(*SingularBatch) if !ok { - return nil, NewCriticalError(errors.New("failed type assertion to SingularBatch")) + return nil, false, NewCriticalError(errors.New("failed type assertion to SingularBatch")) } nextBatch = singularBatch case SpanBatchType: spanBatch, ok := batch.(*SpanBatch) if !ok { - return nil, NewCriticalError(errors.New("failed type assertion to SpanBatch")) + return nil, false, NewCriticalError(errors.New("failed type assertion to SpanBatch")) } // If next batch is SpanBatch, convert it to SingularBatches. singularBatches, err := spanBatch.GetSingularBatches(bq.l1Blocks, safeL2Head) if err != nil { - return nil, NewCriticalError(err) + return nil, false, NewCriticalError(err) } bq.nextSpan = singularBatches // span-batches are non-empty, so the below pop is safe. nextBatch = bq.popNextBatch(safeL2Head) default: - return nil, NewCriticalError(fmt.Errorf("unrecognized batch type: %d", batch.GetBatchType())) + return nil, false, NewCriticalError(fmt.Errorf("unrecognized batch type: %d", batch.GetBatchType())) } - bq.maybeAdvanceEpoch(nextBatch) - return nextBatch, nil + return nextBatch, len(bq.nextSpan) == 0, nil } func (bq *BatchQueue) Reset(ctx context.Context, base eth.L1BlockRef, _ eth.SystemConfig) error { diff --git a/op-node/rollup/derive/batch_queue_test.go b/op-node/rollup/derive/batch_queue_test.go index 3580f78c40d6..fbd9ae1e86dc 100644 --- a/op-node/rollup/derive/batch_queue_test.go +++ b/op-node/rollup/derive/batch_queue_test.go @@ -197,7 +197,7 @@ func BatchQueueNewOrigin(t *testing.T, batchType int) { // Prev Origin: 0; Safehead Origin: 2; Internal Origin: 0 // Should return no data but keep the same origin - data, err := bq.NextBatch(context.Background(), safeHead) + data, _, err := bq.NextBatch(context.Background(), safeHead) require.Nil(t, data) require.Equal(t, io.EOF, err) require.Equal(t, []eth.L1BlockRef{l1[0]}, bq.l1Blocks) @@ -206,7 +206,7 @@ func BatchQueueNewOrigin(t *testing.T, batchType int) { // Prev Origin: 1; Safehead Origin: 2; Internal Origin: 0 // Should wipe l1blocks + advance internal origin input.origin = l1[1] - data, err = bq.NextBatch(context.Background(), safeHead) + data, _, err = bq.NextBatch(context.Background(), safeHead) require.Nil(t, data) require.Equal(t, io.EOF, err) require.Empty(t, bq.l1Blocks) @@ -215,7 +215,7 @@ func BatchQueueNewOrigin(t *testing.T, batchType int) { // Prev Origin: 2; Safehead Origin: 2; Internal Origin: 1 // Should add to l1Blocks + advance internal origin input.origin = l1[2] - data, err = bq.NextBatch(context.Background(), safeHead) + data, _, err = bq.NextBatch(context.Background(), safeHead) require.Nil(t, data) require.Equal(t, io.EOF, err) require.Equal(t, []eth.L1BlockRef{l1[2]}, bq.l1Blocks) @@ -286,7 +286,7 @@ func BatchQueueEager(t *testing.T, batchType int) { input.origin = l1[1] for i := 0; i < len(expectedOutputBatches); i++ { - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, expectedOutputErrors[i]) if b == nil { require.Nil(t, expectedOutputBatches[i]) @@ -363,7 +363,7 @@ func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { // Load continuous batches for epoch 0 for i := 0; i < len(expectedOutputBatches); i++ { - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, expectedOutputErrors[i]) if b == nil { require.Nil(t, expectedOutputBatches[i]) @@ -378,20 +378,20 @@ func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { // Advance to origin 1. No forced batches yet. input.origin = l1[1] - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, io.EOF) require.Nil(t, b) // Advance to origin 2. No forced batches yet because we are still on epoch 0 // & have batches for epoch 0. input.origin = l1[2] - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, io.EOF) require.Nil(t, b) // Advance to origin 3. Should generate one empty batch. input.origin = l1[3] - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.NotNil(t, b) require.Equal(t, safeHead.Time+2, b.Timestamp) @@ -400,13 +400,13 @@ func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { safeHead.Time += 2 safeHead.Hash = mockHash(b.Timestamp, 2) safeHead.L1Origin = b.Epoch() - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, io.EOF) require.Nil(t, b) // Advance to origin 4. Should generate one empty batch. input.origin = l1[4] - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.NotNil(t, b) require.Equal(t, rollup.Epoch(2), b.EpochNum) @@ -415,7 +415,7 @@ func BatchQueueInvalidInternalAdvance(t *testing.T, batchType int) { safeHead.Time += 2 safeHead.Hash = mockHash(b.Timestamp, 2) safeHead.L1Origin = b.Epoch() - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, io.EOF) require.Nil(t, b) @@ -477,7 +477,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { _ = bq.Reset(context.Background(), l1[0], eth.SystemConfig{}) for i := 0; i < len(expectedOutputBatches); i++ { - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, NotEnoughData) require.Nil(t, b) } @@ -485,7 +485,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { // advance origin. Underlying stage still has no more inputBatches // This is not enough to auto advance yet input.origin = l1[1] - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, io.EOF) require.Nil(t, b) @@ -493,7 +493,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { input.origin = l1[2] // Check for a generated batch at t = 12 - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b.Timestamp, uint64(12)) require.Empty(t, b.Transactions) @@ -503,7 +503,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { safeHead.Hash = mockHash(b.Timestamp, 2) // Check for generated batch at t = 14 - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b.Timestamp, uint64(14)) require.Empty(t, b.Transactions) @@ -513,7 +513,7 @@ func BatchQueueMissing(t *testing.T, batchType int) { safeHead.Hash = mockHash(b.Timestamp, 2) // Check for the inputted batch at t = 16 - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b, expectedOutputBatches[0]) require.Equal(t, rollup.Epoch(0), b.EpochNum) @@ -527,9 +527,9 @@ func BatchQueueMissing(t *testing.T, batchType int) { // Check for the generated batch at t = 18. This batch advances the epoch // Note: We need one io.EOF returned from the bq that advances the internal L1 Blocks view // before the batch will be auto generated - _, e = bq.NextBatch(context.Background(), safeHead) + _, _, e = bq.NextBatch(context.Background(), safeHead) require.Equal(t, e, io.EOF) - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) require.Nil(t, e) require.Equal(t, b.Timestamp, uint64(18)) require.Empty(t, b.Transactions) @@ -610,13 +610,12 @@ func BatchQueueAdvancedEpoch(t *testing.T, batchType int) { inputOriginNumber += 1 input.origin = l1[inputOriginNumber] } - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, expectedOutputErrors[i]) if b == nil { require.Nil(t, expectedOutput) } else { require.Equal(t, expectedOutput, b) - require.Equal(t, bq.l1Blocks[0].Number, uint64(b.EpochNum)) safeHead.Number += 1 safeHead.Time += cfg.BlockTime safeHead.Hash = mockHash(b.Timestamp, 2) @@ -706,7 +705,7 @@ func BatchQueueShuffle(t *testing.T, batchType int) { var e error for j := 0; j < len(expectedOutputBatches); j++ { // Multiple NextBatch() executions may be required because the order of input is shuffled - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) if !errors.Is(e, NotEnoughData) { break } @@ -716,7 +715,6 @@ func BatchQueueShuffle(t *testing.T, batchType int) { require.Nil(t, expectedOutput) } else { require.Equal(t, expectedOutput, b) - require.Equal(t, bq.l1Blocks[0].Number, uint64(b.EpochNum)) safeHead.Number += 1 safeHead.Time += cfg.BlockTime safeHead.Hash = mockHash(b.Timestamp, 2) @@ -814,7 +812,7 @@ func TestBatchQueueOverlappingSpanBatch(t *testing.T) { input.origin = l1[1] for i := 0; i < len(expectedOutputBatches); i++ { - b, e := bq.NextBatch(context.Background(), safeHead) + b, _, e := bq.NextBatch(context.Background(), safeHead) require.ErrorIs(t, e, expectedOutputErrors[i]) if b == nil { require.Nil(t, expectedOutputBatches[i]) @@ -928,7 +926,7 @@ func TestBatchQueueComplex(t *testing.T) { var e error for j := 0; j < len(expectedOutputBatches); j++ { // Multiple NextBatch() executions may be required because the order of input is shuffled - b, e = bq.NextBatch(context.Background(), safeHead) + b, _, e = bq.NextBatch(context.Background(), safeHead) if !errors.Is(e, NotEnoughData) { break } @@ -938,7 +936,6 @@ func TestBatchQueueComplex(t *testing.T) { require.Nil(t, expectedOutput) } else { require.Equal(t, expectedOutput, b) - require.Equal(t, bq.l1Blocks[0].Number, uint64(b.EpochNum)) safeHead.Number += 1 safeHead.Time += cfg.BlockTime safeHead.Hash = mockHash(b.Timestamp, 2) @@ -948,3 +945,70 @@ func TestBatchQueueComplex(t *testing.T) { l2Client.Mock.AssertExpectations(t) } + +func TestBatchQueueResetSpan(t *testing.T) { + log := testlog.Logger(t, log.LvlCrit) + chainId := big.NewInt(1234) + l1 := L1Chain([]uint64{0, 4, 8}) + safeHead := eth.L2BlockRef{ + Hash: mockHash(0, 2), + Number: 0, + ParentHash: common.Hash{}, + Time: 0, + L1Origin: l1[0].ID(), + SequenceNumber: 0, + } + cfg := &rollup.Config{ + Genesis: rollup.Genesis{ + L2Time: 10, + }, + BlockTime: 2, + MaxSequencerDrift: 600, + SeqWindowSize: 30, + SpanBatchTime: getSpanBatchTime(SpanBatchType), + L2ChainID: chainId, + } + + singularBatches := []*SingularBatch{ + b(cfg.L2ChainID, 2, l1[0]), + b(cfg.L2ChainID, 4, l1[1]), + b(cfg.L2ChainID, 6, l1[1]), + b(cfg.L2ChainID, 8, l1[2]), + } + + input := &fakeBatchQueueInput{ + batches: []Batch{NewSpanBatch(singularBatches)}, + errors: []error{nil}, + origin: l1[2], + } + l2Client := testutils.MockL2Client{} + bq := NewBatchQueue(log, cfg, input, &l2Client) + bq.l1Blocks = l1 // Set enough l1 blocks to derive span batch + + // This NextBatch() will derive the span batch, return the first singular batch and save rest of batches in span. + nextBatch, _, err := bq.NextBatch(context.Background(), safeHead) + require.NoError(t, err) + require.Equal(t, nextBatch, singularBatches[0]) + require.Equal(t, len(bq.nextSpan), len(singularBatches)-1) + // batch queue's epoch should not be advanced until the entire span batch is returned + require.Equal(t, bq.l1Blocks[0], l1[0]) + + // This NextBatch() will return the second singular batch. + safeHead.Number += 1 + safeHead.Time += cfg.BlockTime + safeHead.Hash = mockHash(nextBatch.Timestamp, 2) + safeHead.L1Origin = nextBatch.Epoch() + nextBatch, _, err = bq.NextBatch(context.Background(), safeHead) + require.NoError(t, err) + require.Equal(t, nextBatch, singularBatches[1]) + require.Equal(t, len(bq.nextSpan), len(singularBatches)-2) + // batch queue's epoch should not be advanced until the entire span batch is returned + require.Equal(t, bq.l1Blocks[0], l1[0]) + + // Call NextBatch() with stale safeHead. It means the second batch failed to be processed. + // Batch queue should drop the entire span batch. + nextBatch, _, err = bq.NextBatch(context.Background(), safeHead) + require.Nil(t, nextBatch) + require.ErrorIs(t, err, io.EOF) + require.Equal(t, len(bq.nextSpan), 0) +} diff --git a/op-node/rollup/derive/engine_queue.go b/op-node/rollup/derive/engine_queue.go index b8cd3ae5917f..8073849aa7c3 100644 --- a/op-node/rollup/derive/engine_queue.go +++ b/op-node/rollup/derive/engine_queue.go @@ -17,14 +17,15 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" ) -type attributesWithParent struct { - attributes *eth.PayloadAttributes - parent eth.L2BlockRef +type AttributesWithParent struct { + attributes *eth.PayloadAttributes + parent eth.L2BlockRef + isLastInSpan bool } type NextAttributesProvider interface { Origin() eth.L1BlockRef - NextAttributes(context.Context, eth.L2BlockRef) (*eth.PayloadAttributes, error) + NextAttributes(context.Context, eth.L2BlockRef) (*AttributesWithParent, error) } type Engine interface { @@ -103,6 +104,10 @@ type EngineQueue struct { safeHead eth.L2BlockRef unsafeHead eth.L2BlockRef + // L2 block processed from the batch, but not consolidated to the safe block yet. + // Consolidation will be pending until the entire batch is processed successfully, to guarantee the span batch atomicity. + pendingSafeHead eth.L2BlockRef + // Target L2 block the engine is currently syncing to. // If the engine p2p sync is enabled, it can be different with unsafeHead. Otherwise, it must be same with unsafeHead. engineSyncTarget eth.L2BlockRef @@ -124,7 +129,7 @@ type EngineQueue struct { triedFinalizeAt eth.L1BlockRef // The queued-up attributes - safeAttributes *attributesWithParent + safeAttributes *AttributesWithParent unsafePayloads *PayloadsQueue // queue of unsafe payloads, ordered by ascending block number, may have gaps and duplicates // Tracks which L2 blocks where last derived from which L1 block. At most finalityLookback large. @@ -235,6 +240,10 @@ func (eq *EngineQueue) SafeL2Head() eth.L2BlockRef { return eq.safeHead } +func (eq *EngineQueue) PendingSafeL2Head() eth.L2BlockRef { + return eq.pendingSafeHead +} + func (eq *EngineQueue) EngineSyncTarget() eth.L2BlockRef { return eq.engineSyncTarget } @@ -275,16 +284,14 @@ func (eq *EngineQueue) Step(ctx context.Context) error { if err := eq.tryFinalizePastL2Blocks(ctx); err != nil { return err } - if next, err := eq.prev.NextAttributes(ctx, eq.safeHead); err == io.EOF { + if next, err := eq.prev.NextAttributes(ctx, eq.pendingSafeHead); err == io.EOF { outOfData = true } else if err != nil { return err } else { - eq.safeAttributes = &attributesWithParent{ - attributes: next, - parent: eq.safeHead, - } - eq.log.Debug("Adding next safe attributes", "safe_head", eq.safeHead, "next", next) + eq.safeAttributes = next + eq.log.Debug("Adding next safe attributes", "safe_head", eq.safeHead, + "pending_safe_head", eq.pendingSafeHead, "next", next) return NotEnoughData } @@ -411,6 +418,7 @@ func (eq *EngineQueue) logSyncProgress(reason string) { "reason", reason, "l2_finalized", eq.finalized, "l2_safe", eq.safeHead, + "l2_safe_pending", eq.pendingSafeHead, "l2_unsafe", eq.unsafeHead, "l2_engineSyncTarget", eq.engineSyncTarget, "l2_time", eq.unsafeHead.Time, @@ -552,29 +560,30 @@ func (eq *EngineQueue) tryNextSafeAttributes(ctx context.Context) error { return nil } // validate the safe attributes before processing them. The engine may have completed processing them through other means. - if eq.safeHead != eq.safeAttributes.parent { - // Previously the attribute's parent was the safe head. If the safe head advances so safe head's parent is the same as the + if eq.pendingSafeHead != eq.safeAttributes.parent { + // Previously the attribute's parent was the pending safe head. If the pending safe head advances so pending safe head's parent is the same as the // attribute's parent then we need to cancel the attributes. - if eq.safeHead.ParentHash == eq.safeAttributes.parent.Hash { + if eq.pendingSafeHead.ParentHash == eq.safeAttributes.parent.Hash { eq.log.Warn("queued safe attributes are stale, safehead progressed", - "safe_head", eq.safeHead, "safe_head_parent", eq.safeHead.ParentID(), "attributes_parent", eq.safeAttributes.parent) + "pending_safe_head", eq.pendingSafeHead, "pending_safe_head_parent", eq.pendingSafeHead.ParentID(), + "attributes_parent", eq.safeAttributes.parent) eq.safeAttributes = nil return nil } // If something other than a simple advance occurred, perform a full reset - return NewResetError(fmt.Errorf("safe head changed to %s with parent %s, conflicting with queued safe attributes on top of %s", - eq.safeHead, eq.safeHead.ParentID(), eq.safeAttributes.parent)) + return NewResetError(fmt.Errorf("pending safe head changed to %s with parent %s, conflicting with queued safe attributes on top of %s", + eq.pendingSafeHead, eq.pendingSafeHead.ParentID(), eq.safeAttributes.parent)) } - if eq.safeHead.Number < eq.unsafeHead.Number { + if eq.pendingSafeHead.Number < eq.unsafeHead.Number { return eq.consolidateNextSafeAttributes(ctx) - } else if eq.safeHead.Number == eq.unsafeHead.Number { + } else if eq.pendingSafeHead.Number == eq.unsafeHead.Number { return eq.forceNextSafeAttributes(ctx) } else { - // For some reason the unsafe head is behind the safe head. Log it, and correct it. - eq.log.Error("invalid sync state, unsafe head is behind safe head", "unsafe", eq.unsafeHead, "safe", eq.safeHead) - eq.unsafeHead = eq.safeHead - eq.engineSyncTarget = eq.safeHead + // For some reason the unsafe head is behind the pending safe head. Log it, and correct it. + eq.log.Error("invalid sync state, unsafe head is behind pending safe head", "unsafe", eq.unsafeHead, "pending_safe", eq.pendingSafeHead) + eq.unsafeHead = eq.pendingSafeHead + eq.engineSyncTarget = eq.pendingSafeHead eq.metrics.RecordL2Ref("l2_unsafe", eq.unsafeHead) eq.metrics.RecordL2Ref("l2_engineSyncTarget", eq.unsafeHead) return nil @@ -588,7 +597,7 @@ func (eq *EngineQueue) consolidateNextSafeAttributes(ctx context.Context) error ctx, cancel := context.WithTimeout(ctx, time.Second*10) defer cancel() - payload, err := eq.engine.PayloadByNumber(ctx, eq.safeHead.Number+1) + payload, err := eq.engine.PayloadByNumber(ctx, eq.pendingSafeHead.Number+1) if err != nil { if errors.Is(err, ethereum.NotFound) { // engine may have restarted, or inconsistent safe head. We need to reset @@ -596,8 +605,8 @@ func (eq *EngineQueue) consolidateNextSafeAttributes(ctx context.Context) error } return NewTemporaryError(fmt.Errorf("failed to get existing unsafe payload to compare against derived attributes from L1: %w", err)) } - if err := AttributesMatchBlock(eq.safeAttributes.attributes, eq.safeHead.Hash, payload, eq.log); err != nil { - eq.log.Warn("L2 reorg: existing unsafe block does not match derived attributes from L1", "err", err, "unsafe", eq.unsafeHead, "safe", eq.safeHead) + if err := AttributesMatchBlock(eq.safeAttributes.attributes, eq.pendingSafeHead.Hash, payload, eq.log); err != nil { + eq.log.Warn("L2 reorg: existing unsafe block does not match derived attributes from L1", "err", err, "unsafe", eq.unsafeHead, "pending_safe", eq.pendingSafeHead, "safe", eq.safeHead) // geth cannot wind back a chain without reorging to a new, previously non-canonical, block return eq.forceNextSafeAttributes(ctx) } @@ -605,12 +614,15 @@ func (eq *EngineQueue) consolidateNextSafeAttributes(ctx context.Context) error if err != nil { return NewResetError(fmt.Errorf("failed to decode L2 block ref from payload: %w", err)) } - eq.safeHead = ref - eq.needForkchoiceUpdate = true - eq.metrics.RecordL2Ref("l2_safe", ref) + eq.pendingSafeHead = ref + if eq.safeAttributes.isLastInSpan { + eq.safeHead = ref + eq.needForkchoiceUpdate = true + eq.metrics.RecordL2Ref("l2_safe", ref) + eq.postProcessSafeL2() + } // unsafe head stays the same, we did not reorg the chain. eq.safeAttributes = nil - eq.postProcessSafeL2() eq.logSyncProgress("reconciled with L1") return nil @@ -622,7 +634,7 @@ func (eq *EngineQueue) forceNextSafeAttributes(ctx context.Context) error { return nil } attrs := eq.safeAttributes.attributes - errType, err := eq.StartPayload(ctx, eq.safeHead, attrs, true) + errType, err := eq.StartPayload(ctx, eq.pendingSafeHead, attrs, true) if err == nil { _, errType, err = eq.ConfirmPayload(ctx) } @@ -648,11 +660,13 @@ func (eq *EngineQueue) forceNextSafeAttributes(ctx context.Context) error { // block is somehow invalid, there is nothing we can do to recover & we should exit. // TODO: Can this be triggered by an empty batch with invalid data (like parent hash or gas limit?) if len(attrs.Transactions) == depositCount { - eq.log.Error("deposit only block was invalid", "parent", eq.safeHead, "err", err) + eq.log.Error("deposit only block was invalid", "parent", eq.safeAttributes.parent, "err", err) return NewCriticalError(fmt.Errorf("failed to process block with only deposit transactions: %w", err)) } // drop the payload without inserting it eq.safeAttributes = nil + // Revert the pending safe head to the safe head. + eq.pendingSafeHead = eq.safeHead // suppress the error b/c we want to retry with the next batch from the batch queue // If there is no valid batch the node will eventually force a deposit only block. If // the deposit only block fails, this will return the critical error above. @@ -703,7 +717,9 @@ func (eq *EngineQueue) ConfirmPayload(ctx context.Context) (out *eth.ExecutionPa SafeBlockHash: eq.safeHead.Hash, FinalizedBlockHash: eq.finalized.Hash, } - payload, errTyp, err := ConfirmPayload(ctx, eq.log, eq.engine, fc, eq.buildingID, eq.buildingSafe) + // Update the safe head if the payload is built with the last attributes in the batch. + updateSafe := eq.buildingSafe && eq.safeAttributes != nil && eq.safeAttributes.isLastInSpan + payload, errTyp, err := ConfirmPayload(ctx, eq.log, eq.engine, fc, eq.buildingID, updateSafe) if err != nil { return nil, errTyp, fmt.Errorf("failed to complete building on top of L2 chain %s, id: %s, error (%d): %w", eq.buildingOnto, eq.buildingID, errTyp, err) } @@ -718,9 +734,12 @@ func (eq *EngineQueue) ConfirmPayload(ctx context.Context) (out *eth.ExecutionPa eq.metrics.RecordL2Ref("l2_engineSyncTarget", ref) if eq.buildingSafe { - eq.safeHead = ref - eq.postProcessSafeL2() - eq.metrics.RecordL2Ref("l2_safe", ref) + eq.pendingSafeHead = ref + if updateSafe { + eq.safeHead = ref + eq.postProcessSafeL2() + eq.metrics.RecordL2Ref("l2_safe", ref) + } } eq.resetBuildingState() return payload, BlockInsertOK, nil @@ -798,6 +817,7 @@ func (eq *EngineQueue) Reset(ctx context.Context, _ eth.L1BlockRef, _ eth.System eq.unsafeHead = unsafe eq.engineSyncTarget = unsafe eq.safeHead = safe + eq.pendingSafeHead = safe eq.safeAttributes = nil eq.finalized = finalized eq.resetBuildingState() diff --git a/op-node/rollup/derive/engine_queue_test.go b/op-node/rollup/derive/engine_queue_test.go index 654b4fe23c25..e9fbd91b7768 100644 --- a/op-node/rollup/derive/engine_queue_test.go +++ b/op-node/rollup/derive/engine_queue_test.go @@ -23,19 +23,20 @@ import ( ) type fakeAttributesQueue struct { - origin eth.L1BlockRef - attrs *eth.PayloadAttributes + origin eth.L1BlockRef + attrs *eth.PayloadAttributes + islastInSpan bool } func (f *fakeAttributesQueue) Origin() eth.L1BlockRef { return f.origin } -func (f *fakeAttributesQueue) NextAttributes(_ context.Context, _ eth.L2BlockRef) (*eth.PayloadAttributes, error) { +func (f *fakeAttributesQueue) NextAttributes(_ context.Context, safeHead eth.L2BlockRef) (*AttributesWithParent, error) { if f.attrs == nil { return nil, io.EOF } - return f.attrs, nil + return &AttributesWithParent{f.attrs, safeHead, f.islastInSpan}, nil } var _ NextAttributesProvider = (*fakeAttributesQueue)(nil) @@ -909,7 +910,7 @@ func TestBlockBuildingRace(t *testing.T) { GasLimit: &gasLimit, } - prev := &fakeAttributesQueue{origin: refA, attrs: attrs} + prev := &fakeAttributesQueue{origin: refA, attrs: attrs, islastInSpan: true} eq := NewEngineQueue(logger, cfg, eng, metrics, prev, l1F, &sync.Config{}) require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), io.EOF) @@ -1078,7 +1079,7 @@ func TestResetLoop(t *testing.T) { l1F.ExpectL1BlockRefByHash(refA.Hash, refA, nil) l1F.ExpectL1BlockRefByHash(refA.Hash, refA, nil) - prev := &fakeAttributesQueue{origin: refA, attrs: attrs} + prev := &fakeAttributesQueue{origin: refA, attrs: attrs, islastInSpan: true} eq := NewEngineQueue(logger, cfg, eng, metrics.NoopMetrics, prev, l1F, &sync.Config{}) eq.unsafeHead = refA2 diff --git a/op-node/rollup/derive/pipeline.go b/op-node/rollup/derive/pipeline.go index d054939f151d..643dc312cce9 100644 --- a/op-node/rollup/derive/pipeline.go +++ b/op-node/rollup/derive/pipeline.go @@ -51,6 +51,7 @@ type EngineQueueStage interface { Finalized() eth.L2BlockRef UnsafeL2Head() eth.L2BlockRef SafeL2Head() eth.L2BlockRef + PendingSafeL2Head() eth.L2BlockRef EngineSyncTarget() eth.L2BlockRef Origin() eth.L1BlockRef SystemConfig() eth.SystemConfig @@ -148,6 +149,10 @@ func (dp *DerivationPipeline) SafeL2Head() eth.L2BlockRef { return dp.eng.SafeL2Head() } +func (dp *DerivationPipeline) PendingSafeL2Head() eth.L2BlockRef { + return dp.eng.PendingSafeL2Head() +} + // UnsafeL2Head returns the head of the L2 chain that we are deriving for, this may be past what we derived from L1 func (dp *DerivationPipeline) UnsafeL2Head() eth.L2BlockRef { return dp.eng.UnsafeL2Head() From 79c1c5ace464015e14677b97fb4c29b96d260ab4 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Mon, 30 Oct 2023 13:50:49 +0900 Subject: [PATCH 247/374] Add comments in batch queue --- op-node/rollup/derive/batch_queue.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index babcd2035861..cbb3fd7e9239 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -93,11 +93,16 @@ func (bq *BatchQueue) popNextBatch(safeL2Head eth.L2BlockRef) *SingularBatch { // It also returns the boolean that indicates if the batch is the last block in the batch. func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) (*SingularBatch, bool, error) { if len(bq.nextSpan) > 0 { + // There are cached singular batches derived from the span batch. + // Check if the next cached batch matches the given parent block. if bq.nextSpan[0].Timestamp == safeL2Head.Time+bq.config.BlockTime { - // If there are cached singular batches, pop first one and return. + // Pop first one and return. nextBatch := bq.popNextBatch(safeL2Head) + // len(bq.nextSpan) == 0 means it's the last batch of the span. return nextBatch, len(bq.nextSpan) == 0, nil } else { + // Given parent block does not match the next batch. It means the previously returned batch is invalid. + // Drop cached batches and find another batch. bq.nextSpan = bq.nextSpan[:0] } } @@ -110,6 +115,7 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) break } } + // If we can't find the origin of parent block, we have to advance bq.origin. } // Note: We use the origin that we will have to determine if it's behind. This is important @@ -189,6 +195,8 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) return nil, false, NewCriticalError(fmt.Errorf("unrecognized batch type: %d", batch.GetBatchType())) } + // If the nextBatch is derived from the span batch, len(bq.nextSpan) == 0 means it's the last batch of the span. + // For singular batches, len(bq.nextSpan) == 0 is always true. return nextBatch, len(bq.nextSpan) == 0, nil } From d72dbe3660290976393a8ec60c9981a022d8c3a0 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Mon, 30 Oct 2023 14:05:46 +0900 Subject: [PATCH 248/374] Rename safeHead to parent --- op-node/rollup/derive/attributes_queue.go | 8 ++-- op-node/rollup/derive/batch_queue.go | 50 +++++++++++------------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/op-node/rollup/derive/attributes_queue.go b/op-node/rollup/derive/attributes_queue.go index 62b917a82934..c9d3f1bc406e 100644 --- a/op-node/rollup/derive/attributes_queue.go +++ b/op-node/rollup/derive/attributes_queue.go @@ -49,10 +49,10 @@ func (aq *AttributesQueue) Origin() eth.L1BlockRef { return aq.prev.Origin() } -func (aq *AttributesQueue) NextAttributes(ctx context.Context, l2SafeHead eth.L2BlockRef) (*AttributesWithParent, error) { +func (aq *AttributesQueue) NextAttributes(ctx context.Context, parent eth.L2BlockRef) (*AttributesWithParent, error) { // Get a batch if we need it if aq.batch == nil { - batch, isLastInSpan, err := aq.prev.NextBatch(ctx, l2SafeHead) + batch, isLastInSpan, err := aq.prev.NextBatch(ctx, parent) if err != nil { return nil, err } @@ -61,11 +61,11 @@ func (aq *AttributesQueue) NextAttributes(ctx context.Context, l2SafeHead eth.L2 } // Actually generate the next attributes - if attrs, err := aq.createNextAttributes(ctx, aq.batch, l2SafeHead); err != nil { + if attrs, err := aq.createNextAttributes(ctx, aq.batch, parent); err != nil { return nil, err } else { // Clear out the local state once we will succeed - attr := AttributesWithParent{attrs, l2SafeHead, aq.isLastInSpan} + attr := AttributesWithParent{attrs, parent, aq.isLastInSpan} aq.batch = nil aq.isLastInSpan = false return &attr, nil diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index cbb3fd7e9239..6a871bc4cf12 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -78,26 +78,26 @@ func (bq *BatchQueue) Origin() eth.L1BlockRef { // popNextBatch pops the next batch from the current queued up span-batch nextSpan. // The queue must be non-empty, or the function will panic. -func (bq *BatchQueue) popNextBatch(safeL2Head eth.L2BlockRef) *SingularBatch { +func (bq *BatchQueue) popNextBatch(parent eth.L2BlockRef) *SingularBatch { if len(bq.nextSpan) == 0 { panic("popping non-existent span-batch, invalid state") } nextBatch := bq.nextSpan[0] bq.nextSpan = bq.nextSpan[1:] - // Must set ParentHash before return. we can use safeL2Head because the parentCheck is verified in CheckBatch(). - nextBatch.ParentHash = safeL2Head.Hash + // Must set ParentHash before return. we can use parent because the parentCheck is verified in CheckBatch(). + nextBatch.ParentHash = parent.Hash return nextBatch } // NextBatch return next valid batch upon the given safe head. // It also returns the boolean that indicates if the batch is the last block in the batch. -func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) (*SingularBatch, bool, error) { +func (bq *BatchQueue) NextBatch(ctx context.Context, parent eth.L2BlockRef) (*SingularBatch, bool, error) { if len(bq.nextSpan) > 0 { // There are cached singular batches derived from the span batch. // Check if the next cached batch matches the given parent block. - if bq.nextSpan[0].Timestamp == safeL2Head.Time+bq.config.BlockTime { + if bq.nextSpan[0].Timestamp == parent.Time+bq.config.BlockTime { // Pop first one and return. - nextBatch := bq.popNextBatch(safeL2Head) + nextBatch := bq.popNextBatch(parent) // len(bq.nextSpan) == 0 means it's the last batch of the span. return nextBatch, len(bq.nextSpan) == 0, nil } else { @@ -108,9 +108,9 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) } // If the epoch is advanced, update bq.l1Blocks - if len(bq.l1Blocks) > 0 && safeL2Head.L1Origin.Number > bq.l1Blocks[0].Number { + if len(bq.l1Blocks) > 0 && parent.L1Origin.Number > bq.l1Blocks[0].Number { for i, l1Block := range bq.l1Blocks { - if safeL2Head.L1Origin.Number == l1Block.Number { + if parent.L1Origin.Number == l1Block.Number { bq.l1Blocks = bq.l1Blocks[i:] break } @@ -122,7 +122,7 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) // because it's the future origin that gets saved into the l1Blocks array. // We always update the origin of this stage if it is not the same so after the update code // runs, this is consistent. - originBehind := bq.prev.Origin().Number < safeL2Head.L1Origin.Number + originBehind := bq.prev.Origin().Number < parent.L1Origin.Number // Advance origin if needed // Note: The entire pipeline has the same origin @@ -147,7 +147,7 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) } else if err != nil { return nil, false, err } else if !originBehind { - bq.AddBatch(ctx, batch, safeL2Head) + bq.AddBatch(ctx, batch, parent) } // Skip adding data unless we are up to date with the origin, but do fully @@ -161,7 +161,7 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) } // Finally attempt to derive more batches - batch, err := bq.deriveNextBatch(ctx, outOfData, safeL2Head) + batch, err := bq.deriveNextBatch(ctx, outOfData, parent) if err == io.EOF && outOfData { return nil, false, io.EOF } else if err == io.EOF { @@ -184,13 +184,13 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, safeL2Head eth.L2BlockRef) return nil, false, NewCriticalError(errors.New("failed type assertion to SpanBatch")) } // If next batch is SpanBatch, convert it to SingularBatches. - singularBatches, err := spanBatch.GetSingularBatches(bq.l1Blocks, safeL2Head) + singularBatches, err := spanBatch.GetSingularBatches(bq.l1Blocks, parent) if err != nil { return nil, false, NewCriticalError(err) } bq.nextSpan = singularBatches // span-batches are non-empty, so the below pop is safe. - nextBatch = bq.popNextBatch(safeL2Head) + nextBatch = bq.popNextBatch(parent) default: return nil, false, NewCriticalError(fmt.Errorf("unrecognized batch type: %d", batch.GetBatchType())) } @@ -214,7 +214,7 @@ func (bq *BatchQueue) Reset(ctx context.Context, base eth.L1BlockRef, _ eth.Syst return io.EOF } -func (bq *BatchQueue) AddBatch(ctx context.Context, batch Batch, l2SafeHead eth.L2BlockRef) { +func (bq *BatchQueue) AddBatch(ctx context.Context, batch Batch, parent eth.L2BlockRef) { if len(bq.l1Blocks) == 0 { panic(fmt.Errorf("cannot add batch with timestamp %d, no origin was prepared", batch.GetTimestamp())) } @@ -222,7 +222,7 @@ func (bq *BatchQueue) AddBatch(ctx context.Context, batch Batch, l2SafeHead eth. L1InclusionBlock: bq.origin, Batch: batch, } - validity := CheckBatch(ctx, bq.config, bq.log, bq.l1Blocks, l2SafeHead, &data, bq.l2) + validity := CheckBatch(ctx, bq.config, bq.log, bq.l1Blocks, parent, &data, bq.l2) if validity == BatchDrop { return // if we do drop the batch, CheckBatch will log the drop reason with WARN level. } @@ -234,24 +234,24 @@ func (bq *BatchQueue) AddBatch(ctx context.Context, batch Batch, l2SafeHead eth. // following the validity rules imposed on consecutive batches, // based on currently available buffered batch and L1 origin information. // If no batch can be derived yet, then (nil, io.EOF) is returned. -func (bq *BatchQueue) deriveNextBatch(ctx context.Context, outOfData bool, l2SafeHead eth.L2BlockRef) (Batch, error) { +func (bq *BatchQueue) deriveNextBatch(ctx context.Context, outOfData bool, parent eth.L2BlockRef) (Batch, error) { if len(bq.l1Blocks) == 0 { return nil, NewCriticalError(errors.New("cannot derive next batch, no origin was prepared")) } epoch := bq.l1Blocks[0] - bq.log.Trace("Deriving the next batch", "epoch", epoch, "l2SafeHead", l2SafeHead, "outOfData", outOfData) + bq.log.Trace("Deriving the next batch", "epoch", epoch, "parent", parent, "outOfData", outOfData) // Note: epoch origin can now be one block ahead of the L2 Safe Head // This is in the case where we auto generate all batches in an epoch & advance the epoch // but don't advance the L2 Safe Head's epoch - if l2SafeHead.L1Origin != epoch.ID() && l2SafeHead.L1Origin.Number != epoch.Number-1 { - return nil, NewResetError(fmt.Errorf("buffered L1 chain epoch %s in batch queue does not match safe head origin %s", epoch, l2SafeHead.L1Origin)) + if parent.L1Origin != epoch.ID() && parent.L1Origin.Number != epoch.Number-1 { + return nil, NewResetError(fmt.Errorf("buffered L1 chain epoch %s in batch queue does not match safe head origin %s", epoch, parent.L1Origin)) } // Find the first-seen batch that matches all validity conditions. // We may not have sufficient information to proceed filtering, and then we stop. // There may be none: in that case we force-create an empty batch - nextTimestamp := l2SafeHead.Time + bq.config.BlockTime + nextTimestamp := parent.Time + bq.config.BlockTime var nextBatch *BatchWithL1InclusionBlock // Go over all batches, in order of inclusion, and find the first batch we can accept. @@ -259,15 +259,15 @@ func (bq *BatchQueue) deriveNextBatch(ctx context.Context, outOfData bool, l2Saf var remaining []*BatchWithL1InclusionBlock batchLoop: for i, batch := range bq.batches { - validity := CheckBatch(ctx, bq.config, bq.log.New("batch_index", i), bq.l1Blocks, l2SafeHead, batch, bq.l2) + validity := CheckBatch(ctx, bq.config, bq.log.New("batch_index", i), bq.l1Blocks, parent, batch, bq.l2) switch validity { case BatchFuture: remaining = append(remaining, batch) continue case BatchDrop: batch.Batch.LogContext(bq.log).Warn("Dropping batch", - "l2_safe_head", l2SafeHead.ID(), - "l2_safe_head_time", l2SafeHead.Time, + "parent", parent.ID(), + "parent_time", parent.Time, ) continue case BatchAccept: @@ -295,7 +295,7 @@ batchLoop: // i.e. if the sequence window expired, we create empty batches for the current epoch expiryEpoch := epoch.Number + bq.config.SeqWindowSize forceEmptyBatches := (expiryEpoch == bq.origin.Number && outOfData) || expiryEpoch < bq.origin.Number - firstOfEpoch := epoch.Number == l2SafeHead.L1Origin.Number+1 + firstOfEpoch := epoch.Number == parent.L1Origin.Number+1 bq.log.Trace("Potentially generating an empty batch", "expiryEpoch", expiryEpoch, "forceEmptyBatches", forceEmptyBatches, "nextTimestamp", nextTimestamp, @@ -318,7 +318,7 @@ batchLoop: if nextTimestamp < nextEpoch.Time || firstOfEpoch { bq.log.Info("Generating next batch", "epoch", epoch, "timestamp", nextTimestamp) return &SingularBatch{ - ParentHash: l2SafeHead.Hash, + ParentHash: parent.Hash, EpochNum: rollup.Epoch(epoch.Number), EpochHash: epoch.Hash, Timestamp: nextTimestamp, From 3e16cd7b086930ae99cb0d84ee9ee8074c71be5c Mon Sep 17 00:00:00 2001 From: protolambda Date: Mon, 30 Oct 2023 23:44:38 +0100 Subject: [PATCH 249/374] ci: fix e2e span batch test pre-requisite jobs --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index e9191803f39d..9d54acd98f80 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1422,6 +1422,9 @@ workflows: name: op-e2e-span-batch-tests module: op-e2e target: test-span-batch + requires: + - op-stack-go-lint + - devnet-allocs - op-program-compat: requires: - op-program-tests From 6bace497013fa50b90f2060b7b948636f02a2f93 Mon Sep 17 00:00:00 2001 From: Ethen Pociask Date: Mon, 30 Oct 2023 15:54:13 -0700 Subject: [PATCH 250/374] [indexer.api.add_withdrawal_hash] Added cross-domain msg hash to API response --- indexer/api/models/models.go | 31 +++++++++++++++ indexer/api/models/models_test.go | 64 +++++++++++++++++++++++++++++++ indexer/api/routes/withdrawals.go | 31 +-------------- 3 files changed, 96 insertions(+), 30 deletions(-) create mode 100644 indexer/api/models/models_test.go diff --git a/indexer/api/models/models.go b/indexer/api/models/models.go index 6ccdeae2f057..4b22957815bc 100644 --- a/indexer/api/models/models.go +++ b/indexer/api/models/models.go @@ -1,5 +1,7 @@ package models +import "github.com/ethereum-optimism/optimism/indexer/database" + // DepositItem ... Deposit item model for API responses type DepositItem struct { Guid string `json:"guid"` @@ -43,3 +45,32 @@ type WithdrawalResponse struct { HasNextPage bool `json:"hasNextPage"` Items []WithdrawalItem `json:"items"` } + +// FIXME make a pure function that returns a struct instead of newWithdrawalResponse +// newWithdrawalResponse ... Converts a database.L2BridgeWithdrawalsResponse to an api.WithdrawalResponse +func CreateWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) WithdrawalResponse { + items := make([]WithdrawalItem, len(withdrawals.Withdrawals)) + for i, withdrawal := range withdrawals.Withdrawals { + item := WithdrawalItem{ + Guid: withdrawal.L2BridgeWithdrawal.TransactionWithdrawalHash.String(), + L2BlockHash: withdrawal.L2BlockHash.String(), + Timestamp: withdrawal.L2BridgeWithdrawal.Tx.Timestamp, + From: withdrawal.L2BridgeWithdrawal.Tx.FromAddress.String(), + To: withdrawal.L2BridgeWithdrawal.Tx.ToAddress.String(), + TransactionHash: withdrawal.L2TransactionHash.String(), + Amount: withdrawal.L2BridgeWithdrawal.Tx.Amount.String(), + MessageHash: withdrawal.L2BridgeWithdrawal.CrossDomainMessageHash.String(), + ProofTransactionHash: withdrawal.ProvenL1TransactionHash.String(), + ClaimTransactionHash: withdrawal.FinalizedL1TransactionHash.String(), + L1TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.RemoteTokenAddress.String(), + L2TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.LocalTokenAddress.String(), + } + items[i] = item + } + + return WithdrawalResponse{ + Cursor: withdrawals.Cursor, + HasNextPage: withdrawals.HasNextPage, + Items: items, + } +} diff --git a/indexer/api/models/models_test.go b/indexer/api/models/models_test.go new file mode 100644 index 000000000000..c2fe8a842c97 --- /dev/null +++ b/indexer/api/models/models_test.go @@ -0,0 +1,64 @@ +package models_test + +import ( + "fmt" + "reflect" + "testing" + + "github.com/ethereum-optimism/optimism/indexer/api/models" + "github.com/ethereum-optimism/optimism/indexer/database" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestCreateWithdrawal(t *testing.T) { + // (1) Create a dummy database response object + + cdh := common.HexToHash("0x2") + dbWithdrawals := &database.L2BridgeWithdrawalsResponse{ + Withdrawals: []database.L2BridgeWithdrawalWithTransactionHashes{ + { + L2BridgeWithdrawal: database.L2BridgeWithdrawal{ + TransactionWithdrawalHash: common.HexToHash("0x1"), + BridgeTransfer: database.BridgeTransfer{ + CrossDomainMessageHash: &cdh, + Tx: database.Transaction{ + FromAddress: common.HexToAddress("0x3"), + ToAddress: common.HexToAddress("0x4"), + Timestamp: 5, + }, + TokenPair: database.TokenPair{ + LocalTokenAddress: common.HexToAddress("0x6"), + RemoteTokenAddress: common.HexToAddress("0x7"), + }, + }, + }, + }, + }, + } + + // (2) Create and validate response object + + response := models.CreateWithdrawalResponse(dbWithdrawals) + require.NotEmpty(t, response.Items) + require.Len(t, response.Items, 1) + + // (3) Use reflection to check that all fields in WithdrawalItem are populated correctly + + item := response.Items[0] + structType := reflect.TypeOf(item) + + structVal := reflect.ValueOf(item) + fieldNum := structVal.NumField() + + for i := 0; i < fieldNum; i++ { + field := structVal.Field(i) + fieldName := structType.Field(i).Name + + isSet := field.IsValid() && !field.IsZero() + + require.True(t, isSet, fmt.Sprintf("%s in not set", fieldName)) + + } + +} diff --git a/indexer/api/routes/withdrawals.go b/indexer/api/routes/withdrawals.go index 7c3ed399c00e..c408f2ab350d 100644 --- a/indexer/api/routes/withdrawals.go +++ b/indexer/api/routes/withdrawals.go @@ -4,38 +4,9 @@ import ( "net/http" "github.com/ethereum-optimism/optimism/indexer/api/models" - "github.com/ethereum-optimism/optimism/indexer/database" "github.com/go-chi/chi/v5" ) -// FIXME make a pure function that returns a struct instead of newWithdrawalResponse -// newWithdrawalResponse ... Converts a database.L2BridgeWithdrawalsResponse to an api.WithdrawalResponse -func newWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) models.WithdrawalResponse { - items := make([]models.WithdrawalItem, len(withdrawals.Withdrawals)) - for i, withdrawal := range withdrawals.Withdrawals { - item := models.WithdrawalItem{ - Guid: withdrawal.L2BridgeWithdrawal.TransactionWithdrawalHash.String(), - L2BlockHash: withdrawal.L2BlockHash.String(), - Timestamp: withdrawal.L2BridgeWithdrawal.Tx.Timestamp, - From: withdrawal.L2BridgeWithdrawal.Tx.FromAddress.String(), - To: withdrawal.L2BridgeWithdrawal.Tx.ToAddress.String(), - TransactionHash: withdrawal.L2TransactionHash.String(), - Amount: withdrawal.L2BridgeWithdrawal.Tx.Amount.String(), - ProofTransactionHash: withdrawal.ProvenL1TransactionHash.String(), - ClaimTransactionHash: withdrawal.FinalizedL1TransactionHash.String(), - L1TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.RemoteTokenAddress.String(), - L2TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.LocalTokenAddress.String(), - } - items[i] = item - } - - return models.WithdrawalResponse{ - Cursor: withdrawals.Cursor, - HasNextPage: withdrawals.HasNextPage, - Items: items, - } -} - // L2WithdrawalsHandler ... Handles /api/v0/withdrawals/{address} GET requests func (h Routes) L2WithdrawalsHandler(w http.ResponseWriter, r *http.Request) { addressValue := chi.URLParam(r, "address") @@ -69,7 +40,7 @@ func (h Routes) L2WithdrawalsHandler(w http.ResponseWriter, r *http.Request) { h.logger.Error("Unable to read withdrawals from DB", "err", err.Error()) return } - response := newWithdrawalResponse(withdrawals) + response := models.CreateWithdrawalResponse(withdrawals) err = jsonResponse(w, response, http.StatusOK) if err != nil { From 53f54e4f58671cbee421437c28eb97221e9d5d6a Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Mon, 30 Oct 2023 16:22:11 -0700 Subject: [PATCH 251/374] op-node: Enable Canyon on Goerli & Sepolia via superchain registry --- go.mod | 4 ++-- go.sum | 8 ++++---- op-node/chaincfg/chains_test.go | 2 ++ 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 7b15580851dd..0905c0fea4fb 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 - github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231026175037-2cff0d130e74 + github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492 github.com/ethereum/go-ethereum v1.13.1 github.com/fsnotify/fsnotify v1.7.0 github.com/go-chi/chi/v5 v5.0.10 @@ -209,7 +209,7 @@ require ( rsc.io/tmplfunc v0.0.3 // indirect ) -replace github.com/ethereum/go-ethereum v1.13.1 => github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231026180835-94fbbd04522e +replace github.com/ethereum/go-ethereum v1.13.1 => github.com/ethereum-optimism/op-geth v1.101304.0-rc.2.0.20231030225546-cd491fa3b588 //replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain //replace github.com/ethereum/go-ethereum v1.13.1 => ../go-ethereum diff --git a/go.sum b/go.sum index 87fbcbcfa36f..14269d6d3ab7 100644 --- a/go.sum +++ b/go.sum @@ -151,10 +151,10 @@ github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/ github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= -github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231026180835-94fbbd04522e h1:5ucLyIBCwo07ejZOKFY+6QbCqbLgITHWVqkmLoO6604= -github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231026180835-94fbbd04522e/go.mod h1:m6GrpSyAe1zdFLJlSctgYKSXUdHwj/yfq2WSOc5vs2A= -github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231026175037-2cff0d130e74 h1:02gXBD+Cas7xj9rpkke5wD1+vpfYxyF/+31M5tosP9A= -github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231026175037-2cff0d130e74/go.mod h1:/70H/KqrtKcvWvNGVj6S3rAcLC+kUPr3t2aDmYIS+Xk= +github.com/ethereum-optimism/op-geth v1.101304.0-rc.2.0.20231030225546-cd491fa3b588 h1:jrvFoV3aSGJcTT8Pyo8R2Sp7CZ0v3hqrdhfSmyZbJVw= +github.com/ethereum-optimism/op-geth v1.101304.0-rc.2.0.20231030225546-cd491fa3b588/go.mod h1:12W+vBetjYbDj5D2+V8hizke5yWuLrUDf7UmVkXTnCQ= +github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492 h1:FyzLzMLKMc9zcDYcSxbrLDglIRrGQJE9juFzIO35RmE= +github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492/go.mod h1:/70H/KqrtKcvWvNGVj6S3rAcLC+kUPr3t2aDmYIS+Xk= github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg= github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= diff --git a/op-node/chaincfg/chains_test.go b/op-node/chaincfg/chains_test.go index f2db441a2447..98dbfa9ee1e3 100644 --- a/op-node/chaincfg/chains_test.go +++ b/op-node/chaincfg/chains_test.go @@ -93,6 +93,7 @@ var goerliCfg = rollup.Config{ DepositContractAddress: common.HexToAddress("0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383"), L1SystemConfigAddress: common.HexToAddress("0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60"), RegolithTime: u64Ptr(1679079600), + CanyonTime: u64Ptr(1699981200), ProtocolVersionsAddress: common.HexToAddress("0x0C24F5098774aA366827D667494e9F889f7cFc08"), } @@ -124,6 +125,7 @@ var sepoliaCfg = rollup.Config{ DepositContractAddress: common.HexToAddress("0x16fc5058f25648194471939df75cf27a2fdc48bc"), L1SystemConfigAddress: common.HexToAddress("0x034edd2a225f7f429a63e0f1d2084b9e0a93b538"), RegolithTime: u64Ptr(0), + CanyonTime: u64Ptr(1699981200), ProtocolVersionsAddress: common.HexToAddress("0x79ADD5713B383DAa0a138d3C4780C7A1804a8090"), } From 240340b0d58a4df9e4a01be77ade9244e8cd2f43 Mon Sep 17 00:00:00 2001 From: Ethen Pociask Date: Mon, 30 Oct 2023 16:22:53 -0700 Subject: [PATCH 252/374] [indexer.api.add_withdrawal_hash] verify message hash not nil --- .vscode/launch.json | 22 ++++++++++++++++++++++ indexer/api/models/models.go | 13 +++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000000..527eefb0df3f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,22 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + + "type": "go", + "request": "launch", + "name": "Launch Program", + "program": "${workspaceFolder}/indexer/cmd/indexer", + "mode": "debug", + "env": { + "INDEXER_CONFIG": "/Users/ethen.pociask@coinbase.com/coinbase/indexer.sepolia.toml", + }, + "args": [ + "index" + ] + } + ] +} diff --git a/indexer/api/models/models.go b/indexer/api/models/models.go index 4b22957815bc..6e1a2d23eb7f 100644 --- a/indexer/api/models/models.go +++ b/indexer/api/models/models.go @@ -1,6 +1,9 @@ package models -import "github.com/ethereum-optimism/optimism/indexer/database" +import ( + "github.com/ethereum-optimism/optimism/indexer/database" + "github.com/ethereum/go-ethereum/common" +) // DepositItem ... Deposit item model for API responses type DepositItem struct { @@ -51,6 +54,12 @@ type WithdrawalResponse struct { func CreateWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) WithdrawalResponse { items := make([]WithdrawalItem, len(withdrawals.Withdrawals)) for i, withdrawal := range withdrawals.Withdrawals { + + msg := withdrawal.L2BridgeWithdrawal.CrossDomainMessageHash + if msg == nil { + msg = &common.Hash{} + } + item := WithdrawalItem{ Guid: withdrawal.L2BridgeWithdrawal.TransactionWithdrawalHash.String(), L2BlockHash: withdrawal.L2BlockHash.String(), @@ -59,7 +68,7 @@ func CreateWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) To: withdrawal.L2BridgeWithdrawal.Tx.ToAddress.String(), TransactionHash: withdrawal.L2TransactionHash.String(), Amount: withdrawal.L2BridgeWithdrawal.Tx.Amount.String(), - MessageHash: withdrawal.L2BridgeWithdrawal.CrossDomainMessageHash.String(), + MessageHash: msg.String(), ProofTransactionHash: withdrawal.ProvenL1TransactionHash.String(), ClaimTransactionHash: withdrawal.FinalizedL1TransactionHash.String(), L1TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.RemoteTokenAddress.String(), From 1e641e9c579a05d5f585c681af94c6afd38b64e3 Mon Sep 17 00:00:00 2001 From: Ethen Pociask Date: Mon, 30 Oct 2023 16:23:21 -0700 Subject: [PATCH 253/374] [indexer.api.add_withdrawal_hash] Remove .vscode --- .vscode/launch.json | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 527eefb0df3f..000000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - - "type": "go", - "request": "launch", - "name": "Launch Program", - "program": "${workspaceFolder}/indexer/cmd/indexer", - "mode": "debug", - "env": { - "INDEXER_CONFIG": "/Users/ethen.pociask@coinbase.com/coinbase/indexer.sepolia.toml", - }, - "args": [ - "index" - ] - } - ] -} From 18f6d6311ad8e1e6c22adac471e604e24539597e Mon Sep 17 00:00:00 2001 From: Ethen Pociask Date: Tue, 31 Oct 2023 00:24:04 -0700 Subject: [PATCH 254/374] [indexer.api.add_withdrawal_hash] better code comments and variable naming --- indexer/api-ts/generated.ts | 4 +-- indexer/api/api_test.go | 4 +-- indexer/api/models/models.go | 54 ++++++++++++++++++------------------ 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/indexer/api-ts/generated.ts b/indexer/api-ts/generated.ts index 9b19bb6da987..940d3af499dd 100644 --- a/indexer/api-ts/generated.ts +++ b/indexer/api-ts/generated.ts @@ -38,8 +38,8 @@ export interface WithdrawalItem { timestamp: number /* uint64 */; l2BlockHash: string; amount: string; - proofTransactionHash: string; - claimTransactionHash: string; + L1ProvenTxHash: string; + L1FinalizedTxHash: string; l1TokenAddress: string; l2TokenAddress: string; } diff --git a/indexer/api/api_test.go b/indexer/api/api_test.go index 554fce28ce51..8cea08d434db 100644 --- a/indexer/api/api_test.go +++ b/indexer/api/api_test.go @@ -149,8 +149,8 @@ func TestL2BridgeWithdrawalsByAddressHandler(t *testing.T) { assert.Equal(t, resp.Items[0].To, withdrawal.Tx.ToAddress.String()) assert.Equal(t, resp.Items[0].TransactionHash, common.HexToHash("0x789").String()) assert.Equal(t, resp.Items[0].Amount, withdrawal.Tx.Amount.String()) - assert.Equal(t, resp.Items[0].ProofTransactionHash, common.HexToHash("0x123").String()) - assert.Equal(t, resp.Items[0].ClaimTransactionHash, common.HexToHash("0x123").String()) + assert.Equal(t, resp.Items[0].L1ProvenTxHash, common.HexToHash("0x123").String()) + assert.Equal(t, resp.Items[0].L1FinalizedTxHash, common.HexToHash("0x123").String()) assert.Equal(t, resp.Items[0].L1TokenAddress, withdrawal.TokenPair.RemoteTokenAddress.String()) assert.Equal(t, resp.Items[0].L2TokenAddress, withdrawal.TokenPair.LocalTokenAddress.String()) assert.Equal(t, resp.Items[0].Timestamp, withdrawal.Tx.Timestamp) diff --git a/indexer/api/models/models.go b/indexer/api/models/models.go index 6e1a2d23eb7f..e33a0b5b1d41 100644 --- a/indexer/api/models/models.go +++ b/indexer/api/models/models.go @@ -28,18 +28,18 @@ type DepositResponse struct { // WithdrawalItem ... Data model for API JSON response type WithdrawalItem struct { - Guid string `json:"guid"` - From string `json:"from"` - To string `json:"to"` - TransactionHash string `json:"transactionHash"` - MessageHash string `json:"messageHash"` - Timestamp uint64 `json:"timestamp"` - L2BlockHash string `json:"l2BlockHash"` - Amount string `json:"amount"` - ProofTransactionHash string `json:"proofTransactionHash"` - ClaimTransactionHash string `json:"claimTransactionHash"` - L1TokenAddress string `json:"l1TokenAddress"` - L2TokenAddress string `json:"l2TokenAddress"` + Guid string `json:"guid"` + From string `json:"from"` + To string `json:"to"` + TransactionHash string `json:"transactionHash"` + CrossDomainMessageHash string `json:"crossDomainMessageHash"` + Timestamp uint64 `json:"timestamp"` + L2BlockHash string `json:"l2BlockHash"` + Amount string `json:"amount"` + L1ProvenTxHash string `json:"L1ProvenTxHash"` + L1FinalizedTxHash string `json:"L1FinalizedTxHash"` + L1TokenAddress string `json:"l1TokenAddress"` + L2TokenAddress string `json:"l2TokenAddress"` } // WithdrawalResponse ... Data model for API JSON response @@ -55,24 +55,24 @@ func CreateWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) items := make([]WithdrawalItem, len(withdrawals.Withdrawals)) for i, withdrawal := range withdrawals.Withdrawals { - msg := withdrawal.L2BridgeWithdrawal.CrossDomainMessageHash - if msg == nil { - msg = &common.Hash{} + cdh := withdrawal.L2BridgeWithdrawal.CrossDomainMessageHash + if cdh == nil { // Zero value indicates that the withdrawal didn't have a cross domain message + cdh = &common.Hash{0} } item := WithdrawalItem{ - Guid: withdrawal.L2BridgeWithdrawal.TransactionWithdrawalHash.String(), - L2BlockHash: withdrawal.L2BlockHash.String(), - Timestamp: withdrawal.L2BridgeWithdrawal.Tx.Timestamp, - From: withdrawal.L2BridgeWithdrawal.Tx.FromAddress.String(), - To: withdrawal.L2BridgeWithdrawal.Tx.ToAddress.String(), - TransactionHash: withdrawal.L2TransactionHash.String(), - Amount: withdrawal.L2BridgeWithdrawal.Tx.Amount.String(), - MessageHash: msg.String(), - ProofTransactionHash: withdrawal.ProvenL1TransactionHash.String(), - ClaimTransactionHash: withdrawal.FinalizedL1TransactionHash.String(), - L1TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.RemoteTokenAddress.String(), - L2TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.LocalTokenAddress.String(), + Guid: withdrawal.L2BridgeWithdrawal.TransactionWithdrawalHash.String(), + L2BlockHash: withdrawal.L2BlockHash.String(), + Timestamp: withdrawal.L2BridgeWithdrawal.Tx.Timestamp, + From: withdrawal.L2BridgeWithdrawal.Tx.FromAddress.String(), + To: withdrawal.L2BridgeWithdrawal.Tx.ToAddress.String(), + TransactionHash: withdrawal.L2TransactionHash.String(), + Amount: withdrawal.L2BridgeWithdrawal.Tx.Amount.String(), + CrossDomainMessageHash: cdh.String(), + L1ProvenTxHash: withdrawal.ProvenL1TransactionHash.String(), + L1FinalizedTxHash: withdrawal.FinalizedL1TransactionHash.String(), + L1TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.RemoteTokenAddress.String(), + L2TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.LocalTokenAddress.String(), } items[i] = item } From 290fe11523ee14cc3c5ba12232d692d26befb43f Mon Sep 17 00:00:00 2001 From: Ethen Pociask Date: Tue, 31 Oct 2023 00:25:12 -0700 Subject: [PATCH 255/374] [indexer.api.add_withdrawal_hash] update client bindings --- indexer/api-ts/generated.ts | 4 ++-- indexer/api/models/models.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/indexer/api-ts/generated.ts b/indexer/api-ts/generated.ts index 940d3af499dd..38d2d157fdea 100644 --- a/indexer/api-ts/generated.ts +++ b/indexer/api-ts/generated.ts @@ -38,8 +38,8 @@ export interface WithdrawalItem { timestamp: number /* uint64 */; l2BlockHash: string; amount: string; - L1ProvenTxHash: string; - L1FinalizedTxHash: string; + l1ProvenTxHash: string; + l1FinalizedTxHash: string; l1TokenAddress: string; l2TokenAddress: string; } diff --git a/indexer/api/models/models.go b/indexer/api/models/models.go index e33a0b5b1d41..1bf86ee26192 100644 --- a/indexer/api/models/models.go +++ b/indexer/api/models/models.go @@ -36,8 +36,8 @@ type WithdrawalItem struct { Timestamp uint64 `json:"timestamp"` L2BlockHash string `json:"l2BlockHash"` Amount string `json:"amount"` - L1ProvenTxHash string `json:"L1ProvenTxHash"` - L1FinalizedTxHash string `json:"L1FinalizedTxHash"` + L1ProvenTxHash string `json:"l1ProvenTxHash"` + L1FinalizedTxHash string `json:"l1FinalizedTxHash"` L1TokenAddress string `json:"l1TokenAddress"` L2TokenAddress string `json:"l2TokenAddress"` } From ce93b94539ca49391f8c0b7d97883a9f55cd8b86 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Tue, 31 Oct 2023 16:36:07 +0900 Subject: [PATCH 256/374] Fix op-program to get output root from specified block number --- op-program/client/driver/driver.go | 8 ++++---- op-program/client/driver/driver_test.go | 12 ++++++------ op-program/client/l2/engine.go | 7 +++++-- op-program/client/program.go | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/op-program/client/driver/driver.go b/op-program/client/driver/driver.go index 95a3df751f32..5487d8f19fd5 100644 --- a/op-program/client/driver/driver.go +++ b/op-program/client/driver/driver.go @@ -25,13 +25,13 @@ type Derivation interface { type L2Source interface { derive.Engine - L2OutputRoot() (eth.Bytes32, error) + L2OutputRoot(uint64) (eth.Bytes32, error) } type Driver struct { logger log.Logger pipeline Derivation - l2OutputRoot func() (eth.Bytes32, error) + l2OutputRoot func(uint64) (eth.Bytes32, error) targetBlockNum uint64 } @@ -77,8 +77,8 @@ func (d *Driver) SafeHead() eth.L2BlockRef { return d.pipeline.SafeL2Head() } -func (d *Driver) ValidateClaim(claimedOutputRoot eth.Bytes32) error { - outputRoot, err := d.l2OutputRoot() +func (d *Driver) ValidateClaim(l2ClaimBlockNum uint64, claimedOutputRoot eth.Bytes32) error { + outputRoot, err := d.l2OutputRoot(l2ClaimBlockNum) if err != nil { return fmt.Errorf("calculate L2 output root: %w", err) } diff --git a/op-program/client/driver/driver_test.go b/op-program/client/driver/driver_test.go index cc24c696cf84..3262ab7ed986 100644 --- a/op-program/client/driver/driver_test.go +++ b/op-program/client/driver/driver_test.go @@ -73,29 +73,29 @@ func TestValidateClaim(t *testing.T) { t.Run("Valid", func(t *testing.T) { driver := createDriver(t, io.EOF) expected := eth.Bytes32{0x11} - driver.l2OutputRoot = func() (eth.Bytes32, error) { + driver.l2OutputRoot = func(_ uint64) (eth.Bytes32, error) { return expected, nil } - err := driver.ValidateClaim(expected) + err := driver.ValidateClaim(uint64(0), expected) require.NoError(t, err) }) t.Run("Invalid", func(t *testing.T) { driver := createDriver(t, io.EOF) - driver.l2OutputRoot = func() (eth.Bytes32, error) { + driver.l2OutputRoot = func(_ uint64) (eth.Bytes32, error) { return eth.Bytes32{0x22}, nil } - err := driver.ValidateClaim(eth.Bytes32{0x11}) + err := driver.ValidateClaim(uint64(0), eth.Bytes32{0x11}) require.ErrorIs(t, err, ErrClaimNotValid) }) t.Run("Error", func(t *testing.T) { driver := createDriver(t, io.EOF) expectedErr := errors.New("boom") - driver.l2OutputRoot = func() (eth.Bytes32, error) { + driver.l2OutputRoot = func(_ uint64) (eth.Bytes32, error) { return eth.Bytes32{}, expectedErr } - err := driver.ValidateClaim(eth.Bytes32{0x11}) + err := driver.ValidateClaim(uint64(0), eth.Bytes32{0x11}) require.ErrorIs(t, err, expectedErr) }) } diff --git a/op-program/client/l2/engine.go b/op-program/client/l2/engine.go index e6ffadebf470..2bc808e4a78a 100644 --- a/op-program/client/l2/engine.go +++ b/op-program/client/l2/engine.go @@ -34,8 +34,11 @@ func NewOracleEngine(rollupCfg *rollup.Config, logger log.Logger, backend engine } } -func (o *OracleEngine) L2OutputRoot() (eth.Bytes32, error) { - outBlock := o.backend.CurrentHeader() +func (o *OracleEngine) L2OutputRoot(l2ClaimBlockNum uint64) (eth.Bytes32, error) { + outBlock := o.backend.GetHeaderByNumber(l2ClaimBlockNum) + if outBlock == nil { + return eth.Bytes32{}, fmt.Errorf("failed to get L2 block at %d", l2ClaimBlockNum) + } stateDB, err := o.backend.StateAt(outBlock.Root) if err != nil { return eth.Bytes32{}, fmt.Errorf("failed to open L2 state db at block %s: %w", outBlock.Hash(), err) diff --git a/op-program/client/program.go b/op-program/client/program.go index 7d037a7b6ebe..b43950bfb871 100644 --- a/op-program/client/program.go +++ b/op-program/client/program.go @@ -79,7 +79,7 @@ func runDerivation(logger log.Logger, cfg *rollup.Config, l2Cfg *params.ChainCon return err } } - return d.ValidateClaim(eth.Bytes32(l2Claim)) + return d.ValidateClaim(l2ClaimBlockNum, eth.Bytes32(l2Claim)) } func CreateHinterChannel() oppio.FileChannel { From fc6daa713d23f943c09a9aecd6c47b804e04d104 Mon Sep 17 00:00:00 2001 From: Ethen Pociask Date: Tue, 31 Oct 2023 00:42:33 -0700 Subject: [PATCH 257/374] [indexer.api.add_withdrawal_hash] update client bindings --- indexer/api-ts/generated.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indexer/api-ts/generated.ts b/indexer/api-ts/generated.ts index 38d2d157fdea..957d72fddc07 100644 --- a/indexer/api-ts/generated.ts +++ b/indexer/api-ts/generated.ts @@ -34,7 +34,7 @@ export interface WithdrawalItem { from: string; to: string; transactionHash: string; - messageHash: string; + crossDomainMessageHash: string; timestamp: number /* uint64 */; l2BlockHash: string; amount: string; From 8f59b112ca0e656c408b639399883202d45a8a4b Mon Sep 17 00:00:00 2001 From: Tei Im Date: Tue, 31 Oct 2023 16:56:17 +0900 Subject: [PATCH 258/374] Add PendingSafeL2 to SyncStatus --- op-e2e/actions/l2_verifier.go | 1 + op-node/node/server_test.go | 1 + op-node/rollup/driver/driver.go | 1 + op-node/rollup/driver/state.go | 1 + op-service/eth/sync_status.go | 2 ++ op-service/testutils/random.go | 1 + 6 files changed, 7 insertions(+) diff --git a/op-e2e/actions/l2_verifier.go b/op-e2e/actions/l2_verifier.go index 8a99b593a866..6419a68ce669 100644 --- a/op-e2e/actions/l2_verifier.go +++ b/op-e2e/actions/l2_verifier.go @@ -157,6 +157,7 @@ func (s *L2Verifier) SyncStatus() *eth.SyncStatus { UnsafeL2: s.L2Unsafe(), SafeL2: s.L2Safe(), FinalizedL2: s.L2Finalized(), + PendingSafeL2: s.L2PendingSafe(), UnsafeL2SyncTarget: s.derivation.UnsafeL2SyncTarget(), EngineSyncTarget: s.EngineSyncTarget(), } diff --git a/op-node/node/server_test.go b/op-node/node/server_test.go index eda1c8252750..d63879f00a52 100644 --- a/op-node/node/server_test.go +++ b/op-node/node/server_test.go @@ -161,6 +161,7 @@ func randomSyncStatus(rng *rand.Rand) *eth.SyncStatus { UnsafeL2: testutils.RandomL2BlockRef(rng), SafeL2: testutils.RandomL2BlockRef(rng), FinalizedL2: testutils.RandomL2BlockRef(rng), + PendingSafeL2: testutils.RandomL2BlockRef(rng), UnsafeL2SyncTarget: testutils.RandomL2BlockRef(rng), EngineSyncTarget: testutils.RandomL2BlockRef(rng), } diff --git a/op-node/rollup/driver/driver.go b/op-node/rollup/driver/driver.go index c41fea100a12..1db8d5dff87e 100644 --- a/op-node/rollup/driver/driver.go +++ b/op-node/rollup/driver/driver.go @@ -60,6 +60,7 @@ type DerivationPipeline interface { Finalized() eth.L2BlockRef SafeL2Head() eth.L2BlockRef UnsafeL2Head() eth.L2BlockRef + PendingSafeL2Head() eth.L2BlockRef Origin() eth.L1BlockRef EngineReady() bool EngineSyncTarget() eth.L2BlockRef diff --git a/op-node/rollup/driver/state.go b/op-node/rollup/driver/state.go index 87d8ca8ec521..6236c763f4f4 100644 --- a/op-node/rollup/driver/state.go +++ b/op-node/rollup/driver/state.go @@ -481,6 +481,7 @@ func (s *Driver) syncStatus() *eth.SyncStatus { UnsafeL2: s.derivation.UnsafeL2Head(), SafeL2: s.derivation.SafeL2Head(), FinalizedL2: s.derivation.Finalized(), + PendingSafeL2: s.derivation.PendingSafeL2Head(), UnsafeL2SyncTarget: s.derivation.UnsafeL2SyncTarget(), EngineSyncTarget: s.derivation.EngineSyncTarget(), } diff --git a/op-service/eth/sync_status.go b/op-service/eth/sync_status.go index 74ac24c12cc0..2217fa9439e3 100644 --- a/op-service/eth/sync_status.go +++ b/op-service/eth/sync_status.go @@ -32,6 +32,8 @@ type SyncStatus struct { // FinalizedL2 points to the L2 block that was derived fully from // finalized L1 information, thus irreversible. FinalizedL2 L2BlockRef `json:"finalized_l2"` + // PendingSafeL2 points to the L2 block processed from the batch, but not consolidated to the safe block yet. + PendingSafeL2 L2BlockRef `json:"pending_safe_l2"` // UnsafeL2SyncTarget points to the first unprocessed unsafe L2 block. // It may be zeroed if there is no targeted block. UnsafeL2SyncTarget L2BlockRef `json:"queued_unsafe_l2"` diff --git a/op-service/testutils/random.go b/op-service/testutils/random.go index d1363ecf3f5d..234dc1c64211 100644 --- a/op-service/testutils/random.go +++ b/op-service/testutils/random.go @@ -324,6 +324,7 @@ func RandomOutputResponse(rng *rand.Rand) *eth.OutputResponse { UnsafeL2: RandomL2BlockRef(rng), SafeL2: RandomL2BlockRef(rng), FinalizedL2: RandomL2BlockRef(rng), + PendingSafeL2: RandomL2BlockRef(rng), EngineSyncTarget: RandomL2BlockRef(rng), }, } From 7005d12c641d31d053c825caf3b932213bf7be6d Mon Sep 17 00:00:00 2001 From: Tei Im Date: Tue, 31 Oct 2023 16:56:39 +0900 Subject: [PATCH 259/374] Fix TestStopStartBatcher to wait for processing full batch --- op-e2e/e2eutils/wait/blocks.go | 11 +++++++++++ op-e2e/system_test.go | 2 ++ 2 files changed, 13 insertions(+) diff --git a/op-e2e/e2eutils/wait/blocks.go b/op-e2e/e2eutils/wait/blocks.go index dd6ef178cd41..066b16df6884 100644 --- a/op-e2e/e2eutils/wait/blocks.go +++ b/op-e2e/e2eutils/wait/blocks.go @@ -6,6 +6,8 @@ import ( "math/big" "time" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum/go-ethereum/core/types" ) @@ -57,3 +59,12 @@ func ForNextBlock(ctx context.Context, client BlockCaller) error { } return ForBlock(ctx, client, current+1) } + +func ForProcessingFullBatch(ctx context.Context, rollupCl *sources.RollupClient) error { + _, err := AndGet(ctx, time.Second, func() (*eth.SyncStatus, error) { + return rollupCl.SyncStatus(ctx) + }, func(syncStatus *eth.SyncStatus) bool { + return syncStatus.PendingSafeL2 == syncStatus.SafeL2 + }) + return err +} diff --git a/op-e2e/system_test.go b/op-e2e/system_test.go index 649bb678890c..603322c8fdd5 100644 --- a/op-e2e/system_test.go +++ b/op-e2e/system_test.go @@ -1259,6 +1259,7 @@ func TestStopStartBatcher(t *testing.T) { safeBlockInclusionDuration := time.Duration(6*cfg.DeployConfig.L1BlockTime) * time.Second _, err = geth.WaitForBlock(receipt.BlockNumber, l2Verif, safeBlockInclusionDuration) require.Nil(t, err, "Waiting for block on verifier") + require.NoError(t, wait.ForProcessingFullBatch(context.Background(), rollupClient)) // ensure the safe chain advances newSeqStatus, err := rollupClient.SyncStatus(context.Background()) @@ -1296,6 +1297,7 @@ func TestStopStartBatcher(t *testing.T) { // wait until the block the tx was first included in shows up in the safe chain on the verifier _, err = geth.WaitForBlock(receipt.BlockNumber, l2Verif, safeBlockInclusionDuration) require.Nil(t, err, "Waiting for block on verifier") + require.NoError(t, wait.ForProcessingFullBatch(context.Background(), rollupClient)) // ensure that the safe chain advances after restarting the batcher newSeqStatus, err = rollupClient.SyncStatus(context.Background()) From 861678bd5dc9817125dd75c6c67573f10339166a Mon Sep 17 00:00:00 2001 From: Ethen Pociask Date: Tue, 31 Oct 2023 01:51:33 -0700 Subject: [PATCH 260/374] [indexer.api.add_withdrawal_hash] Adding code comment --- indexer/api/models/models.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indexer/api/models/models.go b/indexer/api/models/models.go index 1bf86ee26192..6d34afab5909 100644 --- a/indexer/api/models/models.go +++ b/indexer/api/models/models.go @@ -55,9 +55,9 @@ func CreateWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) items := make([]WithdrawalItem, len(withdrawals.Withdrawals)) for i, withdrawal := range withdrawals.Withdrawals { - cdh := withdrawal.L2BridgeWithdrawal.CrossDomainMessageHash - if cdh == nil { // Zero value indicates that the withdrawal didn't have a cross domain message - cdh = &common.Hash{0} + crossDomainHash := withdrawal.L2BridgeWithdrawal.CrossDomainMessageHash + if crossDomainHash == nil { // Zero value indicates that the withdrawal didn't have a cross domain message + crossDomainHash = &common.Hash{0} } item := WithdrawalItem{ @@ -68,7 +68,7 @@ func CreateWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) To: withdrawal.L2BridgeWithdrawal.Tx.ToAddress.String(), TransactionHash: withdrawal.L2TransactionHash.String(), Amount: withdrawal.L2BridgeWithdrawal.Tx.Amount.String(), - CrossDomainMessageHash: cdh.String(), + CrossDomainMessageHash: crossDomainHash.String(), L1ProvenTxHash: withdrawal.ProvenL1TransactionHash.String(), L1FinalizedTxHash: withdrawal.FinalizedL1TransactionHash.String(), L1TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.RemoteTokenAddress.String(), From 54e3cfe2257e17035deb739e02d6399cd929a94a Mon Sep 17 00:00:00 2001 From: Tei Im Date: Tue, 31 Oct 2023 19:42:04 +0900 Subject: [PATCH 261/374] Add commets for advancing epoch --- op-node/rollup/derive/batch_queue.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/op-node/rollup/derive/batch_queue.go b/op-node/rollup/derive/batch_queue.go index 6a871bc4cf12..8e9dca29473d 100644 --- a/op-node/rollup/derive/batch_queue.go +++ b/op-node/rollup/derive/batch_queue.go @@ -108,6 +108,9 @@ func (bq *BatchQueue) NextBatch(ctx context.Context, parent eth.L2BlockRef) (*Si } // If the epoch is advanced, update bq.l1Blocks + // Advancing epoch must be done after the pipeline successfully apply the entire span batch to the chain. + // Because the span batch can be reverted during processing the batch, then we must preserve existing l1Blocks + // to verify the epochs of the next candidate batch. if len(bq.l1Blocks) > 0 && parent.L1Origin.Number > bq.l1Blocks[0].Number { for i, l1Block := range bq.l1Blocks { if parent.L1Origin.Number == l1Block.Number { From 249d9e78740b222b7f202b7d3915bd88b8c660fa Mon Sep 17 00:00:00 2001 From: Tei Im Date: Mon, 30 Oct 2023 19:44:08 +0900 Subject: [PATCH 262/374] batches_test refactoring Support log based test for batch validation rules Add more test cases for span batch --- op-node/rollup/derive/batches.go | 4 +- op-node/rollup/derive/batches_test.go | 735 ++++++++++++++------------ 2 files changed, 407 insertions(+), 332 deletions(-) diff --git a/op-node/rollup/derive/batches.go b/op-node/rollup/derive/batches.go index ee64eda4519c..622d4bc2068f 100644 --- a/op-node/rollup/derive/batches.go +++ b/op-node/rollup/derive/batches.go @@ -199,11 +199,11 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B if batch.GetTimestamp() < nextTimestamp { if batch.GetTimestamp() > l2SafeHead.Time { // batch timestamp cannot be between safe head and next timestamp - log.Warn("batch has misaligned timestamp") + log.Warn("batch has misaligned timestamp, block time is too short") return BatchDrop } if (l2SafeHead.Time-batch.GetTimestamp())%cfg.BlockTime != 0 { - log.Warn("batch has misaligned timestamp") + log.Warn("batch has misaligned timestamp, not overlapped exactly") return BatchDrop } parentNum = l2SafeHead.Number - (l2SafeHead.Time-batch.GetTimestamp())/cfg.BlockTime - 1 diff --git a/op-node/rollup/derive/batches_test.go b/op-node/rollup/derive/batches_test.go index a3948fa1a27a..25934f0acd2b 100644 --- a/op-node/rollup/derive/batches_test.go +++ b/op-node/rollup/derive/batches_test.go @@ -1,10 +1,12 @@ package derive import ( + "bytes" "context" "errors" "math/big" "math/rand" + "strings" "testing" "github.com/stretchr/testify/require" @@ -20,27 +22,31 @@ import ( ) type ValidBatchTestCase struct { - Name string - L1Blocks []eth.L1BlockRef - L2SafeHead eth.L2BlockRef - Batch BatchWithL1InclusionBlock - Expected BatchValidity + Name string + L1Blocks []eth.L1BlockRef + L2SafeHead eth.L2BlockRef + Batch BatchWithL1InclusionBlock + Expected BatchValidity + ExpectedLog string // log message that must be included + NotExpectedLog string // log message that must not be included + SpanBatchTime *uint64 } -type SpanBatchHardForkTestCase struct { - Name string - L1Blocks []eth.L1BlockRef - L2SafeHead eth.L2BlockRef - Batch BatchWithL1InclusionBlock - Expected BatchValidity - SpanBatchTime uint64 +type TestLogHandler struct { + handler log.Handler + logs *bytes.Buffer +} + +func (th *TestLogHandler) Log(r *log.Record) error { + th.logs.WriteString(r.Msg + "\n") + return th.handler.Log(r) } var HashA = common.Hash{0x0a} var HashB = common.Hash{0x0b} -func TestValidSingularBatch(t *testing.T) { - conf := rollup.Config{ +func TestValidBatch(t *testing.T) { + defaultConf := rollup.Config{ Genesis: rollup.Genesis{ L2Time: 31, // a genesis time that itself does not align to make it more interesting }, @@ -48,9 +54,17 @@ func TestValidSingularBatch(t *testing.T) { SeqWindowSize: 4, MaxSequencerDrift: 6, // other config fields are ignored and can be left empty. + SpanBatchTime: nil, } rng := rand.New(rand.NewSource(1234)) + + minTs := uint64(0) + chainId := new(big.Int).SetUint64(rng.Uint64()) + signer := types.NewLondonSigner(chainId) + randTx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) + randTxData, _ := randTx.MarshalBinary() + l1A := testutils.RandomBlockRef(rng) l1B := eth.L1BlockRef{ Hash: testutils.RandomHash(rng), @@ -96,7 +110,7 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: l2A0.Number + 1, ParentHash: l2A0.Hash, - Time: l2A0.Time + conf.BlockTime, + Time: l2A0.Time + defaultConf.BlockTime, L1Origin: l1A.ID(), SequenceNumber: 1, } @@ -105,7 +119,7 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: l2A1.Number + 1, ParentHash: l2A1.Hash, - Time: l2A1.Time + conf.BlockTime, + Time: l2A1.Time + defaultConf.BlockTime, L1Origin: l1A.ID(), SequenceNumber: 2, } @@ -114,7 +128,7 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: l2A2.Number + 1, ParentHash: l2A2.Hash, - Time: l2A2.Time + conf.BlockTime, + Time: l2A2.Time + defaultConf.BlockTime, L1Origin: l1A.ID(), SequenceNumber: 3, } @@ -123,11 +137,29 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: l2A3.Number + 1, ParentHash: l2A3.Hash, - Time: l2A3.Time + conf.BlockTime, // 8 seconds larger than l1A0, 1 larger than origin + Time: l2A3.Time + defaultConf.BlockTime, // 8 seconds larger than l1A0, 1 larger than origin L1Origin: l1B.ID(), SequenceNumber: 0, } + l2B1 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2B0.Number + 1, + ParentHash: l2B0.Hash, + Time: l2B0.Time + defaultConf.BlockTime, + L1Origin: l1B.ID(), + SequenceNumber: 1, + } + + l2B2 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2B1.Number + 1, + ParentHash: l2B1.Hash, + Time: l2B1.Time + defaultConf.BlockTime, + L1Origin: l1B.ID(), + SequenceNumber: 1, + } + l1X := eth.L1BlockRef{ Hash: testutils.RandomHash(rng), Number: 42, @@ -150,7 +182,7 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: 1000, ParentHash: testutils.RandomHash(rng), - Time: 10_000 + 12 + 6 - 1, // add one block, and you get ahead of next l1 block by more than the drift + Time: 10_000 + 24 + 6 - 1, // add one block, and you get ahead of next l1 block by more than the drift L1Origin: l1X.ID(), SequenceNumber: 0, } @@ -158,16 +190,24 @@ func TestValidSingularBatch(t *testing.T) { Hash: testutils.RandomHash(rng), Number: l2X0.Number + 1, ParentHash: l2X0.Hash, - Time: l2X0.Time + conf.BlockTime, // exceeds sequencer time drift, forced to be empty block + Time: l2X0.Time + defaultConf.BlockTime, // exceeds sequencer time drift, forced to be empty block L1Origin: l1Y.ID(), SequenceNumber: 0, } + l2Z0 := eth.L2BlockRef{ + Hash: testutils.RandomHash(rng), + Number: l2Y0.Number + 1, + ParentHash: l2Y0.Hash, + Time: l2Y0.Time + defaultConf.BlockTime, // exceeds sequencer time drift, forced to be empty block + L1Origin: l1Z.ID(), + SequenceNumber: 0, + } l2A4 := eth.L2BlockRef{ Hash: testutils.RandomHash(rng), Number: l2A3.Number + 1, ParentHash: l2A3.Hash, - Time: l2A3.Time + conf.BlockTime, // 4*2 = 8, higher than seq time drift + Time: l2A3.Time + defaultConf.BlockTime, // 4*2 = 8, higher than seq time drift L1Origin: l1A.ID(), SequenceNumber: 4, } @@ -179,7 +219,7 @@ func TestValidSingularBatch(t *testing.T) { Time: l2A4.Time + 1, // too late for l2A4 to adopt yet } - testCases := []ValidBatchTestCase{ + singularBatchTestCases := []ValidBatchTestCase{ { Name: "missing L1 info", L1Blocks: []eth.L1BlockRef{}, @@ -286,7 +326,7 @@ func TestValidSingularBatch(t *testing.T) { ParentHash: l2B0.Hash, // build on top of safe head to continue EpochNum: rollup.Epoch(l2A3.L1Origin.Number), // epoch A is no longer valid EpochHash: l2A3.L1Origin.Hash, - Timestamp: l2B0.Time + conf.BlockTime, // pass the timestamp check to get too epoch check + Timestamp: l2B0.Time + defaultConf.BlockTime, // pass the timestamp check to get too epoch check Transactions: nil, }, }, @@ -520,173 +560,14 @@ func TestValidSingularBatch(t *testing.T) { ParentHash: l2A2.Hash, EpochNum: rollup.Epoch(l2B0.L1Origin.Number), EpochHash: l2B0.L1Origin.Hash, - Timestamp: l2A2.Time + conf.BlockTime, + Timestamp: l2A2.Time + defaultConf.BlockTime, Transactions: nil, }, }, Expected: BatchDrop, }, } - - // Log level can be increased for debugging purposes - logger := testlog.Logger(t, log.LvlError) - - for _, testCase := range testCases { - t.Run(testCase.Name, func(t *testing.T) { - ctx := context.Background() - validity := CheckBatch(ctx, &conf, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, nil) - require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") - }) - } -} - -func TestValidSpanBatch(t *testing.T) { - minTs := uint64(0) - conf := rollup.Config{ - Genesis: rollup.Genesis{ - L2Time: 31, // a genesis time that itself does not align to make it more interesting - }, - BlockTime: 2, - SeqWindowSize: 4, - MaxSequencerDrift: 6, - SpanBatchTime: &minTs, - // other config fields are ignored and can be left empty. - } - - rng := rand.New(rand.NewSource(1234)) - chainId := new(big.Int).SetUint64(rng.Uint64()) - signer := types.NewLondonSigner(chainId) - randTx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - randTxData, _ := randTx.MarshalBinary() - l1A := testutils.RandomBlockRef(rng) - l1B := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1A.Number + 1, - ParentHash: l1A.Hash, - Time: l1A.Time + 7, - } - l1C := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1B.Number + 1, - ParentHash: l1B.Hash, - Time: l1B.Time + 7, - } - l1D := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1C.Number + 1, - ParentHash: l1C.Hash, - Time: l1C.Time + 7, - } - l1E := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1D.Number + 1, - ParentHash: l1D.Hash, - Time: l1D.Time + 7, - } - l1F := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1E.Number + 1, - ParentHash: l1E.Hash, - Time: l1E.Time + 7, - } - - l2A0 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: 100, - ParentHash: testutils.RandomHash(rng), - Time: l1A.Time, - L1Origin: l1A.ID(), - SequenceNumber: 0, - } - - l2A1 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A0.Number + 1, - ParentHash: l2A0.Hash, - Time: l2A0.Time + conf.BlockTime, - L1Origin: l1A.ID(), - SequenceNumber: 1, - } - - l2A2 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A1.Number + 1, - ParentHash: l2A1.Hash, - Time: l2A1.Time + conf.BlockTime, - L1Origin: l1A.ID(), - SequenceNumber: 2, - } - - l2A3 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A2.Number + 1, - ParentHash: l2A2.Hash, - Time: l2A2.Time + conf.BlockTime, - L1Origin: l1A.ID(), - SequenceNumber: 3, - } - - l2B0 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A3.Number + 1, - ParentHash: l2A3.Hash, - Time: l2A3.Time + conf.BlockTime, // 8 seconds larger than l1A0, 1 larger than origin - L1Origin: l1B.ID(), - SequenceNumber: 0, - } - - l1X := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: 42, - ParentHash: testutils.RandomHash(rng), - Time: 10_000, - } - l1Y := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1X.Number + 1, - ParentHash: l1X.Hash, - Time: l1X.Time + 12, - } - l1Z := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1Y.Number + 1, - ParentHash: l1Y.Hash, - Time: l1Y.Time + 12, - } - l2X0 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: 1000, - ParentHash: testutils.RandomHash(rng), - Time: 10_000 + 12 + 6 - 1, // add one block, and you get ahead of next l1 block by more than the drift - L1Origin: l1X.ID(), - SequenceNumber: 0, - } - l2Y0 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2X0.Number + 1, - ParentHash: l2X0.Hash, - Time: l2X0.Time + conf.BlockTime, // exceeds sequencer time drift, forced to be empty block - L1Origin: l1Y.ID(), - SequenceNumber: 0, - } - - l2A4 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A3.Number + 1, - ParentHash: l2A3.Hash, - Time: l2A3.Time + conf.BlockTime, // 4*2 = 8, higher than seq time drift - L1Origin: l1A.ID(), - SequenceNumber: 4, - } - - l1BLate := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1A.Number + 1, - ParentHash: l1A.Hash, - Time: l2A4.Time + 1, // too late for l2A4 to adopt yet - } - - testCases := []ValidBatchTestCase{ + spanBatchTestCases := []ValidBatchTestCase{ { Name: "missing L1 info", L1Blocks: []eth.L1BlockRef{}, @@ -703,7 +584,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchUndecided, + Expected: BatchUndecided, + ExpectedLog: "missing L1 block input, cannot proceed with batch checking", + SpanBatchTime: &minTs, }, { Name: "future timestamp", @@ -721,25 +604,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchFuture, - }, - { - Name: "old timestamp", - L1Blocks: []eth.L1BlockRef{l1A, l1B, l1C}, - L2SafeHead: l2A0, - Batch: BatchWithL1InclusionBlock{ - L1InclusionBlock: l1B, - Batch: NewSpanBatch([]*SingularBatch{ - { - ParentHash: l2A1.ParentHash, - EpochNum: rollup.Epoch(l2A1.L1Origin.Number), - EpochHash: l2A1.L1Origin.Hash, - Timestamp: l2A0.Time, // repeating the same time - Transactions: nil, - }, - }), - }, - Expected: BatchDrop, + Expected: BatchFuture, + ExpectedLog: "received out-of-order batch for future processing after next batch", + SpanBatchTime: &minTs, }, { Name: "misaligned timestamp", @@ -757,7 +624,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "span batch has no new blocks after safe head", + SpanBatchTime: &minTs, }, { Name: "invalid parent block hash", @@ -775,7 +644,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "ignoring batch with mismatching parent hash", + SpanBatchTime: &minTs, }, { Name: "sequence window expired", @@ -793,7 +664,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch was included too late, sequence window expired", + SpanBatchTime: &minTs, }, { Name: "epoch too old, but good parent hash and timestamp", // repeat of now outdated l2A3 data @@ -806,18 +679,20 @@ func TestValidSpanBatch(t *testing.T) { ParentHash: l2B0.Hash, // build on top of safe head to continue EpochNum: rollup.Epoch(l2A3.L1Origin.Number), // epoch A is no longer valid EpochHash: l2A3.L1Origin.Hash, - Timestamp: l2B0.Time + conf.BlockTime, // pass the timestamp check to get too epoch check + Timestamp: l2B0.Time + defaultConf.BlockTime, // pass the timestamp check to get too epoch check Transactions: nil, }, { EpochNum: rollup.Epoch(l1B.Number), EpochHash: l1B.Hash, // pass the l1 origin check - Timestamp: l2B0.Time + conf.BlockTime*2, + Timestamp: l2B0.Time + defaultConf.BlockTime*2, Transactions: nil, }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "dropped batch, epoch is too old", + SpanBatchTime: &minTs, }, { Name: "insufficient L1 info for eager derivation", @@ -835,7 +710,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchUndecided, + Expected: BatchUndecided, + ExpectedLog: "need more l1 blocks to check entire origins of span batch", + SpanBatchTime: &minTs, }, { Name: "epoch too new", @@ -853,7 +730,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch is for future epoch too far ahead, while it has the next timestamp, so it must be invalid", + SpanBatchTime: &minTs, }, { Name: "epoch hash wrong", @@ -871,7 +750,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch is for different L1 chain, epoch hash does not match", + SpanBatchTime: &minTs, }, { Name: "epoch hash wrong - long span", @@ -896,7 +777,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch is for different L1 chain, epoch hash does not match", + SpanBatchTime: &minTs, }, { Name: "sequencer time drift on same epoch with non-empty txs", @@ -914,7 +797,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch exceeded sequencer time drift, sequencer must adopt new L1 origin to include transactions again", + SpanBatchTime: &minTs, }, { Name: "sequencer time drift on same epoch with non-empty txs - long span", @@ -939,7 +824,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch exceeded sequencer time drift, sequencer must adopt new L1 origin to include transactions again", + SpanBatchTime: &minTs, }, { Name: "sequencer time drift on changing epoch with non-empty txs", @@ -957,7 +844,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "batch exceeded sequencer time drift, sequencer must adopt new L1 origin to include transactions again", + SpanBatchTime: &minTs, }, { Name: "sequencer time drift on same epoch with empty txs and late next epoch", @@ -975,7 +864,8 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchAccept, // accepted because empty & preserving L2 time invariant + Expected: BatchAccept, // accepted because empty & preserving L2 time invariant + SpanBatchTime: &minTs, }, { Name: "sequencer time drift on changing epoch with empty txs", @@ -991,9 +881,18 @@ func TestValidSpanBatch(t *testing.T) { Timestamp: l2Y0.Time, // valid, but more than 6 ahead of l1Y.Time Transactions: nil, }, + { + ParentHash: l2Z0.ParentHash, + EpochNum: rollup.Epoch(l2Z0.L1Origin.Number), + EpochHash: l2Z0.L1Origin.Hash, + Timestamp: l2Z0.Time, // valid, but more than 6 ahead of l1Y.Time + Transactions: nil, + }, }), }, - Expected: BatchAccept, // accepted because empty & still advancing epoch + Expected: BatchAccept, // accepted because empty & still advancing epoch + SpanBatchTime: &minTs, + NotExpectedLog: "continuing with empty batch before late L1 block to preserve L2 time invariant", }, { Name: "sequencer time drift on same epoch with empty txs and no next epoch in sight yet", @@ -1011,7 +910,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time + Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time + ExpectedLog: "without the next L1 origin we cannot determine yet if this empty batch that exceeds the time drift is still valid", + SpanBatchTime: &minTs, }, { Name: "sequencer time drift on same epoch with empty txs and no next epoch in sight yet - long span", @@ -1036,7 +937,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time + Expected: BatchUndecided, // we have to wait till the next epoch is in sight to check the time + ExpectedLog: "without the next L1 origin we cannot determine yet if this empty batch that exceeds the time drift is still valid", + SpanBatchTime: &minTs, }, { Name: "sequencer time drift on same epoch with empty txs and but in-sight epoch that invalidates it", @@ -1054,7 +957,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, // dropped because it could have advanced the epoch to B + Expected: BatchDrop, // dropped because it could have advanced the epoch to B + ExpectedLog: "batch exceeded sequencer time drift without adopting next origin, and next L1 origin would have been valid", + SpanBatchTime: &minTs, }, { Name: "sequencer time drift on same epoch with empty txs and but in-sight epoch that invalidates it - long span", @@ -1079,7 +984,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, // dropped because it could have advanced the epoch to B + Expected: BatchDrop, // dropped because it could have advanced the epoch to B + ExpectedLog: "batch exceeded sequencer time drift without adopting next origin, and next L1 origin would have been valid", + SpanBatchTime: &minTs, }, { Name: "empty tx included", @@ -1099,7 +1006,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "transaction data must not be empty, but found empty tx", + SpanBatchTime: &minTs, }, { Name: "deposit tx included", @@ -1119,7 +1028,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "sequencers may not embed any deposits into batch data, but found tx that has one", + SpanBatchTime: &minTs, }, { Name: "valid batch same epoch", @@ -1137,7 +1048,8 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchAccept, + Expected: BatchAccept, + SpanBatchTime: &minTs, }, { Name: "valid batch changing epoch", @@ -1155,7 +1067,8 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchAccept, + Expected: BatchAccept, + SpanBatchTime: &minTs, }, { Name: "batch with L2 time before L1 time", @@ -1168,12 +1081,14 @@ func TestValidSpanBatch(t *testing.T) { ParentHash: l2A2.Hash, EpochNum: rollup.Epoch(l2B0.L1Origin.Number), EpochHash: l2B0.L1Origin.Hash, - Timestamp: l2A2.Time + conf.BlockTime, + Timestamp: l2A2.Time + defaultConf.BlockTime, Transactions: nil, }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "block timestamp is less than L1 origin timestamp", + SpanBatchTime: &minTs, }, { Name: "batch with L2 time before L1 time - long span", @@ -1193,12 +1108,14 @@ func TestValidSpanBatch(t *testing.T) { ParentHash: l2A2.Hash, EpochNum: rollup.Epoch(l2B0.L1Origin.Number), EpochHash: l2B0.L1Origin.Hash, - Timestamp: l2A2.Time + conf.BlockTime, + Timestamp: l2A2.Time + defaultConf.BlockTime, Transactions: nil, }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "block timestamp is less than L1 origin timestamp", + SpanBatchTime: &minTs, }, { Name: "valid overlapping batch", @@ -1223,7 +1140,8 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchAccept, + Expected: BatchAccept, + SpanBatchTime: &minTs, }, { Name: "longer overlapping batch", @@ -1255,7 +1173,8 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchAccept, + Expected: BatchAccept, + SpanBatchTime: &minTs, }, { Name: "fully overlapping batch", @@ -1280,7 +1199,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "span batch has no new blocks after safe head", + SpanBatchTime: &minTs, }, { Name: "overlapping batch with invalid parent hash", @@ -1305,7 +1226,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "ignoring batch with mismatching parent hash", + SpanBatchTime: &minTs, }, { Name: "overlapping batch with invalid origin number", @@ -1330,7 +1253,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "overlapped block's L1 origin number does not match", + SpanBatchTime: &minTs, }, { Name: "overlapping batch with invalid tx", @@ -1355,7 +1280,9 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchDrop, + Expected: BatchDrop, + ExpectedLog: "overlapped block's tx count does not match", + SpanBatchTime: &minTs, }, { Name: "overlapping batch l2 fetcher error", @@ -1387,89 +1314,91 @@ func TestValidSpanBatch(t *testing.T) { }, }), }, - Expected: BatchUndecided, + Expected: BatchUndecided, + ExpectedLog: "failed to fetch L2 block", + SpanBatchTime: &minTs, }, - } - - // Log level can be increased for debugging purposes - logger := testlog.Logger(t, log.LvlError) - - l2Client := testutils.MockL2Client{} - var nilErr error - // will be return error for block #99 (parent of l2A0) - tempErr := errors.New("temp error") - l2Client.Mock.On("L2BlockRefByNumber", l2A0.Number-1).Times(9999).Return(eth.L2BlockRef{}, &tempErr) - l2Client.Mock.On("PayloadByNumber", l2A0.Number-1).Times(9999).Return(nil, &tempErr) - - // make payloads for L2 blocks and set as expected return value of MockL2Client - for _, l2Block := range []eth.L2BlockRef{l2A0, l2A1, l2A2, l2A3, l2A4, l2B0} { - l2Client.ExpectL2BlockRefByNumber(l2Block.Number, l2Block, nil) - txData := l1InfoDepositTx(t, l2Block.L1Origin.Number) - payload := eth.ExecutionPayload{ - ParentHash: l2Block.ParentHash, - BlockNumber: hexutil.Uint64(l2Block.Number), - Timestamp: hexutil.Uint64(l2Block.Time), - BlockHash: l2Block.Hash, - Transactions: []hexutil.Bytes{txData}, - } - l2Client.Mock.On("L2BlockRefByNumber", l2Block.Number).Times(9999).Return(l2Block, &nilErr) - l2Client.Mock.On("PayloadByNumber", l2Block.Number).Times(9999).Return(&payload, &nilErr) - } - - for _, testCase := range testCases { - t.Run(testCase.Name, func(t *testing.T) { - ctx := context.Background() - validity := CheckBatch(ctx, &conf, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, &l2Client) - require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") - }) - } -} - -func TestSpanBatchHardFork(t *testing.T) { - minTs := uint64(0) - conf := rollup.Config{ - Genesis: rollup.Genesis{ - L2Time: 31, // a genesis time that itself does not align to make it more interesting + { + Name: "short block time", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A0.Hash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A0.Time + 1, + Transactions: nil, + }, + { + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A1.Time + 1, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + ExpectedLog: "batch has misaligned timestamp, block time is too short", + SpanBatchTime: &minTs, + }, + { + Name: "misaligned batch", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A0, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A0.Hash, + EpochNum: rollup.Epoch(l2A1.L1Origin.Number), + EpochHash: l2A1.L1Origin.Hash, + Timestamp: l2A0.Time - 1, + Transactions: nil, + }, + { + ParentHash: l2A1.Hash, + EpochNum: rollup.Epoch(l2A2.L1Origin.Number), + EpochHash: l2A2.L1Origin.Hash, + Timestamp: l2A1.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + ExpectedLog: "batch has misaligned timestamp, not overlapped exactly", + SpanBatchTime: &minTs, + }, + { + Name: "failed to fetch overlapping block payload", + L1Blocks: []eth.L1BlockRef{l1A, l1B}, + L2SafeHead: l2A3, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A2.Hash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + { + ParentHash: l2A3.Hash, + EpochNum: rollup.Epoch(l2B0.L1Origin.Number), + EpochHash: l2B0.L1Origin.Hash, + Timestamp: l2B0.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchUndecided, + ExpectedLog: "failed to fetch L2 block payload", + SpanBatchTime: &minTs, }, - BlockTime: 2, - SeqWindowSize: 4, - MaxSequencerDrift: 6, - SpanBatchTime: &minTs, - // other config fields are ignored and can be left empty. - } - - rng := rand.New(rand.NewSource(1234)) - chainId := new(big.Int).SetUint64(rng.Uint64()) - signer := types.NewLondonSigner(chainId) - randTx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) - randTxData, _ := randTx.MarshalBinary() - l1A := testutils.RandomBlockRef(rng) - l1B := eth.L1BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l1A.Number + 1, - ParentHash: l1A.Hash, - Time: l1A.Time + 7, - } - - l2A0 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: 100, - ParentHash: testutils.RandomHash(rng), - Time: l1A.Time, - L1Origin: l1A.ID(), - SequenceNumber: 0, - } - - l2A1 := eth.L2BlockRef{ - Hash: testutils.RandomHash(rng), - Number: l2A0.Number + 1, - ParentHash: l2A0.Hash, - Time: l2A0.Time + conf.BlockTime, - L1Origin: l1A.ID(), - SequenceNumber: 1, - } - - testCases := []SpanBatchHardForkTestCase{ { Name: "singular batch before hard fork", L1Blocks: []eth.L1BlockRef{l1A, l1B}, @@ -1484,7 +1413,7 @@ func TestSpanBatchHardFork(t *testing.T) { Transactions: []hexutil.Bytes{randTxData}, }, }, - SpanBatchTime: l2A1.Time + 2, + SpanBatchTime: &l2A2.Time, Expected: BatchAccept, }, { @@ -1503,7 +1432,7 @@ func TestSpanBatchHardFork(t *testing.T) { }, }), }, - SpanBatchTime: l2A1.Time + 2, + SpanBatchTime: &l2A2.Time, Expected: BatchDrop, }, { @@ -1520,7 +1449,7 @@ func TestSpanBatchHardFork(t *testing.T) { Transactions: []hexutil.Bytes{randTxData}, }, }, - SpanBatchTime: l2A1.Time - 2, + SpanBatchTime: &l2A0.Time, Expected: BatchAccept, }, { @@ -1539,21 +1468,167 @@ func TestSpanBatchHardFork(t *testing.T) { }, }), }, - SpanBatchTime: l2A1.Time - 2, + SpanBatchTime: &l2A0.Time, Expected: BatchAccept, }, } // Log level can be increased for debugging purposes - logger := testlog.Logger(t, log.LvlInfo) + logger := testlog.Logger(t, log.LvlError) + + // Create a test log handler to check expected logs + var logBuf bytes.Buffer + handler := TestLogHandler{handler: logger.GetHandler(), logs: &logBuf} + logger.SetHandler(&handler) + + l2Client := testutils.MockL2Client{} + var nilErr error + tempErr := errors.New("temp error") + // will return an error for block #99 (parent of l2A0) + l2Client.Mock.On("L2BlockRefByNumber", l2A0.Number-1).Return(eth.L2BlockRef{}, &tempErr) + // will return an error for l2A3 + l2Client.Mock.On("PayloadByNumber", l2A3.Number).Return(ð.ExecutionPayload{}, &tempErr) + + // make payloads for L2 blocks and set as expected return value of MockL2Client + for _, l2Block := range []eth.L2BlockRef{l2A0, l2A1, l2A2, l2B0} { + l2Client.ExpectL2BlockRefByNumber(l2Block.Number, l2Block, nil) + txData := l1InfoDepositTx(t, l2Block.L1Origin.Number) + payload := eth.ExecutionPayload{ + ParentHash: l2Block.ParentHash, + BlockNumber: hexutil.Uint64(l2Block.Number), + Timestamp: hexutil.Uint64(l2Block.Time), + BlockHash: l2Block.Hash, + Transactions: []hexutil.Bytes{txData}, + } + l2Client.Mock.On("L2BlockRefByNumber", l2Block.Number).Return(l2Block, &nilErr) + l2Client.Mock.On("PayloadByNumber", l2Block.Number).Return(&payload, &nilErr) + } - for _, testCase := range testCases { - t.Run(testCase.Name, func(t *testing.T) { - rcfg := conf - rcfg.SpanBatchTime = &testCase.SpanBatchTime - ctx := context.Background() - validity := CheckBatch(ctx, &rcfg, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, nil) - require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") + runTestCase := func(t *testing.T, testCase ValidBatchTestCase) { + ctx := context.Background() + rcfg := defaultConf + if testCase.SpanBatchTime != nil { + rcfg.SpanBatchTime = testCase.SpanBatchTime + } + validity := CheckBatch(ctx, &rcfg, logger, testCase.L1Blocks, testCase.L2SafeHead, &testCase.Batch, &l2Client) + require.Equal(t, testCase.Expected, validity, "batch check must return expected validity level") + if testCase.ExpectedLog != "" { + // Check if ExpectedLog is contained in the log buffer + if !strings.Contains(logBuf.String(), testCase.ExpectedLog) { + t.Errorf("Expected log message was not found in the buffer: %s", testCase.ExpectedLog) + } + } + if testCase.NotExpectedLog != "" { + // Check if NotExpectedLog is contained in the log buffer + if strings.Contains(logBuf.String(), testCase.NotExpectedLog) { + t.Errorf("Not expected log message was found in the buffer: %s", testCase.NotExpectedLog) + } + } + logBuf.Reset() + } + + // Run singular batch test cases + for _, testCase := range singularBatchTestCases { + t.Run("singular_"+testCase.Name, func(t *testing.T) { + runTestCase(t, testCase) }) } + + // Run span batch test cases + for _, testCase := range spanBatchTestCases { + t.Run("span_"+testCase.Name, func(t *testing.T) { + runTestCase(t, testCase) + }) + } + + // ====== Test different TX for overlapping batches ====== + l2Client.ExpectL2BlockRefByNumber(l2B1.Number, l2B1, nil) + txData := l1InfoDepositTx(t, l2B1.L1Origin.Number) + randTx = testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) + randTxData, _ = randTx.MarshalBinary() + payload := eth.ExecutionPayload{ + ParentHash: l2B0.Hash, + BlockNumber: hexutil.Uint64(l2B1.Number), + Timestamp: hexutil.Uint64(l2B1.Time), + BlockHash: l2B1.Hash, + Transactions: []hexutil.Bytes{txData, randTxData}, + } + l2Client.Mock.On("PayloadByNumber", l2B1.Number).Return(&payload, &nilErr).Once() + + randTx = testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) + randTxData, _ = randTx.MarshalBinary() + differentTxtestCase := ValidBatchTestCase{ + Name: "different_tx_overlapping_batch", + L1Blocks: []eth.L1BlockRef{l1B}, + L2SafeHead: l2B1, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2B0.Hash, + EpochNum: rollup.Epoch(l2B1.L1Origin.Number), + EpochHash: l2B1.L1Origin.Hash, + Timestamp: l2B1.Time, + Transactions: []hexutil.Bytes{randTxData}, // Random generated TX that does not match overlapping block + }, + { + ParentHash: l2B1.Hash, + EpochNum: rollup.Epoch(l2B2.L1Origin.Number), + EpochHash: l2B2.L1Origin.Hash, + Timestamp: l2B2.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + ExpectedLog: "overlapped block's transaction does not match", + SpanBatchTime: &minTs, + } + + t.Run(differentTxtestCase.Name, func(t *testing.T) { + runTestCase(t, differentTxtestCase) + }) + + // ====== Test invalid TX for overlapping batches ====== + payload = eth.ExecutionPayload{ + ParentHash: l2B0.Hash, + BlockNumber: hexutil.Uint64(l2B1.Number), + Timestamp: hexutil.Uint64(l2B1.Time), + BlockHash: l2B1.Hash, + // First TX is not a deposit TX. it will make error when extracting L2BlockRef from the payload + Transactions: []hexutil.Bytes{randTxData}, + } + l2Client.Mock.On("PayloadByNumber", l2B1.Number).Return(&payload, &nilErr).Once() + + invalidTxTestCase := ValidBatchTestCase{ + Name: "invalid_tx_overlapping_batch", + L1Blocks: []eth.L1BlockRef{l1B}, + L2SafeHead: l2B1, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1B, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2B0.Hash, + EpochNum: rollup.Epoch(l2B1.L1Origin.Number), + EpochHash: l2B1.L1Origin.Hash, + Timestamp: l2B1.Time, + Transactions: []hexutil.Bytes{randTxData}, + }, + { + ParentHash: l2B1.Hash, + EpochNum: rollup.Epoch(l2B2.L1Origin.Number), + EpochHash: l2B2.L1Origin.Hash, + Timestamp: l2B2.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchDrop, + ExpectedLog: "failed to extract L2BlockRef from execution payload", + SpanBatchTime: &minTs, + } + + t.Run(invalidTxTestCase.Name, func(t *testing.T) { + runTestCase(t, invalidTxTestCase) + }) } From 590ec9b9094cd9a9bbe77ed8cfc069b0a060b20a Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 31 Oct 2023 18:05:44 +0300 Subject: [PATCH 263/374] ci: solc building requires xlarge Modularize out a small change from https://github.com/ethereum-optimism/optimism/pull/7928 where any `forge build` runs oom unless at least an `xlarge` box is used in circleci. As we have added more contracts to the repo, building the contracts has consumed more and more CPU/memory. The deploy script is quite large and uses a lot of memory, so adding it to our tests makes the tests use more memory. I have not noticed the tests taking a longer time to run locally. We could also do a better job at encapsulating where solc builds happen such that it only happens once and the results are cached as much as possible. Making the boxes bigger in the meantime works, as it should also speed up CI for the tasks where the boxes are made bigger. --- .circleci/config.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9804389292ee..79dfbdfdd5e2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -433,7 +433,7 @@ jobs: contracts-bedrock-slither: docker: - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - resource_class: large + resource_class: xlarge steps: - checkout - check-changed: @@ -446,6 +446,7 @@ jobs: contracts-bedrock-validate-spaces: docker: - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + resource_class: xlarge steps: - checkout - attach_workspace: { at: "." } @@ -467,7 +468,7 @@ jobs: op-bindings-build: docker: - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - resource_class: large + resource_class: xlarge steps: - checkout - run: @@ -876,7 +877,7 @@ jobs: docker: - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - image: cimg/postgres:14.1 - resource_class: large + resource_class: xlarge steps: - checkout - check-changed: @@ -952,6 +953,7 @@ jobs: devnet-allocs: docker: - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest + resource_class: xlarge steps: - checkout - restore_cache: From e4b6580b22dadb8750728f3d70d9227bc7e114cb Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 31 Oct 2023 18:17:41 +0300 Subject: [PATCH 264/374] contracts-bedrock: simplify safecall test Modularizes out a bit from https://github.com/ethereum-optimism/optimism/pull/7928 where the `SafeCall` test doesn't require `CommonTest` but instead can just use `Test`. This simplifies the `setUp` and should reduce the amount of computation required to set up the tests. This also reduces the need to use `vm.assume` to ignore contracts that are deployed as part of the `CommonTest` setup. --- packages/contracts-bedrock/.gas-snapshot | 2 +- packages/contracts-bedrock/test/SafeCall.t.sol | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 06d5f60a3ad8..89f86297e5af 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -672,7 +672,7 @@ ResourceMetering_Test:test_meter_updateTwoEmptyBlocks_succeeds() (gas: 23703) ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20020816) ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 19549) SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1021670598) -SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1095190710) +SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1095190688) Semver_Test:test_behindProxy_succeeds() (gas: 507558) Semver_Test:test_version_succeeds() (gas: 9418) SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 78333) diff --git a/packages/contracts-bedrock/test/SafeCall.t.sol b/packages/contracts-bedrock/test/SafeCall.t.sol index 550e7dd982b4..36690e4de376 100644 --- a/packages/contracts-bedrock/test/SafeCall.t.sol +++ b/packages/contracts-bedrock/test/SafeCall.t.sol @@ -2,12 +2,12 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; // Target contract import { SafeCall } from "src/libraries/SafeCall.sol"; -contract SafeCall_Test is CommonTest { +contract SafeCall_Test is Test { /// @dev Tests that the `send` function succeeds. function testFuzz_send_succeeds(address from, address to, uint256 gas, uint64 value) external { vm.assume(from.balance == 0); @@ -21,8 +21,7 @@ contract SafeCall_Test is CommonTest { vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67)); // don't call the create2 deployer vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C)); - // don't call the ffi interface - vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f)); + vm.assume(to != address(this)); assertEq(from.balance, 0, "from balance is 0"); vm.deal(from, value); @@ -56,8 +55,7 @@ contract SafeCall_Test is CommonTest { vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67)); // don't call the create2 deployer vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C)); - // don't call the ffi interface - vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f)); + vm.assume(to != address(this)); assertEq(from.balance, 0, "from balance is 0"); vm.deal(from, value); @@ -99,8 +97,7 @@ contract SafeCall_Test is CommonTest { vm.assume(to != address(0x000000000000000000636F6e736F6c652e6c6f67)); // don't call the create2 deployer vm.assume(to != address(0x4e59b44847b379578588920cA78FbF26c0B4956C)); - // don't call the FFIInterface - vm.assume(to != address(0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f)); + vm.assume(to != address(this)); assertEq(from.balance, 0, "from balance is 0"); vm.deal(from, value); From 3468586d3bbe947f7be2b515c164cba2d9e9a5d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 15:18:50 +0000 Subject: [PATCH 265/374] build(deps-dev): bump typedoc from 0.25.2 to 0.25.3 Bumps [typedoc](https://github.com/TypeStrong/TypeDoc) from 0.25.2 to 0.25.3. - [Release notes](https://github.com/TypeStrong/TypeDoc/releases) - [Changelog](https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md) - [Commits](https://github.com/TypeStrong/TypeDoc/compare/v0.25.2...v0.25.3) --- updated-dependencies: - dependency-name: typedoc dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/sdk/package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 207ff6a90704..52bf429c5fad 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -54,7 +54,7 @@ "mocha": "^10.2.0", "nyc": "^15.1.0", "ts-node": "^10.9.1", - "typedoc": "^0.25.2", + "typedoc": "^0.25.3", "typescript": "^5.2.2", "viem": "^1.18.1", "vitest": "^0.34.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85cbb8be2889..882aa1e8a2f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -523,8 +523,8 @@ importers: specifier: ^10.9.1 version: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) typedoc: - specifier: ^0.25.2 - version: 0.25.2(typescript@5.2.2) + specifier: ^0.25.3 + version: 0.25.3(typescript@5.2.2) typescript: specifier: ^5.2.2 version: 5.2.2 @@ -14019,8 +14019,8 @@ packages: dependencies: is-typedarray: 1.0.0 - /typedoc@0.25.2(typescript@5.2.2): - resolution: {integrity: sha512-286F7BeATBiWe/qC4PCOCKlSTwfnsLbC/4cZ68oGBbvAqb9vV33quEOXx7q176OXotD+JdEerdQ1OZGJ818lnA==} + /typedoc@0.25.3(typescript@5.2.2): + resolution: {integrity: sha512-Ow8Bo7uY1Lwy7GTmphRIMEo6IOZ+yYUyrc8n5KXIZg1svpqhZSWgni2ZrDhe+wLosFS8yswowUzljTAV/3jmWw==} engines: {node: '>= 16'} hasBin: true peerDependencies: From ebe2f2ff9d34f92cfba137581a866d2204d91a91 Mon Sep 17 00:00:00 2001 From: protolambda Date: Tue, 31 Oct 2023 18:34:10 +0100 Subject: [PATCH 266/374] indexer: refactor service lifecycle to start/stop resoures more cleanly --- indexer/api/api.go | 208 ++++++++++++++------------ indexer/api/api_test.go | 36 ++++- indexer/api/config.go | 61 ++++++++ indexer/cmd/indexer/cli.go | 49 +++--- indexer/e2e_tests/setup.go | 72 ++++----- indexer/etl/etl.go | 99 ++++++------ indexer/etl/l1_etl.go | 187 ++++++++++++++--------- indexer/etl/l2_etl.go | 152 ++++++++++++------- indexer/indexer.go | 281 ++++++++++++++++++++++------------- indexer/node/client.go | 16 +- indexer/node/client_test.go | 7 +- indexer/node/mocks.go | 3 + indexer/processors/bridge.go | 73 +++++++-- 13 files changed, 779 insertions(+), 465 deletions(-) create mode 100644 indexer/api/config.go diff --git a/indexer/api/api.go b/indexer/api/api.go index 37a572515e26..89f63cf4e403 100644 --- a/indexer/api/api.go +++ b/indexer/api/api.go @@ -6,33 +6,24 @@ import ( "fmt" "net" "net/http" - "runtime/debug" "strconv" - "sync" + "sync/atomic" + + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" + "github.com/prometheus/client_golang/prometheus" + + "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/indexer/api/routes" "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/op-service/httputil" "github.com/ethereum-optimism/optimism/op-service/metrics" - "github.com/ethereum/go-ethereum/log" - "github.com/go-chi/chi/v5" - "github.com/go-chi/chi/v5/middleware" - "github.com/prometheus/client_golang/prometheus" ) const ethereumAddressRegex = `^0x[a-fA-F0-9]{40}$` -// Api ... Indexer API struct -// TODO : Structured error responses -type API struct { - log log.Logger - router *chi.Mux - serverConfig config.ServerConfig - metricsConfig config.ServerConfig - metricsRegistry *prometheus.Registry -} - const ( MetricsNamespace = "op_indexer_api" addressParam = "{address:%s}" @@ -45,6 +36,23 @@ const ( WithdrawalsPath = "/api/v0/withdrawals/" ) +// Api ... Indexer API struct +// TODO : Structured error responses +type APIService struct { + log log.Logger + router *chi.Mux + + bv database.BridgeTransfersView + dbClose func() error + + metricsRegistry *prometheus.Registry + + apiServer *httputil.HTTPServer + metricsServer *httputil.HTTPServer + + stopped atomic.Bool +} + // chiMetricsMiddleware ... Injects a metrics recorder into request processing middleware func chiMetricsMiddleware(rec metrics.HTTPRecorder) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { @@ -53,112 +61,116 @@ func chiMetricsMiddleware(rec metrics.HTTPRecorder) func(http.Handler) http.Hand } // NewApi ... Construct a new api instance -func NewApi(logger log.Logger, bv database.BridgeTransfersView, serverConfig config.ServerConfig, metricsConfig config.ServerConfig) *API { - // (1) Initialize dependencies - apiRouter := chi.NewRouter() - h := routes.NewRoutes(logger, bv, apiRouter) - - mr := metrics.NewRegistry() - promRecorder := metrics.NewPromHTTPRecorder(mr, MetricsNamespace) - - // (2) Inject routing middleware - apiRouter.Use(chiMetricsMiddleware(promRecorder)) - apiRouter.Use(middleware.Recoverer) - apiRouter.Use(middleware.Heartbeat(HealthPath)) +func NewApi(ctx context.Context, log log.Logger, cfg *Config) (*APIService, error) { + out := &APIService{log: log, metricsRegistry: metrics.NewRegistry()} + if err := out.initFromConfig(ctx, cfg); err != nil { + return nil, errors.Join(err, out.Stop(ctx)) // close any resources we may have opened already + } + return out, nil +} - // (3) Set GET routes - apiRouter.Get(fmt.Sprintf(DepositsPath+addressParam, ethereumAddressRegex), h.L1DepositsHandler) - apiRouter.Get(fmt.Sprintf(WithdrawalsPath+addressParam, ethereumAddressRegex), h.L2WithdrawalsHandler) +func (a *APIService) initFromConfig(ctx context.Context, cfg *Config) error { + if err := a.initDB(ctx, cfg.DB); err != nil { + return fmt.Errorf("failed to init DB: %w", err) + } + if err := a.startMetricsServer(cfg.MetricsServer); err != nil { + return fmt.Errorf("failed to start metrics server: %w", err) + } + a.initRouter() + if err := a.startServer(cfg.HTTPServer); err != nil { + return fmt.Errorf("failed to start API server: %w", err) + } + return nil +} - return &API{log: logger, router: apiRouter, metricsRegistry: mr, serverConfig: serverConfig, metricsConfig: metricsConfig} +func (a *APIService) Start(ctx context.Context) error { + // Completed all setup-up jobs at init-time already, + // and the API service does not have any other special starting routines or background-jobs to start. + return nil } -// Run ... Runs the API server routines -func (a *API) Run(ctx context.Context) error { - var wg sync.WaitGroup - errCh := make(chan error, 2) - - // (1) Construct an inner function that will start a goroutine - // and handle any panics that occur on a shared error channel - processCtx, processCancel := context.WithCancel(ctx) - runProcess := func(start func(ctx context.Context) error) { - wg.Add(1) - go func() { - defer func() { - if err := recover(); err != nil { - a.log.Error("halting api on panic", "err", err) - debug.PrintStack() - errCh <- fmt.Errorf("panic: %v", err) - } - - processCancel() - wg.Done() - }() - - errCh <- start(processCtx) - }() +func (a *APIService) Stop(ctx context.Context) error { + var result error + if a.apiServer != nil { + if err := a.apiServer.Stop(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to stop API server: %w", err)) + } + } + if a.metricsServer != nil { + if err := a.metricsServer.Stop(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err)) + } } + if a.dbClose != nil { + if err := a.dbClose(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close DB: %w", err)) + } + } + a.stopped.Store(true) + a.log.Info("API service shutdown complete") + return result +} - // (2) Start the API and metrics servers - runProcess(a.startServer) - runProcess(a.startMetricsServer) +func (a *APIService) Stopped() bool { + return a.stopped.Load() +} - // (3) Wait for all processes to complete - wg.Wait() +// Addr ... returns the address that the HTTP server is listening on (excl. http:// prefix, just the host and port) +func (a *APIService) Addr() string { + if a.apiServer == nil { + return "" + } + return a.apiServer.Addr().String() +} - err := <-errCh +func (a *APIService) initDB(ctx context.Context, connector DBConnector) error { + db, err := connector.OpenDB(ctx, a.log) if err != nil { - a.log.Error("api stopped", "err", err) - } else { - a.log.Info("api stopped") + return fmt.Errorf("failed to connect to databse: %w", err) } - - return err + a.dbClose = db.Closer + a.bv = db.BridgeTransfers + return nil } -// Port ... Returns the the port that server is listening on -func (a *API) Port() int { - return a.serverConfig.Port +func (a *APIService) initRouter() { + apiRouter := chi.NewRouter() + h := routes.NewRoutes(a.log, a.bv, apiRouter) + + promRecorder := metrics.NewPromHTTPRecorder(a.metricsRegistry, MetricsNamespace) + + // (2) Inject routing middleware + apiRouter.Use(chiMetricsMiddleware(promRecorder)) + apiRouter.Use(middleware.Recoverer) + apiRouter.Use(middleware.Heartbeat(HealthPath)) + + // (3) Set GET routes + apiRouter.Get(fmt.Sprintf(DepositsPath+addressParam, ethereumAddressRegex), h.L1DepositsHandler) + apiRouter.Get(fmt.Sprintf(WithdrawalsPath+addressParam, ethereumAddressRegex), h.L2WithdrawalsHandler) + a.router = apiRouter } // startServer ... Starts the API server -func (a *API) startServer(ctx context.Context) error { - a.log.Debug("api server listening...", "port", a.serverConfig.Port) - addr := net.JoinHostPort(a.serverConfig.Host, strconv.Itoa(a.serverConfig.Port)) +func (a *APIService) startServer(serverConfig config.ServerConfig) error { + a.log.Debug("API server listening...", "port", serverConfig.Port) + addr := net.JoinHostPort(serverConfig.Host, strconv.Itoa(serverConfig.Port)) srv, err := httputil.StartHTTPServer(addr, a.router) if err != nil { return fmt.Errorf("failed to start API server: %w", err) } - - host, portStr, err := net.SplitHostPort(srv.Addr().String()) - if err != nil { - return errors.Join(err, srv.Close()) - } - port, err := strconv.Atoi(portStr) - if err != nil { - return errors.Join(err, srv.Close()) - } - - // Update the port in the config in case the OS chose a different port - // than the one we requested (e.g. using port 0 to fetch a random open port) - a.serverConfig.Host = host - a.serverConfig.Port = port - - <-ctx.Done() - if err := srv.Stop(context.Background()); err != nil { - return fmt.Errorf("failed to shutdown api server: %w", err) - } + a.log.Info("API server started", "addr", srv.Addr().String()) + a.apiServer = srv return nil } // startMetricsServer ... Starts the metrics server -func (a *API) startMetricsServer(ctx context.Context) error { - a.log.Debug("starting metrics server...", "port", a.metricsConfig.Port) - srv, err := metrics.StartServer(a.metricsRegistry, a.metricsConfig.Host, a.metricsConfig.Port) +func (a *APIService) startMetricsServer(metricsConfig config.ServerConfig) error { + a.log.Debug("starting metrics server...", "port", metricsConfig.Port) + srv, err := metrics.StartServer(a.metricsRegistry, metricsConfig.Host, metricsConfig.Port) if err != nil { return fmt.Errorf("failed to start metrics server: %w", err) } - <-ctx.Done() - defer a.log.Info("metrics server stopped") - return srv.Stop(context.Background()) + a.log.Info("Metrics server started", "addr", srv.Addr().String()) + a.metricsServer = srv + return nil } diff --git a/indexer/api/api_test.go b/indexer/api/api_test.go index 554fce28ce51..1d92d82481fb 100644 --- a/indexer/api/api_test.go +++ b/indexer/api/api_test.go @@ -1,6 +1,7 @@ package api import ( + "context" "encoding/json" "fmt" "net/http" @@ -24,11 +25,12 @@ var mockAddress = "0x4204204204204204204204204204204204204204" var apiConfig = config.ServerConfig{ Host: "localhost", - Port: 8080, + Port: 0, // random port, to allow parallel tests } + var metricsConfig = config.ServerConfig{ Host: "localhost", - Port: 7300, + Port: 0, // random port, to allow parallel tests } var ( @@ -95,8 +97,14 @@ func (mbv *MockBridgeTransfersView) L2BridgeWithdrawalsByAddress(address common. } func TestHealthz(t *testing.T) { logger := testlog.Logger(t, log.LvlInfo) - api := NewApi(logger, &MockBridgeTransfersView{}, apiConfig, metricsConfig) - request, err := http.NewRequest("GET", "/healthz", nil) + cfg := &Config{ + DB: &TestDBConnector{BridgeTransfers: &MockBridgeTransfersView{}}, + HTTPServer: apiConfig, + MetricsServer: metricsConfig, + } + api, err := NewApi(context.Background(), logger, cfg) + require.NoError(t, err) + request, err := http.NewRequest("GET", "http://"+api.Addr()+"/healthz", nil) assert.Nil(t, err) responseRecorder := httptest.NewRecorder() @@ -107,8 +115,14 @@ func TestHealthz(t *testing.T) { func TestL1BridgeDepositsHandler(t *testing.T) { logger := testlog.Logger(t, log.LvlInfo) - api := NewApi(logger, &MockBridgeTransfersView{}, apiConfig, metricsConfig) - request, err := http.NewRequest("GET", fmt.Sprintf("/api/v0/deposits/%s", mockAddress), nil) + cfg := &Config{ + DB: &TestDBConnector{BridgeTransfers: &MockBridgeTransfersView{}}, + HTTPServer: apiConfig, + MetricsServer: metricsConfig, + } + api, err := NewApi(context.Background(), logger, cfg) + require.NoError(t, err) + request, err := http.NewRequest("GET", fmt.Sprintf("http://"+api.Addr()+"/api/v0/deposits/%s", mockAddress), nil) assert.Nil(t, err) responseRecorder := httptest.NewRecorder() @@ -130,8 +144,14 @@ func TestL1BridgeDepositsHandler(t *testing.T) { func TestL2BridgeWithdrawalsByAddressHandler(t *testing.T) { logger := testlog.Logger(t, log.LvlInfo) - api := NewApi(logger, &MockBridgeTransfersView{}, apiConfig, metricsConfig) - request, err := http.NewRequest("GET", fmt.Sprintf("/api/v0/withdrawals/%s", mockAddress), nil) + cfg := &Config{ + DB: &TestDBConnector{BridgeTransfers: &MockBridgeTransfersView{}}, + HTTPServer: apiConfig, + MetricsServer: metricsConfig, + } + api, err := NewApi(context.Background(), logger, cfg) + require.NoError(t, err) + request, err := http.NewRequest("GET", fmt.Sprintf("http://"+api.Addr()+"/api/v0/withdrawals/%s", mockAddress), nil) assert.Nil(t, err) responseRecorder := httptest.NewRecorder() diff --git a/indexer/api/config.go b/indexer/api/config.go new file mode 100644 index 000000000000..6e2cece73ede --- /dev/null +++ b/indexer/api/config.go @@ -0,0 +1,61 @@ +package api + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/indexer/config" + "github.com/ethereum-optimism/optimism/indexer/database" +) + +// DB represents the abstract DB access the API has. +type DB struct { + BridgeTransfers database.BridgeTransfersView + Closer func() error +} + +// DBConfigConnector implements a fully config based DBConnector +type DBConfigConnector struct { + config.DBConfig +} + +func (cfg *DBConfigConnector) OpenDB(ctx context.Context, log log.Logger) (*DB, error) { + // TODO: pass through the ctx argument, so we can interrupt while connecting + db, err := database.NewDB(log, cfg.DBConfig) + if err != nil { + return nil, fmt.Errorf("failed to connect to databse: %w", err) + } + return &DB{ + BridgeTransfers: db.BridgeTransfers, + Closer: db.Close, + }, nil +} + +type TestDBConnector struct { + BridgeTransfers database.BridgeTransfersView +} + +func (tdb *TestDBConnector) OpenDB(ctx context.Context, log log.Logger) (*DB, error) { + return &DB{ + BridgeTransfers: tdb.BridgeTransfers, + Closer: func() error { + log.Info("API service closed test DB view") + return nil + }, + }, nil +} + +// DBConnector is an interface: the config may provide different ways to access the DB. +// This is implemented in tests to provide custom DB views, or share the DB with other services. +type DBConnector interface { + OpenDB(ctx context.Context, log log.Logger) (*DB, error) +} + +// Config for the API service +type Config struct { + DB DBConnector + HTTPServer config.ServerConfig + MetricsServer config.ServerConfig +} diff --git a/indexer/cmd/indexer/cli.go b/indexer/cmd/indexer/cli.go index ebf3b2a48db9..efb7677aec04 100644 --- a/indexer/cmd/indexer/cli.go +++ b/indexer/cmd/indexer/cli.go @@ -1,14 +1,18 @@ package main import ( + "context" + + "github.com/urfave/cli/v2" + + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum-optimism/optimism/indexer" "github.com/ethereum-optimism/optimism/indexer/api" "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" + "github.com/ethereum-optimism/optimism/op-service/cliapp" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum/go-ethereum/params" - - "github.com/urfave/cli/v2" ) var ( @@ -27,7 +31,7 @@ var ( } ) -func runIndexer(ctx *cli.Context) error { +func runIndexer(ctx *cli.Context, shutdown context.CancelCauseFunc) (cliapp.Lifecycle, error) { log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "indexer") oplog.SetGlobalLogHandler(log.GetHandler()) log.Info("running indexer...") @@ -35,26 +39,13 @@ func runIndexer(ctx *cli.Context) error { cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name)) if err != nil { log.Error("failed to load config", "err", err) - return err - } - - db, err := database.NewDB(log, cfg.DB) - if err != nil { - log.Error("failed to connect to database", "err", err) - return err - } - defer db.Close() - - indexer, err := indexer.NewIndexer(log, db, cfg.Chain, cfg.RPCs, cfg.HTTPServer, cfg.MetricsServer) - if err != nil { - log.Error("failed to create indexer", "err", err) - return err + return nil, err } - return indexer.Run(ctx.Context) + return indexer.NewIndexer(ctx.Context, log, &cfg, shutdown) } -func runApi(ctx *cli.Context) error { +func runApi(ctx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, error) { log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "api") oplog.SetGlobalLogHandler(log.GetHandler()) log.Info("running api...") @@ -62,18 +53,16 @@ func runApi(ctx *cli.Context) error { cfg, err := config.LoadConfig(log, ctx.String(ConfigFlag.Name)) if err != nil { log.Error("failed to load config", "err", err) - return err + return nil, err } - db, err := database.NewDB(log, cfg.DB) - if err != nil { - log.Error("failed to connect to database", "err", err) - return err + apiCfg := &api.Config{ + DB: &api.DBConfigConnector{DBConfig: cfg.DB}, + HTTPServer: cfg.HTTPServer, + MetricsServer: cfg.MetricsServer, } - defer db.Close() - api := api.NewApi(log, db.BridgeTransfers, cfg.HTTPServer, cfg.MetricsServer) - return api.Run(ctx.Context) + return api.NewApi(ctx.Context, log, apiCfg) } func runMigrations(ctx *cli.Context) error { @@ -112,13 +101,13 @@ func newCli(GitCommit string, GitDate string) *cli.App { Name: "api", Flags: flags, Description: "Runs the api service", - Action: runApi, + Action: cliapp.LifecycleCmd(runApi), }, { Name: "index", Flags: flags, Description: "Runs the indexing service", - Action: runIndexer, + Action: cliapp.LifecycleCmd(runIndexer), }, { Name: "migrate", diff --git a/indexer/e2e_tests/setup.go b/indexer/e2e_tests/setup.go index ebd69112c8aa..0191ece83da2 100644 --- a/indexer/e2e_tests/setup.go +++ b/indexer/e2e_tests/setup.go @@ -34,7 +34,7 @@ type E2ETestSuite struct { // API Client *client.Client - API *api.API + API *api.APIService // Indexer DB *database.DB @@ -73,7 +73,7 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite { t.Cleanup(func() { opSys.Close() }) // Indexer Configuration and Start - indexerCfg := config.Config{ + indexerCfg := &config.Config{ DB: config.DBConfig{ Host: "127.0.0.1", Port: 5432, @@ -106,51 +106,40 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite { // the system is running, mark this test for Parallel execution t.Parallel() - // provide a DB for the unit test. disable logging - silentLog := testlog.Logger(t, log.LvlInfo) - silentLog.SetHandler(log.DiscardHandler()) - db, err := database.NewDB(silentLog, indexerCfg.DB) - require.NoError(t, err) - t.Cleanup(func() { db.Close() }) - indexerLog := testlog.Logger(t, log.LvlInfo).New("role", "indexer") - indexer, err := indexer.NewIndexer(indexerLog, db, indexerCfg.Chain, indexerCfg.RPCs, indexerCfg.HTTPServer, indexerCfg.MetricsServer) + ix, err := indexer.NewIndexer(context.Background(), indexerLog, indexerCfg, func(cause error) { + if cause != nil { + t.Fatalf("indexer shut down with critical error: %v", cause) + } + }) require.NoError(t, err) - indexerCtx, indexerStop := context.WithCancel(context.Background()) - go func() { - err := indexer.Run(indexerCtx) - if err != nil { // panicking here ensures that the test will exit - // during service failure. Using t.Fail() wouldn't be caught - // until all awaiting routines finish which would never happen. - panic(err) - } - }() + require.NoError(t, ix.Start(context.Background()), "cleanly start indexer") - apiLog := testlog.Logger(t, log.LvlInfo).New("role", "indexer_api") + t.Cleanup(func() { + require.NoError(t, ix.Stop(context.Background()), "cleanly shut down indexer") + }) - apiCfg := config.ServerConfig{ - Host: "127.0.0.1", - Port: 0, - } + apiLog := testlog.Logger(t, log.LvlInfo).New("role", "indexer_api") - mCfg := config.ServerConfig{ - Host: "127.0.0.1", - Port: 0, + apiCfg := &api.Config{ + DB: &api.TestDBConnector{BridgeTransfers: ix.DB.BridgeTransfers}, // reuse the same DB + HTTPServer: config.ServerConfig{ + Host: "127.0.0.1", + Port: 0, + }, + MetricsServer: config.ServerConfig{ + Host: "127.0.0.1", + Port: 0, + }, } - api := api.NewApi(apiLog, db.BridgeTransfers, apiCfg, mCfg) - apiCtx, apiStop := context.WithCancel(context.Background()) - go func() { - err := api.Run(apiCtx) - if err != nil { - panic(err) - } - }() + apiService, err := api.NewApi(context.Background(), apiLog, apiCfg) + require.NoError(t, err, "create indexer API service") + require.NoError(t, apiService.Start(context.Background()), "start indexer API service") t.Cleanup(func() { - apiStop() - indexerStop() + require.NoError(t, apiService.Stop(context.Background()), "cleanly shut down indexer") }) // Wait for the API to start listening @@ -158,16 +147,15 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite { client, err := client.NewClient(&client.Config{ PaginationLimit: 100, - BaseURL: fmt.Sprintf("http://%s:%d", apiCfg.Host, api.Port()), + BaseURL: "http://" + apiService.Addr(), }) - - require.NoError(t, err) + require.NoError(t, err, "must open indexer API client") return E2ETestSuite{ t: t, Client: client, - DB: db, - Indexer: indexer, + DB: ix.DB, + Indexer: ix, OpCfg: &opCfg, OpSys: opSys, L1Client: opSys.Clients["l1"], diff --git a/indexer/etl/etl.go b/indexer/etl/etl.go index 501bc795ae93..e317df87a528 100644 --- a/indexer/etl/etl.go +++ b/indexer/etl/etl.go @@ -7,11 +7,13 @@ import ( "math/big" "time" - "github.com/ethereum-optimism/optimism/indexer/node" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/indexer/node" + "github.com/ethereum-optimism/optimism/op-service/clock" ) type Config struct { @@ -31,9 +33,15 @@ type ETL struct { headerTraversal *node.HeaderTraversal contracts []common.Address - etlBatches chan ETLBatch + etlBatches chan *ETLBatch EthClient node.EthClient + + // A reference that'll stay populated between intervals + // in the event of failures in order to retry. + headers []types.Header + + worker *clock.LoopFn } type ETLBatch struct { @@ -46,51 +54,54 @@ type ETLBatch struct { HeadersWithLog map[common.Hash]bool } -func (etl *ETL) Start(ctx context.Context) error { - done := ctx.Done() - pollTicker := time.NewTicker(etl.loopInterval) - defer pollTicker.Stop() +// Start starts the ETL polling routine. The ETL work should be stopped with Close(). +func (etl *ETL) Start() error { + if etl.worker != nil { + return errors.New("already started") + } + etl.log.Info("starting etl...") + etl.worker = clock.NewLoopFn(clock.SystemClock, etl.tick, func() error { + close(etl.etlBatches) // can close the channel now, to signal to the consumer that we're done + etl.log.Info("stopped etl worker loop") + return nil + }, etl.loopInterval) + return nil +} + +func (etl *ETL) Close() error { + if etl.worker == nil { + return nil // worker was not running + } + return etl.worker.Close() +} - // A reference that'll stay populated between intervals - // in the event of failures in order to retry. - var headers []types.Header +func (etl *ETL) tick(_ context.Context) { + done := etl.metrics.RecordInterval() + if len(etl.headers) > 0 { + etl.log.Info("retrying previous batch") + } else { + newHeaders, err := etl.headerTraversal.NextHeaders(etl.headerBufferSize) + if err != nil { + etl.log.Error("error querying for headers", "err", err) + } else if len(newHeaders) == 0 { + etl.log.Warn("no new headers. etl at head?") + } else { + etl.headers = newHeaders + } - etl.log.Info("starting etl...") - for { - select { - case <-done: - etl.log.Info("stopping etl") - return nil - - case <-pollTicker.C: - done := etl.metrics.RecordInterval() - if len(headers) > 0 { - etl.log.Info("retrying previous batch") - } else { - newHeaders, err := etl.headerTraversal.NextHeaders(etl.headerBufferSize) - if err != nil { - etl.log.Error("error querying for headers", "err", err) - } else if len(newHeaders) == 0 { - etl.log.Warn("no new headers. etl at head?") - } else { - headers = newHeaders - } - - latestHeader := etl.headerTraversal.LatestHeader() - if latestHeader != nil { - etl.metrics.RecordLatestHeight(latestHeader.Number) - } - } - - // only clear the reference if we were able to process this batch - err := etl.processBatch(headers) - if err == nil { - headers = nil - } - - done(err) + latestHeader := etl.headerTraversal.LatestHeader() + if latestHeader != nil { + etl.metrics.RecordLatestHeight(latestHeader.Number) } } + + // only clear the reference if we were able to process this batch + err := etl.processBatch(etl.headers) + if err == nil { + etl.headers = nil + } + + done(err) } func (etl *ETL) processBatch(headers []types.Header) error { @@ -143,6 +154,6 @@ func (etl *ETL) processBatch(headers []types.Header) error { // ensure we use unique downstream references for the etl batch headersRef := headers - etl.etlBatches <- ETLBatch{Logger: batchLog, Headers: headersRef, HeaderMap: headerMap, Logs: logs.Logs, HeadersWithLog: headersWithLog} + etl.etlBatches <- &ETLBatch{Logger: batchLog, Headers: headersRef, HeaderMap: headerMap, Logs: logs.Logs, HeadersWithLog: headersWithLog} return nil } diff --git a/indexer/etl/l1_etl.go b/indexer/etl/l1_etl.go index 490d45fe69ab..8ad8677aa59f 100644 --- a/indexer/etl/l1_etl.go +++ b/indexer/etl/l1_etl.go @@ -4,10 +4,13 @@ import ( "context" "errors" "fmt" + "runtime/debug" "strings" "sync" "time" + "golang.org/x/sync/errgroup" + "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/node" @@ -20,8 +23,16 @@ import ( type L1ETL struct { ETL - db *database.DB - mu *sync.Mutex + // the batch handler may do work that we can interrupt on shutdown + resourceCtx context.Context + resourceCancel context.CancelFunc + + tasks errgroup.Group + + db *database.DB + + mu sync.Mutex + listeners []chan interface{} } @@ -71,8 +82,10 @@ func NewL1ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, cli } // NOTE - The use of un-buffered channel here assumes that downstream consumers - // will be able to keep up with the rate of incoming batches - etlBatches := make(chan ETLBatch) + // will be able to keep up with the rate of incoming batches. + // When the producer closes the channel we stop consuming from it. + etlBatches := make(chan *ETLBatch) + etl := ETL{ loopInterval: time.Duration(cfg.LoopIntervalMsec) * time.Millisecond, headerBufferSize: uint64(cfg.HeaderBufferSize), @@ -86,82 +99,120 @@ func NewL1ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, cli EthClient: client, } - return &L1ETL{ETL: etl, db: db, mu: new(sync.Mutex)}, nil + resCtx, resCancel := context.WithCancel(context.Background()) + return &L1ETL{ + ETL: etl, + db: db, + resourceCtx: resCtx, + resourceCancel: resCancel, + }, nil } -func (l1Etl *L1ETL) Start(ctx context.Context) error { - errCh := make(chan error, 1) - go func() { - errCh <- l1Etl.ETL.Start(ctx) - }() +func (l1Etl *L1ETL) Close() error { + var result error + // close the producer + if err := l1Etl.ETL.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close internal ETL: %w", err)) + } + // tell the consumer it can stop what it's doing + l1Etl.resourceCancel() + // wait for consumer to pick up on closure of producer + if err := l1Etl.tasks.Wait(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to await batch handler completion: %w", err)) + } + return result +} - for { - select { - case err := <-errCh: - return err - - // Index incoming batches (only L1 blocks that have an emitted log) - case batch := <-l1Etl.etlBatches: - l1BlockHeaders := make([]database.L1BlockHeader, 0, len(batch.Headers)) - for i := range batch.Headers { - if _, ok := batch.HeadersWithLog[batch.Headers[i].Hash()]; ok { - l1BlockHeaders = append(l1BlockHeaders, database.L1BlockHeader{BlockHeader: database.BlockHeaderFromHeader(&batch.Headers[i])}) - } +func (l1Etl *L1ETL) Start(shutdown context.CancelCauseFunc) error { + // start ETL batch producer + if err := l1Etl.ETL.Start(); err != nil { + return fmt.Errorf("failed to start internal ETL: %w", err) + } + // start ETL batch consumer + l1Etl.tasks.Go(func() error { + defer func() { + if err := recover(); err != nil { + l1Etl.log.Error("halting indexer on L1 ETL panic", "err", err) + debug.PrintStack() + shutdown(fmt.Errorf("panic: %v", err)) } - - if len(l1BlockHeaders) == 0 { - batch.Logger.Info("no l1 blocks with logs in batch") - continue + }() + + for { + // Index incoming batches (only L1 blocks that have an emitted log) + batch, ok := <-l1Etl.etlBatches + if !ok { + l1Etl.log.Info("No more batches, shutting down L1 batch handler") + return nil } - - l1ContractEvents := make([]database.L1ContractEvent, len(batch.Logs)) - for i := range batch.Logs { - timestamp := batch.HeaderMap[batch.Logs[i].BlockHash].Time - l1ContractEvents[i] = database.L1ContractEvent{ContractEvent: database.ContractEventFromLog(&batch.Logs[i], timestamp)} - l1Etl.ETL.metrics.RecordIndexedLog(batch.Logs[i].Address) + if err := l1Etl.handleBatch(batch); err != nil { + return fmt.Errorf("failed to handle batch, stopping L2 ETL: %w", err) } + } + }) + return nil +} + +func (l1Etl *L1ETL) handleBatch(batch *ETLBatch) error { + l1BlockHeaders := make([]database.L1BlockHeader, 0, len(batch.Headers)) + for i := range batch.Headers { + if _, ok := batch.HeadersWithLog[batch.Headers[i].Hash()]; ok { + l1BlockHeaders = append(l1BlockHeaders, database.L1BlockHeader{BlockHeader: database.BlockHeaderFromHeader(&batch.Headers[i])}) + } + } - // Continually try to persist this batch. If it fails after 10 attempts, we simply error out - retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250} - if _, err := retry.Do[interface{}](ctx, 10, retryStrategy, func() (interface{}, error) { - if err := l1Etl.db.Transaction(func(tx *database.DB) error { - if err := tx.Blocks.StoreL1BlockHeaders(l1BlockHeaders); err != nil { - return err - } - // we must have logs if we have l1 blocks - if err := tx.ContractEvents.StoreL1ContractEvents(l1ContractEvents); err != nil { - return err - } - return nil - }); err != nil { - batch.Logger.Error("unable to persist batch", "err", err) - return nil, err - } - - l1Etl.ETL.metrics.RecordIndexedHeaders(len(l1BlockHeaders)) - l1Etl.ETL.metrics.RecordIndexedLatestHeight(l1BlockHeaders[len(l1BlockHeaders)-1].Number) - - // a-ok! - return nil, nil - }); err != nil { + if len(l1BlockHeaders) == 0 { + batch.Logger.Info("no l1 blocks with logs in batch") + return nil + } + + l1ContractEvents := make([]database.L1ContractEvent, len(batch.Logs)) + for i := range batch.Logs { + timestamp := batch.HeaderMap[batch.Logs[i].BlockHash].Time + l1ContractEvents[i] = database.L1ContractEvent{ContractEvent: database.ContractEventFromLog(&batch.Logs[i], timestamp)} + l1Etl.ETL.metrics.RecordIndexedLog(batch.Logs[i].Address) + } + + // Continually try to persist this batch. If it fails after 10 attempts, we simply error out + retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250} + if _, err := retry.Do[interface{}](l1Etl.resourceCtx, 10, retryStrategy, func() (interface{}, error) { + if err := l1Etl.db.Transaction(func(tx *database.DB) error { + if err := tx.Blocks.StoreL1BlockHeaders(l1BlockHeaders); err != nil { return err } - - batch.Logger.Info("indexed batch") - - // Notify Listeners - l1Etl.mu.Lock() - for i := range l1Etl.listeners { - select { - case l1Etl.listeners[i] <- struct{}{}: - default: - // do nothing if the listener hasn't picked - // up the previous notif - } + // we must have logs if we have l1 blocks + if err := tx.ContractEvents.StoreL1ContractEvents(l1ContractEvents); err != nil { + return err } - l1Etl.mu.Unlock() + return nil + }); err != nil { + batch.Logger.Error("unable to persist batch", "err", err) + return nil, fmt.Errorf("unable to persist batch: %w", err) + } + + l1Etl.ETL.metrics.RecordIndexedHeaders(len(l1BlockHeaders)) + l1Etl.ETL.metrics.RecordIndexedLatestHeight(l1BlockHeaders[len(l1BlockHeaders)-1].Number) + + // a-ok! + return nil, nil + }); err != nil { + return err + } + + batch.Logger.Info("indexed batch") + + // Notify Listeners + l1Etl.mu.Lock() + for i := range l1Etl.listeners { + select { + case l1Etl.listeners[i] <- struct{}{}: + default: + // do nothing if the listener hasn't picked + // up the previous notif } } + l1Etl.mu.Unlock() + return nil } // Notify returns a channel that'll receive a value every time new data has diff --git a/indexer/etl/l2_etl.go b/indexer/etl/l2_etl.go index f6b5ab0fabab..aebf31c1d19f 100644 --- a/indexer/etl/l2_etl.go +++ b/indexer/etl/l2_etl.go @@ -3,20 +3,31 @@ package etl import ( "context" "errors" + "fmt" + "runtime/debug" "time" + "golang.org/x/sync/errgroup" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/node" "github.com/ethereum-optimism/optimism/op-service/retry" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" ) type L2ETL struct { ETL + // the batch handler may do work that we can interrupt on shutdown + resourceCtx context.Context + resourceCancel context.CancelFunc + + tasks errgroup.Group + db *database.DB } @@ -54,7 +65,7 @@ func NewL2ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, cli log.Info("no indexed state, starting from genesis") } - etlBatches := make(chan ETLBatch) + etlBatches := make(chan *ETLBatch) etl := ETL{ loopInterval: time.Duration(cfg.LoopIntervalMsec) * time.Millisecond, headerBufferSize: uint64(cfg.HeaderBufferSize), @@ -68,62 +79,101 @@ func NewL2ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, cli EthClient: client, } - return &L2ETL{ETL: etl, db: db}, nil + resCtx, resCancel := context.WithCancel(context.Background()) + return &L2ETL{ + ETL: etl, + resourceCtx: resCtx, + resourceCancel: resCancel, + db: db, + }, nil } -func (l2Etl *L2ETL) Start(ctx context.Context) error { - errCh := make(chan error, 1) - go func() { - errCh <- l2Etl.ETL.Start(ctx) - }() - - for { - select { - case err := <-errCh: - return err - - // Index incoming batches (all L2 Blocks) - case batch := <-l2Etl.etlBatches: - l2BlockHeaders := make([]database.L2BlockHeader, len(batch.Headers)) - for i := range batch.Headers { - l2BlockHeaders[i] = database.L2BlockHeader{BlockHeader: database.BlockHeaderFromHeader(&batch.Headers[i])} - } +func (l2Etl *L2ETL) Close() error { + var result error + // close the producer + if err := l2Etl.ETL.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close internal ETL: %w", err)) + } + // tell the consumer it can stop what it's doing + l2Etl.resourceCancel() + // wait for consumer to pick up on closure of producer + if err := l2Etl.tasks.Wait(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to await batch handler completion: %w", err)) + } + return result +} + +func (l2Etl *L2ETL) Start(shutdown context.CancelCauseFunc) error { + // start ETL batch producer + if err := l2Etl.ETL.Start(); err != nil { + return fmt.Errorf("failed to start internal ETL: %w", err) + } - l2ContractEvents := make([]database.L2ContractEvent, len(batch.Logs)) - for i := range batch.Logs { - timestamp := batch.HeaderMap[batch.Logs[i].BlockHash].Time - l2ContractEvents[i] = database.L2ContractEvent{ContractEvent: database.ContractEventFromLog(&batch.Logs[i], timestamp)} - l2Etl.ETL.metrics.RecordIndexedLog(batch.Logs[i].Address) + // start ETL batch consumer + l2Etl.tasks.Go(func() error { + defer func() { + if err := recover(); err != nil { + l2Etl.log.Error("halting indexer on L2 ETL panic", "err", err) + debug.PrintStack() + shutdown(fmt.Errorf("panic: %v", err)) + } + }() + + for { + // Index incoming batches (all L2 blocks) + batch, ok := <-l2Etl.etlBatches + if !ok { + l2Etl.log.Info("No more batches, shutting down L2 batch handler") + return nil } + if err := l2Etl.handleBatch(batch); err != nil { + return fmt.Errorf("failed to handle batch, stopping L2 ETL: %w", err) + } + } + }) + return nil +} - // Continually try to persist this batch. If it fails after 10 attempts, we simply error out - retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250} - if _, err := retry.Do[interface{}](ctx, 10, retryStrategy, func() (interface{}, error) { - if err := l2Etl.db.Transaction(func(tx *database.DB) error { - if err := tx.Blocks.StoreL2BlockHeaders(l2BlockHeaders); err != nil { - return err - } - if len(l2ContractEvents) > 0 { - if err := tx.ContractEvents.StoreL2ContractEvents(l2ContractEvents); err != nil { - return err - } - } - return nil - }); err != nil { - batch.Logger.Error("unable to persist batch", "err", err) - return nil, err - } +func (l2Etl *L2ETL) handleBatch(batch *ETLBatch) error { + l2BlockHeaders := make([]database.L2BlockHeader, len(batch.Headers)) + for i := range batch.Headers { + l2BlockHeaders[i] = database.L2BlockHeader{BlockHeader: database.BlockHeaderFromHeader(&batch.Headers[i])} + } - l2Etl.ETL.metrics.RecordIndexedHeaders(len(l2BlockHeaders)) - l2Etl.ETL.metrics.RecordIndexedLatestHeight(l2BlockHeaders[len(l2BlockHeaders)-1].Number) + l2ContractEvents := make([]database.L2ContractEvent, len(batch.Logs)) + for i := range batch.Logs { + timestamp := batch.HeaderMap[batch.Logs[i].BlockHash].Time + l2ContractEvents[i] = database.L2ContractEvent{ContractEvent: database.ContractEventFromLog(&batch.Logs[i], timestamp)} + l2Etl.ETL.metrics.RecordIndexedLog(batch.Logs[i].Address) + } - // a-ok! - return nil, nil - }); err != nil { + // Continually try to persist this batch. If it fails after 10 attempts, we simply error out + retryStrategy := &retry.ExponentialStrategy{Min: 1000, Max: 20_000, MaxJitter: 250} + if _, err := retry.Do[interface{}](l2Etl.resourceCtx, 10, retryStrategy, func() (interface{}, error) { + if err := l2Etl.db.Transaction(func(tx *database.DB) error { + if err := tx.Blocks.StoreL2BlockHeaders(l2BlockHeaders); err != nil { return err } - - batch.Logger.Info("indexed batch") + if len(l2ContractEvents) > 0 { + if err := tx.ContractEvents.StoreL2ContractEvents(l2ContractEvents); err != nil { + return err + } + } + return nil + }); err != nil { + batch.Logger.Error("unable to persist batch", "err", err) + return nil, err } + + l2Etl.ETL.metrics.RecordIndexedHeaders(len(l2BlockHeaders)) + l2Etl.ETL.metrics.RecordIndexedLatestHeight(l2BlockHeaders[len(l2BlockHeaders)-1].Number) + + // a-ok! + return nil, nil + }); err != nil { + return err } + + batch.Logger.Info("indexed batch") + return nil } diff --git a/indexer/indexer.go b/indexer/indexer.go index 07f566650604..6280c604e6ea 100644 --- a/indexer/indexer.go +++ b/indexer/indexer.go @@ -2,12 +2,12 @@ package indexer import ( "context" + "errors" "fmt" "math/big" "net" - "runtime/debug" "strconv" - "sync" + "sync/atomic" "github.com/ethereum/go-ethereum/log" @@ -30,149 +30,228 @@ import ( // indexing the configured L1 and L2 chains type Indexer struct { log log.Logger - db *database.DB + DB *database.DB + + l1Client node.EthClient + l2Client node.EthClient + + // api server only really serves a /health endpoint here, but this may change in the future + apiServer *httputil.HTTPServer + + metricsServer *httputil.HTTPServer - httpConfig config.ServerConfig - metricsConfig config.ServerConfig metricsRegistry *prometheus.Registry L1ETL *etl.L1ETL L2ETL *etl.L2ETL BridgeProcessor *processors.BridgeProcessor + + // shutdown requests the service that maintains the indexer to shut down, + // and provides the error-cause of the critical failure (if any). + shutdown context.CancelCauseFunc + + stopped atomic.Bool } // NewIndexer initializes an instance of the Indexer -func NewIndexer( - log log.Logger, - db *database.DB, - chainConfig config.ChainConfig, - rpcsConfig config.RPCsConfig, - httpConfig config.ServerConfig, - metricsConfig config.ServerConfig, -) (*Indexer, error) { - metricsRegistry := metrics.NewRegistry() - - // L1 - l1EthClient, err := node.DialEthClient(rpcsConfig.L1RPC, node.NewMetrics(metricsRegistry, "l1")) +func NewIndexer(ctx context.Context, log log.Logger, cfg *config.Config, shutdown context.CancelCauseFunc) (*Indexer, error) { + out := &Indexer{ + log: log, + metricsRegistry: metrics.NewRegistry(), + shutdown: shutdown, + } + if err := out.initFromConfig(ctx, cfg); err != nil { + return nil, errors.Join(err, out.Stop(ctx)) + } + return out, nil +} + +func (ix *Indexer) Start(ctx context.Context) error { + // If any of these services has a critical failure, + // the service can request a shutdown, while providing the error cause. + if err := ix.L1ETL.Start(ix.shutdown); err != nil { + return fmt.Errorf("failed to start L1 ETL: %w", err) + } + if err := ix.L2ETL.Start(ix.shutdown); err != nil { + return fmt.Errorf("failed to start L2 ETL: %w", err) + } + if err := ix.BridgeProcessor.Start(ix.shutdown); err != nil { + return fmt.Errorf("failed to start bridge processor: %w", err) + } + return nil +} + +func (ix *Indexer) Stop(ctx context.Context) error { + var result error + + if ix.L1ETL != nil { + if err := ix.L1ETL.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close L1 ETL: %w", err)) + } + } + + if ix.L2ETL != nil { + if err := ix.L2ETL.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close L2 ETL: %w", err)) + } + } + + if ix.BridgeProcessor != nil { + if err := ix.BridgeProcessor.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close bridge processor: %w", err)) + } + } + + // Now that the ETLs are closed, we can stop the RPC clients + if ix.l1Client != nil { + ix.l1Client.Close() + } + if ix.l2Client != nil { + ix.l2Client.Close() + } + + if ix.apiServer != nil { + if err := ix.apiServer.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close indexer API server: %w", err)) + } + } + + // DB connection can be closed last, after all its potential users have shut down + if ix.DB != nil { + if err := ix.DB.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close DB: %w", err)) + } + } + + if ix.metricsServer != nil { + if err := ix.metricsServer.Close(); err != nil { + result = errors.Join(result, fmt.Errorf("failed to close metrics server: %w", err)) + } + } + + ix.stopped.Store(true) + + ix.log.Info("indexer stopped") + + return result +} + +func (ix *Indexer) Stopped() bool { + return ix.stopped.Load() +} + +func (ix *Indexer) initFromConfig(ctx context.Context, cfg *config.Config) error { + if err := ix.initRPCClients(ctx, cfg.RPCs); err != nil { + return fmt.Errorf("failed to start RPC clients: %w", err) + } + if err := ix.initDB(ctx, cfg.DB); err != nil { + return fmt.Errorf("failed to init DB: %w", err) + } + if err := ix.initL1ETL(cfg.Chain); err != nil { + return fmt.Errorf("failed to init L1 ETL: %w", err) + } + if err := ix.initL2ETL(cfg.Chain); err != nil { + return fmt.Errorf("failed to init L2 ETL: %w", err) + } + if err := ix.initBridgeProcessor(cfg.Chain); err != nil { + return fmt.Errorf("failed to init Bridge-Processor: %w", err) + } + if err := ix.startHttpServer(ctx, cfg.HTTPServer); err != nil { + return fmt.Errorf("failed to start HTTP server: %w", err) + } + if err := ix.startMetricsServer(ctx, cfg.MetricsServer); err != nil { + return fmt.Errorf("failed to start Metrics server: %w", err) + } + return nil +} + +func (ix *Indexer) initRPCClients(ctx context.Context, rpcsConfig config.RPCsConfig) error { + l1EthClient, err := node.DialEthClient(ctx, rpcsConfig.L1RPC, node.NewMetrics(ix.metricsRegistry, "l1")) + if err != nil { + return fmt.Errorf("failed to dial L1 client: %w", err) + } + ix.l1Client = l1EthClient + + l2EthClient, err := node.DialEthClient(ctx, rpcsConfig.L2RPC, node.NewMetrics(ix.metricsRegistry, "l2")) + if err != nil { + return fmt.Errorf("failed to dial L2 client: %w", err) + } + ix.l2Client = l2EthClient + return nil +} + +func (ix *Indexer) initDB(ctx context.Context, cfg config.DBConfig) error { + // TODO thread ctx for interrupt during dial + db, err := database.NewDB(ix.log, cfg) if err != nil { - return nil, err + return fmt.Errorf("failed to connect to database: %w", err) } + ix.DB = db + return nil +} + +func (ix *Indexer) initL1ETL(chainConfig config.ChainConfig) error { l1Cfg := etl.Config{ LoopIntervalMsec: chainConfig.L1PollingInterval, HeaderBufferSize: chainConfig.L1HeaderBufferSize, ConfirmationDepth: big.NewInt(int64(chainConfig.L1ConfirmationDepth)), StartHeight: big.NewInt(int64(chainConfig.L1StartingHeight)), } - l1Etl, err := etl.NewL1ETL(l1Cfg, log, db, etl.NewMetrics(metricsRegistry, "l1"), l1EthClient, chainConfig.L1Contracts) + l1Etl, err := etl.NewL1ETL(l1Cfg, ix.log, ix.DB, etl.NewMetrics(ix.metricsRegistry, "l1"), ix.l1Client, chainConfig.L1Contracts) if err != nil { - return nil, err + return err } + ix.L1ETL = l1Etl + return nil +} +func (ix *Indexer) initL2ETL(chainConfig config.ChainConfig) error { // L2 (defaults to predeploy contracts) - l2EthClient, err := node.DialEthClient(rpcsConfig.L2RPC, node.NewMetrics(metricsRegistry, "l2")) - if err != nil { - return nil, err - } l2Cfg := etl.Config{ LoopIntervalMsec: chainConfig.L2PollingInterval, HeaderBufferSize: chainConfig.L2HeaderBufferSize, ConfirmationDepth: big.NewInt(int64(chainConfig.L2ConfirmationDepth)), } - l2Etl, err := etl.NewL2ETL(l2Cfg, log, db, etl.NewMetrics(metricsRegistry, "l2"), l2EthClient, chainConfig.L2Contracts) + l2Etl, err := etl.NewL2ETL(l2Cfg, ix.log, ix.DB, etl.NewMetrics(ix.metricsRegistry, "l2"), ix.l2Client, chainConfig.L2Contracts) if err != nil { - return nil, err + return err } + ix.L2ETL = l2Etl + return nil +} - // Bridge - bridgeProcessor, err := processors.NewBridgeProcessor(log, db, bridge.NewMetrics(metricsRegistry), l1Etl, chainConfig) +func (ix *Indexer) initBridgeProcessor(chainConfig config.ChainConfig) error { + bridgeProcessor, err := processors.NewBridgeProcessor(ix.log, ix.DB, bridge.NewMetrics(ix.metricsRegistry), ix.L1ETL, chainConfig) if err != nil { - return nil, err + return err } - - indexer := &Indexer{ - log: log, - db: db, - - httpConfig: httpConfig, - metricsConfig: metricsConfig, - metricsRegistry: metricsRegistry, - - L1ETL: l1Etl, - L2ETL: l2Etl, - BridgeProcessor: bridgeProcessor, - } - - return indexer, nil + ix.BridgeProcessor = bridgeProcessor + return nil } -func (i *Indexer) startHttpServer(ctx context.Context) error { - i.log.Debug("starting http server...", "port", i.httpConfig.Host) +func (ix *Indexer) startHttpServer(ctx context.Context, cfg config.ServerConfig) error { + ix.log.Debug("starting http server...", "port", cfg.Port) r := chi.NewRouter() r.Use(middleware.Heartbeat("/healthz")) - addr := net.JoinHostPort(i.httpConfig.Host, strconv.Itoa(i.httpConfig.Port)) + addr := net.JoinHostPort(cfg.Host, strconv.Itoa(cfg.Port)) srv, err := httputil.StartHTTPServer(addr, r) if err != nil { return fmt.Errorf("http server failed to start: %w", err) } - i.log.Info("http server started", "addr", srv.Addr()) - <-ctx.Done() - defer i.log.Info("http server stopped") - return srv.Stop(context.Background()) + ix.apiServer = srv + ix.log.Info("http server started", "addr", srv.Addr()) + return nil } -func (i *Indexer) startMetricsServer(ctx context.Context) error { - i.log.Debug("starting metrics server...", "port", i.metricsConfig.Port) - srv, err := metrics.StartServer(i.metricsRegistry, i.metricsConfig.Host, i.metricsConfig.Port) +func (ix *Indexer) startMetricsServer(ctx context.Context, cfg config.ServerConfig) error { + ix.log.Debug("starting metrics server...", "port", cfg.Port) + srv, err := metrics.StartServer(ix.metricsRegistry, cfg.Host, cfg.Port) if err != nil { return fmt.Errorf("metrics server failed to start: %w", err) } - i.log.Info("metrics server started", "addr", srv.Addr()) - <-ctx.Done() - defer i.log.Info("metrics server stopped") - return srv.Stop(context.Background()) -} - -// Start starts the indexing service on L1 and L2 chains -func (i *Indexer) Run(ctx context.Context) error { - var wg sync.WaitGroup - errCh := make(chan error, 5) - - // if any goroutine halts, we stop the entire indexer - processCtx, processCancel := context.WithCancel(ctx) - runProcess := func(start func(ctx context.Context) error) { - wg.Add(1) - go func() { - defer func() { - if err := recover(); err != nil { - i.log.Error("halting indexer on panic", "err", err) - debug.PrintStack() - errCh <- fmt.Errorf("panic: %v", err) - } - - processCancel() - wg.Done() - }() - - errCh <- start(processCtx) - }() - } - - // Kick off all the dependent routines - runProcess(i.L1ETL.Start) - runProcess(i.L2ETL.Start) - runProcess(i.BridgeProcessor.Start) - runProcess(i.startMetricsServer) - runProcess(i.startHttpServer) - wg.Wait() - - err := <-errCh - if err != nil { - i.log.Error("indexer stopped", "err", err) - } else { - i.log.Info("indexer stopped") - } - - return err + ix.metricsServer = srv + ix.log.Info("metrics server started", "addr", srv.Addr()) + return nil } diff --git a/indexer/node/client.go b/indexer/node/client.go index be046f930b48..1ad6f0a21e0a 100644 --- a/indexer/node/client.go +++ b/indexer/node/client.go @@ -40,23 +40,27 @@ type EthClient interface { StorageHash(common.Address, *big.Int) (common.Hash, error) FilterLogs(ethereum.FilterQuery) (Logs, error) + + // Close closes the underlying RPC connection. + // RPC close does not return any errors, but does shut down e.g. a websocket connection. + Close() } type clnt struct { rpc RPC } -func DialEthClient(rpcUrl string, metrics Metricer) (EthClient, error) { - ctxwt, cancel := context.WithTimeout(context.Background(), defaultDialTimeout) +func DialEthClient(ctx context.Context, rpcUrl string, metrics Metricer) (EthClient, error) { + ctx, cancel := context.WithTimeout(ctx, defaultDialTimeout) defer cancel() bOff := retry.Exponential() - rpcClient, err := retry.Do(ctxwt, defaultDialAttempts, bOff, func() (*rpc.Client, error) { + rpcClient, err := retry.Do(ctx, defaultDialAttempts, bOff, func() (*rpc.Client, error) { if !client.IsURLAvailable(rpcUrl) { return nil, fmt.Errorf("address unavailable (%s)", rpcUrl) } - client, err := rpc.DialContext(ctxwt, rpcUrl) + client, err := rpc.DialContext(ctx, rpcUrl) if err != nil { return nil, fmt.Errorf("failed to dial address (%s): %w", rpcUrl, err) } @@ -192,6 +196,10 @@ func (c *clnt) StorageHash(address common.Address, blockNumber *big.Int) (common return proof.StorageHash, nil } +func (c *clnt) Close() { + c.rpc.Close() +} + type Logs struct { Logs []types.Log ToBlockHeader *types.Header diff --git a/indexer/node/client_test.go b/indexer/node/client_test.go index 39e7eb2974a7..78cf5b5b82a5 100644 --- a/indexer/node/client_test.go +++ b/indexer/node/client_test.go @@ -1,6 +1,7 @@ package node import ( + "context" "fmt" "net" "strings" @@ -21,14 +22,14 @@ func TestDialEthClientUnavailable(t *testing.T) { metrics := &clientMetrics{} // available - _, err = DialEthClient(addr, metrics) + _, err = DialEthClient(context.Background(), addr, metrics) require.NoError(t, err) // :0 requests a new unbound port - _, err = DialEthClient("http://localhost:0", metrics) + _, err = DialEthClient(context.Background(), "http://localhost:0", metrics) require.Error(t, err) // Fail open if we don't recognize the scheme - _, err = DialEthClient("mailto://example.com", metrics) + _, err = DialEthClient(context.Background(), "mailto://example.com", metrics) require.Error(t, err) } diff --git a/indexer/node/mocks.go b/indexer/node/mocks.go index b18196307ee1..e01c6fcb1bca 100644 --- a/indexer/node/mocks.go +++ b/indexer/node/mocks.go @@ -45,3 +45,6 @@ func (m *MockEthClient) FilterLogs(query ethereum.FilterQuery) (Logs, error) { args := m.Called(query) return args.Get(0).(Logs), args.Error(1) } + +func (m *MockEthClient) Close() { +} diff --git a/indexer/processors/bridge.go b/indexer/processors/bridge.go index aed182a70bbb..5896d777c73a 100644 --- a/indexer/processors/bridge.go +++ b/indexer/processors/bridge.go @@ -3,7 +3,11 @@ package processors import ( "context" "errors" + "fmt" "math/big" + "runtime/debug" + + "golang.org/x/sync/errgroup" "github.com/ethereum-optimism/optimism/indexer/bigint" "github.com/ethereum-optimism/optimism/indexer/config" @@ -20,6 +24,10 @@ type BridgeProcessor struct { db *database.DB metrics bridge.Metricer + resourceCtx context.Context + resourceCancel context.CancelFunc + tasks errgroup.Group + l1Etl *etl.L1ETL chainConfig config.ChainConfig @@ -57,11 +65,22 @@ func NewBridgeProcessor(log log.Logger, db *database.DB, metrics bridge.Metricer log.Info("detected latest indexed bridge state", "l1_block_number", l1Height, "l2_block_number", l2Height) } - return &BridgeProcessor{log, db, metrics, l1Etl, chainConfig, l1Header, l2Header}, nil + resCtx, resCancel := context.WithCancel(context.Background()) + return &BridgeProcessor{ + log: log, + db: db, + metrics: metrics, + l1Etl: l1Etl, + resourceCtx: resCtx, + resourceCancel: resCancel, + chainConfig: chainConfig, + LatestL1Header: l1Header, + LatestL2Header: l2Header, + }, nil } -func (b *BridgeProcessor) Start(ctx context.Context) error { - done := ctx.Done() +func (b *BridgeProcessor) Start(shutdown context.CancelCauseFunc) error { + b.log.Info("starting bridge processor...") // Fire off independently on startup to check for // new data or if we've indexed new L1 data. @@ -69,21 +88,43 @@ func (b *BridgeProcessor) Start(ctx context.Context) error { startup := make(chan interface{}, 1) startup <- nil - b.log.Info("starting bridge processor...") - for { - select { - case <-done: - b.log.Info("stopping bridge processor") - return nil - - // Tickers - case <-startup: - case <-l1EtlUpdates: + b.tasks.Go(func() error { + defer func() { + if err := recover(); err != nil { + b.log.Error("halting indexer on bridge-processor panic", "err", err) + debug.PrintStack() + shutdown(fmt.Errorf("panic: %v", err)) + } + }() + + for { + select { + case <-b.resourceCtx.Done(): + b.log.Info("stopping bridge processor") + return nil + + // Tickers + case <-startup: + case <-l1EtlUpdates: + } + + done := b.metrics.RecordInterval() + // TODO: why log all the errors and return the same thing, if we just return the error, and log here? + err := b.run() + if err != nil { + b.log.Error("bridge processor error", "err", err) + } + done(err) } + }) + return nil +} - done := b.metrics.RecordInterval() - done(b.run()) - } +func (b *BridgeProcessor) Close() error { + // signal that we can stop any ongoing work + b.resourceCancel() + // await the work to stop + return b.tasks.Wait() } // Runs the processing loop. In order to ensure all seen bridge finalization events From f7759150bc3b62b0df0cdd46af37a4ea39f415b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 19:04:31 +0000 Subject: [PATCH 267/374] build(deps-dev): bump @typescript-eslint/parser from 6.9.0 to 6.9.1 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.9.0 to 6.9.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- packages/contracts-bedrock/package.json | 2 +- pnpm-lock.yaml | 84 +++++++------------------ 3 files changed, 23 insertions(+), 65 deletions(-) diff --git a/package.json b/package.json index 87a2d27132ec..4ef0eea511f8 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@types/mocha": "^10.0.3", "@types/node": "^20.8.9", "@typescript-eslint/eslint-plugin": "^6.9.1", - "@typescript-eslint/parser": "^6.9.0", + "@typescript-eslint/parser": "^6.9.1", "chai": "^4.3.10", "depcheck": "^1.4.7", "doctoc": "^2.2.0", diff --git a/packages/contracts-bedrock/package.json b/packages/contracts-bedrock/package.json index 18a7c09db2ca..144dbf9ceaf0 100644 --- a/packages/contracts-bedrock/package.json +++ b/packages/contracts-bedrock/package.json @@ -45,7 +45,7 @@ }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^6.9.1", - "@typescript-eslint/parser": "^6.9.0", + "@typescript-eslint/parser": "^6.9.1", "tsx": "^3.14.0", "typescript": "^5.2.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 84f999878908..05099a3cfc89 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,10 +35,10 @@ importers: version: 20.8.9 '@typescript-eslint/eslint-plugin': specifier: ^6.9.1 - version: 6.9.1(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2) + version: 6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.52.0)(typescript@5.2.2) '@typescript-eslint/parser': - specifier: ^6.9.0 - version: 6.9.0(eslint@8.52.0)(typescript@5.2.2) + specifier: ^6.9.1 + version: 6.9.1(eslint@8.52.0)(typescript@5.2.2) chai: specifier: ^4.3.10 version: 4.3.10 @@ -59,7 +59,7 @@ importers: version: 16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.52.0) eslint-plugin-import: specifier: ^2.29.0 - version: 2.29.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0) + version: 2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.52.0) eslint-plugin-jsdoc: specifier: ^35.1.2 version: 35.5.1(eslint@8.52.0) @@ -269,10 +269,10 @@ importers: devDependencies: '@typescript-eslint/eslint-plugin': specifier: ^6.9.1 - version: 6.9.1(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2) + version: 6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.52.0)(typescript@5.2.2) '@typescript-eslint/parser': - specifier: ^6.9.0 - version: 6.9.0(eslint@8.52.0)(typescript@5.2.2) + specifier: ^6.9.1 + version: 6.9.1(eslint@8.52.0)(typescript@5.2.2) tsx: specifier: ^3.14.0 version: 3.14.0 @@ -4201,7 +4201,7 @@ packages: '@types/node': 20.8.9 dev: false - /@typescript-eslint/eslint-plugin@6.9.1(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2): + /@typescript-eslint/eslint-plugin@6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.52.0)(typescript@5.2.2): resolution: {integrity: sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -4213,7 +4213,7 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 6.9.0(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.9.1(eslint@8.52.0)(typescript@5.2.2) '@typescript-eslint/scope-manager': 6.9.1 '@typescript-eslint/type-utils': 6.9.1(eslint@8.52.0)(typescript@5.2.2) '@typescript-eslint/utils': 6.9.1(eslint@8.52.0)(typescript@5.2.2) @@ -4230,8 +4230,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@6.9.0(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==} + /@typescript-eslint/parser@6.9.1(eslint@8.52.0)(typescript@5.2.2): + resolution: {integrity: sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -4240,10 +4240,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.9.0 - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/typescript-estree': 6.9.0(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.9.0 + '@typescript-eslint/scope-manager': 6.9.1 + '@typescript-eslint/types': 6.9.1 + '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.9.1 debug: 4.3.4(supports-color@8.1.1) eslint: 8.52.0 typescript: 5.2.2 @@ -4251,14 +4251,6 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager@6.9.0: - resolution: {integrity: sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/visitor-keys': 6.9.0 - dev: true - /@typescript-eslint/scope-manager@6.9.1: resolution: {integrity: sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4287,37 +4279,11 @@ packages: - supports-color dev: true - /@typescript-eslint/types@6.9.0: - resolution: {integrity: sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==} - engines: {node: ^16.0.0 || >=18.0.0} - dev: true - /@typescript-eslint/types@6.9.1: resolution: {integrity: sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.9.0(typescript@5.2.2): - resolution: {integrity: sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/visitor-keys': 6.9.0 - debug: 4.3.4(supports-color@8.1.1) - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.2.2) - typescript: 5.2.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/typescript-estree@6.9.1(typescript@5.2.2): resolution: {integrity: sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4358,14 +4324,6 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys@6.9.0: - resolution: {integrity: sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.9.0 - eslint-visitor-keys: 3.4.3 - dev: true - /@typescript-eslint/visitor-keys@6.9.1: resolution: {integrity: sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -7517,7 +7475,7 @@ packages: eslint-plugin-promise: ^4.2.1 || ^5.0.0 dependencies: eslint: 8.52.0 - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0) + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.52.0) eslint-plugin-node: 11.1.0(eslint@8.52.0) eslint-plugin-promise: 5.2.0(eslint@8.52.0) dev: true @@ -7532,7 +7490,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.9.0)(eslint-import-resolver-node@0.3.9)(eslint@8.52.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.9)(eslint@8.52.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -7553,7 +7511,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.9.0(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.9.1(eslint@8.52.0)(typescript@5.2.2) debug: 3.2.7 eslint: 8.52.0 eslint-import-resolver-node: 0.3.9 @@ -7572,7 +7530,7 @@ packages: regexpp: 3.2.0 dev: true - /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0): + /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.52.0): resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==} engines: {node: '>=4'} peerDependencies: @@ -7582,7 +7540,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.9.0(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.9.1(eslint@8.52.0)(typescript@5.2.2) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 @@ -7591,7 +7549,7 @@ packages: doctrine: 2.1.0 eslint: 8.52.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.9.0)(eslint-import-resolver-node@0.3.9)(eslint@8.52.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.9)(eslint@8.52.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 From ec4c4f50ed27934a5735ccd9358a6fa6f3ce1540 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 31 Oct 2023 22:21:23 +0300 Subject: [PATCH 268/374] contracts-bedrock: make `implSalt()` internal There is no reason for the `implSalt` method on the deploy script to be public, so make it internal. This reduces the external abi of the deploy script to prevent accidental leaky abstractions. Co-authored-by: Matt Solomon --- packages/contracts-bedrock/scripts/Deploy.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/scripts/Deploy.s.sol b/packages/contracts-bedrock/scripts/Deploy.s.sol index c293825a359d..0ada7415edb4 100644 --- a/packages/contracts-bedrock/scripts/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/Deploy.s.sol @@ -97,7 +97,7 @@ contract Deploy is Deployer { /// @notice The create2 salt used for deployment of the contract implementations. /// Using this helps to reduce config across networks as the implementation /// addresses will be the same across networks when deployed with create2. - function implSalt() public returns (bytes32) { + function implSalt() internal returns (bytes32) { return keccak256(bytes(vm.envOr("IMPL_SALT", string("ethers phoenix")))); } From 7f70dd72b0499fc5ced0435925cb76afc9464d83 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 31 Oct 2023 22:46:42 +0300 Subject: [PATCH 269/374] contracts-bedrock: update in memory deploy config The `hardhat.json` deploy config is used for the internal solidity tests. It is used because the default chain id is the same as what hardhat uses for testing and the chain id is what is used to specify which deploy config to use. The values are updated to ensure that sane, testable values are configured into the in memory tests for https://github.com/ethereum-optimism/optimism/pull/7928. This smaller commit exists to reduce the diff in that PR. --- packages/contracts-bedrock/deploy-config/hardhat.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/contracts-bedrock/deploy-config/hardhat.json b/packages/contracts-bedrock/deploy-config/hardhat.json index 3a59eb60ccb8..79ebd620d1d8 100644 --- a/packages/contracts-bedrock/deploy-config/hardhat.json +++ b/packages/contracts-bedrock/deploy-config/hardhat.json @@ -5,8 +5,8 @@ "l1StartingBlockTag": "earliest", "l1ChainID": 900, "l2ChainID": 901, - "l2BlockTime": 1, - "l1BlockTime": 2, + "l2BlockTime": 2, + "l1BlockTime": 12, "maxSequencerDrift": 300, "sequencerWindowSize": 15, "channelTimeout": 40, @@ -14,8 +14,8 @@ "batchInboxAddress": "0xff00000000000000000000000000000000000000", "batchSenderAddress": "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", "l2OutputOracleSubmissionInterval": 6, - "l2OutputOracleStartingTimestamp": 0, - "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleStartingTimestamp": 1, + "l2OutputOracleStartingBlockNumber": 1, "gasPriceOracleOverhead": 2100, "gasPriceOracleScalar": 1000000, "l2OutputOracleProposer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", @@ -35,7 +35,7 @@ "governanceTokenName": "Optimism", "governanceTokenSymbol": "OP", "governanceTokenOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", - "finalizationPeriodSeconds": 2, + "finalizationPeriodSeconds": 36, "eip1559Denominator": 50, "eip1559DenominatorCanyon": 250, "eip1559Elasticity": 10, From 4376aaa2860d7298794b62ebcf573868468486a5 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 31 Oct 2023 22:59:35 +0300 Subject: [PATCH 270/374] contracts-bedrock: update solidity deploy config Updates the solidity deploy config with extra configuration that was not previously required to be read in solidity but it exists in the Go code. These particular config values are used to build the L2 genesis state. We will read in these values as part of https://github.com/ethereum-optimism/optimism/pull/7928. They were previously not used in solidity. The Go deploy config check does ensure that they exist. --- packages/contracts-bedrock/scripts/DeployConfig.s.sol | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/scripts/DeployConfig.s.sol b/packages/contracts-bedrock/scripts/DeployConfig.s.sol index 89157e04a545..b2b924b9cb60 100644 --- a/packages/contracts-bedrock/scripts/DeployConfig.s.sol +++ b/packages/contracts-bedrock/scripts/DeployConfig.s.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; import { console2 as console } from "forge-std/console2.sol"; import { stdJson } from "forge-std/StdJson.sol"; -import { Executables } from "./Executables.sol"; -import { Chains } from "./Chains.sol"; +import { Executables } from "scripts/Executables.sol"; +import { Chains } from "scripts/Chains.sol"; /// @title DeployConfig /// @notice Represents the configuration required to deploy the system. It is expected @@ -33,8 +33,11 @@ contract DeployConfig is Script { uint256 public finalizationPeriodSeconds; address public proxyAdminOwner; address public baseFeeVaultRecipient; + uint256 public baseFeeVaultMinimumWithdrawalAmount; address public l1FeeVaultRecipient; + uint256 public l1FeeVaultMinimumWithdrawalAmount; address public sequencerFeeVaultRecipient; + uint256 public sequencerFeeVaultMinimumWithdrawalAmount; string public governanceTokenName; string public governanceTokenSymbol; address public governanceTokenOwner; @@ -79,8 +82,11 @@ contract DeployConfig is Script { finalizationPeriodSeconds = stdJson.readUint(_json, "$.finalizationPeriodSeconds"); proxyAdminOwner = stdJson.readAddress(_json, "$.proxyAdminOwner"); baseFeeVaultRecipient = stdJson.readAddress(_json, "$.baseFeeVaultRecipient"); + baseFeeVaultMinimumWithdrawalAmount = stdJson.readUint(_json, "$.baseFeeVaultMinimumWithdrawalAmount"); l1FeeVaultRecipient = stdJson.readAddress(_json, "$.l1FeeVaultRecipient"); + l1FeeVaultMinimumWithdrawalAmount = stdJson.readUint(_json, "$.l1FeeVaultMinimumWithdrawalAmount"); sequencerFeeVaultRecipient = stdJson.readAddress(_json, "$.sequencerFeeVaultRecipient"); + sequencerFeeVaultMinimumWithdrawalAmount = stdJson.readUint(_json, "$.sequencerFeeVaultMinimumWithdrawalAmount"); governanceTokenName = stdJson.readString(_json, "$.governanceTokenName"); governanceTokenSymbol = stdJson.readString(_json, "$.governanceTokenSymbol"); governanceTokenOwner = stdJson.readAddress(_json, "$.governanceTokenOwner"); From c1d06ca30a001894c837493dc9389f450f00c48b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 20:15:32 +0000 Subject: [PATCH 271/374] build(deps): bump @sentry/node from 7.75.0 to 7.77.0 Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 7.75.0 to 7.77.0. - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/7.75.0...7.77.0) --- updated-dependencies: - dependency-name: "@sentry/node" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/common-ts/package.json | 2 +- pnpm-lock.yaml | 46 ++++++++++++++++----------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/common-ts/package.json b/packages/common-ts/package.json index 72060a89145c..a16362195b7b 100644 --- a/packages/common-ts/package.json +++ b/packages/common-ts/package.json @@ -35,7 +35,7 @@ }, "dependencies": { "@eth-optimism/core-utils": "workspace:*", - "@sentry/node": "^7.75.0", + "@sentry/node": "^7.77.0", "bcfg": "^0.2.1", "body-parser": "^1.20.2", "commander": "^11.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2dd62f504744..c10ff8cba083 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -195,8 +195,8 @@ importers: specifier: workspace:* version: link:../core-utils '@sentry/node': - specifier: ^7.75.0 - version: 7.75.0 + specifier: ^7.77.0 + version: 7.77.0 bcfg: specifier: ^0.2.1 version: 0.2.1 @@ -3251,13 +3251,13 @@ packages: '@noble/hashes': 1.3.2 '@scure/base': 1.1.3 - /@sentry-internal/tracing@7.75.0: - resolution: {integrity: sha512-/j4opF/jB9j8qnSiQK75/lFLtkfqXS5/MoOKc2KWK/pOaf15W+6uJzGQ8jRBHLYd9dDg6AyqsF48Wqy561/mNg==} + /@sentry-internal/tracing@7.77.0: + resolution: {integrity: sha512-8HRF1rdqWwtINqGEdx8Iqs9UOP/n8E0vXUu3Nmbqj4p5sQPA7vvCfq+4Y4rTqZFc7sNdFpDsRION5iQEh8zfZw==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.75.0 - '@sentry/types': 7.75.0 - '@sentry/utils': 7.75.0 + '@sentry/core': 7.77.0 + '@sentry/types': 7.77.0 + '@sentry/utils': 7.77.0 dev: false /@sentry/core@5.30.0: @@ -3271,12 +3271,12 @@ packages: tslib: 1.14.1 dev: true - /@sentry/core@7.75.0: - resolution: {integrity: sha512-vXg3cdJgwzP24oTS9zFCgLW4MgTkMZqXx+ESRq7gTD9qJTpcmAmYT+Ckmvebg8K6DBThV6+0v61r50na2+XdrA==} + /@sentry/core@7.77.0: + resolution: {integrity: sha512-Tj8oTYFZ/ZD+xW8IGIsU6gcFXD/gfE+FUxUaeSosd9KHwBQNOLhZSsYo/tTVf/rnQI/dQnsd4onPZLiL+27aTg==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.75.0 - '@sentry/utils': 7.75.0 + '@sentry/types': 7.77.0 + '@sentry/utils': 7.77.0 dev: false /@sentry/hub@5.30.0: @@ -3314,14 +3314,14 @@ packages: - supports-color dev: true - /@sentry/node@7.75.0: - resolution: {integrity: sha512-z5Xanf9QeTd4YrEuZiJfvtAy2C874Zg4KpurEo3okJ8uYjnbXMsQ3EwVHbKEoYSwE3ExTrqOggPfk2NNSJIECA==} + /@sentry/node@7.77.0: + resolution: {integrity: sha512-Ob5tgaJOj0OYMwnocc6G/CDLWC7hXfVvKX/ofkF98+BbN/tQa5poL+OwgFn9BA8ud8xKzyGPxGU6LdZ8Oh3z/g==} engines: {node: '>=8'} dependencies: - '@sentry-internal/tracing': 7.75.0 - '@sentry/core': 7.75.0 - '@sentry/types': 7.75.0 - '@sentry/utils': 7.75.0 + '@sentry-internal/tracing': 7.77.0 + '@sentry/core': 7.77.0 + '@sentry/types': 7.77.0 + '@sentry/utils': 7.77.0 https-proxy-agent: 5.0.1 transitivePeerDependencies: - supports-color @@ -3343,8 +3343,8 @@ packages: engines: {node: '>=6'} dev: true - /@sentry/types@7.75.0: - resolution: {integrity: sha512-xG8OLADxG7HpGhMxrF4v4tKq/v/gqmLsTZ858R51pz0xCWM8SK6ZSWOKudkAGBIpRjI6RUHMnkBtRAN2aKDOkQ==} + /@sentry/types@7.77.0: + resolution: {integrity: sha512-nfb00XRJVi0QpDHg+JkqrmEBHsqBnxJu191Ded+Cs1OJ5oPXEW6F59LVcBScGvMqe+WEk1a73eH8XezwfgrTsA==} engines: {node: '>=8'} dev: false @@ -3356,11 +3356,11 @@ packages: tslib: 1.14.1 dev: true - /@sentry/utils@7.75.0: - resolution: {integrity: sha512-UHWKeevhUNRp+mAWDbMVFOMgseoq8t/xFgdUywO/2PC14qZKRBH+0k1BKoNkp5sOzDT06ETj2w6wYoYhy6i+dA==} + /@sentry/utils@7.77.0: + resolution: {integrity: sha512-NmM2kDOqVchrey3N5WSzdQoCsyDkQkiRxExPaNI2oKQ/jMWHs9yt0tSy7otPBcXs0AP59ihl75Bvm1tDRcsp5g==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.75.0 + '@sentry/types': 7.77.0 dev: false /@sinclair/typebox@0.27.8: @@ -11968,7 +11968,7 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - '@sentry/node': 7.75.0 + '@sentry/node': 7.77.0 commander: 2.20.3 pumpify: 2.0.1 split2: 3.2.2 From 72872892b9130a6f13433b342983502f3b29e68a Mon Sep 17 00:00:00 2001 From: Ethen Pociask Date: Tue, 31 Oct 2023 13:28:16 -0700 Subject: [PATCH 272/374] [indexer.api.add_withdrawal_hash] changed variable naming --- indexer/api/models/models.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indexer/api/models/models.go b/indexer/api/models/models.go index 6d34afab5909..1bf86ee26192 100644 --- a/indexer/api/models/models.go +++ b/indexer/api/models/models.go @@ -55,9 +55,9 @@ func CreateWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) items := make([]WithdrawalItem, len(withdrawals.Withdrawals)) for i, withdrawal := range withdrawals.Withdrawals { - crossDomainHash := withdrawal.L2BridgeWithdrawal.CrossDomainMessageHash - if crossDomainHash == nil { // Zero value indicates that the withdrawal didn't have a cross domain message - crossDomainHash = &common.Hash{0} + cdh := withdrawal.L2BridgeWithdrawal.CrossDomainMessageHash + if cdh == nil { // Zero value indicates that the withdrawal didn't have a cross domain message + cdh = &common.Hash{0} } item := WithdrawalItem{ @@ -68,7 +68,7 @@ func CreateWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) To: withdrawal.L2BridgeWithdrawal.Tx.ToAddress.String(), TransactionHash: withdrawal.L2TransactionHash.String(), Amount: withdrawal.L2BridgeWithdrawal.Tx.Amount.String(), - CrossDomainMessageHash: crossDomainHash.String(), + CrossDomainMessageHash: cdh.String(), L1ProvenTxHash: withdrawal.ProvenL1TransactionHash.String(), L1FinalizedTxHash: withdrawal.FinalizedL1TransactionHash.String(), L1TokenAddress: withdrawal.L2BridgeWithdrawal.TokenPair.RemoteTokenAddress.String(), From 961c966fd797bddff8cd4cfd3fcc329346fa2b26 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 31 Oct 2023 23:32:03 +0300 Subject: [PATCH 273/374] contracts-bedrock: fuzz message passer This commit migrates a few `L2ToL1MessagePasser` tests to being fuzz tests instead of being regular tests. This helps to improve coverage of the message passer and also removes unnecessary constants. This work is done as part of making https://github.com/ethereum-optimism/optimism/pull/7928 more modular so it is easier to review. --- packages/contracts-bedrock/.gas-snapshot | 3 - .../test/L2ToL1MessagePasser.t.sol | 61 +++++++++++++------ 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 89f86297e5af..db8e1cf3eabc 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -291,9 +291,6 @@ L2StandardBridge_Test:test_initialize_succeeds() (gas: 26316) L2StandardBridge_Test:test_receive_succeeds() (gas: 177125) L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 143366) L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16552) -L2ToL1MessagePasserTest:test_burn_succeeds() (gas: 112530) -L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract_succeeds() (gas: 70343) -L2ToL1MessagePasserTest:test_initiateWithdrawal_fromEOA_succeeds() (gas: 75830) LegacyERC20ETH_Test:test_approve_doesNotExist_reverts() (gas: 10702) LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10637) LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6341) diff --git a/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol b/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol index 9e62c74944b4..82ee90454b6c 100644 --- a/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol +++ b/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol @@ -72,37 +72,56 @@ contract L2ToL1MessagePasserTest is CommonTest { /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed /// log when called by a contract. - function test_initiateWithdrawal_fromContract_succeeds() external { + function testFuzz_initiateWithdrawal_fromContract_succeeds( + address _target, + uint256 _gasLimit, + uint256 _value, + bytes memory _data + ) + external + { bytes32 withdrawalHash = Hashing.hashWithdrawal( - Types.WithdrawalTransaction(messagePasser.messageNonce(), address(this), address(4), 100, 64000, hex"") + Types.WithdrawalTransaction({ + nonce: messagePasser.messageNonce(), + sender: address(this), + target: _target, + value: _value, + gasLimit: _gasLimit, + data: _data + }) ); - vm.expectEmit(true, true, true, true); - emit MessagePassed(messagePasser.messageNonce(), address(this), address(4), 100, 64000, hex"", withdrawalHash); + vm.expectEmit(address(messagePasser)); + emit MessagePassed( + messagePasser.messageNonce(), address(this), _target, _value, _gasLimit, _data, withdrawalHash + ); - vm.deal(address(this), 2 ** 64); - messagePasser.initiateWithdrawal{ value: 100 }(address(4), 64000, hex""); + vm.deal(address(this), _value); + messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data); } /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed /// log when called by an EOA. - function test_initiateWithdrawal_fromEOA_succeeds() external { - uint256 gasLimit = 64000; - address target = address(4); - uint256 value = 100; - bytes memory data = hex"ff"; + function testFuzz_initiateWithdrawal_fromEOA_succeeds( + uint256 _gasLimit, + address _target, + uint256 _value, + bytes memory _data + ) + external + { uint256 nonce = messagePasser.messageNonce(); // EOA emulation vm.prank(alice, alice); - vm.deal(alice, 2 ** 64); + vm.deal(alice, _value); bytes32 withdrawalHash = - Hashing.hashWithdrawal(Types.WithdrawalTransaction(nonce, alice, target, value, gasLimit, data)); + Hashing.hashWithdrawal(Types.WithdrawalTransaction(nonce, alice, _target, _value, _gasLimit, _data)); - vm.expectEmit(true, true, true, true); - emit MessagePassed(nonce, alice, target, value, gasLimit, data, withdrawalHash); + vm.expectEmit(address(messagePasser)); + emit MessagePassed(nonce, alice, _target, _value, _gasLimit, _data, withdrawalHash); - messagePasser.initiateWithdrawal{ value: value }(target, gasLimit, data); + messagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); // the sent messages mapping is filled assertEq(messagePasser.sentMessages(withdrawalHash), true); @@ -111,12 +130,14 @@ contract L2ToL1MessagePasserTest is CommonTest { } /// @dev Tests that `burn` succeeds and destroys the ETH held in the contract. - function test_burn_succeeds() external { - messagePasser.initiateWithdrawal{ value: NON_ZERO_VALUE }(NON_ZERO_ADDRESS, NON_ZERO_GASLIMIT, NON_ZERO_DATA); + function testFuzz_burn_succeeds(uint256 _value, address _target, uint256 _gasLimit, bytes memory _data) external { + vm.deal(address(this), _value); + + messagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); - assertEq(address(messagePasser).balance, NON_ZERO_VALUE); + assertEq(address(messagePasser).balance, _value); vm.expectEmit(true, false, false, false); - emit WithdrawerBalanceBurnt(NON_ZERO_VALUE); + emit WithdrawerBalanceBurnt(_value); messagePasser.burn(); // The Withdrawer should have no balance From 7b2cb349bc7ec256f9b4956a46297a36ebecf6b5 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 31 Oct 2023 23:54:02 +0300 Subject: [PATCH 274/374] contracts-bedrock: virtual setup in deploy script Makes the `setUp` function virtual in the deploy script. Part of https://github.com/ethereum-optimism/optimism/pull/7928 --- packages/contracts-bedrock/scripts/Deploy.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/scripts/Deploy.s.sol b/packages/contracts-bedrock/scripts/Deploy.s.sol index c293825a359d..d8a69d454338 100644 --- a/packages/contracts-bedrock/scripts/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/Deploy.s.sol @@ -58,7 +58,7 @@ contract Deploy is Deployer { name_ = "Deploy"; } - function setUp() public override { + function setUp() public virtual override { super.setUp(); string memory path = string.concat(vm.projectRoot(), "/deploy-config/", deploymentContext, ".json"); From 0eb27a974160f7d32802719f3e9fa136c4c65e60 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Wed, 1 Nov 2023 07:14:39 +1000 Subject: [PATCH 275/374] docker: Fix golang-docker target The GIT_COMMIT env var isn't available yet when setting IMAGE_TAGS - in only becomes available in the docker executable, not on the command line. --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 01a42d947702..6125ed93ef13 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ golang-docker: # We don't use a buildx builder here, and just load directly into regular docker, for convenience. GIT_COMMIT=$$(git rev-parse HEAD) \ GIT_DATE=$$(git show -s --format='%ct') \ - IMAGE_TAGS=$$GIT_COMMIT,latest \ + IMAGE_TAGS=$$(git rev-parse HEAD),latest \ docker buildx bake \ --progress plain \ --load \ @@ -189,4 +189,3 @@ install-geth: go install -v github.com/ethereum/go-ethereum/cmd/geth@$(shell cat .gethrc); \ echo "Installed geth!"; true) .PHONY: install-geth - From fae4e077159712b29a6f93c85ad5e001037a6931 Mon Sep 17 00:00:00 2001 From: Michael de Hoog Date: Tue, 31 Oct 2023 12:43:21 -1000 Subject: [PATCH 276/374] Fix batcher panic --- op-batcher/batcher/service.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/op-batcher/batcher/service.go b/op-batcher/batcher/service.go index 1c9a493d0c7e..9af086a3143a 100644 --- a/op-batcher/batcher/service.go +++ b/op-batcher/batcher/service.go @@ -290,8 +290,10 @@ func (bs *BatcherService) Stop(ctx context.Context) error { bs.Log.Info("Stopping batcher") var result error - if err := bs.driver.StopBatchSubmittingIfRunning(ctx); err != nil { - result = errors.Join(result, fmt.Errorf("failed to stop batch submitting: %w", err)) + if bs.driver != nil { + if err := bs.driver.StopBatchSubmittingIfRunning(ctx); err != nil { + result = errors.Join(result, fmt.Errorf("failed to stop batch submitting: %w", err)) + } } if bs.rpcServer != nil { @@ -328,7 +330,7 @@ func (bs *BatcherService) Stop(ctx context.Context) error { if result == nil { bs.stopped.Store(true) - bs.driver.Log.Info("Batch Submitter stopped") + bs.Log.Info("Batch Submitter stopped") } return result } From 87a064415a1b384895a2d64c226acedec5ec9434 Mon Sep 17 00:00:00 2001 From: protolambda Date: Tue, 31 Oct 2023 23:56:29 +0100 Subject: [PATCH 277/374] op-node: span-batch test log level tweak, minor test-vector fix --- op-node/rollup/derive/batches.go | 4 ++-- op-node/rollup/derive/batches_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/op-node/rollup/derive/batches.go b/op-node/rollup/derive/batches.go index 622d4bc2068f..b5ca17088a41 100644 --- a/op-node/rollup/derive/batches.go +++ b/op-node/rollup/derive/batches.go @@ -210,7 +210,7 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B var err error parentBlock, err = l2Fetcher.L2BlockRefByNumber(ctx, parentNum) if err != nil { - log.Error("failed to fetch L2 block", "number", parentNum, "err", err) + log.Warn("failed to fetch L2 block", "number", parentNum, "err", err) // unable to validate the batch for now. retry later. return BatchUndecided } @@ -332,7 +332,7 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B safeBlockNum := parentNum + i + 1 safeBlockPayload, err := l2Fetcher.PayloadByNumber(ctx, safeBlockNum) if err != nil { - log.Error("failed to fetch L2 block payload", "number", parentNum, "err", err) + log.Warn("failed to fetch L2 block payload", "number", parentNum, "err", err) // unable to validate the batch for now. retry later. return BatchUndecided } diff --git a/op-node/rollup/derive/batches_test.go b/op-node/rollup/derive/batches_test.go index 25934f0acd2b..7021a714031e 100644 --- a/op-node/rollup/derive/batches_test.go +++ b/op-node/rollup/derive/batches_test.go @@ -157,7 +157,7 @@ func TestValidBatch(t *testing.T) { ParentHash: l2B1.Hash, Time: l2B1.Time + defaultConf.BlockTime, L1Origin: l1B.ID(), - SequenceNumber: 1, + SequenceNumber: 2, } l1X := eth.L1BlockRef{ From f6662356a2a817ec9fc39e5e065fdb3eb7720c43 Mon Sep 17 00:00:00 2001 From: Michael de Hoog Date: Tue, 31 Oct 2023 13:16:06 -1000 Subject: [PATCH 278/374] Add test --- op-e2e/setup.go | 9 ++++++++- op-e2e/system_test.go | 11 +++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/op-e2e/setup.go b/op-e2e/setup.go index dc6b0e2e9627..236a4cf6e8e4 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -203,6 +203,9 @@ type SystemConfig struct { // Target L1 tx size for the batcher transactions BatcherTargetL1TxSizeBytes uint64 + // Max L1 tx size for the batcher transactions + BatcherMaxL1TxSizeBytes uint64 + // SupportL1TimeTravel determines if the L1 node supports quickly skipping forward in time SupportL1TimeTravel bool } @@ -684,13 +687,17 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste if os.Getenv("OP_E2E_USE_SPAN_BATCH") == "true" { batchType = derive.SpanBatchType } + batcherMaxL1TxSizeBytes := cfg.BatcherMaxL1TxSizeBytes + if batcherMaxL1TxSizeBytes == 0 { + batcherMaxL1TxSizeBytes = 240_000 + } batcherCLIConfig := &bss.CLIConfig{ L1EthRpc: sys.EthInstances["l1"].WSEndpoint(), L2EthRpc: sys.EthInstances["sequencer"].WSEndpoint(), RollupRpc: sys.RollupNodes["sequencer"].HTTPEndpoint(), MaxPendingTransactions: 0, MaxChannelDuration: 1, - MaxL1TxSize: 240_000, + MaxL1TxSize: batcherMaxL1TxSizeBytes, CompressorConfig: compressor.CLIConfig{ TargetL1TxSizeBytes: cfg.BatcherTargetL1TxSizeBytes, TargetNumFrames: 1, diff --git a/op-e2e/system_test.go b/op-e2e/system_test.go index 649bb678890c..bb9999f112b6 100644 --- a/op-e2e/system_test.go +++ b/op-e2e/system_test.go @@ -1553,3 +1553,14 @@ func TestRequiredProtocolVersionChangeAndHalt(t *testing.T) { require.NoError(t, err) t.Log("verified that op-geth closed!") } + +func TestIncorrectBatcherConfiguration(t *testing.T) { + InitParallel(t) + + cfg := DefaultSystemConfig(t) + // make the batcher configuration invalid + cfg.BatcherMaxL1TxSizeBytes = 1 + + _, err := cfg.Start(t) + require.Error(t, err, "Expected error on invalid batcher configuration") +} From c6cd795fefdcbbcb93c60421a32f596950f3d90e Mon Sep 17 00:00:00 2001 From: tre Date: Tue, 31 Oct 2023 17:03:49 -0700 Subject: [PATCH 279/374] Configure scripts for drippie --- .../periphery-deploy-config/4460.json | 16 +- .../periphery-deploy-config/58008.json | 16 +- .../periphery-deploy-config/84532.json | 16 +- .../periphery-deploy-config/901.json | 16 +- .../periphery-deploy-config/919.json | 16 +- .../periphery-deploy-config/999999999.json | 16 +- .../optimism-goerli.json | 16 +- .../optimism-sepolia.json | 16 +- .../periphery-deploy-config/sepolia.json | 38 ++++ .../scripts/DeployPeriphery.s.sol | 178 ++++++++++++++++++ .../scripts/PeripheryDeployConfig.s.sol | 44 +++++ 11 files changed, 380 insertions(+), 8 deletions(-) create mode 100644 packages/contracts-bedrock/periphery-deploy-config/sepolia.json diff --git a/packages/contracts-bedrock/periphery-deploy-config/4460.json b/packages/contracts-bedrock/periphery-deploy-config/4460.json index a429b89f9a69..f52288d9ce57 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/4460.json +++ b/packages/contracts-bedrock/periphery-deploy-config/4460.json @@ -20,5 +20,19 @@ "faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleTtl": 86400, - "faucetOffchainAuthModuleAmount": 50000000000000000 + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "installOpChainFaucetsDrips": false, + "dripVersion": 1, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 } diff --git a/packages/contracts-bedrock/periphery-deploy-config/58008.json b/packages/contracts-bedrock/periphery-deploy-config/58008.json index a429b89f9a69..f52288d9ce57 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/58008.json +++ b/packages/contracts-bedrock/periphery-deploy-config/58008.json @@ -20,5 +20,19 @@ "faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleTtl": 86400, - "faucetOffchainAuthModuleAmount": 50000000000000000 + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "installOpChainFaucetsDrips": false, + "dripVersion": 1, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 } diff --git a/packages/contracts-bedrock/periphery-deploy-config/84532.json b/packages/contracts-bedrock/periphery-deploy-config/84532.json index a429b89f9a69..f52288d9ce57 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/84532.json +++ b/packages/contracts-bedrock/periphery-deploy-config/84532.json @@ -20,5 +20,19 @@ "faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleTtl": 86400, - "faucetOffchainAuthModuleAmount": 50000000000000000 + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "installOpChainFaucetsDrips": false, + "dripVersion": 1, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 } diff --git a/packages/contracts-bedrock/periphery-deploy-config/901.json b/packages/contracts-bedrock/periphery-deploy-config/901.json index a429b89f9a69..f52288d9ce57 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/901.json +++ b/packages/contracts-bedrock/periphery-deploy-config/901.json @@ -20,5 +20,19 @@ "faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleTtl": 86400, - "faucetOffchainAuthModuleAmount": 50000000000000000 + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "installOpChainFaucetsDrips": false, + "dripVersion": 1, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 } diff --git a/packages/contracts-bedrock/periphery-deploy-config/919.json b/packages/contracts-bedrock/periphery-deploy-config/919.json index a429b89f9a69..f52288d9ce57 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/919.json +++ b/packages/contracts-bedrock/periphery-deploy-config/919.json @@ -20,5 +20,19 @@ "faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleTtl": 86400, - "faucetOffchainAuthModuleAmount": 50000000000000000 + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "installOpChainFaucetsDrips": false, + "dripVersion": 1, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 } diff --git a/packages/contracts-bedrock/periphery-deploy-config/999999999.json b/packages/contracts-bedrock/periphery-deploy-config/999999999.json index a429b89f9a69..f52288d9ce57 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/999999999.json +++ b/packages/contracts-bedrock/periphery-deploy-config/999999999.json @@ -20,5 +20,19 @@ "faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleTtl": 86400, - "faucetOffchainAuthModuleAmount": 50000000000000000 + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "installOpChainFaucetsDrips": false, + "dripVersion": 1, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 } diff --git a/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json b/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json index a429b89f9a69..7d369d97a179 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json +++ b/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json @@ -20,5 +20,19 @@ "faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleTtl": 86400, - "faucetOffchainAuthModuleAmount": 50000000000000000 + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "installOpChainFaucetsDrips": false, + "dripVersion": 1, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 } diff --git a/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json b/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json index a429b89f9a69..f52288d9ce57 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json +++ b/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json @@ -20,5 +20,19 @@ "faucetOnchainAuthModuleAmount": 1000000000000000000, "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", "faucetOffchainAuthModuleTtl": 86400, - "faucetOffchainAuthModuleAmount": 50000000000000000 + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "installOpChainFaucetsDrips": false, + "dripVersion": 1, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 } diff --git a/packages/contracts-bedrock/periphery-deploy-config/sepolia.json b/packages/contracts-bedrock/periphery-deploy-config/sepolia.json new file mode 100644 index 000000000000..70e8b5aa5141 --- /dev/null +++ b/packages/contracts-bedrock/periphery-deploy-config/sepolia.json @@ -0,0 +1,38 @@ +{ + "faucetAdmin": "0x212E789D4523D4BAF464f8Fb2A9B9dff2B36e5A6", + "faucetDrippieOwner": "0x10ab157483dd308f8B38aCF2ad823dfD255F56b5", + "faucetDripV1Value": 20000000000000000000, + "faucetDripV1Interval": 3600, + "faucetDripV1Threshold": 100000000000000000000, + "faucetDripV2Interval": 604800, + "faucetDripV2Threshold": 20000000000000000000, + "faucetDripV2Value": 500000000000000000000, + "faucetAdminDripV1Interval": 86400, + "faucetAdminDripV1Threshold": 100000000000000000, + "faucetAdminDripV1Value": 1000000000000000000, + "faucetGelatoTreasury": "0x644CB00854EDC55FE8CCC9c1967BABb22F08Ad2f", + "faucetGelatoRecipient": "0x0E9b4649eB0760A4F01646636E032D68cFDe58FF", + "faucetGelatoBalanceV1DripInterval": 86400, + "faucetGelatoBalanceV1Value": 1000000000000000000, + "faucetGelatoThreshold": 100000000000000000, + "faucetOnchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOnchainAuthModuleTtl": 86400, + "faucetOnchainAuthModuleAmount": 1000000000000000000, + "faucetOffchainAuthModuleAdmin": "0xFe44Ae787A632c45ACea658492dDBebE39f002aC", + "faucetOffchainAuthModuleTtl": 86400, + "faucetOffchainAuthModuleAmount": 50000000000000000, + "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", + "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", + "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", + "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", + "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", + "installOpChainFaucetsDrips": true, + "dripVersion": 1, + "smallOpChainFaucetDripValue": 2000000000000000000, + "smallOpChainFaucetDripInterval": 86400, + "largeOpChainFaucetDripValue": 34000000000000000000, + "largeOpChainFaucetDripInterval": 86400, + "opChainAdminWalletDripValue": 1000000000000000000, + "opChainAdminWalletDripInterval": 2592000 +} diff --git a/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol b/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol index 9099a21a02ce..aa4f614f8a1c 100644 --- a/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol +++ b/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol @@ -47,6 +47,10 @@ contract DeployPeriphery is Deployer { initializeFaucet(); installFaucetAuthModulesConfigs(); + + if (cfg.installOpChainFaucetsDrips()) { + installOpChainFaucetsDrippieConfigs(); + } } /// @notice Deploy all of the proxies @@ -264,6 +268,180 @@ contract DeployPeriphery is Deployer { console.log("Faucet drip configs successfully installed"); } + /// @notice installs drip configs that deposit funds to all OP Chain faucets. This function + /// should only be called on an L1 testnet. + function installOpChainFaucetsDrippieConfigs() public { + uint256 drippieOwnerPrivateKey = vm.envUint("DRIPPIE_OWNER_PRIVATE_KEY"); + vm.startBroadcast(drippieOwnerPrivateKey); + + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + console.log("Installing OP Chain faucet drips at %s", address(drippie)); + installSmallOpChainFaucetsDrips(); + installLargeOpChainFaucetsDrips(); + installSmallOpChainAdminWalletDrips(); + installLargeOpChainAdminWalletDrips(); + + vm.stopBroadcast(); + + console.log("OP chain faucet drip configs successfully installed"); + } + + /// @notice installs drips that send funds to small OP chain faucets on the scheduled interval. + function installSmallOpChainFaucetsDrips() public { + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + address faucetProxy = mustGetAddress("FaucetProxy"); + uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i); + string memory dripNamePrefix = string.concat("faucet-drip-", vm.toString(l1BridgeAddress)); + string memory versionSuffix = string.concat("-", vm.toString(cfg.dripVersion())); + string memory dripName = string.concat(dripNamePrefix, versionSuffix); + if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) { + console.log("installing %s", dripName); + Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); + actions[0] = Drippie.DripAction({ + target: payable(l1BridgeAddress), + data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", faucetProxy, 200000, ""), + value: cfg.smallOpChainFaucetDripValue() + }); + drippie.create({ + _name: dripName, + _config: Drippie.DripConfig({ + reentrant: false, + interval: cfg.smallOpChainFaucetDripInterval(), + dripcheck: CheckTrue(mustGetAddress("CheckTrue")), + checkparams: abi.encode(""), + actions: actions + }) + }); + console.log("%s installed successfully", dripName); + } else { + console.log("%s already installed.", dripName); + } + + _activateIfPausedDrip(drippie, dripName); + } + } + + /// @notice installs drips that send funds to small OP chain faucets on the scheduled interval. + function installSmallOpChainAdminWalletDrips() public { + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + require( + cfg.faucetOnchainAuthModuleAdmin() == cfg.faucetOffchainAuthModuleAdmin(), + "installSmallOpChainAdminWalletDrips: Only handles identical admin wallet addresses" + ); + address adminWallet = cfg.faucetOnchainAuthModuleAdmin(); + uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i); + string memory dripNamePrefix = string.concat("faucet-admin-drip-", vm.toString(l1BridgeAddress)); + string memory versionSuffix = string.concat("-", vm.toString(cfg.dripVersion())); + string memory dripName = string.concat(dripNamePrefix, versionSuffix); + if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) { + console.log("installing %s", dripName); + Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); + actions[0] = Drippie.DripAction({ + target: payable(l1BridgeAddress), + data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", adminWallet, 200000, ""), + value: cfg.opChainAdminWalletDripValue() + }); + drippie.create({ + _name: dripName, + _config: Drippie.DripConfig({ + reentrant: false, + interval: cfg.opChainAdminWalletDripInterval(), + dripcheck: CheckTrue(mustGetAddress("CheckTrue")), + checkparams: abi.encode(""), + actions: actions + }) + }); + console.log("%s installed successfully", dripName); + } else { + console.log("%s already installed.", dripName); + } + + _activateIfPausedDrip(drippie, dripName); + } + } + + /// @notice installs drips that send funds to small OP chain faucets on the scheduled interval. + function installLargeOpChainAdminWalletDrips() public { + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + require( + cfg.faucetOnchainAuthModuleAdmin() == cfg.faucetOffchainAuthModuleAdmin(), + "installLargeOpChainAdminWalletDrips: Only handles identical admin wallet addresses" + ); + address adminWallet = cfg.faucetOnchainAuthModuleAdmin(); + uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i); + string memory dripNamePrefix = string.concat("faucet-admin-drip-", vm.toString(l1BridgeAddress)); + string memory versionSuffix = string.concat("-", vm.toString(cfg.dripVersion())); + string memory dripName = string.concat(dripNamePrefix, versionSuffix); + if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) { + console.log("installing %s", dripName); + Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); + actions[0] = Drippie.DripAction({ + target: payable(l1BridgeAddress), + data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", adminWallet, 200000, ""), + value: cfg.opChainAdminWalletDripValue() + }); + drippie.create({ + _name: dripName, + _config: Drippie.DripConfig({ + reentrant: false, + interval: cfg.opChainAdminWalletDripInterval(), + dripcheck: CheckTrue(mustGetAddress("CheckTrue")), + checkparams: abi.encode(""), + actions: actions + }) + }); + console.log("%s installed successfully", dripName); + } else { + console.log("%s already installed.", dripName); + } + + _activateIfPausedDrip(drippie, dripName); + } + } + + /// @notice installs drips that send funds to large OP chain faucets on the scheduled interval. + function installLargeOpChainFaucetsDrips() public { + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + address faucetProxy = mustGetAddress("FaucetProxy"); + uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i); + string memory dripNamePrefix = string.concat("faucet-drip-", vm.toString(l1BridgeAddress)); + string memory versionSuffix = string.concat("-", vm.toString(cfg.dripVersion())); + string memory dripName = string.concat(dripNamePrefix, versionSuffix); + if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) { + console.log("installing %s", dripName); + Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); + actions[0] = Drippie.DripAction({ + target: payable(l1BridgeAddress), + data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", faucetProxy, 200000, ""), + value: cfg.smallOpChainFaucetDripValue() + }); + drippie.create({ + _name: dripName, + _config: Drippie.DripConfig({ + reentrant: false, + interval: cfg.smallOpChainFaucetDripInterval(), + dripcheck: CheckTrue(mustGetAddress("CheckTrue")), + checkparams: abi.encode(""), + actions: actions + }) + }); + console.log("%s installed successfully", dripName); + } else { + console.log("%s already installed.", dripName); + } + + _activateIfPausedDrip(drippie, dripName); + } + } + /// @notice installs the FaucetDripV1 drip on the faucet drippie contract. function installFaucetDripV1() public broadcast { Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); diff --git a/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol b/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol index 900d6b898950..c00ecbc74e1c 100644 --- a/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol +++ b/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol @@ -34,6 +34,22 @@ contract PeripheryDeployConfig is Script { address public faucetOffchainAuthModuleAdmin; uint256 public faucetOffchainAuthModuleTtl; uint256 public faucetOffchainAuthModuleAmount; + bool public installOpChainFaucetsDrips; + uint256 public smallOpChainFaucetDripValue; + uint256 public smallOpChainFaucetDripInterval; + uint256 public largeOpChainFaucetDripValue; + uint256 public largeOpChainFaucetDripInterval; + uint256 public opChainAdminWalletDripValue; + uint256 public opChainAdminWalletDripInterval; + address public opL1BridgeAddress; + address public zoraL1BridgeAddress; + address public pgnL1BridgeAddress; + address public orderlyL1BridgeAddress; + address public modeL1BridgeAddress; + address public lyraL1BridgeAddress; + address[5] public smallFaucetsL1BridgeAddresses; + address[1] public largeFaucetsL1BridgeAddresses; + uint256 public dripVersion; constructor(string memory _path) { console.log("PeripheryDeployConfig: reading file %s", _path); @@ -66,5 +82,33 @@ contract PeripheryDeployConfig is Script { faucetOffchainAuthModuleAdmin = stdJson.readAddress(_json, "$.faucetOffchainAuthModuleAdmin"); faucetOffchainAuthModuleTtl = stdJson.readUint(_json, "$.faucetOffchainAuthModuleTtl"); faucetOffchainAuthModuleAmount = stdJson.readUint(_json, "$.faucetOffchainAuthModuleAmount"); + installOpChainFaucetsDrips = stdJson.readBool(_json, "$.installOpChainFaucetsDrips"); + opL1BridgeAddress = stdJson.readAddress(_json, "$.opL1BridgeAddress"); + zoraL1BridgeAddress = stdJson.readAddress(_json, "$.zoraL1BridgeAddress"); + pgnL1BridgeAddress = stdJson.readAddress(_json, "$.pgnL1BridgeAddress"); + orderlyL1BridgeAddress = stdJson.readAddress(_json, "$.orderlyL1BridgeAddress"); + modeL1BridgeAddress = stdJson.readAddress(_json, "$.modeL1BridgeAddress"); + lyraL1BridgeAddress = stdJson.readAddress(_json, "$.lyraL1BridgeAddress"); + dripVersion = stdJson.readUint(_json, "$.dripVersion"); + smallOpChainFaucetDripValue = stdJson.readUint(_json, "$.smallOpChainFaucetDripValue"); + smallOpChainFaucetDripInterval = stdJson.readUint(_json, "$.smallOpChainFaucetDripInterval"); + largeOpChainFaucetDripValue = stdJson.readUint(_json, "$.largeOpChainFaucetDripValue"); + largeOpChainFaucetDripInterval = stdJson.readUint(_json, "$.largeOpChainFaucetDripInterval"); + opChainAdminWalletDripValue = stdJson.readUint(_json, "$.opChainAdminWalletDripValue"); + opChainAdminWalletDripInterval = stdJson.readUint(_json, "$.opChainAdminWalletDripInterval"); + largeFaucetsL1BridgeAddresses[0] = opL1BridgeAddress; + smallFaucetsL1BridgeAddresses[0] = zoraL1BridgeAddress; + smallFaucetsL1BridgeAddresses[1] = pgnL1BridgeAddress; + smallFaucetsL1BridgeAddresses[2] = orderlyL1BridgeAddress; + smallFaucetsL1BridgeAddresses[3] = modeL1BridgeAddress; + smallFaucetsL1BridgeAddresses[4] = lyraL1BridgeAddress; + } + + function getSmallFaucetsL1BridgeAddressesCount() public view returns (uint256 count) { + return smallFaucetsL1BridgeAddresses.length; + } + + function getLargeFaucetsL1BridgeAddressesCount() public view returns (uint256 count) { + return largeFaucetsL1BridgeAddresses.length; } } From 8b1df75b6cc75d7889fc6aaca34074903d228396 Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Tue, 24 Oct 2023 21:00:58 +0900 Subject: [PATCH 280/374] op-node: Check l1 inclusion time for span batch --- op-node/rollup/derive/batches.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-node/rollup/derive/batches.go b/op-node/rollup/derive/batches.go index b5ca17088a41..e4acd71d1be5 100644 --- a/op-node/rollup/derive/batches.go +++ b/op-node/rollup/derive/batches.go @@ -47,7 +47,7 @@ func CheckBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1Block log.Error("failed type assertion to SpanBatch") return BatchDrop } - if !cfg.IsSpanBatch(batch.Batch.GetTimestamp()) { + if !cfg.IsSpanBatch(batch.Batch.GetTimestamp()) || !cfg.IsSpanBatch(batch.L1InclusionBlock.Time) { log.Warn("received SpanBatch before SpanBatch hard fork") return BatchDrop } From 57a0209f17f2745f9db3603c6d4d8aa9f333e7b8 Mon Sep 17 00:00:00 2001 From: pcw109550 Date: Wed, 25 Oct 2023 00:05:40 +0900 Subject: [PATCH 281/374] specs: Add span batch hardfork rule --- specs/span-batches.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/specs/span-batches.md b/specs/span-batches.md index 0b0738497e03..3b13d3b69e96 100644 --- a/specs/span-batches.md +++ b/specs/span-batches.md @@ -9,6 +9,7 @@ - [Introduction](#introduction) - [Span batch format](#span-batch-format) +- [Span batch Hard Fork Rule](#span-batch-hard-fork-rule) - [Optimization Strategies](#optimization-strategies) - [Truncating information and storing only necessary data](#truncating-information-and-storing-only-necessary-data) - [`tx_data_headers` removal from initial specs](#tx_data_headers-removal-from-initial-specs) @@ -153,6 +154,20 @@ decoding. For example, lets say bad batcher wrote span batch which `block_count the explicit limit, not trying to consume data until EOF is reached. We can also safely preallocate memory for decoding because we know the upper limit of memory usage. +## Span batch Hard Fork Rule + +Span batch hard fork is activated based on timestamp. + +Activation Rule: `x != null && x >= upgradeTime && y != null && y >= upgradeTime` + +Let `inclusion_block` be the L1 block when the span batch was first fully derived. + +`x == span_start.timestamp`, which is the timestamp of first L2 block timestamp derived from span batch. + +`y == inclusion_block.timestamp`, which is the timestamp of L1 block when span batch was first fully derived. +We need this additional check because span batch hard fork is a derivation update, and +`x` becomes dependent of the hard fork(we must run span batch decoding to find `x`). + ## Optimization Strategies ### Truncating information and storing only necessary data From 662999611fa85ae617a2e9cd1daee8e1a9440a6a Mon Sep 17 00:00:00 2001 From: Tei Im Date: Wed, 1 Nov 2023 16:23:17 +0900 Subject: [PATCH 282/374] Use L1 origin block time for Span batch hard fork activation check --- op-node/rollup/derive/batches.go | 20 ++++++++---- op-node/rollup/derive/batches_test.go | 36 +++++++++++++++++++--- op-node/rollup/derive/channel_in_reader.go | 3 ++ specs/span-batches.md | 12 +++----- 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/op-node/rollup/derive/batches.go b/op-node/rollup/derive/batches.go index e4acd71d1be5..9cba08686f4c 100644 --- a/op-node/rollup/derive/batches.go +++ b/op-node/rollup/derive/batches.go @@ -47,10 +47,6 @@ func CheckBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1Block log.Error("failed type assertion to SpanBatch") return BatchDrop } - if !cfg.IsSpanBatch(batch.Batch.GetTimestamp()) || !cfg.IsSpanBatch(batch.L1InclusionBlock.Time) { - log.Warn("received SpanBatch before SpanBatch hard fork") - return BatchDrop - } return checkSpanBatch(ctx, cfg, log, l1Blocks, l2SafeHead, spanBatch, batch.L1InclusionBlock, l2Fetcher) default: log.Warn("Unrecognized batch type: %d", batch.Batch.GetBatchType()) @@ -181,6 +177,20 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B } epoch := l1Blocks[0] + startEpochNum := uint64(batch.GetStartEpochNum()) + batchOrigin := epoch + if startEpochNum == batchOrigin.Number+1 { + if len(l1Blocks) < 2 { + log.Info("eager batch wants to advance epoch, but could not without more L1 blocks", "current_epoch", epoch.ID()) + return BatchUndecided + } + batchOrigin = l1Blocks[1] + } + if !cfg.IsSpanBatch(batchOrigin.Time) { + log.Warn("received SpanBatch with L1 origin before SpanBatch hard fork") + return BatchDrop + } + nextTimestamp := l2SafeHead.Time + cfg.BlockTime if batch.GetTimestamp() > nextTimestamp { @@ -220,8 +230,6 @@ func checkSpanBatch(ctx context.Context, cfg *rollup.Config, log log.Logger, l1B return BatchDrop } - startEpochNum := uint64(batch.GetStartEpochNum()) - // Filter out batches that were included too late. if startEpochNum+cfg.SeqWindowSize < l1InclusionBlock.Number { log.Warn("batch was included too late, sequence window expired") diff --git a/op-node/rollup/derive/batches_test.go b/op-node/rollup/derive/batches_test.go index 7021a714031e..b122a61e0e79 100644 --- a/op-node/rollup/derive/batches_test.go +++ b/op-node/rollup/derive/batches_test.go @@ -711,6 +711,33 @@ func TestValidBatch(t *testing.T) { }), }, Expected: BatchUndecided, + ExpectedLog: "eager batch wants to advance epoch, but could not without more L1 blocks", + SpanBatchTime: &minTs, + }, + { + Name: "insufficient L1 info for eager derivation - long span", + L1Blocks: []eth.L1BlockRef{l1A}, // don't know about l1B yet + L2SafeHead: l2A2, + Batch: BatchWithL1InclusionBlock{ + L1InclusionBlock: l1C, + Batch: NewSpanBatch([]*SingularBatch{ + { + ParentHash: l2A3.ParentHash, + EpochNum: rollup.Epoch(l2A3.L1Origin.Number), + EpochHash: l2A3.L1Origin.Hash, + Timestamp: l2A3.Time, + Transactions: nil, + }, + { + ParentHash: l2B0.ParentHash, + EpochNum: rollup.Epoch(l2B0.L1Origin.Number), + EpochHash: l2B0.L1Origin.Hash, + Timestamp: l2B0.Time, + Transactions: nil, + }, + }), + }, + Expected: BatchUndecided, ExpectedLog: "need more l1 blocks to check entire origins of span batch", SpanBatchTime: &minTs, }, @@ -1413,7 +1440,7 @@ func TestValidBatch(t *testing.T) { Transactions: []hexutil.Bytes{randTxData}, }, }, - SpanBatchTime: &l2A2.Time, + SpanBatchTime: &l1B.Time, Expected: BatchAccept, }, { @@ -1432,8 +1459,9 @@ func TestValidBatch(t *testing.T) { }, }), }, - SpanBatchTime: &l2A2.Time, + SpanBatchTime: &l1B.Time, Expected: BatchDrop, + ExpectedLog: "received SpanBatch with L1 origin before SpanBatch hard fork", }, { Name: "singular batch after hard fork", @@ -1449,7 +1477,7 @@ func TestValidBatch(t *testing.T) { Transactions: []hexutil.Bytes{randTxData}, }, }, - SpanBatchTime: &l2A0.Time, + SpanBatchTime: &l1A.Time, Expected: BatchAccept, }, { @@ -1468,7 +1496,7 @@ func TestValidBatch(t *testing.T) { }, }), }, - SpanBatchTime: &l2A0.Time, + SpanBatchTime: &l1A.Time, Expected: BatchAccept, }, } diff --git a/op-node/rollup/derive/channel_in_reader.go b/op-node/rollup/derive/channel_in_reader.go index 24530b903e1f..374b676ccf0e 100644 --- a/op-node/rollup/derive/channel_in_reader.go +++ b/op-node/rollup/derive/channel_in_reader.go @@ -99,6 +99,9 @@ func (cr *ChannelInReader) NextBatch(ctx context.Context) (Batch, error) { return singularBatch, nil case SpanBatchType: if origin := cr.Origin(); !cr.cfg.IsSpanBatch(origin.Time) { + // Check hard fork activation with the L1 inclusion block time instead of the L1 origin block time. + // Therefore, even if the batch passed this rule, it can be dropped in the batch queue. + // This is just for early dropping invalid batches as soon as possible. return nil, NewTemporaryError(fmt.Errorf("cannot accept span batch in L1 block %s at time %d", origin, origin.Time)) } rawSpanBatch, ok := batchData.inner.(*RawSpanBatch) diff --git a/specs/span-batches.md b/specs/span-batches.md index 3b13d3b69e96..34cfbd3cd287 100644 --- a/specs/span-batches.md +++ b/specs/span-batches.md @@ -158,15 +158,11 @@ because we know the upper limit of memory usage. Span batch hard fork is activated based on timestamp. -Activation Rule: `x != null && x >= upgradeTime && y != null && y >= upgradeTime` +Activation Rule: `upgradeNumber != null && x >= upgradeTime` -Let `inclusion_block` be the L1 block when the span batch was first fully derived. - -`x == span_start.timestamp`, which is the timestamp of first L2 block timestamp derived from span batch. - -`y == inclusion_block.timestamp`, which is the timestamp of L1 block when span batch was first fully derived. -We need this additional check because span batch hard fork is a derivation update, and -`x` becomes dependent of the hard fork(we must run span batch decoding to find `x`). +`x == span_start.l1_origin.timestamp`, which is the L1 origin block timestamp of the first block in the span. +This rule ensures that every chain activity regarding this span batch is done after the hard fork. +i.e. Every block in the span is created, submitted to the L1, and derived from the L1 after the hard fork. ## Optimization Strategies From 9cbb9fb3e8f9fa1cf93772eaa049b22e392a7861 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 31 Oct 2023 23:19:50 +0300 Subject: [PATCH 283/374] contracts-bedrock: modularize mocks There are a bunch of contracts mocks used only for testing. This commit moves the mocks to a particular directory `test/mocks` so that we can standardize around that as being the location for mock contracts only used for testing to go. This commit exists to make https://github.com/ethereum-optimism/optimism/pull/7928 easier to implement. --- .../test/AdminFaucetAuthModule.t.sol | 2 +- .../test/AssetReceiver.t.sol | 4 +- packages/contracts-bedrock/test/Drippie.t.sol | 2 +- packages/contracts-bedrock/test/Faucet.t.sol | 2 +- packages/contracts-bedrock/test/Helpers.sol | 195 ------------------ .../contracts-bedrock/test/Optimist.t.sol | 2 +- .../test/OptimistAllowlist.t.sol | 2 +- .../test/OptimistInviter.t.sol | 4 +- .../contracts-bedrock/test/Transactor.t.sol | 3 +- .../contracts-bedrock/test/mocks/Callers.sol | 26 +++ .../test/mocks/FaucetHelper.sol | 59 ++++++ .../test/mocks/OptimistInviterHelper.sol | 96 +++++++++ .../test/mocks/SimpleStorage.sol | 14 ++ .../test/mocks/TestERC1271Wallet.sol | 20 ++ .../test/mocks/TestERC20.sol | 12 ++ .../test/mocks/TestERC721.sol | 14 ++ 16 files changed, 251 insertions(+), 206 deletions(-) create mode 100644 packages/contracts-bedrock/test/mocks/Callers.sol create mode 100644 packages/contracts-bedrock/test/mocks/FaucetHelper.sol create mode 100644 packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol create mode 100644 packages/contracts-bedrock/test/mocks/SimpleStorage.sol create mode 100644 packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol create mode 100644 packages/contracts-bedrock/test/mocks/TestERC20.sol create mode 100644 packages/contracts-bedrock/test/mocks/TestERC721.sol diff --git a/packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol b/packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol index 340bbfe4aa83..93a10329b452 100644 --- a/packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol +++ b/packages/contracts-bedrock/test/AdminFaucetAuthModule.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; import { Faucet } from "src/periphery/faucet/Faucet.sol"; -import { FaucetHelper } from "test/Helpers.sol"; +import { FaucetHelper } from "test/mocks/FaucetHelper.sol"; /// @title AdminFaucetAuthModuleTest /// @notice Tests the AdminFaucetAuthModule contract. diff --git a/packages/contracts-bedrock/test/AssetReceiver.t.sol b/packages/contracts-bedrock/test/AssetReceiver.t.sol index 87c14e2608dd..4ee74e43d127 100644 --- a/packages/contracts-bedrock/test/AssetReceiver.t.sol +++ b/packages/contracts-bedrock/test/AssetReceiver.t.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { TestERC20 } from "test/Helpers.sol"; -import { TestERC721 } from "test/Helpers.sol"; +import { TestERC20 } from "test/mocks/TestERC20.sol"; +import { TestERC721 } from "test/mocks/TestERC721.sol"; import { AssetReceiver } from "src/periphery/AssetReceiver.sol"; contract AssetReceiver_Initializer is Test { diff --git a/packages/contracts-bedrock/test/Drippie.t.sol b/packages/contracts-bedrock/test/Drippie.t.sol index 758011448608..c56b9292378a 100644 --- a/packages/contracts-bedrock/test/Drippie.t.sol +++ b/packages/contracts-bedrock/test/Drippie.t.sol @@ -5,7 +5,7 @@ import { Test } from "forge-std/Test.sol"; import { Drippie } from "src/periphery/drippie/Drippie.sol"; import { IDripCheck } from "src/periphery/drippie/IDripCheck.sol"; import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol"; -import { SimpleStorage } from "test/Helpers.sol"; +import { SimpleStorage } from "test/mocks/SimpleStorage.sol"; /// @title TestDrippie /// @notice This is a wrapper contract around Drippie used for testing. diff --git a/packages/contracts-bedrock/test/Faucet.t.sol b/packages/contracts-bedrock/test/Faucet.t.sol index 3c4da9c98798..24494edfb1a6 100644 --- a/packages/contracts-bedrock/test/Faucet.t.sol +++ b/packages/contracts-bedrock/test/Faucet.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; import { Faucet } from "src/periphery/faucet/Faucet.sol"; import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; -import { FaucetHelper } from "test/Helpers.sol"; +import { FaucetHelper } from "test/mocks/FaucetHelper.sol"; contract Faucet_Initializer is Test { event Drip(string indexed authModule, bytes32 indexed userId, uint256 amount, address indexed recipient); diff --git a/packages/contracts-bedrock/test/Helpers.sol b/packages/contracts-bedrock/test/Helpers.sol index a27da6e2b2fb..e64dbdaf803a 100644 --- a/packages/contracts-bedrock/test/Helpers.sol +++ b/packages/contracts-bedrock/test/Helpers.sol @@ -1,33 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol"; -import { ERC721 } from "@rari-capital/solmate/src/tokens/ERC721.sol"; -import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; -import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol"; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { ECDSAUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol"; -import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; - -contract TestERC20 is ERC20 { - constructor() ERC20("TEST", "TST", 18) { } - - function mint(address to, uint256 value) public { - _mint(to, value); - } -} - -contract TestERC721 is ERC721 { - constructor() ERC721("TEST", "TST") { } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function tokenURI(uint256) public pure virtual override returns (string memory) { } -} - contract CallRecorder { struct CallInfo { address sender; @@ -51,171 +24,3 @@ contract Reverter { revert("Reverter reverted"); } } - -contract SimpleStorage { - mapping(bytes32 => bytes32) public db; - - function set(bytes32 _key, bytes32 _value) public payable { - db[_key] = _value; - } - - function get(bytes32 _key) public view returns (bytes32) { - return db[_key]; - } -} - -/// @notice Simple helper contract that helps with testing flow and signature for -/// OptimistInviter contract. Made this a separate contract instead of including -/// in OptimistInviter.t.sol for reusability. -contract OptimistInviterHelper { - /// @notice EIP712 typehash for the ClaimableInvite type. - bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = keccak256("ClaimableInvite(address issuer,bytes32 nonce)"); - - /// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature. - bytes32 public constant EIP712_DOMAIN_TYPEHASH = - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); - - /// @notice Address of OptimistInviter contract we are testing. - OptimistInviter public optimistInviter; - - /// @notice OptimistInviter contract name. Used to construct the EIP-712 domain. - string public name; - - /// @notice Keeps track of current nonce to generate new nonces for each invite. - uint256 public currentNonce; - - constructor(OptimistInviter _optimistInviter, string memory _name) { - optimistInviter = _optimistInviter; - name = _name; - } - - /// @notice Returns the hash of the struct ClaimableInvite. - /// @param _claimableInvite ClaimableInvite struct to hash. - /// @return EIP-712 typed struct hash. - function getClaimableInviteStructHash(OptimistInviter.ClaimableInvite memory _claimableInvite) - public - pure - returns (bytes32) - { - return keccak256(abi.encode(CLAIMABLE_INVITE_TYPEHASH, _claimableInvite.issuer, _claimableInvite.nonce)); - } - - /// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use - /// pseudorandom nonces. - /// @return Nonce that should be used as part of ClaimableInvite. - function consumeNonce() public returns (bytes32) { - return bytes32(keccak256(abi.encode(currentNonce++))); - } - - /// @notice Returns a ClaimableInvite with the issuer and current nonce. - /// @param _issuer Issuer to include in the ClaimableInvite. - /// @return ClaimableInvite that can be hashed & signed. - function getClaimableInviteWithNewNonce(address _issuer) public returns (OptimistInviter.ClaimableInvite memory) { - return OptimistInviter.ClaimableInvite(_issuer, consumeNonce()); - } - - /// @notice Computes the EIP712 digest with default correct parameters. - /// @param _claimableInvite ClaimableInvite struct to hash. - /// @return EIP-712 compatible digest. - function getDigest(OptimistInviter.ClaimableInvite calldata _claimableInvite) public view returns (bytes32) { - return getDigestWithEIP712Domain( - _claimableInvite, - bytes(name), - bytes(optimistInviter.EIP712_VERSION()), - block.chainid, - address(optimistInviter) - ); - } - - /// @notice Computes the EIP712 digest with the given domain parameters. - /// Used for testing that different domain parameters fail. - /// @param _claimableInvite ClaimableInvite struct to hash. - /// @param _name Contract name to use in the EIP712 domain. - /// @param _version Contract version to use in the EIP712 domain. - /// @param _chainid Chain ID to use in the EIP712 domain. - /// @param _verifyingContract Address to use in the EIP712 domain. - /// @return EIP-712 compatible digest. - function getDigestWithEIP712Domain( - OptimistInviter.ClaimableInvite calldata _claimableInvite, - bytes memory _name, - bytes memory _version, - uint256 _chainid, - address _verifyingContract - ) - public - pure - returns (bytes32) - { - bytes32 domainSeparator = keccak256( - abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract) - ); - return ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite)); - } -} - -/// @notice Simple ERC1271 wallet that can be used to test the ERC1271 signature checker. -/// @notice https://github.com/OpenZeppelin/openzeppelin-contracts/ -/// blob/master/contracts/mocks/ERC1271WalletMock.sol -contract TestERC1271Wallet is Ownable, IERC1271 { - constructor(address originalOwner) { - transferOwnership(originalOwner); - } - - function isValidSignature(bytes32 hash, bytes memory signature) public view override returns (bytes4 magicValue) { - return ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0); - } -} - -/// @notice Simple helper contract that helps with testing the Faucet contract. -contract FaucetHelper { - /// @notice EIP712 typehash for the Proof type. - bytes32 public constant PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)"); - - /// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature. - bytes32 public constant EIP712_DOMAIN_TYPEHASH = - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); - - /// @notice Keeps track of current nonce to generate new nonces for each drip. - uint256 public currentNonce; - - /// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use - /// pseudorandom nonces. - /// @return Nonce that should be used as part of drip parameters. - function consumeNonce() public returns (bytes32) { - return bytes32(keccak256(abi.encode(currentNonce++))); - } - - /// @notice Returns the hash of the struct Proof. - /// @param _proof Proof struct to hash. - /// @return EIP-712 typed struct hash. - function getProofStructHash(AdminFaucetAuthModule.Proof memory _proof) public pure returns (bytes32) { - return keccak256(abi.encode(PROOF_TYPEHASH, _proof.recipient, _proof.nonce, _proof.id)); - } - - /// @notice Computes the EIP712 digest with the given domain parameters. - /// Used for testing that different domain parameters fail. - /// @param _proof Proof struct to hash. - /// @param _name Contract name to use in the EIP712 domain. - /// @param _version Contract version to use in the EIP712 domain. - /// @param _chainid Chain ID to use in the EIP712 domain. - /// @param _verifyingContract Address to use in the EIP712 domain. - /// @param _verifyingContract Address to use in the EIP712 domain. - /// @param _verifyingContract Address to use in the EIP712 domain. - /// @return EIP-712 compatible digest. - function getDigestWithEIP712Domain( - AdminFaucetAuthModule.Proof memory _proof, - bytes memory _name, - bytes memory _version, - uint256 _chainid, - address _verifyingContract - ) - public - pure - returns (bytes32) - { - bytes32 domainSeparator = keccak256( - abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract) - ); - return ECDSAUpgradeable.toTypedDataHash(domainSeparator, getProofStructHash(_proof)); - } -} diff --git a/packages/contracts-bedrock/test/Optimist.t.sol b/packages/contracts-bedrock/test/Optimist.t.sol index a7a84e2b9854..9502796e4e6a 100644 --- a/packages/contracts-bedrock/test/Optimist.t.sol +++ b/packages/contracts-bedrock/test/Optimist.t.sol @@ -7,7 +7,7 @@ import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol" import { Optimist } from "src/periphery/op-nft/Optimist.sol"; import { OptimistAllowlist } from "src/periphery/op-nft/OptimistAllowlist.sol"; import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; -import { OptimistInviterHelper } from "test/Helpers.sol"; +import { OptimistInviterHelper } from "test/mocks/OptimistInviterHelper.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; diff --git a/packages/contracts-bedrock/test/OptimistAllowlist.t.sol b/packages/contracts-bedrock/test/OptimistAllowlist.t.sol index d7f53ff8c23c..4855802489c3 100644 --- a/packages/contracts-bedrock/test/OptimistAllowlist.t.sol +++ b/packages/contracts-bedrock/test/OptimistAllowlist.t.sol @@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol"; import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; import { OptimistAllowlist } from "src/periphery/op-nft/OptimistAllowlist.sol"; import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; -import { OptimistInviterHelper } from "test/Helpers.sol"; +import { OptimistInviterHelper } from "test/mocks/OptimistInviterHelper.sol"; import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; contract OptimistAllowlist_Initializer is Test { diff --git a/packages/contracts-bedrock/test/OptimistInviter.t.sol b/packages/contracts-bedrock/test/OptimistInviter.t.sol index 677dceb7d151..53d24105d122 100644 --- a/packages/contracts-bedrock/test/OptimistInviter.t.sol +++ b/packages/contracts-bedrock/test/OptimistInviter.t.sol @@ -7,8 +7,8 @@ import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol" import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; import { Optimist } from "src/periphery/op-nft/Optimist.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { TestERC1271Wallet } from "test/Helpers.sol"; -import { OptimistInviterHelper } from "test/Helpers.sol"; +import { TestERC1271Wallet } from "test/mocks/TestERC1271Wallet.sol"; +import { OptimistInviterHelper } from "test/mocks/OptimistInviterHelper.sol"; import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; contract OptimistInviter_Initializer is Test { diff --git a/packages/contracts-bedrock/test/Transactor.t.sol b/packages/contracts-bedrock/test/Transactor.t.sol index 70c02e53d813..af6ce0fba1ca 100644 --- a/packages/contracts-bedrock/test/Transactor.t.sol +++ b/packages/contracts-bedrock/test/Transactor.t.sol @@ -3,8 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; -import { CallRecorder } from "test/Helpers.sol"; -import { Reverter } from "test/Helpers.sol"; +import { CallRecorder, Reverter } from "test/mocks/Callers.sol"; import { Transactor } from "src/periphery/Transactor.sol"; contract Transactor_Initializer is Test { diff --git a/packages/contracts-bedrock/test/mocks/Callers.sol b/packages/contracts-bedrock/test/mocks/Callers.sol new file mode 100644 index 000000000000..e64dbdaf803a --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/Callers.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract CallRecorder { + struct CallInfo { + address sender; + bytes data; + uint256 gas; + uint256 value; + } + + CallInfo public lastCall; + + function record() public payable { + lastCall.sender = msg.sender; + lastCall.data = msg.data; + lastCall.gas = gasleft(); + lastCall.value = msg.value; + } +} + +contract Reverter { + function doRevert() public pure { + revert("Reverter reverted"); + } +} diff --git a/packages/contracts-bedrock/test/mocks/FaucetHelper.sol b/packages/contracts-bedrock/test/mocks/FaucetHelper.sol new file mode 100644 index 000000000000..e9023e2d93e8 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/FaucetHelper.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ECDSAUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol"; +import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; + +/// @notice Simple helper contract that helps with testing the Faucet contract. +contract FaucetHelper { + /// @notice EIP712 typehash for the Proof type. + bytes32 public constant PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)"); + + /// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature. + bytes32 public constant EIP712_DOMAIN_TYPEHASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + + /// @notice Keeps track of current nonce to generate new nonces for each drip. + uint256 public currentNonce; + + /// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use + /// pseudorandom nonces. + /// @return Nonce that should be used as part of drip parameters. + function consumeNonce() public returns (bytes32) { + return bytes32(keccak256(abi.encode(currentNonce++))); + } + + /// @notice Returns the hash of the struct Proof. + /// @param _proof Proof struct to hash. + /// @return EIP-712 typed struct hash. + function getProofStructHash(AdminFaucetAuthModule.Proof memory _proof) public pure returns (bytes32) { + return keccak256(abi.encode(PROOF_TYPEHASH, _proof.recipient, _proof.nonce, _proof.id)); + } + + /// @notice Computes the EIP712 digest with the given domain parameters. + /// Used for testing that different domain parameters fail. + /// @param _proof Proof struct to hash. + /// @param _name Contract name to use in the EIP712 domain. + /// @param _version Contract version to use in the EIP712 domain. + /// @param _chainid Chain ID to use in the EIP712 domain. + /// @param _verifyingContract Address to use in the EIP712 domain. + /// @param _verifyingContract Address to use in the EIP712 domain. + /// @param _verifyingContract Address to use in the EIP712 domain. + /// @return EIP-712 compatible digest. + function getDigestWithEIP712Domain( + AdminFaucetAuthModule.Proof memory _proof, + bytes memory _name, + bytes memory _version, + uint256 _chainid, + address _verifyingContract + ) + public + pure + returns (bytes32) + { + bytes32 domainSeparator = keccak256( + abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract) + ); + return ECDSAUpgradeable.toTypedDataHash(domainSeparator, getProofStructHash(_proof)); + } +} diff --git a/packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol b/packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol new file mode 100644 index 000000000000..3eaabbf0be93 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { OptimistInviter } from "src/periphery/op-nft/OptimistInviter.sol"; +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; + +/// @notice Simple helper contract that helps with testing flow and signature for +/// OptimistInviter contract. Made this a separate contract instead of including +/// in OptimistInviter.t.sol for reusability. +contract OptimistInviterHelper { + /// @notice EIP712 typehash for the ClaimableInvite type. + bytes32 public constant CLAIMABLE_INVITE_TYPEHASH = keccak256("ClaimableInvite(address issuer,bytes32 nonce)"); + + /// @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature. + bytes32 public constant EIP712_DOMAIN_TYPEHASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + + /// @notice Address of OptimistInviter contract we are testing. + OptimistInviter public optimistInviter; + + /// @notice OptimistInviter contract name. Used to construct the EIP-712 domain. + string public name; + + /// @notice Keeps track of current nonce to generate new nonces for each invite. + uint256 public currentNonce; + + constructor(OptimistInviter _optimistInviter, string memory _name) { + optimistInviter = _optimistInviter; + name = _name; + } + + /// @notice Returns the hash of the struct ClaimableInvite. + /// @param _claimableInvite ClaimableInvite struct to hash. + /// @return EIP-712 typed struct hash. + function getClaimableInviteStructHash(OptimistInviter.ClaimableInvite memory _claimableInvite) + public + pure + returns (bytes32) + { + return keccak256(abi.encode(CLAIMABLE_INVITE_TYPEHASH, _claimableInvite.issuer, _claimableInvite.nonce)); + } + + /// @notice Returns a bytes32 nonce that should change everytime. In practice, people should use + /// pseudorandom nonces. + /// @return Nonce that should be used as part of ClaimableInvite. + function consumeNonce() public returns (bytes32) { + return bytes32(keccak256(abi.encode(currentNonce++))); + } + + /// @notice Returns a ClaimableInvite with the issuer and current nonce. + /// @param _issuer Issuer to include in the ClaimableInvite. + /// @return ClaimableInvite that can be hashed & signed. + function getClaimableInviteWithNewNonce(address _issuer) public returns (OptimistInviter.ClaimableInvite memory) { + return OptimistInviter.ClaimableInvite(_issuer, consumeNonce()); + } + + /// @notice Computes the EIP712 digest with default correct parameters. + /// @param _claimableInvite ClaimableInvite struct to hash. + /// @return EIP-712 compatible digest. + function getDigest(OptimistInviter.ClaimableInvite calldata _claimableInvite) public view returns (bytes32) { + return getDigestWithEIP712Domain( + _claimableInvite, + bytes(name), + bytes(optimistInviter.EIP712_VERSION()), + block.chainid, + address(optimistInviter) + ); + } + + /// @notice Computes the EIP712 digest with the given domain parameters. + /// Used for testing that different domain parameters fail. + /// @param _claimableInvite ClaimableInvite struct to hash. + /// @param _name Contract name to use in the EIP712 domain. + /// @param _version Contract version to use in the EIP712 domain. + /// @param _chainid Chain ID to use in the EIP712 domain. + /// @param _verifyingContract Address to use in the EIP712 domain. + /// @return EIP-712 compatible digest. + function getDigestWithEIP712Domain( + OptimistInviter.ClaimableInvite calldata _claimableInvite, + bytes memory _name, + bytes memory _version, + uint256 _chainid, + address _verifyingContract + ) + public + pure + returns (bytes32) + { + bytes32 domainSeparator = keccak256( + abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(_name), keccak256(_version), _chainid, _verifyingContract) + ); + return ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite)); + } +} + + diff --git a/packages/contracts-bedrock/test/mocks/SimpleStorage.sol b/packages/contracts-bedrock/test/mocks/SimpleStorage.sol new file mode 100644 index 000000000000..218505b24c05 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/SimpleStorage.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract SimpleStorage { + mapping(bytes32 => bytes32) public db; + + function set(bytes32 _key, bytes32 _value) public payable { + db[_key] = _value; + } + + function get(bytes32 _key) public view returns (bytes32) { + return db[_key]; + } +} diff --git a/packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol b/packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol new file mode 100644 index 000000000000..0266fe26f056 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol"; +import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; + +/// @notice Simple ERC1271 wallet that can be used to test the ERC1271 signature checker. +/// @notice https://github.com/OpenZeppelin/openzeppelin-contracts/ +/// blob/master/contracts/mocks/ERC1271WalletMock.sol +contract TestERC1271Wallet is Ownable, IERC1271 { + constructor(address originalOwner) { + transferOwnership(originalOwner); + } + + function isValidSignature(bytes32 hash, bytes memory signature) public view override returns (bytes4 magicValue) { + return ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0); + } +} + diff --git a/packages/contracts-bedrock/test/mocks/TestERC20.sol b/packages/contracts-bedrock/test/mocks/TestERC20.sol new file mode 100644 index 000000000000..0c6603ce401f --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/TestERC20.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol"; + +contract TestERC20 is ERC20 { + constructor() ERC20("TEST", "TST", 18) { } + + function mint(address to, uint256 value) public { + _mint(to, value); + } +} diff --git a/packages/contracts-bedrock/test/mocks/TestERC721.sol b/packages/contracts-bedrock/test/mocks/TestERC721.sol new file mode 100644 index 000000000000..294b4a93c7e5 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/TestERC721.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ERC721 } from "@rari-capital/solmate/src/tokens/ERC721.sol"; + +contract TestERC721 is ERC721 { + constructor() ERC721("TEST", "TST") { } + + function mint(address to, uint256 tokenId) public { + _mint(to, tokenId); + } + + function tokenURI(uint256) public pure virtual override returns (string memory) { } +} From eeea9ed284e3eb5cf194149736647113b92498f8 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 31 Oct 2023 23:37:25 +0300 Subject: [PATCH 284/374] op-bindings: regenerate --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index cab2a3b89d8d..42d41cd47ad9 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:299;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:299;2534:6:135;400:55:299;382:74;;370:2;355:18;2448:99:135;211:251:299;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:299;;;1743:2;1728:18;26025:6379:135;1609:177:299;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:299;19164:28:135;;;2164:21:299;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:299;14107:30:135;;;2511:21:299;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:299;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:299;37406:29:135;;;2860:21:299;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:299;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:299;20288:41:135;;;3208:21:299;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:299;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:299;;;8234:54:135;3601:23:299;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:299;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:299;21415:72:135;;;4259:21:299;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:299;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:299:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:299;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:299;-1:-1:-1;1349:2:299;1334:18;;1321:32;;-1:-1:-1;1365:16:299;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:299;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:299:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:299;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:299:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:305;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:305;2534:6:135;400:55:305;382:74;;370:2;355:18;2448:99:135;211:251:305;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:305;;;1743:2;1728:18;26025:6379:135;1609:177:305;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:305;19164:28:135;;;2164:21:305;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:305;14107:30:135;;;2511:21:305;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:305;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:305;37406:29:135;;;2860:21:305;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:305;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:305;20288:41:135;;;3208:21:305;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:305;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:305;;;8234:54:135;3601:23:305;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:305;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:305;21415:72:135;;;4259:21:305;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:305;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:305:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:305;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:305;-1:-1:-1;1349:2:305;1334:18;;1321:32;;-1:-1:-1;1365:16:305;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:305;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:305:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:305;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:305:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 82e64da4c864..d03ea4e51ec2 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:299;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:299;;607:22;589:41;;577:2;562:18;680:66:137;449:187:299;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:299;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:299;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:299;906:62:137;;;2890:21:299;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:299:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:299;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:299:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:299;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:299;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:299;1069:19;1056:33;;-1:-1:-1;641:454:299;-1:-1:-1;641:454:299:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:299;;2017:180;-1:-1:-1;2017:180:299:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:299;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:299;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:305;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:305;;607:22;589:41;;577:2;562:18;680:66:137;449:187:305;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:305;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:305;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:305;906:62:137;;;2890:21:305;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:305:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:305;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:305:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:305;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:305;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:305;1069:19;1056:33;;-1:-1:-1;641:454:305;-1:-1:-1;641:454:305:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:305;;2017:180;-1:-1:-1;2017:180:305:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:305;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:305;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { From 5f41b96d53d97355f2bdccdf43a41d367dbc1fd8 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 31 Oct 2023 23:39:21 +0300 Subject: [PATCH 285/374] lint: fix --- packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol | 2 -- packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol | 1 - 2 files changed, 3 deletions(-) diff --git a/packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol b/packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol index 3eaabbf0be93..ebc2289f9c10 100644 --- a/packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol +++ b/packages/contracts-bedrock/test/mocks/OptimistInviterHelper.sol @@ -92,5 +92,3 @@ contract OptimistInviterHelper { return ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite)); } } - - diff --git a/packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol b/packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol index 0266fe26f056..c04ed608b7d7 100644 --- a/packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol +++ b/packages/contracts-bedrock/test/mocks/TestERC1271Wallet.sol @@ -17,4 +17,3 @@ contract TestERC1271Wallet is Ownable, IERC1271 { return ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0); } } - From b0895c0906688b529a189d7a473166004ca2ad14 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 14:35:56 +0300 Subject: [PATCH 286/374] contracts-bedrock: delete dead file --- packages/contracts-bedrock/test/Helpers.sol | 26 --------------------- 1 file changed, 26 deletions(-) delete mode 100644 packages/contracts-bedrock/test/Helpers.sol diff --git a/packages/contracts-bedrock/test/Helpers.sol b/packages/contracts-bedrock/test/Helpers.sol deleted file mode 100644 index e64dbdaf803a..000000000000 --- a/packages/contracts-bedrock/test/Helpers.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -contract CallRecorder { - struct CallInfo { - address sender; - bytes data; - uint256 gas; - uint256 value; - } - - CallInfo public lastCall; - - function record() public payable { - lastCall.sender = msg.sender; - lastCall.data = msg.data; - lastCall.gas = gasleft(); - lastCall.value = msg.value; - } -} - -contract Reverter { - function doRevert() public pure { - revert("Reverter reverted"); - } -} From b37523786c815498e147a1b499f601ca20e61ea0 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 14:46:48 +0300 Subject: [PATCH 287/374] contracts-bedrock: modularize the `AlphabetVM` Moves the `AlphabetVM` contract into its own file because previously it was resulting in an import cycle. This was causing compilation errors when refactoring the code to use the deploy script to set up the tests. All mock contracts used for testing can now live in `test/mocks` instead of being randomly placed around the codebase. --- op-bindings/bindings/alphabetvm_more.go | 2 +- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- .../contracts-bedrock/scripts/Deploy.s.sol | 2 +- .../test/FaultDisputeGame.t.sol | 36 +----------------- .../test/mocks/AlphabetVM.sol | 38 +++++++++++++++++++ 6 files changed, 44 insertions(+), 38 deletions(-) create mode 100644 packages/contracts-bedrock/test/mocks/AlphabetVM.sol diff --git a/op-bindings/bindings/alphabetvm_more.go b/op-bindings/bindings/alphabetvm_more.go index 1236b475958b..78bacad2b036 100644 --- a/op-bindings/bindings/alphabetvm_more.go +++ b/op-bindings/bindings/alphabetvm_more.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/solc" ) -const AlphabetVMStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"test/FaultDisputeGame.t.sol:AlphabetVM\",\"label\":\"oracle\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_contract(IPreimageOracle)1001\"}],\"types\":{\"t_contract(IPreimageOracle)1001\":{\"encoding\":\"inplace\",\"label\":\"contract IPreimageOracle\",\"numberOfBytes\":\"20\"}}}" +const AlphabetVMStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"test/mocks/AlphabetVM.sol:AlphabetVM\",\"label\":\"oracle\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_contract(IPreimageOracle)1001\"}],\"types\":{\"t_contract(IPreimageOracle)1001\":{\"encoding\":\"inplace\",\"label\":\"contract IPreimageOracle\",\"numberOfBytes\":\"20\"}}}" var AlphabetVMStorageLayout = new(solc.StorageLayout) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index 42d41cd47ad9..f6a602ff5a6d 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:305;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:305;2534:6:135;400:55:305;382:74;;370:2;355:18;2448:99:135;211:251:305;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:305;;;1743:2;1728:18;26025:6379:135;1609:177:305;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:305;19164:28:135;;;2164:21:305;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:305;14107:30:135;;;2511:21:305;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:305;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:305;37406:29:135;;;2860:21:305;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:305;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:305;20288:41:135;;;3208:21:305;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:305;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:305;;;8234:54:135;3601:23:305;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:305;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:305;21415:72:135;;;4259:21:305;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:305;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:305:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:305;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:305;-1:-1:-1;1349:2:305;1334:18;;1321:32;;-1:-1:-1;1365:16:305;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:305;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:305:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:305;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:305:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:306;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:306;2534:6:135;400:55:306;382:74;;370:2;355:18;2448:99:135;211:251:306;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:306;;;1743:2;1728:18;26025:6379:135;1609:177:306;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:306;19164:28:135;;;2164:21:306;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:306;14107:30:135;;;2511:21:306;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:306;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:306;37406:29:135;;;2860:21:306;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:306;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:306;20288:41:135;;;3208:21:306;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:306;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:306;;;8234:54:135;3601:23:306;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:306;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:306;21415:72:135;;;4259:21:306;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:306;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:306:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:306;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:306;-1:-1:-1;1349:2:306;1334:18;;1321:32;;-1:-1:-1;1365:16:306;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:306;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:306:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:306;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:306:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index d03ea4e51ec2..8523b96a5316 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:305;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:305;;607:22;589:41;;577:2;562:18;680:66:137;449:187:305;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:305;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:305;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:305;906:62:137;;;2890:21:305;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:305:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:305;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:305:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:305;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:305;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:305;1069:19;1056:33;;-1:-1:-1;641:454:305;-1:-1:-1;641:454:305:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:305;;2017:180;-1:-1:-1;2017:180:305:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:305;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:305;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:306;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:306;;607:22;589:41;;577:2;562:18;680:66:137;449:187:306;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:306;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:306;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:306;906:62:137;;;2890:21:306;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:306:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:306;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:306:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:306;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:306;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:306;1069:19;1056:33;;-1:-1:-1;641:454:306;-1:-1:-1;641:454:306:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:306;;2017:180;-1:-1:-1;2017:180:306:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:306;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:306;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { diff --git a/packages/contracts-bedrock/scripts/Deploy.s.sol b/packages/contracts-bedrock/scripts/Deploy.s.sol index 7891f934419b..29240100dc00 100644 --- a/packages/contracts-bedrock/scripts/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/Deploy.s.sol @@ -41,7 +41,7 @@ import { Chains } from "scripts/Chains.sol"; import { IBigStepper } from "src/dispute/interfaces/IBigStepper.sol"; import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol"; -import { AlphabetVM } from "../test/FaultDisputeGame.t.sol"; +import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; import "src/libraries/DisputeTypes.sol"; /// @title Deploy diff --git a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol index 40297b6cc8c0..86dbd9bab769 100644 --- a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol @@ -17,6 +17,8 @@ import { Types } from "src/libraries/Types.sol"; import { LibClock } from "src/dispute/lib/LibClock.sol"; import { LibPosition } from "src/dispute/lib/LibPosition.sol"; import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; +import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; + contract FaultDisputeGame_Init is DisputeGameFactory_Init { /// @dev The type of the game being tested. @@ -1093,37 +1095,3 @@ contract VariableDivergentPlayer is GamePlayer { trace = _trace; } } - -//////////////////////////////////////////////////////////////// -// MOCK VMS // -//////////////////////////////////////////////////////////////// - -contract AlphabetVM is IBigStepper { - Claim internal immutable ABSOLUTE_PRESTATE; - IPreimageOracle public oracle; - - constructor(Claim _absolutePrestate) { - ABSOLUTE_PRESTATE = _absolutePrestate; - oracle = new PreimageOracle(); - } - - /// @inheritdoc IBigStepper - function step(bytes calldata _stateData, bytes calldata, uint256) external view returns (bytes32 postState_) { - uint256 traceIndex; - uint256 claim; - if ((keccak256(_stateData) << 8) == (Claim.unwrap(ABSOLUTE_PRESTATE) << 8)) { - // If the state data is empty, then the absolute prestate is the claim. - traceIndex = 0; - (claim) = abi.decode(_stateData, (uint256)); - } else { - // Otherwise, decode the state data. - (traceIndex, claim) = abi.decode(_stateData, (uint256, uint256)); - traceIndex++; - } - // STF: n -> n + 1 - postState_ = keccak256(abi.encode(traceIndex, claim + 1)); - assembly { - postState_ := or(and(postState_, not(shl(248, 0xFF))), shl(248, 1)) - } - } -} diff --git a/packages/contracts-bedrock/test/mocks/AlphabetVM.sol b/packages/contracts-bedrock/test/mocks/AlphabetVM.sol new file mode 100644 index 000000000000..b73c5924b9bb --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/AlphabetVM.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; +import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; +import "src/libraries/DisputeTypes.sol"; + +/// @title AlphabetVM +/// @dev A mock VM for the purpose of testing the dispute game infrastructure. +contract AlphabetVM is IBigStepper { + Claim internal immutable ABSOLUTE_PRESTATE; + IPreimageOracle public oracle; + + constructor(Claim _absolutePrestate) { + ABSOLUTE_PRESTATE = _absolutePrestate; + oracle = new PreimageOracle(); + } + + /// @inheritdoc IBigStepper + function step(bytes calldata _stateData, bytes calldata, uint256) external view returns (bytes32 postState_) { + uint256 traceIndex; + uint256 claim; + if ((keccak256(_stateData) << 8) == (Claim.unwrap(ABSOLUTE_PRESTATE) << 8)) { + // If the state data is empty, then the absolute prestate is the claim. + traceIndex = 0; + (claim) = abi.decode(_stateData, (uint256)); + } else { + // Otherwise, decode the state data. + (traceIndex, claim) = abi.decode(_stateData, (uint256, uint256)); + traceIndex++; + } + // STF: n -> n + 1 + postState_ = keccak256(abi.encode(traceIndex, claim + 1)); + assembly { + postState_ := or(and(postState_, not(shl(248, 0xFF))), shl(248, 1)) + } + } +} From 3d21f9f4eeae18305ade1f8c24f6c4a5179005b0 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 15:19:24 +0300 Subject: [PATCH 288/374] lint: fix --- packages/contracts-bedrock/test/FaultDisputeGame.t.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol index 86dbd9bab769..2dc3d6e7d656 100644 --- a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol @@ -19,7 +19,6 @@ import { LibPosition } from "src/dispute/lib/LibPosition.sol"; import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol"; import { AlphabetVM } from "test/mocks/AlphabetVM.sol"; - contract FaultDisputeGame_Init is DisputeGameFactory_Init { /// @dev The type of the game being tested. GameType internal constant GAME_TYPE = GameType.wrap(0); From 389a805809efd807c666db853155298d4c6453e0 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 16:51:07 +0300 Subject: [PATCH 289/374] contracts-bedrock: modularize test mocks Modularize the testing mocks some more. Breaks out work in https://github.com/ethereum-optimism/optimism/pull/7928 to its own pull request --- .../contracts-bedrock/test/CommonTest.t.sol | 96 ------------------- .../test/CrossDomainMessenger.t.sol | 13 ++- .../test/L1CrossDomainMessenger.t.sol | 7 +- .../test/L2CrossDomainMessenger.t.sol | 7 +- .../test/L2OutputOracle.t.sol | 4 +- .../test/OptimismPortal.t.sol | 3 +- .../test/SequencerFeeVault.t.sol | 3 +- .../test/invariants/OptimismPortal.t.sol | 2 +- .../contracts-bedrock/test/mocks/Callers.sol | 67 +++++++++++++ .../test/mocks/EIP1967Helper.sol | 20 ++++ .../contracts-bedrock/test/mocks/NextImpl.sol | 21 ++++ 11 files changed, 128 insertions(+), 115 deletions(-) create mode 100644 packages/contracts-bedrock/test/mocks/EIP1967Helper.sol create mode 100644 packages/contracts-bedrock/test/mocks/NextImpl.sol diff --git a/packages/contracts-bedrock/test/CommonTest.t.sol b/packages/contracts-bedrock/test/CommonTest.t.sol index a3a64b6d9b22..6e34ba8007b8 100644 --- a/packages/contracts-bedrock/test/CommonTest.t.sol +++ b/packages/contracts-bedrock/test/CommonTest.t.sol @@ -731,99 +731,3 @@ contract FFIInterface is Test { return (memRoot, proof); } } - -library EIP1967Helper { - Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - - function getAdmin(address _proxy) internal view returns (address) { - return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_OWNER_ADDRESS)))); - } - - function getImplementation(address _proxy) internal view returns (address) { - return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_IMPLEMENTATION_ADDRESS)))); - } -} - -// Used for testing a future upgrade beyond the current implementations. -// We include some variables so that we can sanity check accessing storage values after an upgrade. -contract NextImpl is Initializable { - // Initializable occupies the zero-th slot. - bytes32 slot1; - bytes32[19] __gap; - bytes32 slot21; - bytes32 public constant slot21Init = bytes32(hex"1337"); - - function initialize(uint8 _init) public reinitializer(_init) { - // Slot21 is unused by an of our upgradeable contracts. - // This is used to verify that we can access this value after an upgrade. - slot21 = slot21Init; - } -} - -contract Reverter { - fallback() external { - revert(); - } -} - -// Useful for testing reentrancy guards -contract CallerCaller { - event WhatHappened(bool success, bytes returndata); - - fallback() external { - (bool success, bytes memory returndata) = msg.sender.call(msg.data); - emit WhatHappened(success, returndata); - assembly { - switch success - case 0 { revert(add(returndata, 0x20), mload(returndata)) } - default { return(add(returndata, 0x20), mload(returndata)) } - } - } -} - -// Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard. -contract ConfigurableCaller { - bool doRevert = true; - address target; - bytes payload; - - event WhatHappened(bool success, bytes returndata); - - /// @notice Call the configured target with the configured payload OR revert. - function call() external { - if (doRevert) { - revert("ConfigurableCaller: revert"); - } else { - (bool success, bytes memory returndata) = address(target).call(payload); - emit WhatHappened(success, returndata); - assembly { - switch success - case 0 { revert(add(returndata, 0x20), mload(returndata)) } - default { return(add(returndata, 0x20), mload(returndata)) } - } - } - } - - /// @notice Set whether or not to have `call` revert. - function setDoRevert(bool _doRevert) external { - doRevert = _doRevert; - } - - /// @notice Set the target for the call made in `call`. - function setTarget(address _target) external { - target = _target; - } - - /// @notice Set the payload for the call made in `call`. - function setPayload(bytes calldata _payload) external { - payload = _payload; - } - - /// @notice Fallback function that reverts if `doRevert` is true. - /// Otherwise, it does nothing. - fallback() external { - if (doRevert) { - revert("ConfigurableCaller: revert"); - } - } -} diff --git a/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol index f525adc21c1a..df0e34a5f7e6 100644 --- a/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol @@ -2,13 +2,16 @@ pragma solidity 0.8.15; // Testing utilities -import { Messenger_Initializer, Reverter, CallerCaller, CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; +import { Messenger_Initializer, Test } from "test/CommonTest.t.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { Reverter, CallerCaller } from "test/mocks/Callers.sol"; + // Libraries -import { Predeploys } from "../src/libraries/Predeploys.sol"; -import { Hashing } from "../src/libraries/Hashing.sol"; -import { Encoding } from "../src/libraries/Encoding.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Hashing } from "src/libraries/Hashing.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; // CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2 // CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract. @@ -39,7 +42,7 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { /// @title ExternalRelay /// @notice A mock external contract called via the SafeCall inside /// the CrossDomainMessenger's `relayMessage` function. -contract ExternalRelay is CommonTest { +contract ExternalRelay is Test { address internal op; address internal fuzzedSender; L1CrossDomainMessenger internal L1Messenger; diff --git a/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol index 77f966f310d6..8f2f4401378e 100644 --- a/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol @@ -2,8 +2,9 @@ pragma solidity 0.8.15; // Testing utilities -import { Messenger_Initializer, Reverter, ConfigurableCaller } from "test/CommonTest.t.sol"; +import { Messenger_Initializer } from "test/CommonTest.t.sol"; import { L2OutputOracle_Initializer } from "test/L2OutputOracle.t.sol"; +import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol"; // Libraries import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; @@ -12,12 +13,8 @@ import { Hashing } from "src/libraries/Hashing.sol"; import { Encoding } from "src/libraries/Encoding.sol"; // Target contract dependencies -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -// Target contract -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; - contract L1CrossDomainMessenger_Test is Messenger_Initializer { /// @dev The receiver address address recipient = address(0xabbaacdc); diff --git a/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol index ead28756af6d..9066397dcfec 100644 --- a/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol @@ -2,7 +2,8 @@ pragma solidity 0.8.15; // Testing utilities -import { Messenger_Initializer, Reverter, ConfigurableCaller } from "test/CommonTest.t.sol"; +import { Messenger_Initializer } from "test/CommonTest.t.sol"; +import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol"; // Libraries import { Hashing } from "src/libraries/Hashing.sol"; @@ -12,10 +13,6 @@ import { Types } from "src/libraries/Types.sol"; // Target contract dependencies import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; - -// Target contract -import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; contract L2CrossDomainMessenger_Test is Messenger_Initializer { /// @dev Receiver address for testing diff --git a/packages/contracts-bedrock/test/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/L2OutputOracle.t.sol index 52b87b450aa8..4a052ee29cdf 100644 --- a/packages/contracts-bedrock/test/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/L2OutputOracle.t.sol @@ -3,7 +3,9 @@ pragma solidity 0.8.15; // Testing utilities import { stdError } from "forge-std/Test.sol"; -import { L2OutputOracle_Initializer, NextImpl, EIP1967Helper } from "test/CommonTest.t.sol"; +import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; +import { NextImpl } from "test/mocks/NextImpl.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol index d116ff17c275..4b84ac1a4a91 100644 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/OptimismPortal.t.sol @@ -3,7 +3,8 @@ pragma solidity 0.8.15; // Testing utilities import { stdError } from "forge-std/Test.sol"; -import { Portal_Initializer, CommonTest, NextImpl } from "test/CommonTest.t.sol"; +import { Portal_Initializer } from "test/CommonTest.t.sol"; +import { NextImpl } from "test/mocks/NextImpl.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; diff --git a/packages/contracts-bedrock/test/SequencerFeeVault.t.sol b/packages/contracts-bedrock/test/SequencerFeeVault.t.sol index 9c6b391a9194..37975c0d17cb 100644 --- a/packages/contracts-bedrock/test/SequencerFeeVault.t.sol +++ b/packages/contracts-bedrock/test/SequencerFeeVault.t.sol @@ -2,7 +2,8 @@ pragma solidity 0.8.15; // Testing utilities -import { FeeVault_Initializer, Reverter } from "test/CommonTest.t.sol"; +import { FeeVault_Initializer } from "test/CommonTest.t.sol"; +import { Reverter } from "test/mocks/Callers.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; // Libraries diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol index af38e6536bb8..49c73caea789 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol @@ -12,7 +12,7 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Portal_Initializer } from "test/CommonTest.t.sol"; -import { EIP1967Helper } from "test/CommonTest.t.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Types } from "src/libraries/Types.sol"; contract OptimismPortal_Depositor is StdUtils, ResourceMetering { diff --git a/packages/contracts-bedrock/test/mocks/Callers.sol b/packages/contracts-bedrock/test/mocks/Callers.sol index e64dbdaf803a..aa7a2dc8b228 100644 --- a/packages/contracts-bedrock/test/mocks/Callers.sol +++ b/packages/contracts-bedrock/test/mocks/Callers.sol @@ -19,8 +19,75 @@ contract CallRecorder { } } +/// @dev Useful for testing reentrancy guards +contract CallerCaller { + event WhatHappened(bool success, bytes returndata); + + fallback() external { + (bool success, bytes memory returndata) = msg.sender.call(msg.data); + emit WhatHappened(success, returndata); + assembly { + switch success + case 0 { revert(add(returndata, 0x20), mload(returndata)) } + default { return(add(returndata, 0x20), mload(returndata)) } + } + } +} + +/// @dev Used for testing the `CrossDomainMessenger`'s per-message reentrancy guard. +contract ConfigurableCaller { + bool doRevert = true; + address target; + bytes payload; + + event WhatHappened(bool success, bytes returndata); + + /// @notice Call the configured target with the configured payload OR revert. + function call() external { + if (doRevert) { + revert("ConfigurableCaller: revert"); + } else { + (bool success, bytes memory returndata) = address(target).call(payload); + emit WhatHappened(success, returndata); + assembly { + switch success + case 0 { revert(add(returndata, 0x20), mload(returndata)) } + default { return(add(returndata, 0x20), mload(returndata)) } + } + } + } + + /// @notice Set whether or not to have `call` revert. + function setDoRevert(bool _doRevert) external { + doRevert = _doRevert; + } + + /// @notice Set the target for the call made in `call`. + function setTarget(address _target) external { + target = _target; + } + + /// @notice Set the payload for the call made in `call`. + function setPayload(bytes calldata _payload) external { + payload = _payload; + } + + /// @notice Fallback function that reverts if `doRevert` is true. + /// Otherwise, it does nothing. + fallback() external { + if (doRevert) { + revert("ConfigurableCaller: revert"); + } + } +} + +/// @dev Any call will revert contract Reverter { function doRevert() public pure { revert("Reverter reverted"); } + + fallback() external { + revert(); + } } diff --git a/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol b/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol new file mode 100644 index 000000000000..22688c8e0de4 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Vm } from "forge-std/Vm.sol"; +import { Constants } from "src/libraries/Constants.sol"; + +/// @title EIP1967Helper +/// @dev Testing library to help with reading EIP 1967 variables from state +library EIP1967Helper { + Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + function getAdmin(address _proxy) internal view returns (address) { + return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_OWNER_ADDRESS)))); + } + + function getImplementation(address _proxy) internal view returns (address) { + return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_IMPLEMENTATION_ADDRESS)))); + } +} + diff --git a/packages/contracts-bedrock/test/mocks/NextImpl.sol b/packages/contracts-bedrock/test/mocks/NextImpl.sol new file mode 100644 index 000000000000..3d857cfdc2d0 --- /dev/null +++ b/packages/contracts-bedrock/test/mocks/NextImpl.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; + +/// @title NextImpl +/// @dev Used for testing a future upgrade beyond the current implementations. +// We include some variables so that we can sanity check accessing storage values after an upgrade. +contract NextImpl is Initializable { + // Initializable occupies the zero-th slot. + bytes32 slot1; + bytes32[19] __gap; + bytes32 slot21; + bytes32 public constant slot21Init = bytes32(hex"1337"); + + function initialize(uint8 _init) public reinitializer(_init) { + // Slot21 is unused by an of our upgradeable contracts. + // This is used to verify that we can access this value after an upgrade. + slot21 = slot21Init; + } +} From 1f0c753ee59fb17405ce448c96329102a9e5f15e Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 16:59:31 +0300 Subject: [PATCH 290/374] op-bindings: regenerate --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index f6a602ff5a6d..52238e8bef32 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:306;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:306;2534:6:135;400:55:306;382:74;;370:2;355:18;2448:99:135;211:251:306;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:306;;;1743:2;1728:18;26025:6379:135;1609:177:306;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:306;19164:28:135;;;2164:21:306;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:306;14107:30:135;;;2511:21:306;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:306;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:306;37406:29:135;;;2860:21:306;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:306;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:306;20288:41:135;;;3208:21:306;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:306;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:306;;;8234:54:135;3601:23:306;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:306;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:306;21415:72:135;;;4259:21:306;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:306;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:306:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:306;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:306;-1:-1:-1;1349:2:306;1334:18;;1321:32;;-1:-1:-1;1365:16:306;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:306;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:306:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:306;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:306:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:308;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:308;2534:6:135;400:55:308;382:74;;370:2;355:18;2448:99:135;211:251:308;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:308;;;1743:2;1728:18;26025:6379:135;1609:177:308;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:308;19164:28:135;;;2164:21:308;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:308;14107:30:135;;;2511:21:308;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:308;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:308;37406:29:135;;;2860:21:308;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:308;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:308;20288:41:135;;;3208:21:308;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:308;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:308;;;8234:54:135;3601:23:308;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:308;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:308;21415:72:135;;;4259:21:308;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:308;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:308:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:308;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:308;-1:-1:-1;1349:2:308;1334:18;;1321:32;;-1:-1:-1;1365:16:308;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:308;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:308:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:308;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:308:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 8523b96a5316..e123a756178c 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:306;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:306;;607:22;589:41;;577:2;562:18;680:66:137;449:187:306;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:306;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:306;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:306;906:62:137;;;2890:21:306;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:306:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:306;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:306:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:306;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:306;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:306;1069:19;1056:33;;-1:-1:-1;641:454:306;-1:-1:-1;641:454:306:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:306;;2017:180;-1:-1:-1;2017:180:306:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:306;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:306;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:308;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:308;;607:22;589:41;;577:2;562:18;680:66:137;449:187:308;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:308;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:308;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:308;906:62:137;;;2890:21:308;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:308:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:308;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:308:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:308;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:308;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:308;1069:19;1056:33;;-1:-1:-1;641:454:308;-1:-1:-1;641:454:308:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:308;;2017:180;-1:-1:-1;2017:180:308:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:308;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:308;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { From c8544df5ded95a2957bfca75d6e517eb1af42c38 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 17:16:35 +0300 Subject: [PATCH 291/374] lint: fix --- packages/contracts-bedrock/.gas-snapshot | 10 +++++----- .../contracts-bedrock/test/mocks/EIP1967Helper.sol | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index db8e1cf3eabc..741a8468f305 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -171,11 +171,11 @@ L1BlockTest:test_timestamp_succeeds() (gas: 7640) L1BlockTest:test_updateValues_succeeds() (gas: 60482) L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24781) L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49384) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 212329) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 206087) +L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 239657) +L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 233416) L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 126344) L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 79599) -L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 200127) +L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 227456) L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 76590) L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 60779) L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12343) @@ -219,7 +219,7 @@ L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 28383) L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 27239) L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 615130) L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8477) -L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 163749) +L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 191078) L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48913) L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 31136) L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11689) @@ -673,7 +673,7 @@ SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1095190688) Semver_Test:test_behindProxy_succeeds() (gas: 507558) Semver_Test:test_version_succeeds() (gas: 9418) SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 78333) -SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 46486) +SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 46791) SequencerFeeVault_Test:test_constructor_succeeds() (gas: 5526) SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 5464) SequencerFeeVault_Test:test_receive_succeeds() (gas: 17373) diff --git a/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol b/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol index 22688c8e0de4..ade87a814640 100644 --- a/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol +++ b/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol @@ -17,4 +17,3 @@ library EIP1967Helper { return address(uint160(uint256(vm.load(address(_proxy), Constants.PROXY_IMPLEMENTATION_ADDRESS)))); } } - From 189fa9d78af8f70803d3bde896ac0f8ab46da0b8 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 17:48:47 +0300 Subject: [PATCH 292/374] contracts-bedrock: delete `CheckBalanceHigh` dripcheck This dripcheck is not used anywhere so no need to keep it around and add time to building and testing. --- .../scripts/DeployPeriphery.s.sol | 21 ---------- .../drippie/dripchecks/CheckBalanceHigh.sol | 25 ------------ .../test/CheckBalanceHigh.t.sol | 40 ------------------- .../test/CheckGelatoLow.t.sol | 2 +- 4 files changed, 1 insertion(+), 87 deletions(-) delete mode 100644 packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckBalanceHigh.sol delete mode 100644 packages/contracts-bedrock/test/CheckBalanceHigh.t.sol diff --git a/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol b/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol index 3cb7519832d5..f1d976e0c150 100644 --- a/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol +++ b/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol @@ -12,7 +12,6 @@ import { Proxy } from "src/universal/Proxy.sol"; import { Faucet } from "src/periphery/faucet/Faucet.sol"; import { Drippie } from "src/periphery/drippie/Drippie.sol"; import { CheckGelatoLow } from "src/periphery/drippie/dripchecks/CheckGelatoLow.sol"; -import { CheckBalanceHigh } from "src/periphery/drippie/dripchecks/CheckBalanceHigh.sol"; import { CheckBalanceLow } from "src/periphery/drippie/dripchecks/CheckBalanceLow.sol"; import { CheckTrue } from "src/periphery/drippie/dripchecks/CheckTrue.sol"; import { AdminFaucetAuthModule } from "src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol"; @@ -62,7 +61,6 @@ contract DeployPeriphery is Deployer { deployFaucetDrippie(); deployCheckTrue(); deployCheckBalanceLow(); - deployCheckBalanceHigh(); deployCheckGelatoLow(); deployOnChainAuthModule(); deployOffChainAuthModule(); @@ -199,25 +197,6 @@ contract DeployPeriphery is Deployer { } } - /// @notice Deploy CheckBalanceHigh contract. - function deployCheckBalanceHigh() public broadcast returns (address addr_) { - bytes32 salt = keccak256(bytes("CheckBalanceHigh")); - bytes32 initCodeHash = keccak256(abi.encodePacked(type(CheckBalanceHigh).creationCode)); - address preComputedAddress = computeCreate2Address(salt, initCodeHash); - if (preComputedAddress.code.length > 0) { - console.log("CheckBalanceHigh already deployed at %s", preComputedAddress); - save("CheckBalanceHigh", preComputedAddress); - addr_ = preComputedAddress; - } else { - CheckBalanceHigh checkBalanceHigh = new CheckBalanceHigh{ salt: salt }(); - - save("CheckBalanceHigh", address(checkBalanceHigh)); - console.log("CheckBalanceHigh deployed at %s", address(checkBalanceHigh)); - - addr_ = address(checkBalanceHigh); - } - } - /// @notice Deploy CheckGelatoLow contract. function deployCheckGelatoLow() public broadcast returns (address addr_) { bytes32 salt = keccak256(bytes("CheckGelatoLow")); diff --git a/packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckBalanceHigh.sol b/packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckBalanceHigh.sol deleted file mode 100644 index b531c93acb44..000000000000 --- a/packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckBalanceHigh.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { IDripCheck } from "../IDripCheck.sol"; - -/// @title CheckBalanceHigh -/// @notice DripCheck for checking if an account's balance is above a given threshold. -contract CheckBalanceHigh is IDripCheck { - struct Params { - address target; - uint256 threshold; - } - - /// @notice External event used to help client-side tooling encode parameters. - /// @param params Parameters to encode. - event _EventToExposeStructInABI__Params(Params params); - - /// @inheritdoc IDripCheck - function check(bytes memory _params) external view returns (bool execute_) { - Params memory params = abi.decode(_params, (Params)); - - // Check target balance is above threshold. - execute_ = params.target.balance > params.threshold; - } -} diff --git a/packages/contracts-bedrock/test/CheckBalanceHigh.t.sol b/packages/contracts-bedrock/test/CheckBalanceHigh.t.sol deleted file mode 100644 index 3102f560f3c8..000000000000 --- a/packages/contracts-bedrock/test/CheckBalanceHigh.t.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { Test } from "forge-std/Test.sol"; -import { CheckBalanceHigh } from "src/periphery/drippie/dripchecks/CheckBalanceHigh.sol"; - -/// @title CheckBalanceHighTest -/// @notice Tests the CheckBalanceHigh contract via fuzzing both the success case -/// and the failure case. -contract CheckBalanceHighTest is Test { - /// @notice An instance of the CheckBalanceHigh contract. - CheckBalanceHigh c; - - /// @notice Deploy the `CheckTrue` contract. - function setUp() external { - c = new CheckBalanceHigh(); - } - - /// @notice Fuzz the `check` function and assert that it always returns true - /// when the target's balance is larger than the threshold. - function testFuzz_check_succeeds(address _target, uint256 _threshold) external { - CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({ target: _target, threshold: _threshold }); - - // prevent overflows - vm.assume(_threshold != type(uint256).max); - vm.deal(_target, _threshold + 1); - - assertEq(c.check(abi.encode(p)), true); - } - - /// @notice Fuzz the `check` function and assert that it always returns false - /// when the target's balance is smaller than the threshold. - function testFuzz_check_lowBalance_fails(address _target, uint256 _threshold) external { - CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({ target: _target, threshold: _threshold }); - - vm.assume(_target.balance < _threshold); - - assertEq(c.check(abi.encode(p)), false); - } -} diff --git a/packages/contracts-bedrock/test/CheckGelatoLow.t.sol b/packages/contracts-bedrock/test/CheckGelatoLow.t.sol index fb213742c917..b8a25a72e3b3 100644 --- a/packages/contracts-bedrock/test/CheckGelatoLow.t.sol +++ b/packages/contracts-bedrock/test/CheckGelatoLow.t.sol @@ -20,7 +20,7 @@ contract MockGelatoTreasury is IGelatoTreasury { } /// @title CheckGelatoLowTest -/// @notice Tests the CheckBalanceHigh contract via fuzzing both the success case +/// @notice Tests the CheckGelatoLow contract via fuzzing both the success case /// and the failure case. contract CheckGelatoLowTest is Test { /// @notice An instance of the CheckGelatoLow contract. From 258dc4c842c9a7dc08f5d27736f1382c8c94486a Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 18:00:35 +0300 Subject: [PATCH 293/374] op-bindings: rebuild --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index 52238e8bef32..f6a602ff5a6d 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:308;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:308;2534:6:135;400:55:308;382:74;;370:2;355:18;2448:99:135;211:251:308;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:308;;;1743:2;1728:18;26025:6379:135;1609:177:308;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:308;19164:28:135;;;2164:21:308;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:308;14107:30:135;;;2511:21:308;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:308;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:308;37406:29:135;;;2860:21:308;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:308;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:308;20288:41:135;;;3208:21:308;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:308;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:308;;;8234:54:135;3601:23:308;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:308;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:308;21415:72:135;;;4259:21:308;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:308;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:308:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:308;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:308;-1:-1:-1;1349:2:308;1334:18;;1321:32;;-1:-1:-1;1365:16:308;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:308;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:308:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:308;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:308:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:306;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:306;2534:6:135;400:55:306;382:74;;370:2;355:18;2448:99:135;211:251:306;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:306;;;1743:2;1728:18;26025:6379:135;1609:177:306;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:306;19164:28:135;;;2164:21:306;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:306;14107:30:135;;;2511:21:306;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:306;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:306;37406:29:135;;;2860:21:306;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:306;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:306;20288:41:135;;;3208:21:306;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:306;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:306;;;8234:54:135;3601:23:306;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:306;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:306;21415:72:135;;;4259:21:306;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:306;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:306:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:306;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:306;-1:-1:-1;1349:2:306;1334:18;;1321:32;;-1:-1:-1;1365:16:306;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:306;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:306:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:306;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:306:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index e123a756178c..8523b96a5316 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:308;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:308;;607:22;589:41;;577:2;562:18;680:66:137;449:187:308;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:308;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:308;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:308;906:62:137;;;2890:21:308;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:308:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:308;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:308:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:308;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:308;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:308;1069:19;1056:33;;-1:-1:-1;641:454:308;-1:-1:-1;641:454:308:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:308;;2017:180;-1:-1:-1;2017:180:308:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:308;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:308;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:306;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:306;;607:22;589:41;;577:2;562:18;680:66:137;449:187:306;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:306;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:306;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:306;906:62:137;;;2890:21:306;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:306:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:306;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:306:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:306;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:306;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:306;1069:19;1056:33;;-1:-1:-1;641:454:306;-1:-1:-1;641:454:306:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:306;;2017:180;-1:-1:-1;2017:180:306:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:306;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:306;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { From 13faa913e86abf7e270df490e3c18a87d7d5538c Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Sat, 28 Oct 2023 15:53:52 -0600 Subject: [PATCH 294/374] contracts-bedrock: fully deprecate semver Removes the implementation of `Semver` in favor of `ISemver` fully. Now all contracts that previously used `Semver` should use `ISemver` and manually implement the `version()(string)` getter. Also update some import paths in files that were modified with the `Semver` change. Also removes any semver from `SchemaResolver` because it is an abstract contract. The contracts that inherit it should implement `ISemver` so that they can be versioned independently. Each contract that had its source code updated had a minor version bump. Regenerate the bindings, gas-snapshot and semver-lock. Note that the `OptimismMintableERC20Factory` had its semver bumped because it deploys `OptimismMintableERC20` tokens, which had its bytecode changed by moving from `Semver` to `ISemver`. --- op-bindings/bindings/legacyerc20eth.go | 2 +- op-bindings/bindings/legacyerc20eth_more.go | 2 +- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/optimismmintableerc20.go | 2 +- .../bindings/optimismmintableerc20_more.go | 2 +- .../bindings/optimismmintableerc20factory.go | 2 +- .../optimismmintableerc20factory_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- packages/contracts-bedrock/.gas-snapshot | 84 +++++++++---------- .../scripts/universal/EnhancedScript.sol | 6 +- .../scripts/upgrades/Multichain.s.sol | 1 - packages/contracts-bedrock/semver-lock.json | 14 ++-- packages/contracts-bedrock/src/EAS/EAS.sol | 6 +- .../src/EAS/eip1271/EIP1271Verifier.sol | 4 +- .../src/EAS/resolver/SchemaResolver.sol | 12 ++- .../periphery/op-nft/AttestationStation.sol | 9 +- .../src/periphery/op-nft/Optimist.sol | 17 ++-- .../periphery/op-nft/OptimistAllowlist.sol | 16 ++-- .../src/periphery/op-nft/OptimistInviter.sol | 14 ++-- .../src/universal/OptimismMintableERC20.sol | 9 +- .../OptimismMintableERC20Factory.sol | 4 +- .../src/universal/Semver.sol | 40 --------- packages/contracts-bedrock/test/Semver.t.sol | 35 -------- 23 files changed, 109 insertions(+), 178 deletions(-) delete mode 100644 packages/contracts-bedrock/src/universal/Semver.sol delete mode 100644 packages/contracts-bedrock/test/Semver.t.sol diff --git a/op-bindings/bindings/legacyerc20eth.go b/op-bindings/bindings/legacyerc20eth.go index 46f88532deaf..7b433a8206fe 100644 --- a/op-bindings/bindings/legacyerc20eth.go +++ b/op-bindings/bindings/legacyerc20eth.go @@ -31,7 +31,7 @@ var ( // LegacyERC20ETHMetaData contains all meta data concerning the LegacyERC20ETH contract. var LegacyERC20ETHMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REMOTE_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_who\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"remoteToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b5073420000000000000000000000000000000000001060006040518060400160405280600581526020016422ba3432b960d91b8152506040518060400160405280600381526020016208aa8960eb1b8152506012600160026001858581600390816200007f919062000167565b5060046200008e828262000167565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff166101205262000233565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000ed57607f821691505b6020821081036200010e57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200016257600081815260208120601f850160051c810160208610156200013d5750805b601f850160051c820191505b818110156200015e5782815560010162000149565b5050505b505050565b81516001600160401b03811115620001835762000183620000c2565b6200019b81620001948454620000d8565b8462000114565b602080601f831160018114620001d35760008415620001ba5750858301515b600019600386901b1c1916600185901b1785556200015e565b600085815260208120601f198616915b828110156200020457888601518255948401946001909101908401620001e3565b5085821015620002235787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516101005161012051610e79620002916000396000610244015260008181610309015261039e0152600081816101a9015261032f015260006107a40152600061077b015260006107520152610e796000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610353578063e78cea9214610307578063ee9a31a21461039957600080fd5b8063ae1f6aaf14610307578063c01e1bd61461032d578063d6c0b2c41461032d57600080fd5b80639dc29fac116100bd5780639dc29fac146102ce578063a457c2d7146102e1578063a9059cbb146102f457600080fd5b806370a082311461029e57806395d89b41146102c657600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004610ab1565b6103c0565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104b1565b60405161019b9190610b2a565b61018f610213366004610ba4565b610543565b6002545b60405190815260200161019b565b61018f610238366004610bce565b6105d3565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004610ba4565b61065e565b61029461028f366004610ba4565b6106e9565b005b6101f861074b565b61021c6102ac366004610c0a565b73ffffffffffffffffffffffffffffffffffffffff163190565b6101f86107ee565b6102946102dc366004610ba4565b6107fd565b61018f6102ef366004610ba4565b61085f565b61018f610302366004610ba4565b6108ea565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c610361366004610c25565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061047957507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104a857507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104c090610c58565b80601f01602080910402602001604051908101604052809291908181526020018280546104ec90610c58565b80156105395780601f1061050e57610100808354040283529160200191610539565b820191906000526020600020905b81548152906001019060200180831161051c57829003601f168201915b5050505050905090565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4c656761637945524332304554483a20617070726f766520697320646973616260448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526000906084015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4c656761637945524332304554483a207472616e7366657246726f6d2069732060448201527f64697361626c656400000000000000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a20696e637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206d696e742069732064697361626c656460448201526064016105ca565b60606107767f0000000000000000000000000000000000000000000000000000000000000000610974565b61079f7f0000000000000000000000000000000000000000000000000000000000000000610974565b6107c87f0000000000000000000000000000000000000000000000000000000000000000610974565b6040516020016107da93929190610cab565b604051602081830303815290604052905090565b6060600480546104c090610c58565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206275726e2069732064697361626c656460448201526064016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a206465637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4c656761637945524332304554483a207472616e73666572206973206469736160448201527f626c65640000000000000000000000000000000000000000000000000000000060648201526000906084016105ca565b6060816000036109b757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156109e157806109cb81610d50565b91506109da9050600a83610db7565b91506109bb565b60008167ffffffffffffffff8111156109fc576109fc610dcb565b6040519080825280601f01601f191660200182016040528015610a26576020820181803683370190505b5090505b8415610aa957610a3b600183610dfa565b9150610a48600a86610e11565b610a53906030610e25565b60f81b818381518110610a6857610a68610e3d565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610aa2600a86610db7565b9450610a2a565b949350505050565b600060208284031215610ac357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610af357600080fd5b9392505050565b60005b83811015610b15578181015183820152602001610afd565b83811115610b24576000848401525b50505050565b6020815260008251806020840152610b49816040850160208701610afa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b9f57600080fd5b919050565b60008060408385031215610bb757600080fd5b610bc083610b7b565b946020939093013593505050565b600080600060608486031215610be357600080fd5b610bec84610b7b565b9250610bfa60208501610b7b565b9150604084013590509250925092565b600060208284031215610c1c57600080fd5b610af382610b7b565b60008060408385031215610c3857600080fd5b610c4183610b7b565b9150610c4f60208401610b7b565b90509250929050565b600181811c90821680610c6c57607f821691505b602082108103610ca5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008451610cbd818460208901610afa565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610cf9816001850160208a01610afa565b60019201918201528351610d14816002840160208801610afa565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8157610d81610d21565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610dc657610dc6610d88565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015610e0c57610e0c610d21565b500390565b600082610e2057610e20610d88565b500690565b60008219821115610e3857610e38610d21565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", + Bin: "0x60e06040523480156200001157600080fd5b5073420000000000000000000000000000000000001060006040518060400160405280600581526020016422ba3432b960d91b8152506040518060400160405280600381526020016208aa8960eb1b81525060128282816003908162000078919062000152565b50600462000087828262000152565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200021e565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000d857607f821691505b602082108103620000f957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200014d57600081815260208120601f850160051c81016020861015620001285750805b601f850160051c820191505b81811015620001495782815560010162000134565b5050505b505050565b81516001600160401b038111156200016e576200016e620000ad565b62000186816200017f8454620000c3565b84620000ff565b602080601f831160018114620001be5760008415620001a55750858301515b600019600386901b1c1916600185901b17855562000149565b600085815260208120601f198616915b82811015620001ef57888601518255948401946001909101908401620001ce565b50858210156200020e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c051610afe6200025c600039600061024401526000818161033d01526103d20152600081816101a901526103630152610afe6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610387578063e78cea921461033b578063ee9a31a2146103cd57600080fd5b8063ae1f6aaf1461033b578063c01e1bd614610361578063d6c0b2c41461036157600080fd5b80639dc29fac116100bd5780639dc29fac14610302578063a457c2d714610315578063a9059cbb1461032857600080fd5b806370a08231146102d257806395d89b41146102fa57600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004610905565b6103f4565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104e5565b60405161019b919061094e565b61018f6102133660046109ea565b610577565b6002545b60405190815260200161019b565b61018f610238366004610a14565b610607565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c3660046109ea565b610692565b61029461028f3660046109ea565b61071d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e0366004610a50565b73ffffffffffffffffffffffffffffffffffffffff163190565b6101f861077f565b6102946103103660046109ea565b61078e565b61018f6103233660046109ea565b6107f0565b61018f6103363660046109ea565b61087b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c610395366004610a6b565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104ad57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104dc57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104f490610a9e565b80601f016020809104026020016040519081016040528092919081815260200182805461052090610a9e565b801561056d5780601f106105425761010080835404028352916020019161056d565b820191906000526020600020905b81548152906001019060200180831161055057829003601f168201915b5050505050905090565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4c656761637945524332304554483a20617070726f766520697320646973616260448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526000906084015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4c656761637945524332304554483a207472616e7366657246726f6d2069732060448201527f64697361626c656400000000000000000000000000000000000000000000000060648201526000906084016105fe565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a20696e637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105fe565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206d696e742069732064697361626c656460448201526064016105fe565b6060600480546104f490610a9e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206275726e2069732064697361626c656460448201526064016105fe565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a206465637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105fe565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4c656761637945524332304554483a207472616e73666572206973206469736160448201527f626c65640000000000000000000000000000000000000000000000000000000060648201526000906084016105fe565b60006020828403121561091757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461094757600080fd5b9392505050565b600060208083528351808285015260005b8181101561097b5785810183015185820160400152820161095f565b8181111561098d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146109e557600080fd5b919050565b600080604083850312156109fd57600080fd5b610a06836109c1565b946020939093013593505050565b600080600060608486031215610a2957600080fd5b610a32846109c1565b9250610a40602085016109c1565b9150604084013590509250925092565b600060208284031215610a6257600080fd5b610947826109c1565b60008060408385031215610a7e57600080fd5b610a87836109c1565b9150610a95602084016109c1565b90509250929050565b600181811c90821680610ab257607f821691505b602082108103610aeb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b5091905056fea164736f6c634300080f000a", } // LegacyERC20ETHABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/legacyerc20eth_more.go b/op-bindings/bindings/legacyerc20eth_more.go index cb79ddddc2c8..146d22f90323 100644 --- a/op-bindings/bindings/legacyerc20eth_more.go +++ b/op-bindings/bindings/legacyerc20eth_more.go @@ -13,7 +13,7 @@ const LegacyERC20ETHStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contrac var LegacyERC20ETHStorageLayout = new(solc.StorageLayout) -var LegacyERC20ETHDeployedBin = "0x608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610353578063e78cea9214610307578063ee9a31a21461039957600080fd5b8063ae1f6aaf14610307578063c01e1bd61461032d578063d6c0b2c41461032d57600080fd5b80639dc29fac116100bd5780639dc29fac146102ce578063a457c2d7146102e1578063a9059cbb146102f457600080fd5b806370a082311461029e57806395d89b41146102c657600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004610ab1565b6103c0565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104b1565b60405161019b9190610b2a565b61018f610213366004610ba4565b610543565b6002545b60405190815260200161019b565b61018f610238366004610bce565b6105d3565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004610ba4565b61065e565b61029461028f366004610ba4565b6106e9565b005b6101f861074b565b61021c6102ac366004610c0a565b73ffffffffffffffffffffffffffffffffffffffff163190565b6101f86107ee565b6102946102dc366004610ba4565b6107fd565b61018f6102ef366004610ba4565b61085f565b61018f610302366004610ba4565b6108ea565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c610361366004610c25565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061047957507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104a857507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104c090610c58565b80601f01602080910402602001604051908101604052809291908181526020018280546104ec90610c58565b80156105395780601f1061050e57610100808354040283529160200191610539565b820191906000526020600020905b81548152906001019060200180831161051c57829003601f168201915b5050505050905090565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4c656761637945524332304554483a20617070726f766520697320646973616260448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526000906084015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4c656761637945524332304554483a207472616e7366657246726f6d2069732060448201527f64697361626c656400000000000000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a20696e637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206d696e742069732064697361626c656460448201526064016105ca565b60606107767f0000000000000000000000000000000000000000000000000000000000000000610974565b61079f7f0000000000000000000000000000000000000000000000000000000000000000610974565b6107c87f0000000000000000000000000000000000000000000000000000000000000000610974565b6040516020016107da93929190610cab565b604051602081830303815290604052905090565b6060600480546104c090610c58565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206275726e2069732064697361626c656460448201526064016105ca565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a206465637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105ca565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4c656761637945524332304554483a207472616e73666572206973206469736160448201527f626c65640000000000000000000000000000000000000000000000000000000060648201526000906084016105ca565b6060816000036109b757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156109e157806109cb81610d50565b91506109da9050600a83610db7565b91506109bb565b60008167ffffffffffffffff8111156109fc576109fc610dcb565b6040519080825280601f01601f191660200182016040528015610a26576020820181803683370190505b5090505b8415610aa957610a3b600183610dfa565b9150610a48600a86610e11565b610a53906030610e25565b60f81b818381518110610a6857610a68610e3d565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610aa2600a86610db7565b9450610a2a565b949350505050565b600060208284031215610ac357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610af357600080fd5b9392505050565b60005b83811015610b15578181015183820152602001610afd565b83811115610b24576000848401525b50505050565b6020815260008251806020840152610b49816040850160208701610afa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b9f57600080fd5b919050565b60008060408385031215610bb757600080fd5b610bc083610b7b565b946020939093013593505050565b600080600060608486031215610be357600080fd5b610bec84610b7b565b9250610bfa60208501610b7b565b9150604084013590509250925092565b600060208284031215610c1c57600080fd5b610af382610b7b565b60008060408385031215610c3857600080fd5b610c4183610b7b565b9150610c4f60208401610b7b565b90509250929050565b600181811c90821680610c6c57607f821691505b602082108103610ca5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008451610cbd818460208901610afa565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610cf9816001850160208a01610afa565b60019201918201528351610d14816002840160208801610afa565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d8157610d81610d21565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610dc657610dc6610d88565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015610e0c57610e0c610d21565b500390565b600082610e2057610e20610d88565b500690565b60008219821115610e3857610e38610d21565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a" +var LegacyERC20ETHDeployedBin = "0x608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610387578063e78cea921461033b578063ee9a31a2146103cd57600080fd5b8063ae1f6aaf1461033b578063c01e1bd614610361578063d6c0b2c41461036157600080fd5b80639dc29fac116100bd5780639dc29fac14610302578063a457c2d714610315578063a9059cbb1461032857600080fd5b806370a08231146102d257806395d89b41146102fa57600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004610905565b6103f4565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104e5565b60405161019b919061094e565b61018f6102133660046109ea565b610577565b6002545b60405190815260200161019b565b61018f610238366004610a14565b610607565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c3660046109ea565b610692565b61029461028f3660046109ea565b61071d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e0366004610a50565b73ffffffffffffffffffffffffffffffffffffffff163190565b6101f861077f565b6102946103103660046109ea565b61078e565b61018f6103233660046109ea565b6107f0565b61018f6103363660046109ea565b61087b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c610395366004610a6b565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104ad57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104dc57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104f490610a9e565b80601f016020809104026020016040519081016040528092919081815260200182805461052090610a9e565b801561056d5780601f106105425761010080835404028352916020019161056d565b820191906000526020600020905b81548152906001019060200180831161055057829003601f168201915b5050505050905090565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4c656761637945524332304554483a20617070726f766520697320646973616260448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526000906084015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4c656761637945524332304554483a207472616e7366657246726f6d2069732060448201527f64697361626c656400000000000000000000000000000000000000000000000060648201526000906084016105fe565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a20696e637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105fe565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206d696e742069732064697361626c656460448201526064016105fe565b6060600480546104f490610a9e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206275726e2069732064697361626c656460448201526064016105fe565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a206465637265617365416c6c6f77616e6360448201527f652069732064697361626c65640000000000000000000000000000000000000060648201526000906084016105fe565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4c656761637945524332304554483a207472616e73666572206973206469736160448201527f626c65640000000000000000000000000000000000000000000000000000000060648201526000906084016105fe565b60006020828403121561091757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461094757600080fd5b9392505050565b600060208083528351808285015260005b8181101561097b5785810183015185820160400152820161095f565b8181111561098d576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146109e557600080fd5b919050565b600080604083850312156109fd57600080fd5b610a06836109c1565b946020939093013593505050565b600080600060608486031215610a2957600080fd5b610a32846109c1565b9250610a40602085016109c1565b9150604084013590509250925092565b600060208284031215610a6257600080fd5b610947826109c1565b60008060408385031215610a7e57600080fd5b610a87836109c1565b9150610a95602084016109c1565b90509250929050565b600181811c90821680610ab257607f821691505b602082108103610aeb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b5091905056fea164736f6c634300080f000a" func init() { if err := json.Unmarshal([]byte(LegacyERC20ETHStorageLayoutJSON), LegacyERC20ETHStorageLayout); err != nil { diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index 52238e8bef32..f6a602ff5a6d 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:308;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:308;2534:6:135;400:55:308;382:74;;370:2;355:18;2448:99:135;211:251:308;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:308;;;1743:2;1728:18;26025:6379:135;1609:177:308;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:308;19164:28:135;;;2164:21:308;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:308;14107:30:135;;;2511:21:308;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:308;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:308;37406:29:135;;;2860:21:308;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:308;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:308;20288:41:135;;;3208:21:308;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:308;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:308;;;8234:54:135;3601:23:308;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:308;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:308;21415:72:135;;;4259:21:308;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:308;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:308:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:308;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:308;-1:-1:-1;1349:2:308;1334:18;;1321:32;;-1:-1:-1;1365:16:308;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:308;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:308:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:308;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:308:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:306;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:306;2534:6:135;400:55:306;382:74;;370:2;355:18;2448:99:135;211:251:306;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:306;;;1743:2;1728:18;26025:6379:135;1609:177:306;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:306;19164:28:135;;;2164:21:306;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:306;14107:30:135;;;2511:21:306;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:306;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:306;37406:29:135;;;2860:21:306;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:306;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:306;20288:41:135;;;3208:21:306;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:306;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:306;;;8234:54:135;3601:23:306;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:306;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:306;21415:72:135;;;4259:21:306;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:306;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:306:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:306;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:306;-1:-1:-1;1349:2:306;1334:18;;1321:32;;-1:-1:-1;1365:16:306;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:306;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:306:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:306;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:306:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/optimismmintableerc20.go b/op-bindings/bindings/optimismmintableerc20.go index 0450ec37f705..f9ac81a2a95a 100644 --- a/op-bindings/bindings/optimismmintableerc20.go +++ b/op-bindings/bindings/optimismmintableerc20.go @@ -31,7 +31,7 @@ var ( // OptimismMintableERC20MetaData contains all meta data concerning the OptimismMintableERC20 contract. var OptimismMintableERC20MetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"_decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REMOTE_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"remoteToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b5060405162001ad738038062001ad7833981016040819052620000359162000177565b6001600281858560036200004a8382620002b2565b506004620000598282620002b2565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037e565b80516001600160a01b0381168114620000a557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d257600080fd5b81516001600160401b0380821115620000ef57620000ef620000aa565b604051601f8301601f19908116603f011681019082821181831017156200011a576200011a620000aa565b816040528381526020925086838588010111156200013757600080fd5b600091505b838210156200015b57858201830151818301840152908201906200013c565b838211156200016d5760008385830101525b9695505050505050565b600080600080600060a086880312156200019057600080fd5b6200019b866200008d565b9450620001ab602087016200008d565b60408701519094506001600160401b0380821115620001c957600080fd5b620001d789838a01620000c0565b94506060880151915080821115620001ee57600080fd5b50620001fd88828901620000c0565b925050608086015160ff811681146200021557600080fd5b809150509295509295909350565b600181811c908216806200023857607f821691505b6020821081036200025957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ad57600081815260208120601f850160051c81016020861015620002885750805b601f850160051c820191505b81811015620002a95782815560010162000294565b5050505b505050565b81516001600160401b03811115620002ce57620002ce620000aa565b620002e681620002df845462000223565b846200025f565b602080601f8311600181146200031e5760008415620003055750858301515b600019600386901b1c1916600185901b178555620002a9565b600085815260208120601f198616915b828110156200034f578886015182559484019460019091019084016200032e565b50858210156200036e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003ea6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a", + Bin: "0x60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000a", } // OptimismMintableERC20ABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/optimismmintableerc20_more.go b/op-bindings/bindings/optimismmintableerc20_more.go index 9370be0182c4..4a6e59f67e88 100644 --- a/op-bindings/bindings/optimismmintableerc20_more.go +++ b/op-bindings/bindings/optimismmintableerc20_more.go @@ -13,7 +13,7 @@ const OptimismMintableERC20StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\" var OptimismMintableERC20StorageLayout = new(solc.StorageLayout) -var OptimismMintableERC20DeployedBin = "0x608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a" +var OptimismMintableERC20DeployedBin = "0x608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000a" func init() { if err := json.Unmarshal([]byte(OptimismMintableERC20StorageLayoutJSON), OptimismMintableERC20StorageLayout); err != nil { diff --git a/op-bindings/bindings/optimismmintableerc20factory.go b/op-bindings/bindings/optimismmintableerc20factory.go index 59ea87305e34..597a71b641ca 100644 --- a/op-bindings/bindings/optimismmintableerc20factory.go +++ b/op-bindings/bindings/optimismmintableerc20factory.go @@ -31,7 +31,7 @@ var ( // OptimismMintableERC20FactoryMetaData contains all meta data concerning the OptimismMintableERC20Factory contract. var OptimismMintableERC20FactoryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"}],\"name\":\"OptimismMintableERC20Created\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"name\":\"StandardL2TokenCreated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BRIDGE\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createOptimismMintableERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"_decimals\",\"type\":\"uint8\"}],\"name\":\"createOptimismMintableERC20WithDecimals\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_remoteToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"createStandardL2Token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_bridge\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5061001b6000610020565b610118565b600054600390610100900460ff16158015610042575060005460ff8083169116105b6100a95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805461010060ff841661ffff19909216821717610100600160b01b03191661ff0019620100006001600160a01b0387160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6123ce806101276000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e362e3100000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b611ad780620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe6101406040523480156200001257600080fd5b5060405162001ad738038062001ad7833981016040819052620000359162000177565b6001600281858560036200004a8382620002b2565b506004620000598282620002b2565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037e565b80516001600160a01b0381168114620000a557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d257600080fd5b81516001600160401b0380821115620000ef57620000ef620000aa565b604051601f8301601f19908116603f011681019082821181831017156200011a576200011a620000aa565b816040528381526020925086838588010111156200013757600080fd5b600091505b838210156200015b57858201830151818301840152908201906200013c565b838211156200016d5760008385830101525b9695505050505050565b600080600080600060a086880312156200019057600080fd5b6200019b866200008d565b9450620001ab602087016200008d565b60408701519094506001600160401b0380821115620001c957600080fd5b620001d789838a01620000c0565b94506060880151915080821115620001ee57600080fd5b50620001fd88828901620000c0565b925050608086015160ff811681146200021557600080fd5b809150509295509295909350565b600181811c908216806200023857607f821691505b6020821081036200025957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ad57600081815260208120601f850160051c81016020861015620002885750805b601f850160051c820191505b81811015620002a95782815560010162000294565b5050505b505050565b81516001600160401b03811115620002ce57620002ce620000aa565b620002e681620002df845462000223565b846200025f565b602080601f8311600181146200031e5760008415620003055750858301515b600019600386901b1c1916600185901b178555620002a9565b600085815260208120601f198616915b828110156200034f578886015182559484019460019091019084016200032e565b50858210156200036e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003ea6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a", + Bin: "0x608060405234801561001057600080fd5b5061001b6000610020565b610118565b600054600390610100900460ff16158015610042575060005460ff8083169116105b6100a95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805461010060ff841661ffff19909216821717610100600160b01b03191661ff0019620100006001600160a01b0387160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b612081806101276000396000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b61178a80620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a", } // OptimismMintableERC20FactoryABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/optimismmintableerc20factory_more.go b/op-bindings/bindings/optimismmintableerc20factory_more.go index 1542700419d7..955da8c91ed5 100644 --- a/op-bindings/bindings/optimismmintableerc20factory_more.go +++ b/op-bindings/bindings/optimismmintableerc20factory_more.go @@ -13,7 +13,7 @@ const OptimismMintableERC20FactoryStorageLayoutJSON = "{\"storage\":[{\"astId\": var OptimismMintableERC20FactoryStorageLayout = new(solc.StorageLayout) -var OptimismMintableERC20FactoryDeployedBin = "0x60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e362e3100000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b611ad780620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe6101406040523480156200001257600080fd5b5060405162001ad738038062001ad7833981016040819052620000359162000177565b6001600281858560036200004a8382620002b2565b506004620000598282620002b2565b50505060809290925260a05260c0526001600160a01b0393841660e0529390921661010052505060ff16610120526200037e565b80516001600160a01b0381168114620000a557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000d257600080fd5b81516001600160401b0380821115620000ef57620000ef620000aa565b604051601f8301601f19908116603f011681019082821181831017156200011a576200011a620000aa565b816040528381526020925086838588010111156200013757600080fd5b600091505b838210156200015b57858201830151818301840152908201906200013c565b838211156200016d5760008385830101525b9695505050505050565b600080600080600060a086880312156200019057600080fd5b6200019b866200008d565b9450620001ab602087016200008d565b60408701519094506001600160401b0380821115620001c957600080fd5b620001d789838a01620000c0565b94506060880151915080821115620001ee57600080fd5b50620001fd88828901620000c0565b925050608086015160ff811681146200021557600080fd5b809150509295509295909350565b600181811c908216806200023857607f821691505b6020821081036200025957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ad57600081815260208120601f850160051c81016020861015620002885750805b601f850160051c820191505b81811015620002a95782815560010162000294565b5050505b505050565b81516001600160401b03811115620002ce57620002ce620000aa565b620002e681620002df845462000223565b846200025f565b602080601f8311600181146200031e5760008415620003055750858301515b600019600386901b1c1916600185901b178555620002a9565b600085815260208120601f198616915b828110156200034f578886015182559484019460019091019084016200032e565b50858210156200036e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610120516116ed620003ea6000396000610244015260008181610317015281816103ac015281816105f101526107cb0152600081816101a9015261033d0152600061075a015260006107310152600061070801526116ed6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610361578063e78cea9214610315578063ee9a31a2146103a757600080fd5b8063ae1f6aaf14610315578063c01e1bd61461033b578063d6c0b2c41461033b57600080fd5b80639dc29fac116100bd5780639dc29fac146102dc578063a457c2d7146102ef578063a9059cbb1461030257600080fd5b806370a082311461029e57806395d89b41146102d457600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a366004611329565b6103ce565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104bf565b60405161019b919061139e565b61018f610213366004611418565b610551565b6002545b60405190815260200161019b565b61018f610238366004611442565b610569565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611418565b61058d565b61029461028f366004611418565b6105d9565b005b6101f8610701565b61021c6102ac36600461147e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f86107a4565b6102946102ea366004611418565b6107b3565b61018f6102fd366004611418565b6108ca565b61018f610310366004611418565b61099b565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c61036f366004611499565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000851683148061048757507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104b657507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b6060600380546104ce906114cc565b80601f01602080910402602001604051908101604052809291908181526020018280546104fa906114cc565b80156105475780601f1061051c57610100808354040283529160200191610547565b820191906000526020600020905b81548152906001019060200180831161052a57829003601f168201915b5050505050905090565b60003361055f8185856109a9565b5060019392505050565b600033610577858285610b5d565b610582858585610c34565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061055f90829086906105d490879061154e565b6109a9565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106ad8282610ee7565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516106f591815260200190565b60405180910390a25050565b606061072c7f0000000000000000000000000000000000000000000000000000000000000000611007565b6107557f0000000000000000000000000000000000000000000000000000000000000000611007565b61077e7f0000000000000000000000000000000000000000000000000000000000000000611007565b60405160200161079093929190611566565b604051602081830303815290604052905090565b6060600480546104ce906114cc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e000000000000000000000000606482015260840161069a565b6108828282611144565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5826040516106f591815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561098e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161069a565b61058282868684036109a9565b60003361055f818585610c34565b73ffffffffffffffffffffffffffffffffffffffff8316610a4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c2e5781811015610c21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161069a565b610c2e84848484036109a9565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff8216610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e7490849061154e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610eda91815260200190565b60405180910390a3610c2e565b73ffffffffffffffffffffffffffffffffffffffff8216610f64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161069a565b8060026000828254610f76919061154e565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610fb090849061154e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60608160000361104a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611074578061105e816115dc565b915061106d9050600a83611643565b915061104e565b60008167ffffffffffffffff81111561108f5761108f611657565b6040519080825280601f01601f1916602001820160405280156110b9576020820181803683370190505b5090505b841561113c576110ce600183611686565b91506110db600a8661169d565b6110e690603061154e565b60f81b8183815181106110fb576110fb6116b1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611135600a86611643565b94506110bd565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166111e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020548181101561129d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161069a565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906112d9908490611686565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b50565b60006020828403121561133b57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461136b57600080fd5b9392505050565b60005b8381101561138d578181015183820152602001611375565b83811115610c2e5750506000910152565b60208152600082518060208401526113bd816040850160208701611372565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461141357600080fd5b919050565b6000806040838503121561142b57600080fd5b611434836113ef565b946020939093013593505050565b60008060006060848603121561145757600080fd5b611460846113ef565b925061146e602085016113ef565b9150604084013590509250925092565b60006020828403121561149057600080fd5b61136b826113ef565b600080604083850312156114ac57600080fd5b6114b5836113ef565b91506114c3602084016113ef565b90509250929050565b600181811c908216806114e057607f821691505b602082108103611519577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156115615761156161151f565b500190565b60008451611578818460208901611372565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516115b4816001850160208a01611372565b600192019182015283516115cf816002840160208801611372565b0160020195945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361160d5761160d61151f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261165257611652611614565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156116985761169861151f565b500390565b6000826116ac576116ac611614565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000aa164736f6c634300080f000a" +var OptimismMintableERC20FactoryDeployedBin = "0x60806040523480156200001157600080fd5b5060043610620000875760003560e01c8063c4d66de81162000062578063c4d66de81462000135578063ce5ac90f146200014e578063e78cea921462000165578063ee9a31a2146200018c57600080fd5b806354fd4d50146200008c578063896f93d114620000e15780638cf0629c146200011e575b600080fd5b620000c96040518060400160405280600581526020017f312e372e3000000000000000000000000000000000000000000000000000000081525081565b604051620000d89190620005d1565b60405180910390f35b620000f8620000f2366004620006f9565b620001b1565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620000d8565b620000f86200012f36600462000776565b620001c8565b6200014c620001463660046200080d565b620003c6565b005b620000f86200015f366004620006f9565b62000544565b600054620000f89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16620000f8565b6000620001c084848462000544565b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff851662000273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d4d696e7461626c654552433230466163746f72793a206d7560448201527f73742070726f766964652072656d6f746520746f6b656e20616464726573730060648201526084015b60405180910390fd5b6000858585856040516020016200028e94939291906200082b565b604051602081830303815290604052805190602001209050600081600060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688888888604051620002de9062000555565b620002ee95949392919062000885565b8190604051809103906000f59050801580156200030f573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a360405133815273ffffffffffffffffffffffffffffffffffffffff80891691908316907f52fe89dd5930f343d25650b62fd367bae47088bcddffd2a88350a6ecdd620cdb9060200160405180910390a39695505050505050565b600054600390610100900460ff16158015620003e9575060005460ff8083169116105b62000477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016200026a565b6000805461010060ff84167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009092168217177fffffffffffffffffffff000000000000000000000000000000000000000000ff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff6201000073ffffffffffffffffffffffffffffffffffffffff87160216179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000620001c08484846012620001c8565b61178a80620008eb83390190565b6000815180845260005b818110156200058b576020818501810151868301820152016200056d565b818111156200059e576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620005e6602083018462000563565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146200061257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126200065857600080fd5b813567ffffffffffffffff8082111562000676576200067662000617565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715620006bf57620006bf62000617565b81604052838152866020858801011115620006d957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156200070f57600080fd5b6200071a84620005ed565b9250602084013567ffffffffffffffff808211156200073857600080fd5b620007468783880162000646565b935060408601359150808211156200075d57600080fd5b506200076c8682870162000646565b9150509250925092565b600080600080608085870312156200078d57600080fd5b6200079885620005ed565b9350602085013567ffffffffffffffff80821115620007b657600080fd5b620007c48883890162000646565b94506040870135915080821115620007db57600080fd5b50620007ea8782880162000646565b925050606085013560ff811681146200080257600080fd5b939692955090935050565b6000602082840312156200082057600080fd5b620005e682620005ed565b73ffffffffffffffffffffffffffffffffffffffff851681526080602082015260006200085c608083018662000563565b828103604084015262000870818662000563565b91505060ff8316606083015295945050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a06040830152620008c060a083018662000563565b8281036060840152620008d4818662000563565b91505060ff83166080830152969550505050505056fe60e06040523480156200001157600080fd5b506040516200178a3803806200178a833981016040819052620000349162000163565b828260036200004483826200029e565b5060046200005382826200029e565b5050506001600160a01b039384166080529390921660a052505060ff1660c0526200036a565b80516001600160a01b03811681146200009157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000be57600080fd5b81516001600160401b0380821115620000db57620000db62000096565b604051601f8301601f19908116603f0116810190828211818310171562000106576200010662000096565b816040528381526020925086838588010111156200012357600080fd5b600091505b8382101562000147578582018301518183018401529082019062000128565b83821115620001595760008385830101525b9695505050505050565b600080600080600060a086880312156200017c57600080fd5b620001878662000079565b9450620001976020870162000079565b60408701519094506001600160401b0380821115620001b557600080fd5b620001c389838a01620000ac565b94506060880151915080821115620001da57600080fd5b50620001e988828901620000ac565b925050608086015160ff811681146200020157600080fd5b809150509295509295909350565b600181811c908216806200022457607f821691505b6020821081036200024557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029957600081815260208120601f850160051c81016020861015620002745750805b601f850160051c820191505b81811015620002955782815560010162000280565b5050505b505050565b81516001600160401b03811115620002ba57620002ba62000096565b620002d281620002cb84546200020f565b846200024b565b602080601f8311600181146200030a5760008415620002f15750858301515b600019600386901b1c1916600185901b17855562000295565b600085815260208120601f198616915b828110156200033b578886015182559484019460019091019084016200031a565b50858210156200035a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c0516113d4620003b6600039600061024401526000818161034b015281816103e001528181610625015261075c0152600081816101a9015261037101526113d46000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063ae1f6aaf1161008c578063dd62ed3e11610066578063dd62ed3e14610395578063e78cea9214610349578063ee9a31a2146103db57600080fd5b8063ae1f6aaf14610349578063c01e1bd61461036f578063d6c0b2c41461036f57600080fd5b80639dc29fac116100bd5780639dc29fac14610310578063a457c2d714610323578063a9059cbb1461033657600080fd5b806370a08231146102d257806395d89b411461030857600080fd5b806323b872dd1161012f5780633950935111610114578063395093511461026e57806340c10f191461028157806354fd4d501461029657600080fd5b806323b872dd1461022a578063313ce5671461023d57600080fd5b806306fdde031161016057806306fdde03146101f0578063095ea7b31461020557806318160ddd1461021857600080fd5b806301ffc9a71461017c578063033964be146101a4575b600080fd5b61018f61018a36600461117d565b610402565b60405190151581526020015b60405180910390f35b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101f86104f3565b60405161019b91906111c6565b61018f610213366004611262565b610585565b6002545b60405190815260200161019b565b61018f61023836600461128c565b61059d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161019b565b61018f61027c366004611262565b6105c1565b61029461028f366004611262565b61060d565b005b6101f86040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b61021c6102e03660046112c8565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101f8610735565b61029461031e366004611262565b610744565b61018f610331366004611262565b61085b565b61018f610344366004611262565b61092c565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b7f00000000000000000000000000000000000000000000000000000000000000006101cb565b61021c6103a33660046112e3565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101cb7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007fec4fc8e3000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806104bb57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b806104ea57507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b60606003805461050290611316565b80601f016020809104026020016040519081016040528092919081815260200182805461052e90611316565b801561057b5780601f106105505761010080835404028352916020019161057b565b820191906000526020600020905b81548152906001019060200180831161055e57829003601f168201915b5050505050905090565b60003361059381858561093a565b5060019392505050565b6000336105ab858285610aee565b6105b6858585610bc5565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906105939082908690610608908790611398565b61093a565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084015b60405180910390fd5b6106e18282610e78565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161072991815260200190565b60405180910390a25050565b60606004805461050290611316565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610809576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f4f7074696d69736d4d696e7461626c6545524332303a206f6e6c79206272696460448201527f67652063616e206d696e7420616e64206275726e00000000000000000000000060648201526084016106ce565b6108138282610f98565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161072991815260200190565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561091f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106ce565b6105b6828686840361093a565b600033610593818585610bc5565b73ffffffffffffffffffffffffffffffffffffffff83166109dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610a7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bbf5781811015610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106ce565b610bbf848484840361093a565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216610d0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610e05908490611398565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e6b91815260200190565b60405180910390a3610bbf565b73ffffffffffffffffffffffffffffffffffffffff8216610ef5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106ce565b8060026000828254610f079190611398565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f41908490611398565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff821661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156110f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016106ce565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040812083830390556002805484929061112d9084906113b0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610ae1565b60006020828403121561118f57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146111bf57600080fd5b9392505050565b600060208083528351808285015260005b818110156111f3578581018301518582016040015282016111d7565b81811115611205576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461125d57600080fd5b919050565b6000806040838503121561127557600080fd5b61127e83611239565b946020939093013593505050565b6000806000606084860312156112a157600080fd5b6112aa84611239565b92506112b860208501611239565b9150604084013590509250925092565b6000602082840312156112da57600080fd5b6111bf82611239565b600080604083850312156112f657600080fd5b6112ff83611239565b915061130d60208401611239565b90509250929050565b600181811c9082168061132a57607f821691505b602082108103611363577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156113ab576113ab611369565b500190565b6000828210156113c2576113c2611369565b50039056fea164736f6c634300080f000aa164736f6c634300080f000a" func init() { if err := json.Unmarshal([]byte(OptimismMintableERC20FactoryStorageLayoutJSON), OptimismMintableERC20FactoryStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index e123a756178c..8523b96a5316 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:308;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:308;;607:22;589:41;;577:2;562:18;680:66:137;449:187:308;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:308;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:308;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:308;906:62:137;;;2890:21:308;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:308:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:308;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:308:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:308;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:308;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:308;1069:19;1056:33;;-1:-1:-1;641:454:308;-1:-1:-1;641:454:308:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:308;;2017:180;-1:-1:-1;2017:180:308:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:308;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:308;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:306;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:306;;607:22;589:41;;577:2;562:18;680:66:137;449:187:306;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:306;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:306;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:306;906:62:137;;;2890:21:306;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:306:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:306;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:306:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:306;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:306;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:306;1069:19;1056:33;;-1:-1:-1;641:454:306;-1:-1:-1;641:454:306:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:306;;2017:180;-1:-1:-1;2017:180:306:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:306;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:306;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 741a8468f305..f6dde017e500 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -13,9 +13,9 @@ AssetReceiverTest:test_withdrawETH_succeeds() (gas: 28344) AssetReceiverTest:test_withdrawETH_unauthorized_reverts() (gas: 10680) AssetReceiverTest:test_withdrawETHwithAmount_succeeds() (gas: 28241) AssetReceiverTest:test_withdrawETHwithAmount_unauthorized_reverts() (gas: 10738) -AttestationStationTest:test_attest_bulk_succeeds() (gas: 703749) -AttestationStationTest:test_attest_individual_succeeds() (gas: 632087) -AttestationStationTest:test_attest_single_succeeds() (gas: 651325) +AttestationStationTest:test_attest_bulk_succeeds() (gas: 544387) +AttestationStationTest:test_attest_individual_succeeds() (gas: 472850) +AttestationStationTest:test_attest_single_succeeds() (gas: 491962) BlockOracle_Test:test_checkpointAndLoad_succeeds() (gas: 58396) BlockOracle_Test:test_load_noBlockHash_reverts() (gas: 13681) Bytes_slice_Test:test_slice_acrossMultipleWords_works() (gas: 9413) @@ -296,7 +296,7 @@ LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10637) LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6341) LegacyERC20ETH_Test:test_decreaseAllowance_doesNotExist_reverts() (gas: 10724) LegacyERC20ETH_Test:test_increaseAllowance_doesNotExist_reverts() (gas: 10690) -LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15476) +LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15420) LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10627) LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12957) LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10755) @@ -457,10 +457,10 @@ OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140547) OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9005) OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163441) OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 9760) -OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1303953) +OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1142536) OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9570) -OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516769327) -OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1303943) +OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516764385) +OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1142527) OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 11178) OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16111) OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26781) @@ -506,51 +506,51 @@ OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 35651) OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31514) OptimismPortal_Test:test_unpause_succeeds() (gas: 27451) OptimistAllowlistTest:test_constructor_succeeds() (gas: 16407) -OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49842) -OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49304) -OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestorWithFalsyValue_fails() (gas: 49544) -OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestor_succeeds() (gas: 53534) -OptimistAllowlistTest:test_isAllowedToMint_fromInvite_succeeds() (gas: 235508) -OptimistAllowlistTest:test_isAllowedToMint_fromWrongAllowlistAttestor_fails() (gas: 58311) -OptimistAllowlistTest:test_isAllowedToMint_fromWrongCoinbaseQuestAttestor_fails() (gas: 58268) -OptimistAllowlistTest:test_isAllowedToMint_fromWrongOptimistInviter_fails() (gas: 57601) -OptimistAllowlistTest:test_isAllowedToMint_withMultipleAttestations_succeeds() (gas: 324909) -OptimistAllowlistTest:test_isAllowedToMint_withoutAnyAttestations_fails() (gas: 23210) -OptimistInviterTest:test_claimInvite_claimBeforeMinCommitmentPeriod_reverts() (gas: 142819) -OptimistInviterTest:test_claimInvite_claimForSomeoneElse_succeeds() (gas: 245467) -OptimistInviterTest:test_claimInvite_replayingUsedNonce_reverts() (gas: 288437) -OptimistInviterTest:test_claimInvite_succeeds() (gas: 241374) -OptimistInviterTest:test_claimInvite_usingERC1271Wallet_succeeds() (gas: 245742) -OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentChain_reverts() (gas: 156587) -OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentContract_reverts() (gas: 156478) -OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentVersion_reverts() (gas: 155102) -OptimistInviterTest:test_claimInvite_whenIssuerHasNoInvitesLeft_reverts() (gas: 562110) +OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49650) +OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49254) +OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestorWithFalsyValue_fails() (gas: 49352) +OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestor_succeeds() (gas: 53433) +OptimistAllowlistTest:test_isAllowedToMint_fromInvite_succeeds() (gas: 235292) +OptimistAllowlistTest:test_isAllowedToMint_fromWrongAllowlistAttestor_fails() (gas: 58122) +OptimistAllowlistTest:test_isAllowedToMint_fromWrongCoinbaseQuestAttestor_fails() (gas: 58079) +OptimistAllowlistTest:test_isAllowedToMint_fromWrongOptimistInviter_fails() (gas: 57412) +OptimistAllowlistTest:test_isAllowedToMint_withMultipleAttestations_succeeds() (gas: 324720) +OptimistAllowlistTest:test_isAllowedToMint_withoutAnyAttestations_fails() (gas: 23046) +OptimistInviterTest:test_claimInvite_claimBeforeMinCommitmentPeriod_reverts() (gas: 142794) +OptimistInviterTest:test_claimInvite_claimForSomeoneElse_succeeds() (gas: 245313) +OptimistInviterTest:test_claimInvite_replayingUsedNonce_reverts() (gas: 288334) +OptimistInviterTest:test_claimInvite_succeeds() (gas: 241271) +OptimistInviterTest:test_claimInvite_usingERC1271Wallet_succeeds() (gas: 245678) +OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentChain_reverts() (gas: 156562) +OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentContract_reverts() (gas: 156453) +OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentVersion_reverts() (gas: 155077) +OptimistInviterTest:test_claimInvite_whenIssuerHasNoInvitesLeft_reverts() (gas: 561851) OptimistInviterTest:test_claimInvite_whenIssuerNeverReceivedInvites_reverts() (gas: 110711) -OptimistInviterTest:test_claimInvite_withIncorrectSignature_reverts() (gas: 253095) -OptimistInviterTest:test_claimInvite_withoutCommittingHash_reverts() (gas: 119210) -OptimistInviterTest:test_commitInvite_committingForSomeoneElse_succeeds() (gas: 140584) -OptimistInviterTest:test_commitInvite_committingForYourself_succeeds() (gas: 138628) -OptimistInviterTest:test_commitInvite_committingSameHashTwice_reverts() (gas: 142056) -OptimistInviterTest:test_grantInvites_adminAddingInvites_succeeds() (gas: 190757) +OptimistInviterTest:test_claimInvite_withIncorrectSignature_reverts() (gas: 253045) +OptimistInviterTest:test_claimInvite_withoutCommittingHash_reverts() (gas: 119185) +OptimistInviterTest:test_commitInvite_committingForSomeoneElse_succeeds() (gas: 140559) +OptimistInviterTest:test_commitInvite_committingForYourself_succeeds() (gas: 138603) +OptimistInviterTest:test_commitInvite_committingSameHashTwice_reverts() (gas: 142031) +OptimistInviterTest:test_grantInvites_adminAddingInvites_succeeds() (gas: 190682) OptimistInviterTest:test_grantInvites_nonAdminAddingInvites_reverts() (gas: 14026) OptimistInviterTest:test_initialize_succeeds() (gas: 10573) OptimistTest:test_approve_soulbound_reverts() (gas: 70487) -OptimistTest:test_baseURI_returnsCorrectBaseURI_succeeds() (gas: 124568) +OptimistTest:test_baseURI_returnsCorrectBaseURI_succeeds() (gas: 124566) OptimistTest:test_burn_byNonOwner_reverts() (gas: 73197) OptimistTest:test_burn_byOwner_succeeds() (gas: 54487) OptimistTest:test_initialize_succeeds() (gas: 20840) -OptimistTest:test_mint_afterAllowlistAttestation_succeeds() (gas: 121465) -OptimistTest:test_mint_afterCoinbaseQuestAttestation_succeeds() (gas: 130362) -OptimistTest:test_mint_afterInviteClaimed_succeeds() (gas: 311331) -OptimistTest:test_mint_afterMultipleAttestations_succeeds() (gas: 377762) -OptimistTest:test_mint_forAlreadyMintedClaimer_reverts() (gas: 118023) -OptimistTest:test_mint_forNonAllowlistedClaimer_reverts() (gas: 29886) +OptimistTest:test_mint_afterAllowlistAttestation_succeeds() (gas: 121365) +OptimistTest:test_mint_afterCoinbaseQuestAttestation_succeeds() (gas: 130109) +OptimistTest:test_mint_afterInviteClaimed_succeeds() (gas: 310811) +OptimistTest:test_mint_afterMultipleAttestations_succeeds() (gas: 377472) +OptimistTest:test_mint_forAlreadyMintedClaimer_reverts() (gas: 117923) +OptimistTest:test_mint_forNonAllowlistedClaimer_reverts() (gas: 29722) OptimistTest:test_mint_secondaryMinter_succeeds() (gas: 72711) -OptimistTest:test_multicall_batchingClaimAndMint_succeeds() (gas: 308376) +OptimistTest:test_multicall_batchingClaimAndMint_succeeds() (gas: 308008) OptimistTest:test_setApprovalForAll_soulbound_reverts() (gas: 74239) OptimistTest:test_supportsInterface_returnsCorrectInterfaceForERC721_succeeds() (gas: 5805) OptimistTest:test_tokenIdOfAddress_returnsOwnerID_succeeds() (gas: 63730) -OptimistTest:test_tokenURI_returnsCorrectTokenURI_succeeds() (gas: 195908) +OptimistTest:test_tokenURI_returnsCorrectTokenURI_succeeds() (gas: 195905) OptimistTest:test_transferFrom_soulbound_reverts() (gas: 75512) PreimageOracle_Test:test_keccak256PreimageKey_succeeds() (gas: 319) PreimageOracle_Test:test_loadKeccak256PreimagePart_outOfBoundsOffset_reverts() (gas: 8971) @@ -670,8 +670,6 @@ ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20020816) ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 19549) SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1021670598) SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1095190688) -Semver_Test:test_behindProxy_succeeds() (gas: 507558) -Semver_Test:test_version_succeeds() (gas: 9418) SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 78333) SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 46791) SequencerFeeVault_Test:test_constructor_succeeds() (gas: 5526) diff --git a/packages/contracts-bedrock/scripts/universal/EnhancedScript.sol b/packages/contracts-bedrock/scripts/universal/EnhancedScript.sol index fea9521ef733..065756db5b73 100644 --- a/packages/contracts-bedrock/scripts/universal/EnhancedScript.sol +++ b/packages/contracts-bedrock/scripts/universal/EnhancedScript.sol @@ -3,16 +3,16 @@ pragma solidity 0.8.15; import { console } from "forge-std/console.sol"; import { Script } from "forge-std/Script.sol"; -import { Semver } from "../../src/universal/Semver.sol"; +import { ISemver } from "../../src/universal/ISemver.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 + /// @notice Helper function used to compute the hash of ISemver's version string to be used in a /// comparison. function _versionHash(address _addr) internal view returns (bytes32) { - return keccak256(bytes(Semver(_addr).version())); + return keccak256(bytes(ISemver(_addr).version())); } /// @notice Log a tenderly simulation link. The TENDERLY_USERNAME and TENDERLY_PROJECT diff --git a/packages/contracts-bedrock/scripts/upgrades/Multichain.s.sol b/packages/contracts-bedrock/scripts/upgrades/Multichain.s.sol index 1afb79f4c9de..365973b9f620 100644 --- a/packages/contracts-bedrock/scripts/upgrades/Multichain.s.sol +++ b/packages/contracts-bedrock/scripts/upgrades/Multichain.s.sol @@ -10,7 +10,6 @@ import { ProxyAdmin } from "src/universal/ProxyAdmin.sol"; import { Constants } from "src/libraries/Constants.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { Semver } from "src/universal/Semver.sol"; import { DeployConfig } from "scripts/DeployConfig.s.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index baf78554fc45..76eda684aadf 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -1,5 +1,5 @@ { - "src/EAS/EAS.sol": "0xea04b7a9ec170ce9cbd466ede87650f9e9ffe3d725d7951cef5777a98a840173", + "src/EAS/EAS.sol": "0xe5e9700b94a88a2e1baabe4bfa66d5c1c94e811bcc5d2c64526afc649df59118", "src/EAS/SchemaRegistry.sol": "0x5ee1a0c3b2bf1eb5edb53fb0967cf13856be546f0f16fe7acdc3e4f286db6831", "src/L1/DelayedVetoable.sol": "0x276c6276292095e6aa37a70008cf4e0d1cbcc020dbc9107459bbc72ab5ed744f", "src/L1/L1CrossDomainMessenger.sol": "0x2aa4e06827bc48484212eb2bdc30fd604ffd23b37e401b78ef428c12fa9b8385", @@ -26,12 +26,12 @@ "src/legacy/DeployerWhitelist.sol": "0x0a6840074734c9d167321d3299be18ef911a415e4c471fa92af7d6cfaa8336d4", "src/legacy/L1BlockNumber.sol": "0x20d83a636c5e2067fca8c0ed505b295174e6eddb25960d8705e6b6fea8e77fa6", "src/legacy/LegacyMessagePasser.sol": "0x80f355c9710af586f58cf6a86d1925e0073d1e504d0b3d814284af1bafe4dece", - "src/periphery/op-nft/AttestationStation.sol": "0x9cf6f2fd909f9bcff229a137198186749a839cfa3d11ddbb3021fe71c30a2fa9", - "src/periphery/op-nft/Optimist.sol": "0x38407f766aa9d394403e9da388dd0265b48901789f3e8a28af50014f9f5251d9", - "src/periphery/op-nft/OptimistAllowlist.sol": "0x53e9a9dfecbae036fd468e8f34c80c7d9c35bd8908c8a6483db44dbc5128ad69", - "src/periphery/op-nft/OptimistInviter.sol": "0xfdd5b9d45205ef9372ba37f7a6394724695e676d27a47cb154ee6e4148490013", - "src/universal/OptimismMintableERC20.sol": "0x716db294648fce1bb41c5f95a20f92445f165a568886f21edd922d5c9b2cb0b5", - "src/universal/OptimismMintableERC20Factory.sol": "0xfcf2eb56777478f47f3bf2f1111aa2e3769d5ed28a6f5fceff4517683447131a", + "src/periphery/op-nft/AttestationStation.sol": "0x067b29fe24734c121469c1cb2e9b2602ddabb9e07792338b766cab341776cd78", + "src/periphery/op-nft/Optimist.sol": "0x128113cd97433987220f25b59d883d5ee7e70ff2214a536c0df3d892e13287fc", + "src/periphery/op-nft/OptimistAllowlist.sol": "0x7691e96cff85ab225459d075c86dc325abf437c35d9314c395005ba057a3b044", + "src/periphery/op-nft/OptimistInviter.sol": "0x92a7d11cc93aeb079ccaa28bdc56e42534a21a8c137a43bec2620961d57e9050", + "src/universal/OptimismMintableERC20.sol": "0xc5d38eec0497fa6901f49502a479eb8bed0d14d1902b4c0075bb2fb00ba6a55f", + "src/universal/OptimismMintableERC20Factory.sol": "0x8d4cbf4cc30a0bb72925b5d2e0386b8f91559f00933a9c7cf3dcc118e34fe61b", "src/universal/OptimismMintableERC721.sol": "0x4c73bf8474fa7eb091796a4db7e57bc5f26d50a3d1cfcb78d5efa47ced5ced2b", "src/universal/OptimismMintableERC721Factory.sol": "0x935fd97018b6ef10fa813d9d43ab7a77c80885f7a8d7feb430097645cb2abd2c", "src/universal/StorageSetter.sol": "0x6372647d8a67d243bc2fb40d2c4bf5807022d94d52d9423cfed27a7d57918635" diff --git a/packages/contracts-bedrock/src/EAS/EAS.sol b/packages/contracts-bedrock/src/EAS/EAS.sol index 387688e834be..a5ca8e1dfb4a 100644 --- a/packages/contracts-bedrock/src/EAS/EAS.sol +++ b/packages/contracts-bedrock/src/EAS/EAS.sol @@ -16,7 +16,7 @@ import { NotFound, NO_EXPIRATION_TIME, uncheckedInc -} from "./Common.sol"; +} from "src/EAS/Common.sol"; import { Attestation, @@ -31,9 +31,9 @@ import { MultiRevocationRequest, RevocationRequest, RevocationRequestData -} from "./IEAS.sol"; +} from "src/EAS/IEAS.sol"; -import { ISchemaRegistry, SchemaRecord } from "./ISchemaRegistry.sol"; +import { ISchemaRegistry, SchemaRecord } from "src/EAS/ISchemaRegistry.sol"; struct AttestationsResult { uint256 usedValue; // Total ETH amount that was sent to resolvers. diff --git a/packages/contracts-bedrock/src/EAS/eip1271/EIP1271Verifier.sol b/packages/contracts-bedrock/src/EAS/eip1271/EIP1271Verifier.sol index 22c5860bab0c..d32d11d8ee48 100644 --- a/packages/contracts-bedrock/src/EAS/eip1271/EIP1271Verifier.sol +++ b/packages/contracts-bedrock/src/EAS/eip1271/EIP1271Verifier.sol @@ -10,7 +10,7 @@ import { DelegatedAttestationRequest, DelegatedRevocationRequest, RevocationRequestData -} from "../IEAS.sol"; +} from "src/EAS/IEAS.sol"; import { DeadlineExpired, @@ -20,7 +20,7 @@ import { MAX_GAP, stringToBytes32, bytes32ToString -} from "../Common.sol"; +} from "src/EAS/Common.sol"; /// @title EIP1271Verifier /// @notice EIP1271Verifier typed signatures verifier for EAS delegated attestations. diff --git a/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol b/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol index bd3898bebffc..4e51c3e89c0d 100644 --- a/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol +++ b/packages/contracts-bedrock/src/EAS/resolver/SchemaResolver.sol @@ -1,16 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; -import { Semver } from "../../universal/Semver.sol"; +import { IEAS, Attestation } from "src/EAS/IEAS.sol"; +import { AccessDenied, InvalidEAS, InvalidLength, uncheckedInc } from "src/EAS/Common.sol"; -import { IEAS, Attestation } from "../IEAS.sol"; -import { AccessDenied, InvalidEAS, InvalidLength, uncheckedInc } from "../Common.sol"; - -import { ISchemaResolver } from "./ISchemaResolver.sol"; +import { ISchemaResolver } from "src/EAS/resolver/ISchemaResolver.sol"; /// @title SchemaResolver /// @notice The base schema resolver contract. -abstract contract SchemaResolver is ISchemaResolver, Semver { +abstract contract SchemaResolver is ISchemaResolver { error InsufficientValue(); error NotPayable(); @@ -19,7 +17,7 @@ abstract contract SchemaResolver is ISchemaResolver, Semver { /// @dev Creates a new resolver. /// @param eas The address of the global EAS contract. - constructor(IEAS eas) Semver(1, 2, 0) { + constructor(IEAS eas) { if (address(eas) == address(0)) { revert InvalidEAS(); } diff --git a/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol b/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol index c36beb497f72..b9af730a71d4 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/AttestationStation.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Semver } from "../../universal/Semver.sol"; +import { ISemver } from "src/universal/ISemver.sol"; /// @title AttestationStation /// @author Optimism Collective /// @author Gitcoin /// @notice Where attestations live. -contract AttestationStation is Semver { +contract AttestationStation is ISemver { /// @notice Struct representing data that is being attested. /// @custom:field about Address for which the attestation is about. /// @custom:field key A bytes32 key for the attestation. @@ -28,8 +28,9 @@ contract AttestationStation is Semver { /// @param val Value of the attestation. event AttestationCreated(address indexed creator, address indexed about, bytes32 indexed key, bytes val); - /// @custom:semver 1.1.2 - constructor() Semver(1, 1, 2) { } + /// @notice Semantic version. + /// @custom:semver 1.2.0 + string public constant version = "1.2.0"; /// @notice Allows anyone to create an attestation. /// @param _about Address that the attestation is about. diff --git a/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol b/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol index 9fef8007b01c..74d04b087d86 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/Optimist.sol @@ -1,18 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Semver } from "../../universal/Semver.sol"; +import { ISemver } from "src/universal/ISemver.sol"; import { ERC721BurnableUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; -import { AttestationStation } from "./AttestationStation.sol"; -import { OptimistAllowlist } from "./OptimistAllowlist.sol"; +import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; +import { OptimistAllowlist } from "src/periphery/op-nft/OptimistAllowlist.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; /// @author Optimism Collective /// @author Gitcoin /// @title Optimist /// @notice A Soul Bound Token for real humans only(tm). -contract Optimist is ERC721BurnableUpgradeable, Semver { +contract Optimist is ERC721BurnableUpgradeable, ISemver { /// @notice Attestation key used by the attestor to attest the baseURI. bytes32 public constant BASE_URI_ATTESTATION_KEY = bytes32("optimist.base-uri"); @@ -25,7 +25,10 @@ contract Optimist is ERC721BurnableUpgradeable, Semver { /// @notice Address of the OptimistAllowlist contract. OptimistAllowlist public immutable OPTIMIST_ALLOWLIST; - /// @custom:semver 2.0.2 + /// @notice Semantic version. + /// @custom:semver 2.1.0 + string public constant version = "2.1.0"; + /// @param _name Token name. /// @param _symbol Token symbol. /// @param _baseURIAttestor Address of the baseURI attestor. @@ -37,9 +40,7 @@ contract Optimist is ERC721BurnableUpgradeable, Semver { address _baseURIAttestor, AttestationStation _attestationStation, OptimistAllowlist _optimistAllowlist - ) - Semver(2, 0, 2) - { + ) { BASE_URI_ATTESTOR = _baseURIAttestor; ATTESTATION_STATION = _attestationStation; OPTIMIST_ALLOWLIST = _optimistAllowlist; diff --git a/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol b/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol index ad576261bed6..8325571ff343 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Semver } from "../../universal/Semver.sol"; -import { AttestationStation } from "./AttestationStation.sol"; -import { OptimistConstants } from "./libraries/OptimistConstants.sol"; +import { ISemver } from "src/universal/ISemver.sol"; +import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; +import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; /// @title OptimistAllowlist /// @notice Source of truth for whether an address is able to mint an Optimist NFT. /// isAllowedToMint function checks various signals to return boolean value /// for whether an address is eligible or not. -contract OptimistAllowlist is Semver { +contract OptimistAllowlist is ISemver { /// @notice Attestation key used by the AllowlistAttestor to manually add addresses to the /// allowlist. bytes32 public constant OPTIMIST_CAN_MINT_ATTESTATION_KEY = bytes32("optimist.can-mint"); @@ -30,6 +30,10 @@ contract OptimistAllowlist is Semver { /// attestations. address public immutable OPTIMIST_INVITER; + /// @notice Semantic version. + /// @custom:semver 1.1.0 + string public constant version = "1.1.0"; + /// @custom:semver 1.0.2 /// @param _attestationStation Address of the AttestationStation contract. /// @param _allowlistAttestor Address of the allowlist attestor. @@ -40,9 +44,7 @@ contract OptimistAllowlist is Semver { address _allowlistAttestor, address _coinbaseQuestAttestor, address _optimistInviter - ) - Semver(1, 0, 2) - { + ) { ATTESTATION_STATION = _attestationStation; ALLOWLIST_ATTESTOR = _allowlistAttestor; COINBASE_QUEST_ATTESTOR = _coinbaseQuestAttestor; diff --git a/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol b/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol index 805a2a648cf7..01e25ca925f4 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { OptimistConstants } from "./libraries/OptimistConstants.sol"; -import { Semver } from "../../universal/Semver.sol"; -import { AttestationStation } from "./AttestationStation.sol"; +import { OptimistConstants } from "src/periphery/op-nft/libraries/OptimistConstants.sol"; +import { ISemver } from "src/universal/ISemver.sol"; +import { AttestationStation } from "src/periphery/op-nft/AttestationStation.sol"; import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; import { EIP712Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol"; @@ -32,7 +32,7 @@ import { EIP712Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/cry /// 6) claimer waits for the MIN_COMMITMENT_PERIOD to pass. /// 7) claimer reveals the plaintext ClaimableInvite and the signature using the /// claimInvite function, receiving the "optimist.can-mint-from-invite" attestation -contract OptimistInviter is Semver, EIP712Upgradeable { +contract OptimistInviter is ISemver, EIP712Upgradeable { /// @notice Emitted when an invite is claimed. /// @param issuer Address that issued the signature. /// @param claimer Address that claimed the invite. @@ -87,10 +87,14 @@ contract OptimistInviter is Semver, EIP712Upgradeable { /// @notice Maps from addresses to number of invites they have. mapping(address => uint256) public inviteCounts; + /// @notice Semantic version. + /// @custom:semver 1.1.0 + string public constant version = "1.1.0"; + /// @custom:semver 1.0.2 /// @param _inviteGranter Address of the invite granter. /// @param _attestationStation Address of the AttestationStation contract. - constructor(address _inviteGranter, AttestationStation _attestationStation) Semver(1, 0, 2) { + constructor(address _inviteGranter, AttestationStation _attestationStation) { INVITE_GRANTER = _inviteGranter; ATTESTATION_STATION = _attestationStation; } diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol index f00474043fa0..c603814560c7 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; -import { Semver } from "src/universal/Semver.sol"; +import { ISemver } from "src/universal/ISemver.sol"; /// @title OptimismMintableERC20 /// @notice OptimismMintableERC20 is a standard extension of the base ERC20 token contract designed @@ -12,7 +12,7 @@ import { Semver } from "src/universal/Semver.sol"; /// use an OptimismMintablERC20 as the L2 representation of an L1 token, or vice-versa. /// Designed to be backwards compatible with the older StandardL2ERC20 token which was only /// meant for use on L2. -contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, Semver { +contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, ERC20, ISemver { /// @notice Address of the corresponding version of this token on the remote chain. address public immutable REMOTE_TOKEN; @@ -38,6 +38,10 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, _; } + /// @notice Semantic version. + /// @custom:semver 1.3.0 + string public constant version = "1.3.0"; + /// @custom:semver 1.2.1 /// @param _bridge Address of the L2 standard bridge. /// @param _remoteToken Address of the corresponding L1 token. @@ -51,7 +55,6 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, uint8 _decimals ) ERC20(_name, _symbol) - Semver(1, 2, 1) { REMOTE_TOKEN = _remoteToken; BRIDGE = _bridge; diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol index b7f86dbadaab..c254dab3802b 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol @@ -32,8 +32,8 @@ contract OptimismMintableERC20Factory is ISemver, Initializable { event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); /// @notice Semantic version. - /// @custom:semver 1.6.1 - string public constant version = "1.6.1"; + /// @custom:semver 1.7.0 + string public constant version = "1.7.0"; /// @notice The semver MUST be bumped any time that there is a change in /// the OptimismMintableERC20 token contract since this contract diff --git a/packages/contracts-bedrock/src/universal/Semver.sol b/packages/contracts-bedrock/src/universal/Semver.sol deleted file mode 100644 index 5f81053a776a..000000000000 --- a/packages/contracts-bedrock/src/universal/Semver.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; - -/// @title Semver -/// @notice Semver is a simple contract for managing contract versions. -contract Semver { - /// @notice Contract version number (major). - uint256 private immutable MAJOR_VERSION; - - /// @notice Contract version number (minor). - uint256 private immutable MINOR_VERSION; - - /// @notice Contract version number (patch). - uint256 private immutable PATCH_VERSION; - - /// @param _major Version number (major). - /// @param _minor Version number (minor). - /// @param _patch Version number (patch). - constructor(uint256 _major, uint256 _minor, uint256 _patch) { - MAJOR_VERSION = _major; - MINOR_VERSION = _minor; - PATCH_VERSION = _patch; - } - - /// @notice Returns the full semver contract version. - /// @return Semver contract version as a string. - function version() public view returns (string memory) { - return string( - abi.encodePacked( - Strings.toString(MAJOR_VERSION), - ".", - Strings.toString(MINOR_VERSION), - ".", - Strings.toString(PATCH_VERSION) - ) - ); - } -} diff --git a/packages/contracts-bedrock/test/Semver.t.sol b/packages/contracts-bedrock/test/Semver.t.sol deleted file mode 100644 index 08d0dae64f06..000000000000 --- a/packages/contracts-bedrock/test/Semver.t.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import { CommonTest } from "test/CommonTest.t.sol"; -import { Semver } from "src/universal/Semver.sol"; -import { Proxy } from "src/universal/Proxy.sol"; - -/// @notice Test the Semver contract that is used for semantic versioning -/// of various contracts. -contract Semver_Test is CommonTest { - /// @notice Global semver contract deployed in setUp. This is used in - /// the test cases. - Semver semver; - - /// @notice Deploy a Semver contract - function setUp() public virtual override { - semver = new Semver(7, 8, 0); - } - - /// @notice Test the version getter - function test_version_succeeds() external { - assertEq(semver.version(), "7.8.0"); - } - - /// @notice Since the versions are all immutable, they should - /// be able to be accessed from behind a proxy without needing - /// to initialize the contract. - function test_behindProxy_succeeds() external { - Proxy proxy = new Proxy(alice); - vm.prank(alice); - proxy.upgradeTo(address(semver)); - - assertEq(Semver(address(proxy)).version(), "7.8.0"); - } -} From 27e1f494bf6bcc8f31b84bb6965b54f5a0a18d5c Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 17:28:47 +0300 Subject: [PATCH 295/374] contracts-bedrock: delete dead comments --- .../contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol | 1 - .../contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol | 1 - .../contracts-bedrock/src/universal/OptimismMintableERC20.sol | 1 - 3 files changed, 3 deletions(-) diff --git a/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol b/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol index 8325571ff343..b8212a37c674 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/OptimistAllowlist.sol @@ -34,7 +34,6 @@ contract OptimistAllowlist is ISemver { /// @custom:semver 1.1.0 string public constant version = "1.1.0"; - /// @custom:semver 1.0.2 /// @param _attestationStation Address of the AttestationStation contract. /// @param _allowlistAttestor Address of the allowlist attestor. /// @param _coinbaseQuestAttestor Address of the Coinbase Quest attestor. diff --git a/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol b/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol index 01e25ca925f4..222405d77c33 100644 --- a/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol +++ b/packages/contracts-bedrock/src/periphery/op-nft/OptimistInviter.sol @@ -91,7 +91,6 @@ contract OptimistInviter is ISemver, EIP712Upgradeable { /// @custom:semver 1.1.0 string public constant version = "1.1.0"; - /// @custom:semver 1.0.2 /// @param _inviteGranter Address of the invite granter. /// @param _attestationStation Address of the AttestationStation contract. constructor(address _inviteGranter, AttestationStation _attestationStation) { diff --git a/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol b/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol index c603814560c7..43ddd65424f8 100644 --- a/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol +++ b/packages/contracts-bedrock/src/universal/OptimismMintableERC20.sol @@ -42,7 +42,6 @@ contract OptimismMintableERC20 is IOptimismMintableERC20, ILegacyMintableERC20, /// @custom:semver 1.3.0 string public constant version = "1.3.0"; - /// @custom:semver 1.2.1 /// @param _bridge Address of the L2 standard bridge. /// @param _remoteToken Address of the corresponding L1 token. /// @param _name ERC20 name. From 9e6c95b4b09043128c06416beb9f84f7fab410af Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 17:55:18 +0300 Subject: [PATCH 296/374] contracts-bedrock: fix semver lock --- packages/contracts-bedrock/semver-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 76eda684aadf..8fbbb333e0af 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -28,9 +28,9 @@ "src/legacy/LegacyMessagePasser.sol": "0x80f355c9710af586f58cf6a86d1925e0073d1e504d0b3d814284af1bafe4dece", "src/periphery/op-nft/AttestationStation.sol": "0x067b29fe24734c121469c1cb2e9b2602ddabb9e07792338b766cab341776cd78", "src/periphery/op-nft/Optimist.sol": "0x128113cd97433987220f25b59d883d5ee7e70ff2214a536c0df3d892e13287fc", - "src/periphery/op-nft/OptimistAllowlist.sol": "0x7691e96cff85ab225459d075c86dc325abf437c35d9314c395005ba057a3b044", - "src/periphery/op-nft/OptimistInviter.sol": "0x92a7d11cc93aeb079ccaa28bdc56e42534a21a8c137a43bec2620961d57e9050", - "src/universal/OptimismMintableERC20.sol": "0xc5d38eec0497fa6901f49502a479eb8bed0d14d1902b4c0075bb2fb00ba6a55f", + "src/periphery/op-nft/OptimistAllowlist.sol": "0x12e5d0a79c8c05cfd41be8a1bcbd5c889652182a723aeb5eccb35e0ee2a5b6c0", + "src/periphery/op-nft/OptimistInviter.sol": "0xe5353f882475396ca8c3c0f8905baf3450697612ee6ac1d7053a80f6e1ecdd3b", + "src/universal/OptimismMintableERC20.sol": "0x099bea9f5d2f0a827f87485a4e51b8055981f6d84a0e974d226ba6d8ed5ba73d", "src/universal/OptimismMintableERC20Factory.sol": "0x8d4cbf4cc30a0bb72925b5d2e0386b8f91559f00933a9c7cf3dcc118e34fe61b", "src/universal/OptimismMintableERC721.sol": "0x4c73bf8474fa7eb091796a4db7e57bc5f26d50a3d1cfcb78d5efa47ced5ced2b", "src/universal/OptimismMintableERC721Factory.sol": "0x935fd97018b6ef10fa813d9d43ab7a77c80885f7a8d7feb430097645cb2abd2c", From a3d3ae3ed220f72defe0e0be2dc251eed31175e0 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 30 Oct 2023 12:01:36 -0400 Subject: [PATCH 297/374] module console.log cleanup --- packages/contracts-bedrock/.gas-snapshot | 20 +++++----- .../test/LivenessGuard.t.sol | 14 +++---- .../test/LivenessModule.t.sol | 39 +++++++------------ .../contracts-bedrock/test/SafeSigners.t.sol | 4 +- .../test/safe-tools/SafeTestTools.sol | 17 ++------ 5 files changed, 36 insertions(+), 58 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 06d5f60a3ad8..55de5137b35f 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -311,8 +311,8 @@ LivenessGuard_CheckTx_TestFails:test_checkTransaction_callerIsNotSafe_revert() ( LivenessGuard_Constructor_Test:test_constructor_works() (gas: 1198965) LivenessGuard_Getters_Test:test_getters_works() (gas: 10662) LivenessGuard_OwnerManagement_Test:test_addOwner_succeeds() (gas: 274366) -LivenessGuard_OwnerManagement_Test:test_removeOwner_succeeds() (gas: 246263) -LivenessGuard_OwnerManagement_Test:test_swapOwner_succeeds() (gas: 284880) +LivenessGuard_OwnerManagement_Test:test_removeOwner_succeeds() (gas: 243684) +LivenessGuard_OwnerManagement_Test:test_swapOwner_succeeds() (gas: 282299) LivenessGuard_ShowLiveness_Test:test_showLiveness_succeeds() (gas: 28831) LivenessGuard_ShowLiveness_TestFail:test_showLiveness_callIsNotSafeOwner_reverts() (gas: 18770) LivenessModule_CanRemove_Test:test_canRemove_works() (gas: 33026) @@ -321,16 +321,16 @@ LivenessModule_Constructor_TestFail:test_constructor_minOwnersGreaterThanOwners_ LivenessModule_Constructor_TestFail:test_constructor_wrongThreshold_reverts() (gas: 92925) LivenessModule_Get75PercentThreshold_Test:test_get75PercentThreshold_Works() (gas: 26339) LivenessModule_Getters_Test:test_getters_works() (gas: 14853) -LivenessModule_RemoveOwners_Test:test_removeOwners_allOwners_succeeds() (gas: 1326177) -LivenessModule_RemoveOwners_Test:test_removeOwners_oneOwner_succeeds() (gas: 133975) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowEmptiedButNotShutDown_reverts() (gas: 1278643) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowMinButNotEmptied_reverts() (gas: 1281685) +LivenessModule_RemoveOwners_Test:test_removeOwners_allOwners_succeeds() (gas: 1316393) +LivenessModule_RemoveOwners_Test:test_removeOwners_oneOwner_succeeds() (gas: 130750) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowEmptiedButNotShutDown_reverts() (gas: 1269598) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_belowMinButNotEmptied_reverts() (gas: 1273409) LivenessModule_RemoveOwners_TestFail:test_removeOwners_differentArrayLengths_reverts() (gas: 10502) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_guardChanged_reverts() (gas: 2839358) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_guardChanged_reverts() (gas: 2836129) LivenessModule_RemoveOwners_TestFail:test_removeOwners_invalidThreshold_reverts() (gas: 69358) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRecently_reverts() (gas: 80971) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 617629) -LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1288036) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRecently_reverts() (gas: 77749) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 615047) +LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1278252) LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954) MIPS_Test:test_add_succeeds() (gas: 122932) MIPS_Test:test_addiSign_succeeds() (gas: 122923) diff --git a/packages/contracts-bedrock/test/LivenessGuard.t.sol b/packages/contracts-bedrock/test/LivenessGuard.t.sol index e1f7cdd761b2..2ea2159d25dc 100644 --- a/packages/contracts-bedrock/test/LivenessGuard.t.sol +++ b/packages/contracts-bedrock/test/LivenessGuard.t.sol @@ -47,7 +47,7 @@ contract LivenessGuard_Constructor_Test is LivenessGuard_TestInit { function test_constructor_works() external { address[] memory owners = safeInstance.owners; livenessGuard = new WrappedGuard(safeInstance.safe); - for (uint256 i = 0; i < owners.length; i++) { + for (uint256 i; i < owners.length; i++) { assertEq(livenessGuard.lastLive(owners[i]), initTime); } } @@ -242,7 +242,7 @@ contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, Liveness (address[] memory ownerAddrs, uint256[] memory ownerkeys) = SafeTestLib.makeAddrsAndKeys("safeTest", initialOwners); // record the private keys for later use - for (uint256 i = 0; i < ownerAddrs.length; i++) { + for (uint256 i; i < ownerAddrs.length; i++) { privateKeys[ownerAddrs[i]] = ownerkeys[i]; } @@ -251,7 +251,7 @@ contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, Liveness livenessGuard = new WrappedGuard(safeInstance.safe); safeInstance.setGuard(address(livenessGuard)); - for (uint256 i = 0; i < changes.length; i++) { + for (uint256 i; i < changes.length; i++) { vm.warp(block.timestamp + changes[i].timeDelta); OwnerChange memory change = changes[i]; address[] memory currentOwners = safeInstance.safe.getOwners(); @@ -312,16 +312,16 @@ contract LivenessGuard_FuzzOwnerManagement_Test is StdCheats, StdUtils, Liveness // Looks up the private key for each owner uint256[] memory unsortedOwnerPKs = new uint256[](instance.owners.length); - for (uint256 j = 0; j < instance.owners.length; j++) { - unsortedOwnerPKs[j] = privateKeys[instance.owners[j]]; + for (uint256 i; i < instance.owners.length; i++) { + unsortedOwnerPKs[i] = privateKeys[instance.owners[i]]; } // Sort the keys by address and store them in the SafeInstance instance.ownerPKs = SafeTestLib.sortPKsByComputedAddress(unsortedOwnerPKs); // Overwrite the SafeInstances owners array with the computed addresses from the ownerPKs array - for (uint256 k; k < instance.owners.length; k++) { - instance.owners[k] = SafeTestLib.getAddr(instance.ownerPKs[k]); + for (uint256 i; i < instance.owners.length; i++) { + instance.owners[i] = SafeTestLib.getAddr(instance.ownerPKs[i]); } } } diff --git a/packages/contracts-bedrock/test/LivenessModule.t.sol b/packages/contracts-bedrock/test/LivenessModule.t.sol index adc1af45666c..d51ea8fee491 100644 --- a/packages/contracts-bedrock/test/LivenessModule.t.sol +++ b/packages/contracts-bedrock/test/LivenessModule.t.sol @@ -199,7 +199,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { uint256 numOwners = safeInstance.owners.length; address[] memory ownersToRemove = new address[](numOwners); - for (uint256 i = 0; i < numOwners; i++) { + for (uint256 i; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); @@ -218,7 +218,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { uint256 numOwners = safeInstance.owners.length - 2; address[] memory ownersToRemove = new address[](numOwners); - for (uint256 i = 0; i < numOwners; i++) { + for (uint256 i; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); @@ -236,7 +236,7 @@ contract LivenessModule_RemoveOwners_TestFail is LivenessModule_TestInit { uint256 numOwners = safeInstance.owners.length - 1; address[] memory ownersToRemove = new address[](numOwners); - for (uint256 i = 0; i < numOwners; i++) { + for (uint256 i; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); @@ -297,7 +297,7 @@ contract LivenessModule_RemoveOwners_Test is LivenessModule_TestInit { uint256 numOwners = safeInstance.owners.length; address[] memory ownersToRemove = new address[](numOwners); - for (uint256 i = 0; i < numOwners; i++) { + for (uint256 i; i < numOwners; i++) { ownersToRemove[i] = safeInstance.owners[i]; } address[] memory prevOwners = safeInstance.getPrevOwners(ownersToRemove); @@ -348,15 +348,12 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // // _numOwners must be at least 4, so that _minOwners can be set to at least 3 by the following bound() call. // Limiting the owner set to 20 helps to keep the runtime of the test reasonable. - console.log("bounding numOwners"); numOwners_ = bound(_numOwners, 4, 20); // _minOwners must be at least 3, otherwise we don't have any range below _minOwners in which to test all of the // ShutDownBehavior options. - console.log("bounding minOwners"); minOwners_ = bound(_minOwners, 3, numOwners_ - 1); // Ensure that _numLiveOwners is less than _numOwners so that we can remove at least one owner. - console.log("bounding numLiveOwners"); numLiveOwners_ = bound(_numLiveOwners, 0, numOwners_ - 1); // The above bounds are a bit tricky, so we assert that the resulting parameters enable us to test all possible @@ -402,20 +399,19 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // Create an array of live owners, and call showLiveness for each of them address[] memory liveOwners = new address[](numLiveOwners); - for (uint256 i = 0; i < numLiveOwners; i++) { + for (uint256 i; i < numLiveOwners; i++) { liveOwners[i] = safeInstance.owners[i]; vm.prank(safeInstance.owners[i]); livenessGuard.showLiveness(); } address[] memory nonLiveOwners = new address[](numOwners - numLiveOwners); - for (uint256 i = 0; i < numOwners - numLiveOwners; i++) { + for (uint256 i; i < numOwners - numLiveOwners; i++) { nonLiveOwners[i] = safeInstance.owners[i + numLiveOwners]; } address[] memory prevOwners; if (numLiveOwners >= minOwners) { - console.log("No shutdown"); // The safe will remain above the minimum number of owners, so we can remove only those owners which are not // live. prevOwners = safeInstance.getPrevOwners(nonLiveOwners); @@ -424,10 +420,10 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // Validate the resulting state of the Safe assertEq(safeInstance.safe.getOwners().length, numLiveOwners); assertEq(safeInstance.safe.getThreshold(), get75PercentThreshold(numLiveOwners)); - for (uint256 i = 0; i < numLiveOwners; i++) { + for (uint256 i; i < numLiveOwners; i++) { assertTrue(safeInstance.safe.isOwner(liveOwners[i])); } - for (uint256 i = 0; i < nonLiveOwners.length; i++) { + for (uint256 i; i < nonLiveOwners.length; i++) { assertFalse(safeInstance.safe.isOwner(nonLiveOwners[i])); } } else { @@ -439,14 +435,10 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // The safe is below the minimum number of owners. // The ShutDownBehavior enum determines how we handle this case. if (shutDownBehavior == ShutDownBehavior.Correct) { - console.log("Correct Shutdown"); // We remove all owners, and transfer ownership to the shutDown owner. // but we need to do remove the non-live owners first, so we reverse the owners array, since // the first owners in the array were the ones to call showLiveness. - // ownersToRemove = new address[](numOwners); - for (uint256 i = 0; i < numOwners; i++) { - // ownersToRemove[numOwners - i - 1] = safeInstance.owners[i]; - // ownersToRemove[i] = safeInstance.owners[numOwners - i - 1]; + for (uint256 i; i < numOwners; i++) { ownersToRemove.push(safeInstance.owners[numOwners - i - 1]); } prevOwners = safeInstance.getPrevOwners(ownersToRemove); @@ -461,14 +453,11 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // trigger that behavior. We initialize that value here then set it in the if statements below. uint256 numOwnersToRemoveinShutDown; if (shutDownBehavior == ShutDownBehavior.DoesNotRemoveAllOwners) { - console.log("Shutdown DoesNotRemoveAllOwners"); // In the DoesNotRemoveAllOwners case, we should have more than 1 of the pre-existing owners // remaining - console.log("bounding numOwnersToRemoveinShutDown"); numOwnersToRemoveinShutDown = bound(_numOwnersToRemoveinShutDown, numOwners - minOwners + 1, numOwners - 2); - uint256 i = 0; - for (i; i < numOwnersToRemoveinShutDown; i++) { + for (uint256 i; i < numOwnersToRemoveinShutDown; i++) { // Add non-live owners to remove first if (i < nonLiveOwners.length) { ownersToRemove.push(nonLiveOwners[i]); @@ -483,11 +472,9 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { ); livenessModule.removeOwners(prevOwners, ownersToRemove); } else if (shutDownBehavior == ShutDownBehavior.DoesNotTransferToFallbackOwner) { - console.log("Shutdown DoesNotTransferToFallbackOwner"); // In the DoesNotRemoveAllOwners case, we should have exactly 1 pre-existing owners remaining numOwnersToRemoveinShutDown = numOwners - 1; - uint256 i = 0; - for (i; i < numOwnersToRemoveinShutDown; i++) { + for (uint256 i; i < numOwnersToRemoveinShutDown; i++) { // Add non-live owners to remove first if (i < nonLiveOwners.length) { ownersToRemove.push(nonLiveOwners[i]); @@ -503,8 +490,8 @@ contract LivenessModule_RemoveOwnersFuzz_Test is LivenessModule_TestInit { // For both of the incorrect behaviors, verify no change to the Safe state assertEq(safeInstance.safe.getOwners().length, numOwners); assertEq(safeInstance.safe.getThreshold(), get75PercentThreshold(numOwners)); - for (uint256 j = 0; j < numOwners; j++) { - assertTrue(safeInstance.safe.isOwner(safeInstance.owners[j])); + for (uint256 i; i < numOwners; i++) { + assertTrue(safeInstance.safe.isOwner(safeInstance.owners[i])); } } } diff --git a/packages/contracts-bedrock/test/SafeSigners.t.sol b/packages/contracts-bedrock/test/SafeSigners.t.sol index b79386a52238..d94d91382fa3 100644 --- a/packages/contracts-bedrock/test/SafeSigners.t.sol +++ b/packages/contracts-bedrock/test/SafeSigners.t.sol @@ -40,7 +40,7 @@ contract SafeSigners_Test is Test, SafeTestTools { uint256 numSigs = bound(_numSigs, 1, 25); (, uint256[] memory keys) = SafeTestLib.makeAddrsAndKeys("getSigsTest", numSigs); - for (uint256 i = 0; i < keys.length; i++) { + for (uint256 i; i < keys.length; i++) { if (sigType(keys[i]) == SigTypes.Contract) { keys[i] = SafeTestLib.encodeSmartContractWalletAsPK(SafeTestLib.decodeSmartContractWalletAsAddress(keys[i])); @@ -91,7 +91,7 @@ contract SafeSigners_Test is Test, SafeTestTools { // the validation checks that the Safe contract performs on the value of s on contract // signatures. The Safe contract checks that s correctly points to additional data appended // after the signatures, and that the length of the data is within bounds. - for (uint256 i = 0; i < contractSigs; i++) { + for (uint256 i; i < contractSigs; i++) { signatures = bytes.concat(signatures, abi.encode(32, 1)); } diff --git a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol index f4ff521ff0c9..93b33fbab2a9 100644 --- a/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol +++ b/packages/contracts-bedrock/test/safe-tools/SafeTestTools.sol @@ -212,17 +212,10 @@ library SafeTestLib { address[] memory _ownersList ) internal - view - returns ( - // pure - address prevOwner_ - ) + pure + returns (address prevOwner_) { - // console.log("getPrevOwnerFromList"); - for (uint256 i = 0; i < _ownersList.length; i++) { - // console.log(i); - // console.log(_owner); - // console.log("_ownersList[i]:", _ownersList[i]); + for (uint256 i; i < _ownersList.length; i++) { if (_ownersList[i] != _owner) continue; if (i == 0) { prevOwner_ = SENTINEL_OWNERS; @@ -230,8 +223,6 @@ library SafeTestLib { } prevOwner_ = _ownersList[i - 1]; } - - console.log("prevOwner_:", prevOwner_); } /// @dev Given an array of owners to remove, this function will return an array of the previous owners @@ -250,7 +241,7 @@ library SafeTestLib { OwnerSimulator ownerSimulator = new OwnerSimulator(instance.owners, 1); prevOwners_ = new address[](_ownersToRemove.length); address[] memory currentOwners; - for (uint256 i = 0; i < _ownersToRemove.length; i++) { + for (uint256 i; i < _ownersToRemove.length; i++) { currentOwners = ownerSimulator.getOwners(); prevOwners_[i] = SafeTestLib.getPrevOwnerFromList(_ownersToRemove[i], currentOwners); From 6e090f839ea1136440a19b9f4d7bb30b408d43c0 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 30 Oct 2023 15:53:01 -0400 Subject: [PATCH 298/374] specs: Improvements to liveness checking specs --- specs/safe-liveness-checking.md | 54 ++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/specs/safe-liveness-checking.md b/specs/safe-liveness-checking.md index 25068268372b..654516bd5201 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/safe-liveness-checking.md @@ -11,7 +11,11 @@ - [Owner removal call flow](#owner-removal-call-flow) - [Shutdown](#shutdown) - [Security Properties](#security-properties) + - [In the guard](#in-the-guard) + - [In the module](#in-the-module) - [Interdependency between the guard and module](#interdependency-between-the-guard-and-module) +- [Operational considerations](#operational-considerations) + - [Manual validation of new owner liveness](#manual-validation-of-new-owner-liveness) - [Deploying the liveness checking system](#deploying-the-liveness-checking-system) - [Modify the liveness checking system](#modify-the-liveness-checking-system) - [Replacing the module](#replacing-the-module) @@ -45,7 +49,18 @@ For implementing liveness checks a `LivenessGuard` is created which receives the each executed transaction, and tracks the latest time at which a transaction was signed by each signer. This time is made publicly available by calling a `lastLive(address)(Timestamp)` method. -Signers may also call the contract's `showLiveness()()` method directly in order to prove liveness. +Owners are recorded in this mapping in one of 4 ways: + +1. Upon deployment, the guard reads the current set of owners from the Safe contract. +1. When a new owner is added to the safe. Similarly, when an owner is removed from the Safe, it's + entry is deleted from the mapping. +1. When a transaction is executed, the signatures on that transaction are passed to the guard and + used to identify the signers. If more than the required number of signatures is provided, they + are ignored. +1. An owner may call the contract's `showLiveness()()` method directly in order to prove liveness. + +Note that the first two methods do not require the owner to actually sign anything. However these mechanisms +are necessary to prevent new owners from being removed before they have had a chance to show liveness. ### The liveness module @@ -85,25 +100,34 @@ sequenceDiagram ### Shutdown -In the unlikely event that the signer set (`N`) is reduced below the allowed threshold, then (and only then) is a - shutdown mechanism activated which removes the existing signers, and hands control of the - multisig over to a predetermined entity. +In the unlikely event that the signer set (`N`) is reduced below the allowed minimum number of + owners, then (and only then) is a shutdown mechanism activated which removes the existing + signers, and hands control of the multisig over to a predetermined entity. ### Security Properties The following security properties must be upheld: +#### In the guard + 1. Signatures are assigned to the correct signer. 1. Non-signers are unable to create a record of having signed. -1. A signer cannot be censored or griefed such that their signing is not recorded. -1. Signers may demonstrate liveness either by signing a transaction or by calling directly to the +1. An owner cannot be censored or griefed such that their signing is not recorded. +1. Owners may demonstrate liveness either by signing a transaction or by calling directly to the guard. -1. The module only removes a signer if they have demonstrated liveness during the interval, or - if necessary to convert the safe to a 1 of 1. -1. The module sets the correct 75% threshold upon removing a signer. +1. It must be impossible for the guard's `checkTransaction` or `checkAfterExecution` method to + permanently revert given any calldata and the current state. +1. The guard correctly handles updates to the owners list, such that new owners are recorded, and + removed owners are deleted. + 1. An `ownersBefore` enumerable set variable is used to accomplish this, it must be emptied at + the end of the `checkAfterExecution` call. + +#### In the module + 1. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1. -1. It must be impossible for the guard's checkTransaction or checkAfterExecution to permanently - revert given any calldata and the current state. +1. The module only removes an owner if they have not demonstrated liveness during the interval, or + if enough other owners have been removed to activate the shutdown mechanism. +1. The module correctly sets the Safe's threshold upon removing a signer. Note: neither the module nor guard attempt to prevent a quorum of owners from removing either the liveness module or guard. There are legitimate reasons they might wish to do so. Moreover, if such a quorum @@ -119,6 +143,14 @@ This means that the module can be removed or replaced without any affect on the The module however does have a dependency on the guard; if the guard is removed from the Safe, then the module will no longer be functional and calls to its `removeOwners` function will revert. +## Operational considerations + +### Manual validation of new owner liveness + +As [noted above](#the-liveness-guard) newly added owners are recorded in the guard without +necessarily having signed a transaction. Off-chain validation of the liveness of an address must +therefore be done prior to adding a new owner. + ### Deploying the liveness checking system [deploying]: #deploying-the-liveness-checking-system From 4abf2d9797ca836720b8524daa746cc9df7c8c60 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 16:06:55 +0300 Subject: [PATCH 299/374] contracts-bedrock: better comment for deployer `name()(string)` Updates the comment for the `name()(string)` function that is abstract on the `Deployer` contract. It should be more obvious why the function exists now. --- packages/contracts-bedrock/scripts/Deploy.s.sol | 3 +-- packages/contracts-bedrock/scripts/Deployer.sol | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/scripts/Deploy.s.sol b/packages/contracts-bedrock/scripts/Deploy.s.sol index 29240100dc00..72c717e716e8 100644 --- a/packages/contracts-bedrock/scripts/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/Deploy.s.sol @@ -52,8 +52,7 @@ import "src/libraries/DisputeTypes.sol"; contract Deploy is Deployer { DeployConfig cfg; - /// @notice The name of the script, used to ensure the right deploy artifacts - /// are used. + /// @inheritdoc function name() public pure override returns (string memory name_) { name_ = "Deploy"; } diff --git a/packages/contracts-bedrock/scripts/Deployer.sol b/packages/contracts-bedrock/scripts/Deployer.sol index 19b719a1636c..0fe050b4151e 100644 --- a/packages/contracts-bedrock/scripts/Deployer.sol +++ b/packages/contracts-bedrock/scripts/Deployer.sol @@ -163,6 +163,8 @@ abstract contract Deployer is Script { /// @notice Returns the name of the deployment script. Children contracts /// must implement this to ensure that the deploy artifacts can be found. + /// This should be the same as the name of the script and is used as the file + /// name inside of the `broadcast` directory when looking up deployment artifacts. function name() public pure virtual returns (string memory); /// @notice Returns all of the deployments done in the current context. From e8f93e9570637bb5b94ce36708e7475e3732b360 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 18:19:06 +0300 Subject: [PATCH 300/374] contracts-bedrock: fix compiler error --- packages/contracts-bedrock/scripts/Deploy.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/scripts/Deploy.s.sol b/packages/contracts-bedrock/scripts/Deploy.s.sol index 72c717e716e8..10d3b6f0ef9e 100644 --- a/packages/contracts-bedrock/scripts/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/Deploy.s.sol @@ -52,7 +52,7 @@ import "src/libraries/DisputeTypes.sol"; contract Deploy is Deployer { DeployConfig cfg; - /// @inheritdoc + /// @inheritdoc Deployer function name() public pure override returns (string memory name_) { name_ = "Deploy"; } From 73059962799ab79dbb533b653907ae6ce2e7631d Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 18:50:06 +0300 Subject: [PATCH 301/374] contracts-bedrock: fuzz optimism portal Migrate away from using magic variables and towards fuzzing in the `OptimismPortal` instead. This improves test coverage while moving away from an antipattern which is defining variables far away from where they are used. Its good to fuzz in place of this or have explicit visibility into what variables are used. --- packages/contracts-bedrock/.gas-snapshot | 25 +- .../test/OptimismPortal.t.sol | 309 ++++++++++++------ 2 files changed, 219 insertions(+), 115 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index f6dde017e500..5f5bccc49973 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -485,26 +485,17 @@ OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayPro OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227596) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166699) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154430) -OptimismPortal_Test:test_constructor_succeeds() (gas: 28164) -OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14292) -OptimismPortal_Test:test_depositTransaction_createWithZeroValueForContract_succeeds() (gas: 76814) -OptimismPortal_Test:test_depositTransaction_createWithZeroValueForEOA_succeeds() (gas: 77115) -OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512149) -OptimismPortal_Test:test_depositTransaction_noValueContract_succeeds() (gas: 76767) -OptimismPortal_Test:test_depositTransaction_noValueEOA_succeeds() (gas: 77112) +OptimismPortal_Test:test_constructor_succeeds() (gas: 28208) +OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14260) +OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512156) OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14528) -OptimismPortal_Test:test_depositTransaction_withEthValueAndContractContractCreation_succeeds() (gas: 83773) -OptimismPortal_Test:test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() (gas: 75929) -OptimismPortal_Test:test_depositTransaction_withEthValueFromContract_succeeds() (gas: 83476) -OptimismPortal_Test:test_depositTransaction_withEthValueFromEOA_succeeds() (gas: 84069) -OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127617) -OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17430) +OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127638) +OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17641) OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 24487) -OptimismPortal_Test:test_pause_succeeds() (gas: 27344) +OptimismPortal_Test:test_pause_succeeds() (gas: 27323) OptimismPortal_Test:test_receive_succeeds() (gas: 127564) -OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 35651) -OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31514) -OptimismPortal_Test:test_unpause_succeeds() (gas: 27451) +OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31558) +OptimismPortal_Test:test_unpause_succeeds() (gas: 27407) OptimistAllowlistTest:test_constructor_succeeds() (gas: 16407) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49650) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49254) diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol index 4b84ac1a4a91..8bd3361a7dc8 100644 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/OptimismPortal.t.sol @@ -163,145 +163,258 @@ contract OptimismPortal_Test is Portal_Initializer { } /// @dev Tests that `depositTransaction` succeeds for an EOA depositing a tx with 0 value. - function test_depositTransaction_noValueEOA_succeeds() external { - // EOA emulation - vm.prank(address(this), address(this)); - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - address(this), NON_ZERO_ADDRESS, ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA + function testFuzz_depositTransaction_noValueEOA_succeeds( + address _to, + uint64 _gasLimit, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) ); - op.depositTransaction(NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA); + // EOA emulation + vm.expectEmit(address(op)); + emitTransactionDeposited({ + _from: address(this), + _to: _to, + _value: 0, + _mint: 0, + _gasLimit: _gasLimit, + _isCreation: false, + _data: _data + }); + + vm.prank(address(this), address(this)); + op.depositTransaction({ _to: _to, _value: 0, _gasLimit: _gasLimit, _isCreation: false, _data: _data }); } /// @dev Tests that `depositTransaction` succeeds for a contract depositing a tx with 0 value. - function test_depositTransaction_noValueContract_succeeds() external { - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(this)), - NON_ZERO_ADDRESS, - ZERO_VALUE, - ZERO_VALUE, - NON_ZERO_GASLIMIT, - false, - NON_ZERO_DATA + function testFuzz_depositTransaction_noValueContract_succeeds( + address _to, + uint64 _gasLimit, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) ); - op.depositTransaction(NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA); + vm.expectEmit(address(op)); + emitTransactionDeposited({ + _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), + _to: _to, + _value: 0, + _mint: 0, + _gasLimit: _gasLimit, + _isCreation: false, + _data: _data + }); + + op.depositTransaction({ _to: _to, _value: 0, _gasLimit: _gasLimit, _isCreation: false, _data: _data }); } /// @dev Tests that `depositTransaction` succeeds for an EOA /// depositing a contract creation with 0 value. - function test_depositTransaction_createWithZeroValueForEOA_succeeds() external { - // EOA emulation - vm.prank(address(this), address(this)); - - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - address(this), ZERO_ADDRESS, ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA + function testFuzz_depositTransaction_createWithZeroValueForEOA_succeeds( + uint64 _gasLimit, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) ); - op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA); + vm.expectEmit(address(op)); + emitTransactionDeposited({ + _from: address(this), + _to: address(0), + _value: 0, + _mint: 0, + _gasLimit: _gasLimit, + _isCreation: true, + _data: _data + }); + + // EOA emulation + vm.prank(address(this), address(this)); + op.depositTransaction({ _to: address(0), _value: 0, _gasLimit: _gasLimit, _isCreation: true, _data: _data }); } /// @dev Tests that `depositTransaction` succeeds for a contract /// depositing a contract creation with 0 value. - function test_depositTransaction_createWithZeroValueForContract_succeeds() external { - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(this)), - ZERO_ADDRESS, - ZERO_VALUE, - ZERO_VALUE, - NON_ZERO_GASLIMIT, - true, - NON_ZERO_DATA + function testFuzz_depositTransaction_createWithZeroValueForContract_succeeds( + uint64 _gasLimit, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) ); - op.depositTransaction(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA); + vm.expectEmit(address(op)); + emitTransactionDeposited({ + _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), + _to: address(0), + _value: 0, + _mint: 0, + _gasLimit: _gasLimit, + _isCreation: true, + _data: _data + }); + + op.depositTransaction({ _to: address(0), _value: 0, _gasLimit: _gasLimit, _isCreation: true, _data: _data }); } /// @dev Tests that `depositTransaction` succeeds for an EOA depositing a tx with ETH. - function test_depositTransaction_withEthValueFromEOA_succeeds() external { - // EOA emulation - vm.prank(address(this), address(this)); - - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - address(this), NON_ZERO_ADDRESS, NON_ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA + function testFuzz_depositTransaction_withEthValueFromEOA_succeeds( + address _to, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) ); + if (_isCreation) _to = address(0); - op.depositTransaction{ value: NON_ZERO_VALUE }( - NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA - ); - assertEq(address(op).balance, NON_ZERO_VALUE); + // EOA emulation + vm.deal(address(this), _value); + + vm.expectEmit(address(op)); + emitTransactionDeposited({ + _from: address(this), + _to: _to, + _value: _value, + _mint: _value, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + + vm.prank(address(this), address(this)); + op.depositTransaction{ value: _value }({ + _to: _to, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + assertEq(address(op).balance, _value); } /// @dev Tests that `depositTransaction` succeeds for a contract depositing a tx with ETH. - function test_depositTransaction_withEthValueFromContract_succeeds() external { - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(this)), - NON_ZERO_ADDRESS, - NON_ZERO_VALUE, - ZERO_VALUE, - NON_ZERO_GASLIMIT, - false, - NON_ZERO_DATA + function testFuzz_depositTransaction_withEthValueFromContract_succeeds( + address _to, + uint256 _value, + uint64 _gasLimit, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) ); - op.depositTransaction{ value: NON_ZERO_VALUE }( - NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA - ); + vm.deal(address(this), _value); + + vm.expectEmit(address(op)); + emitTransactionDeposited({ + _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), + _to: _to, + _value: _value, + _mint: _value, + _gasLimit: _gasLimit, + _isCreation: false, + _data: _data + }); + + op.depositTransaction{ value: _value }({ + _to: _to, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: false, + _data: _data + }); } /// @dev Tests that `depositTransaction` succeeds for an EOA depositing a contract creation with ETH. - function test_depositTransaction_withEthValueAndEOAContractCreation_succeeds() external { - // EOA emulation - vm.prank(address(this), address(this)); - - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - address(this), ZERO_ADDRESS, NON_ZERO_VALUE, ZERO_VALUE, NON_ZERO_GASLIMIT, true, hex"" + function testFuzz_depositTransaction_withEthValueAndEOAContractCreation_succeeds( + uint256 _mint, + uint64 _gasLimit, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) ); - op.depositTransaction{ value: NON_ZERO_VALUE }(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, hex""); - assertEq(address(op).balance, NON_ZERO_VALUE); - } + vm.deal(address(this), _mint); - /// @dev Tests that `depositTransaction` succeeds for a contract depositing a contract creation with ETH. - function test_depositTransaction_withEthValueAndContractContractCreation_succeeds() external { - vm.expectEmit(true, true, false, true); - emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(this)), - ZERO_ADDRESS, - NON_ZERO_VALUE, - ZERO_VALUE, - NON_ZERO_GASLIMIT, - true, - NON_ZERO_DATA - ); + vm.expectEmit(address(op)); + emitTransactionDeposited({ + _from: address(this), + _to: address(0), + _value: 0, + _mint: _mint, + _gasLimit: _gasLimit, + _isCreation: true, + _data: _data + }); - op.depositTransaction{ value: NON_ZERO_VALUE }(ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, true, NON_ZERO_DATA); - assertEq(address(op).balance, NON_ZERO_VALUE); + // EOA emulation + vm.prank(address(this), address(this)); + op.depositTransaction{ value: _mint }({ + _to: address(0), + _value: 0, + _gasLimit: _gasLimit, + _isCreation: true, + _data: _data + }); + assertEq(address(op).balance, _mint); } - /// @dev Tests that `isOutputFinalized` succeeds for an EOA depositing a tx with ETH and data. - function test_simple_isOutputFinalized_succeeds() external { - uint256 ts = block.timestamp; - vm.mockCall( - address(op.L2_ORACLE()), - abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), - abi.encode(Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))) + /// @dev Tests that `depositTransaction` succeeds for a contract depositing a contract creation with ETH. + function testFuzz_depositTransaction_withEthValueAndContractContractCreation_succeeds( + uint256 _mint, + uint64 _gasLimit, + bytes memory _data + ) + external + { + _gasLimit = uint64( + bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) ); - // warp to the finalization period - vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS()); - assertEq(op.isOutputFinalized(0), false); + vm.deal(address(this), _mint); - // warp past the finalization period - vm.warp(ts + oracle.FINALIZATION_PERIOD_SECONDS() + 1); - assertEq(op.isOutputFinalized(0), true); + vm.expectEmit(address(op)); + emitTransactionDeposited({ + _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), + _to: address(0), + _value: 0, + _mint: _mint, + _gasLimit: _gasLimit, + _isCreation: true, + _data: _data + }); + + op.depositTransaction{ value: _mint }({ + _to: address(0), + _value: 0, + _gasLimit: _gasLimit, + _isCreation: true, + _data: _data + }); + assertEq(address(op).balance, _mint); } /// @dev Tests `isOutputFinalized` for a finalized output. From 056407f3a70069c1988f373761cf7123a2b4705f Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 18:56:13 +0300 Subject: [PATCH 302/374] op-bindings: regenerathttps://github.com/ethereum-optimism/optimism/pull/7991e --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index f6a602ff5a6d..e557605acfea 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:306;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:306;2534:6:135;400:55:306;382:74;;370:2;355:18;2448:99:135;211:251:306;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:306;;;1743:2;1728:18;26025:6379:135;1609:177:306;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:306;19164:28:135;;;2164:21:306;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:306;14107:30:135;;;2511:21:306;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:306;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:306;37406:29:135;;;2860:21:306;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:306;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:306;20288:41:135;;;3208:21:306;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:306;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:306;;;8234:54:135;3601:23:306;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:306;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:306;21415:72:135;;;4259:21:306;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:306;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:306:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:306;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:306;-1:-1:-1;1349:2:306;1334:18;;1321:32;;-1:-1:-1;1365:16:306;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:306;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:306:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:306;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:306:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:304;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:304;2534:6:135;400:55:304;382:74;;370:2;355:18;2448:99:135;211:251:304;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:304;;;1743:2;1728:18;26025:6379:135;1609:177:304;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:304;19164:28:135;;;2164:21:304;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:304;14107:30:135;;;2511:21:304;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:304;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:304;37406:29:135;;;2860:21:304;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:304;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:304;20288:41:135;;;3208:21:304;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:304;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:304;;;8234:54:135;3601:23:304;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:304;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:304;21415:72:135;;;4259:21:304;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:304;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:304:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:304;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:304;-1:-1:-1;1349:2:304;1334:18;;1321:32;;-1:-1:-1;1365:16:304;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:304;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:304:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:304;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:304:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 8523b96a5316..52403fe9a12a 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:306;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:306;;607:22;589:41;;577:2;562:18;680:66:137;449:187:306;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:306;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:306;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:306;906:62:137;;;2890:21:306;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:306:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:306;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:306:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:306;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:306;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:306;1069:19;1056:33;;-1:-1:-1;641:454:306;-1:-1:-1;641:454:306:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:306;;2017:180;-1:-1:-1;2017:180:306:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:306;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:306;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:304;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:304;;607:22;589:41;;577:2;562:18;680:66:137;449:187:304;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:304;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:304;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:304;906:62:137;;;2890:21:304;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:304:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:304;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:304:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:304;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:304;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:304;1069:19;1056:33;;-1:-1:-1;641:454:304;-1:-1:-1;641:454:304:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:304;;2017:180;-1:-1:-1;2017:180:304:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:304;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:304;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { From 97e97347c22179f420ca66492ae9fafa9191fb52 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 19:58:02 +0300 Subject: [PATCH 303/374] contracts-bedrock: deduplicate tests --- .../test/OptimismPortal.t.sol | 233 ++---------------- 1 file changed, 26 insertions(+), 207 deletions(-) diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol index 8bd3361a7dc8..b7f31b1644d5 100644 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/OptimismPortal.t.sol @@ -25,6 +25,15 @@ contract OptimismPortal_Test is Portal_Initializer { event Paused(address); event Unpaused(address); + address depositor; + + function setUp() public override { + super.setUp(); + depositor = makeAddr("depositor"); + vm.deal(depositor, type(uint256).max); + vm.deal(address(this), type(uint256).max); + } + /// @dev Tests that the constructor sets the correct values. function test_constructor_succeeds() external { assertEq(address(op.L2_ORACLE()), address(oracle)); @@ -162,119 +171,12 @@ contract OptimismPortal_Test is Portal_Initializer { assertTrue(op.minimumGasLimit(3) > op.minimumGasLimit(2)); } - /// @dev Tests that `depositTransaction` succeeds for an EOA depositing a tx with 0 value. - function testFuzz_depositTransaction_noValueEOA_succeeds( + /// @dev Tests that `depositTransaction` succeeds for an EOA. + function testFuzz_depositTransaction_eoa_succeeds( address _to, uint64 _gasLimit, - bytes memory _data - ) - external - { - _gasLimit = uint64( - bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) - ); - - // EOA emulation - vm.expectEmit(address(op)); - emitTransactionDeposited({ - _from: address(this), - _to: _to, - _value: 0, - _mint: 0, - _gasLimit: _gasLimit, - _isCreation: false, - _data: _data - }); - - vm.prank(address(this), address(this)); - op.depositTransaction({ _to: _to, _value: 0, _gasLimit: _gasLimit, _isCreation: false, _data: _data }); - } - - /// @dev Tests that `depositTransaction` succeeds for a contract depositing a tx with 0 value. - function testFuzz_depositTransaction_noValueContract_succeeds( - address _to, - uint64 _gasLimit, - bytes memory _data - ) - external - { - _gasLimit = uint64( - bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) - ); - - vm.expectEmit(address(op)); - emitTransactionDeposited({ - _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), - _to: _to, - _value: 0, - _mint: 0, - _gasLimit: _gasLimit, - _isCreation: false, - _data: _data - }); - - op.depositTransaction({ _to: _to, _value: 0, _gasLimit: _gasLimit, _isCreation: false, _data: _data }); - } - - /// @dev Tests that `depositTransaction` succeeds for an EOA - /// depositing a contract creation with 0 value. - function testFuzz_depositTransaction_createWithZeroValueForEOA_succeeds( - uint64 _gasLimit, - bytes memory _data - ) - external - { - _gasLimit = uint64( - bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) - ); - - vm.expectEmit(address(op)); - emitTransactionDeposited({ - _from: address(this), - _to: address(0), - _value: 0, - _mint: 0, - _gasLimit: _gasLimit, - _isCreation: true, - _data: _data - }); - - // EOA emulation - vm.prank(address(this), address(this)); - op.depositTransaction({ _to: address(0), _value: 0, _gasLimit: _gasLimit, _isCreation: true, _data: _data }); - } - - /// @dev Tests that `depositTransaction` succeeds for a contract - /// depositing a contract creation with 0 value. - function testFuzz_depositTransaction_createWithZeroValueForContract_succeeds( - uint64 _gasLimit, - bytes memory _data - ) - external - { - _gasLimit = uint64( - bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) - ); - - vm.expectEmit(address(op)); - emitTransactionDeposited({ - _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), - _to: address(0), - _value: 0, - _mint: 0, - _gasLimit: _gasLimit, - _isCreation: true, - _data: _data - }); - - op.depositTransaction({ _to: address(0), _value: 0, _gasLimit: _gasLimit, _isCreation: true, _data: _data }); - } - - /// @dev Tests that `depositTransaction` succeeds for an EOA depositing a tx with ETH. - function testFuzz_depositTransaction_withEthValueFromEOA_succeeds( - address _to, uint256 _value, - uint64 _gasLimit, + uint256 _mint, bool _isCreation, bytes memory _data ) @@ -286,35 +188,29 @@ contract OptimismPortal_Test is Portal_Initializer { if (_isCreation) _to = address(0); // EOA emulation - vm.deal(address(this), _value); - vm.expectEmit(address(op)); emitTransactionDeposited({ - _from: address(this), + _from: depositor, _to: _to, _value: _value, - _mint: _value, + _mint: _mint, _gasLimit: _gasLimit, _isCreation: _isCreation, _data: _data }); - vm.prank(address(this), address(this)); - op.depositTransaction{ value: _value }({ - _to: _to, - _value: _value, - _gasLimit: _gasLimit, - _isCreation: _isCreation, - _data: _data - }); - assertEq(address(op).balance, _value); + vm.prank(depositor, depositor); + op.depositTransaction{ value: _mint }({ _to: _to, _value: _value, _gasLimit: _gasLimit, _isCreation: _isCreation, _data: _data }); + assertEq(address(op).balance, _mint); } - /// @dev Tests that `depositTransaction` succeeds for a contract depositing a tx with ETH. - function testFuzz_depositTransaction_withEthValueFromContract_succeeds( + /// @dev Tests that `depositTransaction` succeeds for a contract. + function testFuzz_depositTransaction_contract_succeeds( address _to, - uint256 _value, uint64 _gasLimit, + uint256 _value, + uint256 _mint, + bool _isCreation, bytes memory _data ) external @@ -322,98 +218,21 @@ contract OptimismPortal_Test is Portal_Initializer { _gasLimit = uint64( bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) ); - - vm.deal(address(this), _value); + if (_isCreation) _to = address(0); vm.expectEmit(address(op)); emitTransactionDeposited({ _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), _to: _to, _value: _value, - _mint: _value, - _gasLimit: _gasLimit, - _isCreation: false, - _data: _data - }); - - op.depositTransaction{ value: _value }({ - _to: _to, - _value: _value, - _gasLimit: _gasLimit, - _isCreation: false, - _data: _data - }); - } - - /// @dev Tests that `depositTransaction` succeeds for an EOA depositing a contract creation with ETH. - function testFuzz_depositTransaction_withEthValueAndEOAContractCreation_succeeds( - uint256 _mint, - uint64 _gasLimit, - bytes memory _data - ) - external - { - _gasLimit = uint64( - bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) - ); - - vm.deal(address(this), _mint); - - vm.expectEmit(address(op)); - emitTransactionDeposited({ - _from: address(this), - _to: address(0), - _value: 0, - _mint: _mint, - _gasLimit: _gasLimit, - _isCreation: true, - _data: _data - }); - - // EOA emulation - vm.prank(address(this), address(this)); - op.depositTransaction{ value: _mint }({ - _to: address(0), - _value: 0, - _gasLimit: _gasLimit, - _isCreation: true, - _data: _data - }); - assertEq(address(op).balance, _mint); - } - - /// @dev Tests that `depositTransaction` succeeds for a contract depositing a contract creation with ETH. - function testFuzz_depositTransaction_withEthValueAndContractContractCreation_succeeds( - uint256 _mint, - uint64 _gasLimit, - bytes memory _data - ) - external - { - _gasLimit = uint64( - bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) - ); - - vm.deal(address(this), _mint); - - vm.expectEmit(address(op)); - emitTransactionDeposited({ - _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), - _to: address(0), - _value: 0, _mint: _mint, _gasLimit: _gasLimit, - _isCreation: true, + _isCreation: _isCreation, _data: _data }); - op.depositTransaction{ value: _mint }({ - _to: address(0), - _value: 0, - _gasLimit: _gasLimit, - _isCreation: true, - _data: _data - }); + vm.prank(address(this)); + op.depositTransaction{ value: _mint }({ _to: _to, _value: _value, _gasLimit: _gasLimit, _isCreation: _isCreation, _data: _data }); assertEq(address(op).balance, _mint); } From 490983b24548c5c2b180c9a637f8c55d5c620a97 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 19:58:53 +0300 Subject: [PATCH 304/374] lint: fix --- .../contracts-bedrock/test/OptimismPortal.t.sol | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol index b7f31b1644d5..63fe6c47ce91 100644 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/OptimismPortal.t.sol @@ -200,7 +200,13 @@ contract OptimismPortal_Test is Portal_Initializer { }); vm.prank(depositor, depositor); - op.depositTransaction{ value: _mint }({ _to: _to, _value: _value, _gasLimit: _gasLimit, _isCreation: _isCreation, _data: _data }); + op.depositTransaction{ value: _mint }({ + _to: _to, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); assertEq(address(op).balance, _mint); } @@ -232,7 +238,13 @@ contract OptimismPortal_Test is Portal_Initializer { }); vm.prank(address(this)); - op.depositTransaction{ value: _mint }({ _to: _to, _value: _value, _gasLimit: _gasLimit, _isCreation: _isCreation, _data: _data }); + op.depositTransaction{ value: _mint }({ + _to: _to, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); assertEq(address(op).balance, _mint); } From efdf61f744904c2d187dd7f2b9ce88b1860b1e62 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 20:47:27 +0300 Subject: [PATCH 305/374] contracts-bedock: gas snapshot --- packages/contracts-bedrock/.gas-snapshot | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 5f5bccc49973..09a2e82c1a94 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -485,17 +485,17 @@ OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayPro OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227596) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166699) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154430) -OptimismPortal_Test:test_constructor_succeeds() (gas: 28208) -OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14260) -OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512156) +OptimismPortal_Test:test_constructor_succeeds() (gas: 28164) +OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14292) +OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512200) OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14528) -OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127638) -OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17641) +OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127594) +OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17597) OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 24487) -OptimismPortal_Test:test_pause_succeeds() (gas: 27323) +OptimismPortal_Test:test_pause_succeeds() (gas: 27344) OptimismPortal_Test:test_receive_succeeds() (gas: 127564) -OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31558) -OptimismPortal_Test:test_unpause_succeeds() (gas: 27407) +OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31514) +OptimismPortal_Test:test_unpause_succeeds() (gas: 27451) OptimistAllowlistTest:test_constructor_succeeds() (gas: 16407) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49650) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49254) From 78210d4e60970ceed04ab62faca07a5ca642e41e Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 12:23:38 -0600 Subject: [PATCH 306/374] contracts-bedrock: deal uint128 max Co-authored-by: Matt Solomon --- packages/contracts-bedrock/test/OptimismPortal.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol index 63fe6c47ce91..66ff26fa71f0 100644 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/OptimismPortal.t.sol @@ -30,8 +30,8 @@ contract OptimismPortal_Test is Portal_Initializer { function setUp() public override { super.setUp(); depositor = makeAddr("depositor"); - vm.deal(depositor, type(uint256).max); - vm.deal(address(this), type(uint256).max); + vm.deal(depositor, type(uint128).max); + vm.deal(address(this), type(uint128).max); } /// @dev Tests that the constructor sets the correct values. From 8728c764a16479291f59c921f7f7954e4029d45d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 20:40:02 +0000 Subject: [PATCH 307/374] build(deps): bump viem from 1.18.1 to 1.18.2 Bumps [viem](https://github.com/wagmi-dev/viem) from 1.18.1 to 1.18.2. - [Release notes](https://github.com/wagmi-dev/viem/releases) - [Commits](https://github.com/wagmi-dev/viem/compare/viem@1.18.1...viem@1.18.2) --- updated-dependencies: - dependency-name: viem dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/contracts-ts/package.json | 2 +- packages/fee-estimation/package.json | 2 +- packages/sdk/package.json | 2 +- packages/web3js-plugin/package.json | 2 +- pnpm-lock.yaml | 62 ++++++++++++++-------------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/contracts-ts/package.json b/packages/contracts-ts/package.json index 87721b4f2be1..24384796fa19 100644 --- a/packages/contracts-ts/package.json +++ b/packages/contracts-ts/package.json @@ -82,6 +82,6 @@ "change-case": "4.1.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "viem": "^1.18.1" + "viem": "^1.18.2" } } diff --git a/packages/fee-estimation/package.json b/packages/fee-estimation/package.json index 70c823efe258..cd3788ece2f8 100644 --- a/packages/fee-estimation/package.json +++ b/packages/fee-estimation/package.json @@ -44,7 +44,7 @@ "jsdom": "^22.1.0", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.18.1", + "viem": "^1.18.2", "vite": "^4.5.0", "vitest": "^0.34.2" }, diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 52bf429c5fad..367b5741a393 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -56,7 +56,7 @@ "ts-node": "^10.9.1", "typedoc": "^0.25.3", "typescript": "^5.2.2", - "viem": "^1.18.1", + "viem": "^1.18.2", "vitest": "^0.34.2", "zod": "^3.22.4" }, diff --git a/packages/web3js-plugin/package.json b/packages/web3js-plugin/package.json index 5656c5b68390..f80f2dbf2dbc 100644 --- a/packages/web3js-plugin/package.json +++ b/packages/web3js-plugin/package.json @@ -37,7 +37,7 @@ "@vitest/coverage-istanbul": "^0.34.6", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.18.1", + "viem": "^1.18.2", "vite": "^4.5.0", "vitest": "^0.34.1", "zod": "^3.22.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 53d10a3b7b05..211270d87832 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -298,11 +298,11 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) viem: - specifier: ^1.18.1 - version: 1.18.1(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.2 + version: 1.18.2(typescript@5.2.2)(zod@3.22.4) wagmi: specifier: '>1.0.0' - version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) + version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) devDependencies: '@eth-optimism/contracts-bedrock': specifier: workspace:* @@ -324,7 +324,7 @@ importers: version: 1.5.2(@wagmi/core@1.4.5)(typescript@5.2.2)(wagmi@1.0.1) '@wagmi/core': specifier: ^1.4.5 - version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) + version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) abitype: specifier: ^0.10.2 version: 0.10.2(typescript@5.2.2) @@ -438,8 +438,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.1 - version: 1.18.1(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.2 + version: 1.18.2(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -529,8 +529,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.1 - version: 1.18.1(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.2 + version: 1.18.2(typescript@5.2.2)(zod@3.22.4) vitest: specifier: ^0.34.2 version: 0.34.2 @@ -569,8 +569,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.1 - version: 1.18.1(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.2 + version: 1.18.2(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -3197,7 +3197,7 @@ packages: resolution: {integrity: sha512-gYw0ki/EAuV1oSyMxpqandHjnthZjYYy+YWpTAzf8BqfXM3ItcZLpjxfg+3+mXW8HIO+3jw6T9iiqEXsqHaMMw==} dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.7.3 - viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - bufferutil - encoding @@ -4562,7 +4562,7 @@ packages: wagmi: optional: true dependencies: - '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) + '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) abort-controller: 3.0.0 bundle-require: 3.1.2(esbuild@0.16.17) @@ -4584,15 +4584,15 @@ packages: picocolors: 1.0.0 prettier: 2.8.8 typescript: 5.2.2 - viem: 1.18.1(typescript@5.2.2)(zod@3.22.3) - wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) + viem: 1.18.2(typescript@5.2.2)(zod@3.22.3) + wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) zod: 3.22.3 transitivePeerDependencies: - bufferutil - utf-8-validate dev: true - /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.1): + /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.2): resolution: {integrity: sha512-fl01vym19DE1uoE+MlASw5zo3Orr/YXlJRjOKLaKYtV+Q7jOLY4TwHgq7sEMs+JYOvFICFBEAlWNNxidr51AqQ==} peerDependencies: '@wagmi/chains': '>=0.2.0' @@ -4615,7 +4615,7 @@ packages: abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil @@ -4627,7 +4627,7 @@ packages: - utf-8-validate - zod - /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.1): + /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.2): resolution: {integrity: sha512-UgwsQKQDFObJVJMf9pDfFoXTv710o4zrTHyhIWKBTMMkLpCMsMxN5+ZaDhBYt/BgoRinfRYQo8uwuwLhxE6Log==} peerDependencies: typescript: '>=5.0.4' @@ -4647,7 +4647,7 @@ packages: abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - '@types/react' @@ -4660,7 +4660,7 @@ packages: - zod dev: true - /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.1): + /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.2): resolution: {integrity: sha512-Zzg4Ob92QMF9NsC+z5/8JZjMn3NCCnwVWGJlv79qRX9mp5Ku40OzJNvqDnjcSGjshe6H0L/KtFZAqTlmu8lT7w==} peerDependencies: typescript: '>=4.9.4' @@ -4670,11 +4670,11 @@ packages: optional: true dependencies: '@wagmi/chains': 0.2.22(typescript@5.2.2) - '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) + '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -4688,7 +4688,7 @@ packages: - utf-8-validate - zod - /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.1): + /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.2): resolution: {integrity: sha512-N9luRb1Uk4tBN9kaYcQSWKE9AsRt/rvZaFt5IZech4JPzNN2sQlfhKd9GEjOXYRDqEPHdDvos7qyBKiDNTz4GA==} peerDependencies: typescript: '>=5.0.4' @@ -4697,11 +4697,11 @@ packages: typescript: optional: true dependencies: - '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) + '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -14292,8 +14292,8 @@ packages: vfile-message: 2.0.4 dev: true - /viem@1.18.1(typescript@5.2.2)(zod@3.22.3): - resolution: {integrity: sha512-dkZG1jI8iL7G0+KZ8ZKHCXbzZxzu8Iib7OLCxkdaqdrlNrWTEMIZSp/2AHpbjpPeAg3VFD1CUayKPTJv2ZMXCg==} + /viem@1.18.2(typescript@5.2.2)(zod@3.22.3): + resolution: {integrity: sha512-ifobXCKwzztmjHbHowAWqTASO6tAqF6udKB9ONXkJQU1cmt830MABiMwJGtTO9Gb9ION1N+324G7nHDbpPn4wg==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14315,8 +14315,8 @@ packages: - zod dev: true - /viem@1.18.1(typescript@5.2.2)(zod@3.22.4): - resolution: {integrity: sha512-dkZG1jI8iL7G0+KZ8ZKHCXbzZxzu8Iib7OLCxkdaqdrlNrWTEMIZSp/2AHpbjpPeAg3VFD1CUayKPTJv2ZMXCg==} + /viem@1.18.2(typescript@5.2.2)(zod@3.22.4): + resolution: {integrity: sha512-ifobXCKwzztmjHbHowAWqTASO6tAqF6udKB9ONXkJQU1cmt830MABiMwJGtTO9Gb9ION1N+324G7nHDbpPn4wg==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14809,7 +14809,7 @@ packages: xml-name-validator: 4.0.0 dev: true - /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.1): + /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.2): resolution: {integrity: sha512-+2UkZG9eA3tKqXj1wvlvI8mL0Bcff7Tf5CKfUOyQsdKcY+J5rfwYYya25G+jja57umpHFtfxRaL7xDkNjehrRg==} peerDependencies: react: '>=17.0.0' @@ -14822,12 +14822,12 @@ packages: '@tanstack/query-sync-storage-persister': 4.29.25 '@tanstack/react-query': 4.29.25(react-dom@18.2.0)(react@18.2.0) '@tanstack/react-query-persist-client': 4.29.25(@tanstack/react-query@4.29.25) - '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.1) + '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) abitype: 0.8.1(typescript@5.2.2) react: 18.2.0 typescript: 5.2.2 use-sync-external-store: 1.2.0(react@18.2.0) - viem: 1.18.1(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil From f4b6aa35f6ab8c343481f5a843af5962002f7933 Mon Sep 17 00:00:00 2001 From: tre Date: Wed, 1 Nov 2023 14:25:24 -0700 Subject: [PATCH 308/374] Add Base faucet to drippie --- packages/contracts-bedrock/periphery-deploy-config/4460.json | 1 + .../contracts-bedrock/periphery-deploy-config/58008.json | 1 + .../contracts-bedrock/periphery-deploy-config/84532.json | 1 + packages/contracts-bedrock/periphery-deploy-config/901.json | 1 + packages/contracts-bedrock/periphery-deploy-config/919.json | 1 + .../contracts-bedrock/periphery-deploy-config/999999999.json | 1 + .../periphery-deploy-config/optimism-goerli.json | 1 + .../periphery-deploy-config/optimism-sepolia.json | 1 + .../contracts-bedrock/periphery-deploy-config/sepolia.json | 1 + .../contracts-bedrock/scripts/PeripheryDeployConfig.s.sol | 5 ++++- 10 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/periphery-deploy-config/4460.json b/packages/contracts-bedrock/periphery-deploy-config/4460.json index f52288d9ce57..3aea969e5dce 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/4460.json +++ b/packages/contracts-bedrock/periphery-deploy-config/4460.json @@ -22,6 +22,7 @@ "faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleAmount": 50000000000000000, "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", diff --git a/packages/contracts-bedrock/periphery-deploy-config/58008.json b/packages/contracts-bedrock/periphery-deploy-config/58008.json index f52288d9ce57..3aea969e5dce 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/58008.json +++ b/packages/contracts-bedrock/periphery-deploy-config/58008.json @@ -22,6 +22,7 @@ "faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleAmount": 50000000000000000, "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", diff --git a/packages/contracts-bedrock/periphery-deploy-config/84532.json b/packages/contracts-bedrock/periphery-deploy-config/84532.json index f52288d9ce57..3aea969e5dce 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/84532.json +++ b/packages/contracts-bedrock/periphery-deploy-config/84532.json @@ -22,6 +22,7 @@ "faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleAmount": 50000000000000000, "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", diff --git a/packages/contracts-bedrock/periphery-deploy-config/901.json b/packages/contracts-bedrock/periphery-deploy-config/901.json index f52288d9ce57..3aea969e5dce 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/901.json +++ b/packages/contracts-bedrock/periphery-deploy-config/901.json @@ -22,6 +22,7 @@ "faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleAmount": 50000000000000000, "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", diff --git a/packages/contracts-bedrock/periphery-deploy-config/919.json b/packages/contracts-bedrock/periphery-deploy-config/919.json index f52288d9ce57..3aea969e5dce 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/919.json +++ b/packages/contracts-bedrock/periphery-deploy-config/919.json @@ -22,6 +22,7 @@ "faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleAmount": 50000000000000000, "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", diff --git a/packages/contracts-bedrock/periphery-deploy-config/999999999.json b/packages/contracts-bedrock/periphery-deploy-config/999999999.json index f52288d9ce57..3aea969e5dce 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/999999999.json +++ b/packages/contracts-bedrock/periphery-deploy-config/999999999.json @@ -22,6 +22,7 @@ "faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleAmount": 50000000000000000, "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", diff --git a/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json b/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json index 7d369d97a179..906d5f9990c1 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json +++ b/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json @@ -22,6 +22,7 @@ "faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleAmount": 50000000000000000, "opL1BridgeAddress": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", diff --git a/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json b/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json index f52288d9ce57..3aea969e5dce 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json +++ b/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json @@ -22,6 +22,7 @@ "faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleAmount": 50000000000000000, "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", diff --git a/packages/contracts-bedrock/periphery-deploy-config/sepolia.json b/packages/contracts-bedrock/periphery-deploy-config/sepolia.json index 70e8b5aa5141..1bba77af8b51 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/sepolia.json +++ b/packages/contracts-bedrock/periphery-deploy-config/sepolia.json @@ -22,6 +22,7 @@ "faucetOffchainAuthModuleTtl": 86400, "faucetOffchainAuthModuleAmount": 50000000000000000, "opL1BridgeAddress": "0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1", + "baseL1BridgeAddress": "0xfd0Bf71F60660E2f608ed56e1659C450eB113120", "pgnL1BridgeAddress": "0xFaE6abCAF30D23e233AC7faF747F2fC3a5a6Bfa3", "zoraL1BridgeAddress": "0x5376f1D543dcbB5BD416c56C189e4cB7399fCcCB", "orderlyL1BridgeAddress": "0x1Af0494040d6904A9F3EE21921de4b359C736333", diff --git a/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol b/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol index c00ecbc74e1c..4838a3badaa7 100644 --- a/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol +++ b/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol @@ -42,13 +42,14 @@ contract PeripheryDeployConfig is Script { uint256 public opChainAdminWalletDripValue; uint256 public opChainAdminWalletDripInterval; address public opL1BridgeAddress; + address public baseL1BridgeAddress; address public zoraL1BridgeAddress; address public pgnL1BridgeAddress; address public orderlyL1BridgeAddress; address public modeL1BridgeAddress; address public lyraL1BridgeAddress; address[5] public smallFaucetsL1BridgeAddresses; - address[1] public largeFaucetsL1BridgeAddresses; + address[2] public largeFaucetsL1BridgeAddresses; uint256 public dripVersion; constructor(string memory _path) { @@ -84,6 +85,7 @@ contract PeripheryDeployConfig is Script { faucetOffchainAuthModuleAmount = stdJson.readUint(_json, "$.faucetOffchainAuthModuleAmount"); installOpChainFaucetsDrips = stdJson.readBool(_json, "$.installOpChainFaucetsDrips"); opL1BridgeAddress = stdJson.readAddress(_json, "$.opL1BridgeAddress"); + baseL1BridgeAddress = stdJson.readAddress(_json, "$.baseL1BridgeAddress"); zoraL1BridgeAddress = stdJson.readAddress(_json, "$.zoraL1BridgeAddress"); pgnL1BridgeAddress = stdJson.readAddress(_json, "$.pgnL1BridgeAddress"); orderlyL1BridgeAddress = stdJson.readAddress(_json, "$.orderlyL1BridgeAddress"); @@ -97,6 +99,7 @@ contract PeripheryDeployConfig is Script { opChainAdminWalletDripValue = stdJson.readUint(_json, "$.opChainAdminWalletDripValue"); opChainAdminWalletDripInterval = stdJson.readUint(_json, "$.opChainAdminWalletDripInterval"); largeFaucetsL1BridgeAddresses[0] = opL1BridgeAddress; + largeFaucetsL1BridgeAddresses[1] = baseL1BridgeAddress; smallFaucetsL1BridgeAddresses[0] = zoraL1BridgeAddress; smallFaucetsL1BridgeAddresses[1] = pgnL1BridgeAddress; smallFaucetsL1BridgeAddresses[2] = orderlyL1BridgeAddress; From 5cd3bcbe565c3854234c2d0283858d32d81ba901 Mon Sep 17 00:00:00 2001 From: inphi Date: Wed, 1 Nov 2023 17:50:47 -0400 Subject: [PATCH 309/374] op-upgrade: log invalid deploy-config error --- op-chain-ops/cmd/op-upgrade/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-chain-ops/cmd/op-upgrade/main.go b/op-chain-ops/cmd/op-upgrade/main.go index aec5c07addfb..7fdf67c8967e 100644 --- a/op-chain-ops/cmd/op-upgrade/main.go +++ b/op-chain-ops/cmd/op-upgrade/main.go @@ -112,7 +112,7 @@ func entrypoint(ctx *cli.Context) error { name, _ := toDeployConfigName(chainConfig) config, err := genesis.NewDeployConfigWithNetwork(name, deployConfig) if err != nil { - log.Warn("Cannot find deploy config for network", "name", chainConfig.Name, "deploy-config-name", name, "path", deployConfig) + log.Warn("Cannot find deploy config for network", "name", chainConfig.Name, "deploy-config-name", name, "path", deployConfig, "err", err) } if config != nil { From b4e09c3554763f364fdcf732e51782e6a6e77029 Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Wed, 1 Nov 2023 15:47:55 -0700 Subject: [PATCH 310/374] op-bindings: Rebuild --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- op-bindings/bindings/weth9.go | 2 +- op-bindings/bindings/weth9_more.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index f6a602ff5a6d..e557605acfea 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:306;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:306;2534:6:135;400:55:306;382:74;;370:2;355:18;2448:99:135;211:251:306;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:306;;;1743:2;1728:18;26025:6379:135;1609:177:306;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:306;19164:28:135;;;2164:21:306;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:306;14107:30:135;;;2511:21:306;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:306;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:306;37406:29:135;;;2860:21:306;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:306;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:306;20288:41:135;;;3208:21:306;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:306;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:306;;;8234:54:135;3601:23:306;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:306;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:306;21415:72:135;;;4259:21:306;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:306;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:306:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:306;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:306;-1:-1:-1;1349:2:306;1334:18;;1321:32;;-1:-1:-1;1365:16:306;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:306;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:306:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:306;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:306:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:304;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:304;2534:6:135;400:55:304;382:74;;370:2;355:18;2448:99:135;211:251:304;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:304;;;1743:2;1728:18;26025:6379:135;1609:177:304;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:304;19164:28:135;;;2164:21:304;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:304;14107:30:135;;;2511:21:304;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:304;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:304;37406:29:135;;;2860:21:304;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:304;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:304;20288:41:135;;;3208:21:304;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:304;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:304;;;8234:54:135;3601:23:304;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:304;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:304;21415:72:135;;;4259:21:304;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:304;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:304:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:304;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:304;-1:-1:-1;1349:2:304;1334:18;;1321:32;;-1:-1:-1;1365:16:304;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:304;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:304:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:304;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:304:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 8523b96a5316..52403fe9a12a 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:306;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:306;;607:22;589:41;;577:2;562:18;680:66:137;449:187:306;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:306;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:306;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:306;906:62:137;;;2890:21:306;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:306:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:306;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:306:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:306;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:306;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:306;1069:19;1056:33;;-1:-1:-1;641:454:306;-1:-1:-1;641:454:306:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:306;;2017:180;-1:-1:-1;2017:180:306:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:306;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:306;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:304;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:304;;607:22;589:41;;577:2;562:18;680:66:137;449:187:304;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:304;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:304;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:304;906:62:137;;;2890:21:304;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:304:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:304;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:304:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:304;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:304;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:304;1069:19;1056:33;;-1:-1:-1;641:454:304;-1:-1:-1;641:454:304:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:304;;2017:180;-1:-1:-1;2017:180:304:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:304;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:304;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { diff --git a/op-bindings/bindings/weth9.go b/op-bindings/bindings/weth9.go index 587e8bec5f5c..ff06f53092dc 100644 --- a/op-bindings/bindings/weth9.go +++ b/op-bindings/bindings/weth9.go @@ -31,7 +31,7 @@ var ( // WETH9MetaData contains all meta data concerning the WETH9 contract. var WETH9MetaData = &bind.MetaData{ ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158203b5b5adf37f507cc9ca5ac0b72acf7873b794171cc0eeb888a5f850e69fe540d64736f6c63430005110032", + Bin: "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820683910f07c85568ba88afbf94f95d53b286477eb0dd36de9f0a1f5b215dd6f3764736f6c63430005110032", } // WETH9ABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/weth9_more.go b/op-bindings/bindings/weth9_more.go index 7530f273d76b..712844cef953 100644 --- a/op-bindings/bindings/weth9_more.go +++ b/op-bindings/bindings/weth9_more.go @@ -13,7 +13,7 @@ const WETH9StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src var WETH9StorageLayout = new(solc.StorageLayout) -var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158203b5b5adf37f507cc9ca5ac0b72acf7873b794171cc0eeb888a5f850e69fe540d64736f6c63430005110032" +var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820683910f07c85568ba88afbf94f95d53b286477eb0dd36de9f0a1f5b215dd6f3764736f6c63430005110032" func init() { if err := json.Unmarshal([]byte(WETH9StorageLayoutJSON), WETH9StorageLayout); err != nil { From a0e578856547494d92c79b82e7b243c28841cd49 Mon Sep 17 00:00:00 2001 From: tre Date: Wed, 1 Nov 2023 15:48:40 -0700 Subject: [PATCH 311/374] Add ability to archive previous drip configs --- .../periphery-deploy-config/4460.json | 2 + .../periphery-deploy-config/58008.json | 2 + .../periphery-deploy-config/84532.json | 2 + .../periphery-deploy-config/901.json | 2 + .../periphery-deploy-config/919.json | 2 + .../periphery-deploy-config/999999999.json | 2 + .../optimism-goerli.json | 2 + .../optimism-sepolia.json | 2 + .../periphery-deploy-config/sepolia.json | 4 +- .../scripts/DeployPeriphery.s.sol | 276 ++++++++++-------- .../scripts/PeripheryDeployConfig.s.sol | 4 + 11 files changed, 185 insertions(+), 115 deletions(-) diff --git a/packages/contracts-bedrock/periphery-deploy-config/4460.json b/packages/contracts-bedrock/periphery-deploy-config/4460.json index 3aea969e5dce..baa776ddd80a 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/4460.json +++ b/packages/contracts-bedrock/periphery-deploy-config/4460.json @@ -29,7 +29,9 @@ "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, "dripVersion": 1, + "previousDripVersion": 0, "smallOpChainFaucetDripValue": 2000000000000000000, "smallOpChainFaucetDripInterval": 86400, "largeOpChainFaucetDripValue": 34000000000000000000, diff --git a/packages/contracts-bedrock/periphery-deploy-config/58008.json b/packages/contracts-bedrock/periphery-deploy-config/58008.json index 3aea969e5dce..baa776ddd80a 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/58008.json +++ b/packages/contracts-bedrock/periphery-deploy-config/58008.json @@ -29,7 +29,9 @@ "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, "dripVersion": 1, + "previousDripVersion": 0, "smallOpChainFaucetDripValue": 2000000000000000000, "smallOpChainFaucetDripInterval": 86400, "largeOpChainFaucetDripValue": 34000000000000000000, diff --git a/packages/contracts-bedrock/periphery-deploy-config/84532.json b/packages/contracts-bedrock/periphery-deploy-config/84532.json index 3aea969e5dce..baa776ddd80a 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/84532.json +++ b/packages/contracts-bedrock/periphery-deploy-config/84532.json @@ -29,7 +29,9 @@ "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, "dripVersion": 1, + "previousDripVersion": 0, "smallOpChainFaucetDripValue": 2000000000000000000, "smallOpChainFaucetDripInterval": 86400, "largeOpChainFaucetDripValue": 34000000000000000000, diff --git a/packages/contracts-bedrock/periphery-deploy-config/901.json b/packages/contracts-bedrock/periphery-deploy-config/901.json index 3aea969e5dce..baa776ddd80a 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/901.json +++ b/packages/contracts-bedrock/periphery-deploy-config/901.json @@ -29,7 +29,9 @@ "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, "dripVersion": 1, + "previousDripVersion": 0, "smallOpChainFaucetDripValue": 2000000000000000000, "smallOpChainFaucetDripInterval": 86400, "largeOpChainFaucetDripValue": 34000000000000000000, diff --git a/packages/contracts-bedrock/periphery-deploy-config/919.json b/packages/contracts-bedrock/periphery-deploy-config/919.json index 3aea969e5dce..baa776ddd80a 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/919.json +++ b/packages/contracts-bedrock/periphery-deploy-config/919.json @@ -29,7 +29,9 @@ "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, "dripVersion": 1, + "previousDripVersion": 0, "smallOpChainFaucetDripValue": 2000000000000000000, "smallOpChainFaucetDripInterval": 86400, "largeOpChainFaucetDripValue": 34000000000000000000, diff --git a/packages/contracts-bedrock/periphery-deploy-config/999999999.json b/packages/contracts-bedrock/periphery-deploy-config/999999999.json index 3aea969e5dce..baa776ddd80a 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/999999999.json +++ b/packages/contracts-bedrock/periphery-deploy-config/999999999.json @@ -29,7 +29,9 @@ "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, "dripVersion": 1, + "previousDripVersion": 0, "smallOpChainFaucetDripValue": 2000000000000000000, "smallOpChainFaucetDripInterval": 86400, "largeOpChainFaucetDripValue": 34000000000000000000, diff --git a/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json b/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json index 906d5f9990c1..4ba3a39a8d13 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json +++ b/packages/contracts-bedrock/periphery-deploy-config/optimism-goerli.json @@ -29,7 +29,9 @@ "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, "dripVersion": 1, + "previousDripVersion": 0, "smallOpChainFaucetDripValue": 2000000000000000000, "smallOpChainFaucetDripInterval": 86400, "largeOpChainFaucetDripValue": 34000000000000000000, diff --git a/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json b/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json index 3aea969e5dce..baa776ddd80a 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json +++ b/packages/contracts-bedrock/periphery-deploy-config/optimism-sepolia.json @@ -29,7 +29,9 @@ "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", "installOpChainFaucetsDrips": false, + "archivePreviousOpChainFaucetsDrips": false, "dripVersion": 1, + "previousDripVersion": 0, "smallOpChainFaucetDripValue": 2000000000000000000, "smallOpChainFaucetDripInterval": 86400, "largeOpChainFaucetDripValue": 34000000000000000000, diff --git a/packages/contracts-bedrock/periphery-deploy-config/sepolia.json b/packages/contracts-bedrock/periphery-deploy-config/sepolia.json index 1bba77af8b51..d4c80d010480 100644 --- a/packages/contracts-bedrock/periphery-deploy-config/sepolia.json +++ b/packages/contracts-bedrock/periphery-deploy-config/sepolia.json @@ -29,7 +29,9 @@ "modeL1BridgeAddress": "0xbC5C679879B2965296756CD959C3C739769995E2", "lyraL1BridgeAddress": "0x915f179A77FB2e1AeA8b56Ebc0D75A7e1A8a7A17", "installOpChainFaucetsDrips": true, - "dripVersion": 1, + "archivePreviousOpChainFaucetsDrips": false, + "dripVersion": 2, + "previousDripVersion": 1, "smallOpChainFaucetDripValue": 2000000000000000000, "smallOpChainFaucetDripInterval": 86400, "largeOpChainFaucetDripValue": 34000000000000000000, diff --git a/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol b/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol index aa4f614f8a1c..d0659223cea3 100644 --- a/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol +++ b/packages/contracts-bedrock/scripts/DeployPeriphery.s.sol @@ -51,6 +51,10 @@ contract DeployPeriphery is Deployer { if (cfg.installOpChainFaucetsDrips()) { installOpChainFaucetsDrippieConfigs(); } + + if (cfg.archivePreviousOpChainFaucetsDrips()) { + archivePreviousOpChainFaucetsDrippieConfigs(); + } } /// @notice Deploy all of the proxies @@ -286,46 +290,40 @@ contract DeployPeriphery is Deployer { console.log("OP chain faucet drip configs successfully installed"); } + /// @notice archives the previous OP Chain drip configs. + function archivePreviousOpChainFaucetsDrippieConfigs() public { + uint256 drippieOwnerPrivateKey = vm.envUint("DRIPPIE_OWNER_PRIVATE_KEY"); + vm.startBroadcast(drippieOwnerPrivateKey); + + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + console.log("Archiving OP Chain faucet drips at %s", address(drippie)); + archivePreviousSmallOpChainFaucetsDrips(); + archivePreviousLargeOpChainFaucetsDrips(); + + vm.stopBroadcast(); + + console.log("OP chain faucet drip configs successfully installed"); + } + /// @notice installs drips that send funds to small OP chain faucets on the scheduled interval. function installSmallOpChainFaucetsDrips() public { - Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); address faucetProxy = mustGetAddress("FaucetProxy"); uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount(); for (uint256 i = 0; i < arrayLength; i++) { address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i); - string memory dripNamePrefix = string.concat("faucet-drip-", vm.toString(l1BridgeAddress)); - string memory versionSuffix = string.concat("-", vm.toString(cfg.dripVersion())); - string memory dripName = string.concat(dripNamePrefix, versionSuffix); - if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) { - console.log("installing %s", dripName); - Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); - actions[0] = Drippie.DripAction({ - target: payable(l1BridgeAddress), - data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", faucetProxy, 200000, ""), - value: cfg.smallOpChainFaucetDripValue() - }); - drippie.create({ - _name: dripName, - _config: Drippie.DripConfig({ - reentrant: false, - interval: cfg.smallOpChainFaucetDripInterval(), - dripcheck: CheckTrue(mustGetAddress("CheckTrue")), - checkparams: abi.encode(""), - actions: actions - }) - }); - console.log("%s installed successfully", dripName); - } else { - console.log("%s already installed.", dripName); - } - - _activateIfPausedDrip(drippie, dripName); + _installDepositEthToDrip( + faucetProxy, + l1BridgeAddress, + cfg.smallOpChainFaucetDripValue(), + cfg.smallOpChainFaucetDripInterval(), + _faucetDripName(l1BridgeAddress, cfg.dripVersion()) + ); } } - /// @notice installs drips that send funds to small OP chain faucets on the scheduled interval. + /// @notice installs drips that send funds to the admin wallets for small OP chain faucets + /// on the scheduled interval. function installSmallOpChainAdminWalletDrips() public { - Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); require( cfg.faucetOnchainAuthModuleAdmin() == cfg.faucetOffchainAuthModuleAdmin(), "installSmallOpChainAdminWalletDrips: Only handles identical admin wallet addresses" @@ -334,39 +332,19 @@ contract DeployPeriphery is Deployer { uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount(); for (uint256 i = 0; i < arrayLength; i++) { address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i); - string memory dripNamePrefix = string.concat("faucet-admin-drip-", vm.toString(l1BridgeAddress)); - string memory versionSuffix = string.concat("-", vm.toString(cfg.dripVersion())); - string memory dripName = string.concat(dripNamePrefix, versionSuffix); - if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) { - console.log("installing %s", dripName); - Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); - actions[0] = Drippie.DripAction({ - target: payable(l1BridgeAddress), - data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", adminWallet, 200000, ""), - value: cfg.opChainAdminWalletDripValue() - }); - drippie.create({ - _name: dripName, - _config: Drippie.DripConfig({ - reentrant: false, - interval: cfg.opChainAdminWalletDripInterval(), - dripcheck: CheckTrue(mustGetAddress("CheckTrue")), - checkparams: abi.encode(""), - actions: actions - }) - }); - console.log("%s installed successfully", dripName); - } else { - console.log("%s already installed.", dripName); - } - - _activateIfPausedDrip(drippie, dripName); + _installDepositEthToDrip( + adminWallet, + l1BridgeAddress, + cfg.opChainAdminWalletDripValue(), + cfg.opChainAdminWalletDripInterval(), + _adminWalletDripName(l1BridgeAddress, cfg.dripVersion()) + ); } } - /// @notice installs drips that send funds to small OP chain faucets on the scheduled interval. + /// @notice installs drips that send funds to the admin wallets for large OP chain faucets + /// on the scheduled interval. function installLargeOpChainAdminWalletDrips() public { - Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); require( cfg.faucetOnchainAuthModuleAdmin() == cfg.faucetOffchainAuthModuleAdmin(), "installLargeOpChainAdminWalletDrips: Only handles identical admin wallet addresses" @@ -375,70 +353,29 @@ contract DeployPeriphery is Deployer { uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount(); for (uint256 i = 0; i < arrayLength; i++) { address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i); - string memory dripNamePrefix = string.concat("faucet-admin-drip-", vm.toString(l1BridgeAddress)); - string memory versionSuffix = string.concat("-", vm.toString(cfg.dripVersion())); - string memory dripName = string.concat(dripNamePrefix, versionSuffix); - if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) { - console.log("installing %s", dripName); - Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); - actions[0] = Drippie.DripAction({ - target: payable(l1BridgeAddress), - data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", adminWallet, 200000, ""), - value: cfg.opChainAdminWalletDripValue() - }); - drippie.create({ - _name: dripName, - _config: Drippie.DripConfig({ - reentrant: false, - interval: cfg.opChainAdminWalletDripInterval(), - dripcheck: CheckTrue(mustGetAddress("CheckTrue")), - checkparams: abi.encode(""), - actions: actions - }) - }); - console.log("%s installed successfully", dripName); - } else { - console.log("%s already installed.", dripName); - } - - _activateIfPausedDrip(drippie, dripName); + _installDepositEthToDrip( + adminWallet, + l1BridgeAddress, + cfg.opChainAdminWalletDripValue(), + cfg.opChainAdminWalletDripInterval(), + _adminWalletDripName(l1BridgeAddress, cfg.dripVersion()) + ); } } /// @notice installs drips that send funds to large OP chain faucets on the scheduled interval. function installLargeOpChainFaucetsDrips() public { - Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); address faucetProxy = mustGetAddress("FaucetProxy"); uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount(); for (uint256 i = 0; i < arrayLength; i++) { address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i); - string memory dripNamePrefix = string.concat("faucet-drip-", vm.toString(l1BridgeAddress)); - string memory versionSuffix = string.concat("-", vm.toString(cfg.dripVersion())); - string memory dripName = string.concat(dripNamePrefix, versionSuffix); - if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) { - console.log("installing %s", dripName); - Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); - actions[0] = Drippie.DripAction({ - target: payable(l1BridgeAddress), - data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", faucetProxy, 200000, ""), - value: cfg.smallOpChainFaucetDripValue() - }); - drippie.create({ - _name: dripName, - _config: Drippie.DripConfig({ - reentrant: false, - interval: cfg.smallOpChainFaucetDripInterval(), - dripcheck: CheckTrue(mustGetAddress("CheckTrue")), - checkparams: abi.encode(""), - actions: actions - }) - }); - console.log("%s installed successfully", dripName); - } else { - console.log("%s already installed.", dripName); - } - - _activateIfPausedDrip(drippie, dripName); + _installDepositEthToDrip( + faucetProxy, + l1BridgeAddress, + cfg.largeOpChainFaucetDripValue(), + cfg.largeOpChainFaucetDripInterval(), + _faucetDripName(l1BridgeAddress, cfg.dripVersion()) + ); } } @@ -577,12 +514,75 @@ contract DeployPeriphery is Deployer { _activateIfPausedDrip(drippie, dripName); } + function archivePreviousSmallOpChainFaucetsDrips() public { + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + uint256 arrayLength = cfg.getSmallFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.smallFaucetsL1BridgeAddresses(i); + _pauseIfActivatedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion())); + _pauseIfActivatedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion())); + _archiveIfPausedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion())); + _archiveIfPausedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion())); + } + } + + function archivePreviousLargeOpChainFaucetsDrips() public { + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + uint256 arrayLength = cfg.getLargeFaucetsL1BridgeAddressesCount(); + for (uint256 i = 0; i < arrayLength; i++) { + address l1BridgeAddress = cfg.largeFaucetsL1BridgeAddresses(i); + _pauseIfActivatedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion())); + _pauseIfActivatedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion())); + _archiveIfPausedDrip(drippie, _faucetDripName(l1BridgeAddress, cfg.previousDripVersion())); + _archiveIfPausedDrip(drippie, _adminWalletDripName(l1BridgeAddress, cfg.previousDripVersion())); + } + } + function _activateIfPausedDrip(Drippie drippie, string memory dripName) internal { + require( + drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE + || drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED, + "attempting to activate a drip that is not currently paused or activated" + ); if (drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED) { console.log("%s is paused, activating", dripName); drippie.status(dripName, Drippie.DripStatus.ACTIVE); console.log("%s activated", dripName); require(drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE); + } else { + console.log("%s already activated", dripName); + } + } + + function _pauseIfActivatedDrip(Drippie drippie, string memory dripName) internal { + require( + drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE + || drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED, + "attempting to pause a drip that is not currently paused or activated" + ); + if (drippie.getDripStatus(dripName) == Drippie.DripStatus.ACTIVE) { + console.log("%s is active, pausing", dripName); + drippie.status(dripName, Drippie.DripStatus.PAUSED); + console.log("%s paused", dripName); + require(drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED); + } else { + console.log("%s already paused", dripName); + } + } + + function _archiveIfPausedDrip(Drippie drippie, string memory dripName) internal { + require( + drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED + || drippie.getDripStatus(dripName) == Drippie.DripStatus.ARCHIVED, + "attempting to archive a drip that is not currently paused or archived" + ); + if (drippie.getDripStatus(dripName) == Drippie.DripStatus.PAUSED) { + console.log("%s is paused, archiving", dripName); + drippie.status(dripName, Drippie.DripStatus.ARCHIVED); + console.log("%s archived", dripName); + require(drippie.getDripStatus(dripName) == Drippie.DripStatus.ARCHIVED); + } else { + console.log("%s already archived", dripName); } } @@ -692,4 +692,52 @@ contract DeployPeriphery is Deployer { console.log("Faucet Auth Module configs successfully installed"); } + + function _faucetDripName(address _l1Bridge, uint256 version) internal pure returns (string memory) { + string memory dripNamePrefixWithBridgeAddress = string.concat("faucet-drip-", vm.toString(_l1Bridge)); + string memory versionSuffix = string.concat("-", vm.toString(version)); + return string.concat(dripNamePrefixWithBridgeAddress, versionSuffix); + } + + function _adminWalletDripName(address _l1Bridge, uint256 version) internal pure returns (string memory) { + string memory dripNamePrefixWithBridgeAddress = string.concat("faucet-admin-drip-", vm.toString(_l1Bridge)); + string memory versionSuffix = string.concat("-", vm.toString(version)); + return string.concat(dripNamePrefixWithBridgeAddress, versionSuffix); + } + + function _installDepositEthToDrip( + address _depositTo, + address _l1Bridge, + uint256 _dripValue, + uint256 _dripInterval, + string memory dripName + ) + internal + { + Drippie drippie = Drippie(mustGetAddress("FaucetDrippie")); + if (drippie.getDripStatus(dripName) == Drippie.DripStatus.NONE) { + console.log("installing %s", dripName); + Drippie.DripAction[] memory actions = new Drippie.DripAction[](1); + actions[0] = Drippie.DripAction({ + target: payable(_l1Bridge), + data: abi.encodeWithSignature("depositETHTo(address,uint32,bytes)", _depositTo, 200000, ""), + value: _dripValue + }); + drippie.create({ + _name: dripName, + _config: Drippie.DripConfig({ + reentrant: false, + interval: _dripInterval, + dripcheck: CheckTrue(mustGetAddress("CheckTrue")), + checkparams: abi.encode(""), + actions: actions + }) + }); + console.log("%s installed successfully", dripName); + } else { + console.log("%s already installed.", dripName); + } + + _activateIfPausedDrip(drippie, dripName); + } } diff --git a/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol b/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol index 4838a3badaa7..9da41818b385 100644 --- a/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol +++ b/packages/contracts-bedrock/scripts/PeripheryDeployConfig.s.sol @@ -35,6 +35,7 @@ contract PeripheryDeployConfig is Script { uint256 public faucetOffchainAuthModuleTtl; uint256 public faucetOffchainAuthModuleAmount; bool public installOpChainFaucetsDrips; + bool public archivePreviousOpChainFaucetsDrips; uint256 public smallOpChainFaucetDripValue; uint256 public smallOpChainFaucetDripInterval; uint256 public largeOpChainFaucetDripValue; @@ -51,6 +52,7 @@ contract PeripheryDeployConfig is Script { address[5] public smallFaucetsL1BridgeAddresses; address[2] public largeFaucetsL1BridgeAddresses; uint256 public dripVersion; + uint256 public previousDripVersion; constructor(string memory _path) { console.log("PeripheryDeployConfig: reading file %s", _path); @@ -84,6 +86,7 @@ contract PeripheryDeployConfig is Script { faucetOffchainAuthModuleTtl = stdJson.readUint(_json, "$.faucetOffchainAuthModuleTtl"); faucetOffchainAuthModuleAmount = stdJson.readUint(_json, "$.faucetOffchainAuthModuleAmount"); installOpChainFaucetsDrips = stdJson.readBool(_json, "$.installOpChainFaucetsDrips"); + archivePreviousOpChainFaucetsDrips = stdJson.readBool(_json, "$.archivePreviousOpChainFaucetsDrips"); opL1BridgeAddress = stdJson.readAddress(_json, "$.opL1BridgeAddress"); baseL1BridgeAddress = stdJson.readAddress(_json, "$.baseL1BridgeAddress"); zoraL1BridgeAddress = stdJson.readAddress(_json, "$.zoraL1BridgeAddress"); @@ -92,6 +95,7 @@ contract PeripheryDeployConfig is Script { modeL1BridgeAddress = stdJson.readAddress(_json, "$.modeL1BridgeAddress"); lyraL1BridgeAddress = stdJson.readAddress(_json, "$.lyraL1BridgeAddress"); dripVersion = stdJson.readUint(_json, "$.dripVersion"); + previousDripVersion = stdJson.readUint(_json, "$.previousDripVersion"); smallOpChainFaucetDripValue = stdJson.readUint(_json, "$.smallOpChainFaucetDripValue"); smallOpChainFaucetDripInterval = stdJson.readUint(_json, "$.smallOpChainFaucetDripInterval"); largeOpChainFaucetDripValue = stdJson.readUint(_json, "$.largeOpChainFaucetDripValue"); From 0a5076e374dc6f42f3b5ef0f5bcb241d8f19c950 Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Wed, 1 Nov 2023 16:25:04 -0700 Subject: [PATCH 312/374] Remove weth9 local build --- op-bindings/bindings/weth9.go | 2 +- op-bindings/bindings/weth9_more.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-bindings/bindings/weth9.go b/op-bindings/bindings/weth9.go index ff06f53092dc..587e8bec5f5c 100644 --- a/op-bindings/bindings/weth9.go +++ b/op-bindings/bindings/weth9.go @@ -31,7 +31,7 @@ var ( // WETH9MetaData contains all meta data concerning the WETH9 contract. var WETH9MetaData = &bind.MetaData{ ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820683910f07c85568ba88afbf94f95d53b286477eb0dd36de9f0a1f5b215dd6f3764736f6c63430005110032", + Bin: "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158203b5b5adf37f507cc9ca5ac0b72acf7873b794171cc0eeb888a5f850e69fe540d64736f6c63430005110032", } // WETH9ABI is the input ABI used to generate the binding from. diff --git a/op-bindings/bindings/weth9_more.go b/op-bindings/bindings/weth9_more.go index 712844cef953..7530f273d76b 100644 --- a/op-bindings/bindings/weth9_more.go +++ b/op-bindings/bindings/weth9_more.go @@ -13,7 +13,7 @@ const WETH9StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src var WETH9StorageLayout = new(solc.StorageLayout) -var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820683910f07c85568ba88afbf94f95d53b286477eb0dd36de9f0a1f5b215dd6f3764736f6c63430005110032" +var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158203b5b5adf37f507cc9ca5ac0b72acf7873b794171cc0eeb888a5f850e69fe540d64736f6c63430005110032" func init() { if err := json.Unmarshal([]byte(WETH9StorageLayoutJSON), WETH9StorageLayout); err != nil { From e10a2652d201bcf712b082b33fb4d94cd77288fa Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Thu, 2 Nov 2023 07:26:24 +1000 Subject: [PATCH 313/374] batching: Use input instead of data when making eth_Call requests --- op-service/sources/batching/call.go | 2 +- op-service/sources/batching/call_test.go | 2 +- op-service/sources/batching/test/stubs.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/op-service/sources/batching/call.go b/op-service/sources/batching/call.go index 6274c6fcd4a0..bb9b7c88b08c 100644 --- a/op-service/sources/batching/call.go +++ b/op-service/sources/batching/call.go @@ -72,7 +72,7 @@ func toCallArg(msg ethereum.CallMsg) interface{} { "to": msg.To, } if len(msg.Data) > 0 { - arg["data"] = hexutil.Bytes(msg.Data) + arg["input"] = hexutil.Bytes(msg.Data) } if msg.Value != nil { arg["value"] = (*hexutil.Big)(msg.Value) diff --git a/op-service/sources/batching/call_test.go b/op-service/sources/batching/call_test.go index 4d5fca721d3e..79c2c3d68e49 100644 --- a/op-service/sources/batching/call_test.go +++ b/op-service/sources/batching/call_test.go @@ -23,7 +23,7 @@ func TestContractCall_ToCallArgs(t *testing.T) { require.Equal(t, argMap["to"], &addr) expectedData, err := call.Pack() require.NoError(t, err) - require.Equal(t, argMap["data"], hexutil.Bytes(expectedData)) + require.Equal(t, argMap["input"], hexutil.Bytes(expectedData)) require.NotContains(t, argMap, "value") require.NotContains(t, argMap, "gas") diff --git a/op-service/sources/batching/test/stubs.go b/op-service/sources/batching/test/stubs.go index 1be19f22932f..6d53ed0f33f6 100644 --- a/op-service/sources/batching/test/stubs.go +++ b/op-service/sources/batching/test/stubs.go @@ -76,7 +76,7 @@ func (l *AbiBasedRpc) CallContext(_ context.Context, out interface{}, method str callOpts, ok := args[0].(map[string]any) require.True(l.t, ok) require.Equal(l.t, &l.addr, callOpts["to"]) - data, ok := callOpts["data"].(hexutil.Bytes) + data, ok := callOpts["input"].(hexutil.Bytes) require.True(l.t, ok) abiMethod, err := l.abi.MethodById(data[0:4]) require.NoError(l.t, err) From f082bd046879a8886b9a30c1ad6d5ca3f4433ed6 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Thu, 2 Nov 2023 12:00:50 +1000 Subject: [PATCH 314/374] challenger: Move DisputeGameFactory to use new approach to contract reads. --- .../game/fault/contracts/faultdisputegame.go | 14 +-- .../fault/contracts/faultdisputegame_test.go | 7 +- .../game/fault/contracts/gamefactory.go | 60 +++++++++++ .../game/fault/contracts/gamefactory_test.go | 99 +++++++++++++++++++ op-challenger/game/fault/player.go | 2 +- op-challenger/game/loader/game_loader.go | 33 ++----- op-challenger/game/loader/game_loader_test.go | 41 +++----- op-challenger/game/monitor.go | 5 +- op-challenger/game/monitor_test.go | 2 +- op-challenger/game/service.go | 5 +- op-service/sources/batching/call.go | 4 + op-service/sources/batching/call_test.go | 7 ++ op-service/sources/batching/multicall.go | 38 ++++++- op-service/sources/batching/test/stubs.go | 14 ++- 14 files changed, 250 insertions(+), 81 deletions(-) create mode 100644 op-challenger/game/fault/contracts/gamefactory.go create mode 100644 op-challenger/game/fault/contracts/gamefactory_test.go diff --git a/op-challenger/game/fault/contracts/faultdisputegame.go b/op-challenger/game/fault/contracts/faultdisputegame.go index 889dac4e56d5..e50883e7447f 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame.go +++ b/op-challenger/game/fault/contracts/faultdisputegame.go @@ -39,7 +39,7 @@ func NewFaultDisputeGameContract(addr common.Address, caller *batching.MultiCall } func (f *FaultDisputeGameContract) GetGameDuration(ctx context.Context) (uint64, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodGameDuration)) + result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodGameDuration)) if err != nil { return 0, fmt.Errorf("failed to fetch game duration: %w", err) } @@ -47,7 +47,7 @@ func (f *FaultDisputeGameContract) GetGameDuration(ctx context.Context) (uint64, } func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodMaxGameDepth)) + result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodMaxGameDepth)) if err != nil { return 0, fmt.Errorf("failed to fetch max game depth: %w", err) } @@ -55,7 +55,7 @@ func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, } func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodAbsolutePrestate)) + result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodAbsolutePrestate)) if err != nil { return common.Hash{}, fmt.Errorf("failed to fetch absolute prestate hash: %w", err) } @@ -63,7 +63,7 @@ func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context) } func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.GameStatus, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodStatus)) + result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodStatus)) if err != nil { return 0, fmt.Errorf("failed to fetch status: %w", err) } @@ -71,7 +71,7 @@ func (f *FaultDisputeGameContract) GetStatus(ctx context.Context) (gameTypes.Gam } func (f *FaultDisputeGameContract) GetClaimCount(ctx context.Context) (uint64, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodClaimCount)) + result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodClaimCount)) if err != nil { return 0, fmt.Errorf("failed to fetch claim count: %w", err) } @@ -79,7 +79,7 @@ func (f *FaultDisputeGameContract) GetClaimCount(ctx context.Context) (uint64, e } func (f *FaultDisputeGameContract) GetClaim(ctx context.Context, idx uint64) (types.Claim, error) { - result, err := f.multiCaller.SingleCallLatest(ctx, f.contract.Call(methodClaim, new(big.Int).SetUint64(idx))) + result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodClaim, new(big.Int).SetUint64(idx))) if err != nil { return types.Claim{}, fmt.Errorf("failed to fetch claim %v: %w", idx, err) } @@ -97,7 +97,7 @@ func (f *FaultDisputeGameContract) GetAllClaims(ctx context.Context) ([]types.Cl calls[i] = f.contract.Call(methodClaim, new(big.Int).SetUint64(i)) } - results, err := f.multiCaller.CallLatest(ctx, calls...) + results, err := f.multiCaller.Call(ctx, batching.BlockLatest, calls...) if err != nil { return nil, fmt.Errorf("failed to fetch claim data: %w", err) } diff --git a/op-challenger/game/fault/contracts/faultdisputegame_test.go b/op-challenger/game/fault/contracts/faultdisputegame_test.go index 83c9647726b1..6c9e6f2d8075 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame_test.go +++ b/op-challenger/game/fault/contracts/faultdisputegame_test.go @@ -65,7 +65,7 @@ func TestSimpleGetters(t *testing.T) { test := test t.Run(test.method, func(t *testing.T) { stubRpc, game := setup(t) - stubRpc.SetResponse(test.method, nil, []interface{}{test.result}) + stubRpc.SetResponse(test.method, batching.BlockLatest, nil, []interface{}{test.result}) status, err := test.call(game) require.NoError(t, err) expected := test.expected @@ -85,7 +85,7 @@ func TestGetClaim(t *testing.T) { value := common.Hash{0xab} position := big.NewInt(2) clock := big.NewInt(1234) - stubRpc.SetResponse(methodClaim, []interface{}{idx}, []interface{}{parentIndex, countered, value, position, clock}) + stubRpc.SetResponse(methodClaim, batching.BlockLatest, []interface{}{idx}, []interface{}{parentIndex, countered, value, position, clock}) status, err := game.GetClaim(context.Background(), idx.Uint64()) require.NoError(t, err) require.Equal(t, faultTypes.Claim{ @@ -133,7 +133,7 @@ func TestGetAllClaims(t *testing.T) { ParentContractIndex: 1, } expectedClaims := []faultTypes.Claim{claim0, claim1, claim2} - stubRpc.SetResponse(methodClaimCount, nil, []interface{}{big.NewInt(int64(len(expectedClaims)))}) + stubRpc.SetResponse(methodClaimCount, batching.BlockLatest, nil, []interface{}{big.NewInt(int64(len(expectedClaims)))}) for _, claim := range expectedClaims { expectGetClaim(stubRpc, claim) } @@ -145,6 +145,7 @@ func TestGetAllClaims(t *testing.T) { func expectGetClaim(stubRpc *batchingTest.AbiBasedRpc, claim faultTypes.Claim) { stubRpc.SetResponse( methodClaim, + batching.BlockLatest, []interface{}{big.NewInt(int64(claim.ContractIndex))}, []interface{}{ uint32(claim.ParentContractIndex), diff --git a/op-challenger/game/fault/contracts/gamefactory.go b/op-challenger/game/fault/contracts/gamefactory.go new file mode 100644 index 000000000000..7b74ba533ade --- /dev/null +++ b/op-challenger/game/fault/contracts/gamefactory.go @@ -0,0 +1,60 @@ +package contracts + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum/go-ethereum/common" +) + +const ( + methodGameCount = "gameCount" + methodGameAtIndex = "gameAtIndex" +) + +type DisputeGameFactoryContract struct { + multiCaller *batching.MultiCaller + contract *batching.BoundContract +} + +func NewDisputeGameFactoryContract(addr common.Address, caller *batching.MultiCaller) (*DisputeGameFactoryContract, error) { + factoryAbi, err := bindings.DisputeGameFactoryMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to load dispute game factory ABI: %w", err) + } + return &DisputeGameFactoryContract{ + multiCaller: caller, + contract: batching.NewBoundContract(factoryAbi, addr), + }, nil +} + +func (f *DisputeGameFactoryContract) GetGameCount(ctx context.Context, blockNum uint64) (uint64, error) { + result, err := f.multiCaller.SingleCall(ctx, batching.BlockByNumber(blockNum), f.contract.Call(methodGameCount)) + if err != nil { + return 0, fmt.Errorf("failed to load game count: %w", err) + } + return result.GetBigInt(0).Uint64(), nil +} + +func (f *DisputeGameFactoryContract) GetGame(ctx context.Context, idx uint64, blockNum uint64) (types.GameMetadata, error) { + result, err := f.multiCaller.SingleCall(ctx, batching.BlockByNumber(blockNum), f.contract.Call(methodGameAtIndex, new(big.Int).SetUint64(idx))) + if err != nil { + return types.GameMetadata{}, fmt.Errorf("failed to load game %v: %w", idx, err) + } + return f.decodeGame(result), nil +} + +func (f *DisputeGameFactoryContract) decodeGame(result *batching.CallResult) types.GameMetadata { + gameType := result.GetUint8(0) + timestamp := result.GetUint64(1) + proxy := result.GetAddress(2) + return types.GameMetadata{ + GameType: gameType, + Timestamp: timestamp, + Proxy: proxy, + } +} diff --git a/op-challenger/game/fault/contracts/gamefactory_test.go b/op-challenger/game/fault/contracts/gamefactory_test.go new file mode 100644 index 000000000000..15888cc41970 --- /dev/null +++ b/op-challenger/game/fault/contracts/gamefactory_test.go @@ -0,0 +1,99 @@ +package contracts + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" + "github.com/ethereum-optimism/optimism/op-challenger/game/types" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestDisputeGameFactorySimpleGetters(t *testing.T) { + blockNum := uint64(23) + tests := []struct { + method string + args []interface{} + result interface{} + expected interface{} // Defaults to expecting the same as result + call func(game *DisputeGameFactoryContract) (any, error) + }{ + { + method: methodGameCount, + result: big.NewInt(9876), + expected: uint64(9876), + call: func(game *DisputeGameFactoryContract) (any, error) { + return game.GetGameCount(context.Background(), blockNum) + }, + }, + } + for _, test := range tests { + test := test + t.Run(test.method, func(t *testing.T) { + stubRpc, factory := setupDisputeGameFactoryTest(t) + stubRpc.SetResponse(test.method, batching.BlockByNumber(blockNum), nil, []interface{}{test.result}) + status, err := test.call(factory) + require.NoError(t, err) + expected := test.expected + if expected == nil { + expected = test.result + } + require.Equal(t, expected, status) + }) + } +} + +func TestLoadGame(t *testing.T) { + blockNum := uint64(23) + stubRpc, factory := setupDisputeGameFactoryTest(t) + game0 := types.GameMetadata{ + GameType: 0, + Timestamp: 1234, + Proxy: common.Address{0xaa}, + } + game1 := types.GameMetadata{ + GameType: 1, + Timestamp: 5678, + Proxy: common.Address{0xbb}, + } + game2 := types.GameMetadata{ + GameType: 99, + Timestamp: 9988, + Proxy: common.Address{0xcc}, + } + expectedGames := []types.GameMetadata{game0, game1, game2} + for idx, expected := range expectedGames { + expectGetGame(stubRpc, idx, blockNum, expected) + actual, err := factory.GetGame(context.Background(), uint64(idx), blockNum) + require.NoError(t, err) + require.Equal(t, expected, actual) + } +} + +func expectGetGame(stubRpc *batchingTest.AbiBasedRpc, idx int, blockNum uint64, game types.GameMetadata) { + stubRpc.SetResponse( + methodGameAtIndex, + batching.BlockByNumber(blockNum), + []interface{}{big.NewInt(int64(idx))}, + []interface{}{ + game.GameType, + game.Timestamp, + game.Proxy, + }) +} + +func setupDisputeGameFactoryTest(t *testing.T) (*batchingTest.AbiBasedRpc, *DisputeGameFactoryContract) { + fdgAbi, err := bindings.DisputeGameFactoryMetaData.GetAbi() + require.NoError(t, err) + address := common.HexToAddress("0x24112842371dFC380576ebb09Ae16Cb6B6caD7CB") + + stubRpc := batchingTest.NewAbiBasedRpc(t, fdgAbi, address) + caller := batching.NewMultiCaller(stubRpc, 100) + factory, err := NewDisputeGameFactoryContract(address, caller) + require.NoError(t, err) + return stubRpc, factory +} diff --git a/op-challenger/game/fault/player.go b/op-challenger/game/fault/player.go index 10c64df4d195..ca019e5c3041 100644 --- a/op-challenger/game/fault/player.go +++ b/op-challenger/game/fault/player.go @@ -47,7 +47,7 @@ func NewGamePlayer( creator resourceCreator, ) (*GamePlayer, error) { logger = logger.New("game", addr) - loader, err := contracts.NewFaultDisputeGameContract(addr, batching.NewMultiCaller(client.Client(), 100)) + loader, err := contracts.NewFaultDisputeGameContract(addr, batching.NewMultiCaller(client.Client(), batching.DefaultBatchSize)) if err != nil { return nil, fmt.Errorf("failed to create fault dispute game contract wrapper: %w", err) } diff --git a/op-challenger/game/loader/game_loader.go b/op-challenger/game/loader/game_loader.go index d5afee62ebc0..12b126cfc054 100644 --- a/op-challenger/game/loader/game_loader.go +++ b/op-challenger/game/loader/game_loader.go @@ -4,11 +4,8 @@ import ( "context" "errors" "fmt" - "math/big" "github.com/ethereum-optimism/optimism/op-challenger/game/types" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" ) var ( @@ -18,12 +15,8 @@ var ( // MinimalDisputeGameFactoryCaller is a minimal interface around [bindings.DisputeGameFactoryCaller]. // This needs to be updated if the [bindings.DisputeGameFactoryCaller] interface changes. type MinimalDisputeGameFactoryCaller interface { - GameCount(opts *bind.CallOpts) (*big.Int, error) - GameAtIndex(opts *bind.CallOpts, _index *big.Int) (struct { - GameType uint8 - Timestamp uint64 - Proxy common.Address - }, error) + GetGameCount(ctx context.Context, blockNum uint64) (uint64, error) + GetGame(ctx context.Context, idx uint64, blockNum uint64) (types.GameMetadata, error) } type GameLoader struct { @@ -38,27 +31,17 @@ func NewGameLoader(caller MinimalDisputeGameFactoryCaller) *GameLoader { } // FetchAllGamesAtBlock fetches all dispute games from the factory at a given block number. -func (l *GameLoader) FetchAllGamesAtBlock(ctx context.Context, earliestTimestamp uint64, blockNumber *big.Int) ([]types.GameMetadata, error) { - if blockNumber == nil { - return nil, ErrMissingBlockNumber - } - callOpts := &bind.CallOpts{ - Context: ctx, - BlockNumber: blockNumber, - } - gameCount, err := l.caller.GameCount(callOpts) +func (l *GameLoader) FetchAllGamesAtBlock(ctx context.Context, earliestTimestamp uint64, blockNumber uint64) ([]types.GameMetadata, error) { + gameCount, err := l.caller.GetGameCount(ctx, blockNumber) if err != nil { return nil, fmt.Errorf("failed to fetch game count: %w", err) } - games := make([]types.GameMetadata, 0) - if gameCount.Uint64() == 0 { - return games, nil - } - for i := gameCount.Uint64(); i > 0; i-- { - game, err := l.caller.GameAtIndex(callOpts, big.NewInt(int64(i-1))) + games := make([]types.GameMetadata, 0, gameCount) + for i := gameCount; i > 0; i-- { + game, err := l.caller.GetGame(ctx, i-1, blockNumber) if err != nil { - return nil, fmt.Errorf("failed to fetch game at index %d: %w", i, err) + return nil, fmt.Errorf("failed to fetch game at index %d: %w", i-1, err) } if game.Timestamp < earliestTimestamp { break diff --git a/op-challenger/game/loader/game_loader_test.go b/op-challenger/game/loader/game_loader_test.go index 1c6959be3b85..ac25d0b0cf9c 100644 --- a/op-challenger/game/loader/game_loader_test.go +++ b/op-challenger/game/loader/game_loader_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-challenger/game/types" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) @@ -25,44 +24,39 @@ func TestGameLoader_FetchAllGames(t *testing.T) { name string caller *mockMinimalDisputeGameFactoryCaller earliest uint64 - blockNumber *big.Int + blockNumber uint64 expectedErr error expectedLen int }{ { name: "success", caller: newMockMinimalDisputeGameFactoryCaller(10, false, false), - blockNumber: big.NewInt(1), + blockNumber: 1, expectedLen: 10, }, { name: "expired game ignored", caller: newMockMinimalDisputeGameFactoryCaller(10, false, false), earliest: 500, - blockNumber: big.NewInt(1), + blockNumber: 1, expectedLen: 5, }, { name: "game count error", caller: newMockMinimalDisputeGameFactoryCaller(10, true, false), - blockNumber: big.NewInt(1), + blockNumber: 1, expectedErr: gameCountErr, }, { name: "game index error", caller: newMockMinimalDisputeGameFactoryCaller(10, false, true), - blockNumber: big.NewInt(1), + blockNumber: 1, expectedErr: gameIndexErr, }, { name: "no games", caller: newMockMinimalDisputeGameFactoryCaller(0, false, false), - blockNumber: big.NewInt(1), - }, - { - name: "missing block number", - caller: newMockMinimalDisputeGameFactoryCaller(0, false, false), - expectedErr: ErrMissingBlockNumber, + blockNumber: 1, }, } @@ -144,20 +138,15 @@ func newMockMinimalDisputeGameFactoryCaller(count uint64, gameCountErr bool, ind } } -func (m *mockMinimalDisputeGameFactoryCaller) GameCount(opts *bind.CallOpts) (*big.Int, error) { +func (m *mockMinimalDisputeGameFactoryCaller) GetGameCount(_ context.Context, blockNum uint64) (uint64, error) { if m.gameCountErr { - return nil, gameCountErr + return 0, gameCountErr } - return big.NewInt(int64(m.gameCount)), nil + return m.gameCount, nil } -func (m *mockMinimalDisputeGameFactoryCaller) GameAtIndex(opts *bind.CallOpts, _index *big.Int) (struct { - GameType uint8 - Timestamp uint64 - Proxy common.Address -}, error) { - index := _index.Uint64() +func (m *mockMinimalDisputeGameFactoryCaller) GetGame(_ context.Context, index uint64, blockNum uint64) (types.GameMetadata, error) { if m.indexErrors[index] { return struct { GameType uint8 @@ -166,13 +155,5 @@ func (m *mockMinimalDisputeGameFactoryCaller) GameAtIndex(opts *bind.CallOpts, _ }{}, gameIndexErr } - return struct { - GameType uint8 - Timestamp uint64 - Proxy common.Address - }{ - GameType: m.games[index].GameType, - Timestamp: m.games[index].Timestamp, - Proxy: m.games[index].Proxy, - }, nil + return m.games[index], nil } diff --git a/op-challenger/game/monitor.go b/op-challenger/game/monitor.go index a8c9c694b20c..e217bf040ff8 100644 --- a/op-challenger/game/monitor.go +++ b/op-challenger/game/monitor.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "math/big" "time" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" @@ -23,7 +22,7 @@ type blockNumberFetcher func(ctx context.Context) (uint64, error) // gameSource loads information about the games available to play type gameSource interface { - FetchAllGamesAtBlock(ctx context.Context, earliest uint64, blockNumber *big.Int) ([]types.GameMetadata, error) + FetchAllGamesAtBlock(ctx context.Context, earliest uint64, blockNumber uint64) ([]types.GameMetadata, error) } type gameScheduler interface { @@ -101,7 +100,7 @@ func (m *gameMonitor) minGameTimestamp() uint64 { } func (m *gameMonitor) progressGames(ctx context.Context, blockNum uint64) error { - games, err := m.source.FetchAllGamesAtBlock(ctx, m.minGameTimestamp(), new(big.Int).SetUint64(blockNum)) + games, err := m.source.FetchAllGamesAtBlock(ctx, m.minGameTimestamp(), blockNum) if err != nil { return fmt.Errorf("failed to load games: %w", err) } diff --git a/op-challenger/game/monitor_test.go b/op-challenger/game/monitor_test.go index 7295fdb74a3d..e800bd64e8ac 100644 --- a/op-challenger/game/monitor_test.go +++ b/op-challenger/game/monitor_test.go @@ -230,7 +230,7 @@ type stubGameSource struct { func (s *stubGameSource) FetchAllGamesAtBlock( ctx context.Context, earliest uint64, - blockNumber *big.Int, + blockNumber uint64, ) ([]types.GameMetadata, error) { return s.games, nil } diff --git a/op-challenger/game/service.go b/op-challenger/game/service.go index 20c155d28e69..7c43447dd87b 100644 --- a/op-challenger/game/service.go +++ b/op-challenger/game/service.go @@ -5,9 +5,9 @@ import ( "errors" "fmt" - "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/game/fault" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" "github.com/ethereum-optimism/optimism/op-challenger/game/loader" "github.com/ethereum-optimism/optimism/op-challenger/game/registry" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" @@ -18,6 +18,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/dial" "github.com/ethereum-optimism/optimism/op-service/httputil" oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum/go-ethereum/log" ) @@ -88,7 +89,7 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*Se m.StartBalanceMetrics(ctx, logger, l1Client, txMgr.From()) } - factoryContract, err := bindings.NewDisputeGameFactory(cfg.GameFactoryAddress, l1Client) + factoryContract, err := contracts.NewDisputeGameFactoryContract(cfg.GameFactoryAddress, batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize)) if err != nil { return nil, errors.Join(fmt.Errorf("failed to bind the fault dispute game factory contract: %w", err), s.Stop(ctx)) } diff --git a/op-service/sources/batching/call.go b/op-service/sources/batching/call.go index bb9b7c88b08c..f15c63b2753f 100644 --- a/op-service/sources/batching/call.go +++ b/op-service/sources/batching/call.go @@ -110,6 +110,10 @@ func (c *CallResult) GetHash(i int) common.Hash { return *abi.ConvertType(c.out[i], new([32]byte)).(*[32]byte) } +func (c *CallResult) GetAddress(i int) common.Address { + return *abi.ConvertType(c.out[i], new([20]byte)).(*[20]byte) +} + func (c *CallResult) GetBigInt(i int) *big.Int { return *abi.ConvertType(c.out[i], new(*big.Int)).(**big.Int) } diff --git a/op-service/sources/batching/call_test.go b/op-service/sources/batching/call_test.go index 79c2c3d68e49..eaf6fe698845 100644 --- a/op-service/sources/batching/call_test.go +++ b/op-service/sources/batching/call_test.go @@ -118,6 +118,13 @@ func TestCallResult_GetValues(t *testing.T) { }, expected: true, }, + { + name: "GetAddress", + getter: func(result *CallResult, i int) interface{} { + return result.GetAddress(i) + }, + expected: ([20]byte)(common.Address{0xaa, 0xbb, 0xcc}), + }, { name: "GetHash", getter: func(result *CallResult, i int) interface{} { diff --git a/op-service/sources/batching/multicall.go b/op-service/sources/batching/multicall.go index 0ff035ccf94c..79322da1f9b7 100644 --- a/op-service/sources/batching/multicall.go +++ b/op-service/sources/batching/multicall.go @@ -5,10 +5,13 @@ import ( "fmt" "io" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rpc" ) +var DefaultBatchSize = 100 + type EthRpc interface { CallContext(ctx context.Context, out interface{}, method string, args ...interface{}) error BatchCallContext(ctx context.Context, b []rpc.BatchElem) error @@ -26,15 +29,15 @@ func NewMultiCaller(rpc EthRpc, batchSize int) *MultiCaller { } } -func (m *MultiCaller) SingleCallLatest(ctx context.Context, call *ContractCall) (*CallResult, error) { - results, err := m.CallLatest(ctx, call) +func (m *MultiCaller) SingleCall(ctx context.Context, block Block, call *ContractCall) (*CallResult, error) { + results, err := m.Call(ctx, block, call) if err != nil { return nil, err } return results[0], nil } -func (m *MultiCaller) CallLatest(ctx context.Context, calls ...*ContractCall) ([]*CallResult, error) { +func (m *MultiCaller) Call(ctx context.Context, block Block, calls ...*ContractCall) ([]*CallResult, error) { keys := make([]interface{}, len(calls)) for i := 0; i < len(calls); i++ { args, err := calls[i].ToCallArgs() @@ -49,7 +52,7 @@ func (m *MultiCaller) CallLatest(ctx context.Context, calls ...*ContractCall) ([ out := new(hexutil.Bytes) return out, rpc.BatchElem{ Method: "eth_call", - Args: []interface{}{args, "latest"}, + Args: []interface{}{args, block.value}, Result: &out, } }, @@ -79,3 +82,30 @@ func (m *MultiCaller) CallLatest(ctx context.Context, calls ...*ContractCall) ([ } return callResults, nil } + +// Block represents the block ref value in RPC calls. +// It can be either a label (e.g. latest), a block number or block hash. +type Block struct { + value any +} + +func (b Block) ArgValue() any { + return b.value +} + +var ( + BlockPending = Block{"pending"} + BlockLatest = Block{"latest"} + BlockSafe = Block{"safe"} + BlockFinalized = Block{"finalized"} +) + +// BlockByNumber references a canonical block by number. +func BlockByNumber(blockNum uint64) Block { + return Block{rpc.BlockNumber(blockNum)} +} + +// BlockByHash references a block by hash. Canonical or non-canonical blocks may be referenced. +func BlockByHash(hash common.Hash) Block { + return Block{rpc.BlockNumberOrHashWithHash(hash, false)} +} diff --git a/op-service/sources/batching/test/stubs.go b/op-service/sources/batching/test/stubs.go index 6d53ed0f33f6..393a8ebe931b 100644 --- a/op-service/sources/batching/test/stubs.go +++ b/op-service/sources/batching/test/stubs.go @@ -7,22 +7,25 @@ import ( "fmt" "testing" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" "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/rpc" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" ) type expectedCall struct { + block batching.Block args []interface{} packedArgs []byte outputs []interface{} } func (e *expectedCall) String() string { - return fmt.Sprintf("{args: %v, outputs: %v}", e.args, e.outputs) + return fmt.Sprintf("{block: %v, args: %v, outputs: %v}", e.block, e.args, e.outputs) } type AbiBasedRpc struct { @@ -42,7 +45,7 @@ func NewAbiBasedRpc(t *testing.T, contractAbi *abi.ABI, addr common.Address) *Ab } } -func (l *AbiBasedRpc) SetResponse(method string, expected []interface{}, output []interface{}) { +func (l *AbiBasedRpc) SetResponse(method string, block batching.Block, expected []interface{}, output []interface{}) { if expected == nil { expected = []interface{}{} } @@ -54,6 +57,7 @@ func (l *AbiBasedRpc) SetResponse(method string, expected []interface{}, output packedArgs, err := abiMethod.Inputs.Pack(expected...) require.NoErrorf(l.t, err, "Invalid expected arguments for method %v: %v", method, expected) l.expectedCalls[method] = append(l.expectedCalls[method], &expectedCall{ + block: block, args: expected, packedArgs: packedArgs, outputs: output, @@ -72,7 +76,7 @@ func (l *AbiBasedRpc) BatchCallContext(ctx context.Context, b []rpc.BatchElem) e func (l *AbiBasedRpc) CallContext(_ context.Context, out interface{}, method string, args ...interface{}) error { require.Equal(l.t, "eth_call", method) require.Len(l.t, args, 2) - require.Equal(l.t, "latest", args[1]) + actualBlockRef := args[1] callOpts, ok := args[0].(map[string]any) require.True(l.t, ok) require.Equal(l.t, &l.addr, callOpts["to"]) @@ -90,12 +94,12 @@ func (l *AbiBasedRpc) CallContext(_ context.Context, out interface{}, method str require.Truef(l.t, ok, "Unexpected call to %v", abiMethod.Name) var call *expectedCall for _, candidate := range expectedCalls { - if slices.Equal(candidate.packedArgs, argData) { + if slices.Equal(candidate.packedArgs, argData) && assert.ObjectsAreEqualValues(candidate.block.ArgValue(), actualBlockRef) { call = candidate break } } - require.NotNilf(l.t, call, "No expected calls to %v with arguments: %v\nExpected calls: %v", abiMethod.Name, args, expectedCalls) + require.NotNilf(l.t, call, "No expected calls to %v at block %v with arguments: %v\nExpected calls: %v", abiMethod.Name, actualBlockRef, args, expectedCalls) output, err := abiMethod.Outputs.Pack(call.outputs...) require.NoErrorf(l.t, err, "Invalid outputs for method %v: %v", abiMethod.Name, call.outputs) From 283375c999843cd1c5d6e395b550ef06bad811ff Mon Sep 17 00:00:00 2001 From: kafeikui Date: Thu, 2 Nov 2023 12:31:15 +0800 Subject: [PATCH 315/374] fix #8010 --- bedrock-devnet/devnet/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bedrock-devnet/devnet/__init__.py b/bedrock-devnet/devnet/__init__.py index 54a98747bb2e..5e0dcc83f9b7 100644 --- a/bedrock-devnet/devnet/__init__.py +++ b/bedrock-devnet/devnet/__init__.py @@ -288,21 +288,23 @@ def debug_dumpBlock(url): def wait_for_rpc_server(url): log.info(f'Waiting for RPC server at {url}') - conn = http.client.HTTPConnection(url) headers = {'Content-type': 'application/json'} body = '{"id":1, "jsonrpc":"2.0", "method": "eth_chainId", "params":[]}' while True: try: + conn = http.client.HTTPConnection(url) conn.request('POST', '/', body, headers) response = conn.getresponse() - conn.close() if response.status < 300: log.info(f'RPC server at {url} ready') return except Exception as e: log.info(f'Waiting for RPC server at {url}') time.sleep(1) + finally: + if conn: + conn.close() CommandPreset = namedtuple('Command', ['name', 'args', 'cwd', 'timeout']) From a4a7bbc8e32f49e4652c8871f0045a0a191a225b Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 2 Nov 2023 12:14:47 +0300 Subject: [PATCH 316/374] bindings: regenerate --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index f6a602ff5a6d..e557605acfea 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:306;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:306;2534:6:135;400:55:306;382:74;;370:2;355:18;2448:99:135;211:251:306;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:306;;;1743:2;1728:18;26025:6379:135;1609:177:306;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:306;19164:28:135;;;2164:21:306;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:306;14107:30:135;;;2511:21:306;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:306;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:306;37406:29:135;;;2860:21:306;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:306;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:306;20288:41:135;;;3208:21:306;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:306;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:306;;;8234:54:135;3601:23:306;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:306;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:306;21415:72:135;;;4259:21:306;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:306;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:306:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:306;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:306;-1:-1:-1;1349:2:306;1334:18;;1321:32;;-1:-1:-1;1365:16:306;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:306;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:306:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:306;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:306:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:304;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:304;2534:6:135;400:55:304;382:74;;370:2;355:18;2448:99:135;211:251:304;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:304;;;1743:2;1728:18;26025:6379:135;1609:177:304;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:304;19164:28:135;;;2164:21:304;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:304;14107:30:135;;;2511:21:304;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:304;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:304;37406:29:135;;;2860:21:304;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:304;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:304;20288:41:135;;;3208:21:304;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:304;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:304;;;8234:54:135;3601:23:304;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:304;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:304;21415:72:135;;;4259:21:304;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:304;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:304:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:304;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:304;-1:-1:-1;1349:2:304;1334:18;;1321:32;;-1:-1:-1;1365:16:304;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:304;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:304:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:304;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:304:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 8523b96a5316..52403fe9a12a 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:306;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:306;;607:22;589:41;;577:2;562:18;680:66:137;449:187:306;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:306;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:306;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:306;906:62:137;;;2890:21:306;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:306:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:306;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:306:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:306;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:306;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:306;1069:19;1056:33;;-1:-1:-1;641:454:306;-1:-1:-1;641:454:306:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:306;;2017:180;-1:-1:-1;2017:180:306:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:306;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:306;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:304;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:304;;607:22;589:41;;577:2;562:18;680:66:137;449:187:304;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:304;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:304;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:304;906:62:137;;;2890:21:304;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:304:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:304;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:304:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:304;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:304;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:304;1069:19;1056:33;;-1:-1:-1;641:454:304;-1:-1:-1;641:454:304:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:304;;2017:180;-1:-1:-1;2017:180:304:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:304;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:304;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { From 3be62ed7d008c4ffd7f0ce9bac8a57f4447611e4 Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 2 Nov 2023 14:51:23 +0100 Subject: [PATCH 317/374] indexer: lifecycle refactor review fixes --- indexer/api/config.go | 3 +-- indexer/cmd/indexer/cli.go | 6 +++++- indexer/database/db.go | 4 +++- indexer/e2e_tests/setup.go | 2 +- indexer/etl/l1_etl.go | 27 +++++++++++---------------- indexer/etl/l1_etl_test.go | 4 +++- indexer/etl/l2_etl.go | 22 ++++++++-------------- indexer/indexer.go | 18 ++++++++++-------- indexer/processors/bridge.go | 28 +++++++++++----------------- op-service/tasks/tasks.go | 32 ++++++++++++++++++++++++++++++++ 10 files changed, 85 insertions(+), 61 deletions(-) create mode 100644 op-service/tasks/tasks.go diff --git a/indexer/api/config.go b/indexer/api/config.go index 6e2cece73ede..fccf8f86c20d 100644 --- a/indexer/api/config.go +++ b/indexer/api/config.go @@ -22,8 +22,7 @@ type DBConfigConnector struct { } func (cfg *DBConfigConnector) OpenDB(ctx context.Context, log log.Logger) (*DB, error) { - // TODO: pass through the ctx argument, so we can interrupt while connecting - db, err := database.NewDB(log, cfg.DBConfig) + db, err := database.NewDB(ctx, log, cfg.DBConfig) if err != nil { return nil, fmt.Errorf("failed to connect to databse: %w", err) } diff --git a/indexer/cmd/indexer/cli.go b/indexer/cmd/indexer/cli.go index efb7677aec04..153cae9da4fc 100644 --- a/indexer/cmd/indexer/cli.go +++ b/indexer/cmd/indexer/cli.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/op-service/cliapp" oplog "github.com/ethereum-optimism/optimism/op-service/log" + "github.com/ethereum-optimism/optimism/op-service/opio" ) var ( @@ -66,6 +67,9 @@ func runApi(ctx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, erro } func runMigrations(ctx *cli.Context) error { + // We don't maintain a complicated lifecycle here, just interrupt to shut down. + ctx.Context = opio.CancelOnInterrupt(ctx.Context) + log := oplog.NewLogger(oplog.AppOut(ctx), oplog.ReadCLIConfig(ctx)).New("role", "migrations") oplog.SetGlobalLogHandler(log.GetHandler()) log.Info("running migrations...") @@ -76,7 +80,7 @@ func runMigrations(ctx *cli.Context) error { return err } - db, err := database.NewDB(log, cfg.DB) + db, err := database.NewDB(ctx.Context, log, cfg.DB) if err != nil { log.Error("failed to connect to database", "err", err) return err diff --git a/indexer/database/db.go b/indexer/database/db.go index def83841f869..fdb8db253a04 100644 --- a/indexer/database/db.go +++ b/indexer/database/db.go @@ -30,7 +30,9 @@ type DB struct { BridgeTransactions BridgeTransactionsDB } -func NewDB(log log.Logger, dbConfig config.DBConfig) (*DB, error) { +// NewDB connects to the configured DB, and provides client-bindings to it. +// The initial connection may fail, or the dial may be cancelled with the provided context. +func NewDB(ctx context.Context, log log.Logger, dbConfig config.DBConfig) (*DB, error) { log = log.New("module", "db") dsn := fmt.Sprintf("host=%s dbname=%s sslmode=disable", dbConfig.Host, dbConfig.Name) diff --git a/indexer/e2e_tests/setup.go b/indexer/e2e_tests/setup.go index 0191ece83da2..15126bd1fff8 100644 --- a/indexer/e2e_tests/setup.go +++ b/indexer/e2e_tests/setup.go @@ -191,7 +191,7 @@ func setupTestDatabase(t *testing.T) string { silentLog := log.New() silentLog.SetHandler(log.DiscardHandler()) - db, err := database.NewDB(silentLog, dbConfig) + db, err := database.NewDB(context.Background(), silentLog, dbConfig) require.NoError(t, err) defer db.Close() diff --git a/indexer/etl/l1_etl.go b/indexer/etl/l1_etl.go index 8ad8677aa59f..37a19586920a 100644 --- a/indexer/etl/l1_etl.go +++ b/indexer/etl/l1_etl.go @@ -4,20 +4,19 @@ import ( "context" "errors" "fmt" - "runtime/debug" "strings" "sync" "time" - "golang.org/x/sync/errgroup" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/node" "github.com/ethereum-optimism/optimism/op-service/retry" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/tasks" ) type L1ETL struct { @@ -27,7 +26,7 @@ type L1ETL struct { resourceCtx context.Context resourceCancel context.CancelFunc - tasks errgroup.Group + tasks tasks.Group db *database.DB @@ -38,7 +37,8 @@ type L1ETL struct { // NewL1ETL creates a new L1ETL instance that will start indexing from different starting points // depending on the state of the database and the supplied start height. -func NewL1ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, client node.EthClient, contracts config.L1Contracts) (*L1ETL, error) { +func NewL1ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, client node.EthClient, + contracts config.L1Contracts, shutdown context.CancelCauseFunc) (*L1ETL, error) { log = log.New("etl", "l1") zeroAddr := common.Address{} @@ -105,6 +105,9 @@ func NewL1ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, cli db: db, resourceCtx: resCtx, resourceCancel: resCancel, + tasks: tasks.Group{HandleCrit: func(err error) { + shutdown(fmt.Errorf("critical error in L1 ETL: %w", err)) + }}, }, nil } @@ -123,21 +126,13 @@ func (l1Etl *L1ETL) Close() error { return result } -func (l1Etl *L1ETL) Start(shutdown context.CancelCauseFunc) error { +func (l1Etl *L1ETL) Start() error { // start ETL batch producer if err := l1Etl.ETL.Start(); err != nil { return fmt.Errorf("failed to start internal ETL: %w", err) } // start ETL batch consumer l1Etl.tasks.Go(func() error { - defer func() { - if err := recover(); err != nil { - l1Etl.log.Error("halting indexer on L1 ETL panic", "err", err) - debug.PrintStack() - shutdown(fmt.Errorf("panic: %v", err)) - } - }() - for { // Index incoming batches (only L1 blocks that have an emitted log) batch, ok := <-l1Etl.etlBatches diff --git a/indexer/etl/l1_etl_test.go b/indexer/etl/l1_etl_test.go index 0c6b49dbac9a..7ae204afe123 100644 --- a/indexer/etl/l1_etl_test.go +++ b/indexer/etl/l1_etl_test.go @@ -108,7 +108,9 @@ func TestL1ETLConstruction(t *testing.T) { logger := testlog.Logger(t, log.LvlInfo) cfg := Config{StartHeight: ts.start} - etl, err := NewL1ETL(cfg, logger, ts.db.DB, etlMetrics, ts.client, ts.contracts) + etl, err := NewL1ETL(cfg, logger, ts.db.DB, etlMetrics, ts.client, ts.contracts, func(cause error) { + t.Fatalf("crit error: %v", cause) + }) test.assertion(etl, err) }) } diff --git a/indexer/etl/l2_etl.go b/indexer/etl/l2_etl.go index aebf31c1d19f..36fa7574b489 100644 --- a/indexer/etl/l2_etl.go +++ b/indexer/etl/l2_etl.go @@ -4,11 +4,8 @@ import ( "context" "errors" "fmt" - "runtime/debug" "time" - "golang.org/x/sync/errgroup" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" @@ -17,6 +14,7 @@ import ( "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/node" "github.com/ethereum-optimism/optimism/op-service/retry" + "github.com/ethereum-optimism/optimism/op-service/tasks" ) type L2ETL struct { @@ -26,12 +24,13 @@ type L2ETL struct { resourceCtx context.Context resourceCancel context.CancelFunc - tasks errgroup.Group + tasks tasks.Group db *database.DB } -func NewL2ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, client node.EthClient, contracts config.L2Contracts) (*L2ETL, error) { +func NewL2ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, client node.EthClient, + contracts config.L2Contracts, shutdown context.CancelCauseFunc) (*L2ETL, error) { log = log.New("etl", "l2") zeroAddr := common.Address{} @@ -85,6 +84,9 @@ func NewL2ETL(cfg Config, log log.Logger, db *database.DB, metrics Metricer, cli resourceCtx: resCtx, resourceCancel: resCancel, db: db, + tasks: tasks.Group{HandleCrit: func(err error) { + shutdown(fmt.Errorf("critical error in L2 ETL: %w", err)) + }}, }, nil } @@ -103,7 +105,7 @@ func (l2Etl *L2ETL) Close() error { return result } -func (l2Etl *L2ETL) Start(shutdown context.CancelCauseFunc) error { +func (l2Etl *L2ETL) Start() error { // start ETL batch producer if err := l2Etl.ETL.Start(); err != nil { return fmt.Errorf("failed to start internal ETL: %w", err) @@ -111,14 +113,6 @@ func (l2Etl *L2ETL) Start(shutdown context.CancelCauseFunc) error { // start ETL batch consumer l2Etl.tasks.Go(func() error { - defer func() { - if err := recover(); err != nil { - l2Etl.log.Error("halting indexer on L2 ETL panic", "err", err) - debug.PrintStack() - shutdown(fmt.Errorf("panic: %v", err)) - } - }() - for { // Index incoming batches (all L2 blocks) batch, ok := <-l2Etl.etlBatches diff --git a/indexer/indexer.go b/indexer/indexer.go index 6280c604e6ea..5509d80dc1d1 100644 --- a/indexer/indexer.go +++ b/indexer/indexer.go @@ -69,13 +69,13 @@ func NewIndexer(ctx context.Context, log log.Logger, cfg *config.Config, shutdow func (ix *Indexer) Start(ctx context.Context) error { // If any of these services has a critical failure, // the service can request a shutdown, while providing the error cause. - if err := ix.L1ETL.Start(ix.shutdown); err != nil { + if err := ix.L1ETL.Start(); err != nil { return fmt.Errorf("failed to start L1 ETL: %w", err) } - if err := ix.L2ETL.Start(ix.shutdown); err != nil { + if err := ix.L2ETL.Start(); err != nil { return fmt.Errorf("failed to start L2 ETL: %w", err) } - if err := ix.BridgeProcessor.Start(ix.shutdown); err != nil { + if err := ix.BridgeProcessor.Start(); err != nil { return fmt.Errorf("failed to start bridge processor: %w", err) } return nil @@ -181,8 +181,7 @@ func (ix *Indexer) initRPCClients(ctx context.Context, rpcsConfig config.RPCsCon } func (ix *Indexer) initDB(ctx context.Context, cfg config.DBConfig) error { - // TODO thread ctx for interrupt during dial - db, err := database.NewDB(ix.log, cfg) + db, err := database.NewDB(ctx, ix.log, cfg) if err != nil { return fmt.Errorf("failed to connect to database: %w", err) } @@ -197,7 +196,8 @@ func (ix *Indexer) initL1ETL(chainConfig config.ChainConfig) error { ConfirmationDepth: big.NewInt(int64(chainConfig.L1ConfirmationDepth)), StartHeight: big.NewInt(int64(chainConfig.L1StartingHeight)), } - l1Etl, err := etl.NewL1ETL(l1Cfg, ix.log, ix.DB, etl.NewMetrics(ix.metricsRegistry, "l1"), ix.l1Client, chainConfig.L1Contracts) + l1Etl, err := etl.NewL1ETL(l1Cfg, ix.log, ix.DB, etl.NewMetrics(ix.metricsRegistry, "l1"), + ix.l1Client, chainConfig.L1Contracts, ix.shutdown) if err != nil { return err } @@ -212,7 +212,8 @@ func (ix *Indexer) initL2ETL(chainConfig config.ChainConfig) error { HeaderBufferSize: chainConfig.L2HeaderBufferSize, ConfirmationDepth: big.NewInt(int64(chainConfig.L2ConfirmationDepth)), } - l2Etl, err := etl.NewL2ETL(l2Cfg, ix.log, ix.DB, etl.NewMetrics(ix.metricsRegistry, "l2"), ix.l2Client, chainConfig.L2Contracts) + l2Etl, err := etl.NewL2ETL(l2Cfg, ix.log, ix.DB, etl.NewMetrics(ix.metricsRegistry, "l2"), + ix.l2Client, chainConfig.L2Contracts, ix.shutdown) if err != nil { return err } @@ -221,7 +222,8 @@ func (ix *Indexer) initL2ETL(chainConfig config.ChainConfig) error { } func (ix *Indexer) initBridgeProcessor(chainConfig config.ChainConfig) error { - bridgeProcessor, err := processors.NewBridgeProcessor(ix.log, ix.DB, bridge.NewMetrics(ix.metricsRegistry), ix.L1ETL, chainConfig) + bridgeProcessor, err := processors.NewBridgeProcessor( + ix.log, ix.DB, bridge.NewMetrics(ix.metricsRegistry), ix.L1ETL, chainConfig, ix.shutdown) if err != nil { return err } diff --git a/indexer/processors/bridge.go b/indexer/processors/bridge.go index 5896d777c73a..657aa05b2316 100644 --- a/indexer/processors/bridge.go +++ b/indexer/processors/bridge.go @@ -5,18 +5,16 @@ import ( "errors" "fmt" "math/big" - "runtime/debug" - "golang.org/x/sync/errgroup" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/indexer/bigint" "github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/etl" "github.com/ethereum-optimism/optimism/indexer/processors/bridge" - - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum-optimism/optimism/op-service/tasks" ) type BridgeProcessor struct { @@ -26,7 +24,7 @@ type BridgeProcessor struct { resourceCtx context.Context resourceCancel context.CancelFunc - tasks errgroup.Group + tasks tasks.Group l1Etl *etl.L1ETL chainConfig config.ChainConfig @@ -35,7 +33,8 @@ type BridgeProcessor struct { LatestL2Header *types.Header } -func NewBridgeProcessor(log log.Logger, db *database.DB, metrics bridge.Metricer, l1Etl *etl.L1ETL, chainConfig config.ChainConfig) (*BridgeProcessor, error) { +func NewBridgeProcessor(log log.Logger, db *database.DB, metrics bridge.Metricer, l1Etl *etl.L1ETL, + chainConfig config.ChainConfig, shutdown context.CancelCauseFunc) (*BridgeProcessor, error) { log = log.New("processor", "bridge") latestL1Header, err := db.BridgeTransactions.L1LatestBlockHeader() @@ -76,10 +75,13 @@ func NewBridgeProcessor(log log.Logger, db *database.DB, metrics bridge.Metricer chainConfig: chainConfig, LatestL1Header: l1Header, LatestL2Header: l2Header, + tasks: tasks.Group{HandleCrit: func(err error) { + shutdown(fmt.Errorf("critical error in bridge processor: %w", err)) + }}, }, nil } -func (b *BridgeProcessor) Start(shutdown context.CancelCauseFunc) error { +func (b *BridgeProcessor) Start() error { b.log.Info("starting bridge processor...") // Fire off independently on startup to check for @@ -89,14 +91,6 @@ func (b *BridgeProcessor) Start(shutdown context.CancelCauseFunc) error { startup <- nil b.tasks.Go(func() error { - defer func() { - if err := recover(); err != nil { - b.log.Error("halting indexer on bridge-processor panic", "err", err) - debug.PrintStack() - shutdown(fmt.Errorf("panic: %v", err)) - } - }() - for { select { case <-b.resourceCtx.Done(): @@ -109,7 +103,7 @@ func (b *BridgeProcessor) Start(shutdown context.CancelCauseFunc) error { } done := b.metrics.RecordInterval() - // TODO: why log all the errors and return the same thing, if we just return the error, and log here? + // TODO(8013): why log all the errors and return the same thing, if we just return the error, and log here? err := b.run() if err != nil { b.log.Error("bridge processor error", "err", err) diff --git a/op-service/tasks/tasks.go b/op-service/tasks/tasks.go new file mode 100644 index 000000000000..67675995b2c4 --- /dev/null +++ b/op-service/tasks/tasks.go @@ -0,0 +1,32 @@ +package tasks + +import ( + "fmt" + "runtime/debug" + + "golang.org/x/sync/errgroup" +) + +// Group is a tasks group, which can at any point be awaited to complete. +// Tasks in the group are run in separate go routines. +// If a task panics, the panic is recovered with HandleCrit. +type Group struct { + errGroup errgroup.Group + HandleCrit func(err error) +} + +func (t *Group) Go(fn func() error) { + t.errGroup.Go(func() error { + defer func() { + if err := recover(); err != nil { + debug.PrintStack() + t.HandleCrit(fmt.Errorf("panic: %v", err)) + } + }() + return fn() + }) +} + +func (t *Group) Wait() error { + return t.errGroup.Wait() +} From b58f6b44a90a030d715e49acb2dab4866bf13e3c Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 2 Nov 2023 14:58:56 +0100 Subject: [PATCH 318/374] op-service: interrupt handling improvement --- indexer/cmd/indexer/main.go | 13 ++---- op-batcher/cmd/main.go | 7 ++- op-node/cmd/main.go | 4 +- op-service/cliapp/lifecycle.go | 18 ++++---- op-service/cliapp/lifecycle_test.go | 21 +++++---- op-service/opio/interrupts.go | 71 +++++++++++++++++++++++++++++ 6 files changed, 103 insertions(+), 31 deletions(-) diff --git a/indexer/cmd/indexer/main.go b/indexer/cmd/indexer/main.go index 9026ea7c796c..341f10c4366b 100644 --- a/indexer/cmd/indexer/main.go +++ b/indexer/cmd/indexer/main.go @@ -4,9 +4,10 @@ import ( "context" "os" + "github.com/ethereum/go-ethereum/log" + oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/opio" - "github.com/ethereum/go-ethereum/log" ) var ( @@ -15,16 +16,10 @@ var ( ) func main() { - // This is the most root context, used to propagate - // cancellations to all spawned application-level goroutines - ctx, cancel := context.WithCancel(context.Background()) - go func() { - opio.BlockOnInterrupts() - cancel() - }() - oplog.SetupDefaults() app := newCli(GitCommit, GitDate) + // sub-commands set up their individual interrupt lifecycles, which can block on the given interrupt as needed. + ctx := opio.WithInterruptBlocker(context.Background()) if err := app.RunContext(ctx, os.Args); err != nil { log.Error("application failed", "err", err) os.Exit(1) diff --git a/op-batcher/cmd/main.go b/op-batcher/cmd/main.go index cc64b6eeb459..91e032ff36b4 100644 --- a/op-batcher/cmd/main.go +++ b/op-batcher/cmd/main.go @@ -1,17 +1,19 @@ package main import ( + "context" "os" - opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/urfave/cli/v2" "github.com/ethereum-optimism/optimism/op-batcher/batcher" "github.com/ethereum-optimism/optimism/op-batcher/flags" "github.com/ethereum-optimism/optimism/op-batcher/metrics" + opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/metrics/doc" + "github.com/ethereum-optimism/optimism/op-service/opio" "github.com/ethereum/go-ethereum/log" ) @@ -38,7 +40,8 @@ func main() { }, } - err := app.Run(os.Args) + ctx := opio.WithInterruptBlocker(context.Background()) + err := app.RunContext(ctx, os.Args) if err != nil { log.Crit("Application failed", "message", err) } diff --git a/op-node/cmd/main.go b/op-node/cmd/main.go index 135db4059265..ed5377c64021 100644 --- a/op-node/cmd/main.go +++ b/op-node/cmd/main.go @@ -21,6 +21,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/cliapp" oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/metrics/doc" + "github.com/ethereum-optimism/optimism/op-service/opio" ) var ( @@ -58,7 +59,8 @@ func main() { }, } - err := app.Run(os.Args) + ctx := opio.WithInterruptBlocker(context.Background()) + err := app.RunContext(ctx, os.Args) if err != nil { log.Crit("Application failed", "message", err) } diff --git a/op-service/cliapp/lifecycle.go b/op-service/cliapp/lifecycle.go index 3afce92898dc..cd1c9bfb47c5 100644 --- a/op-service/cliapp/lifecycle.go +++ b/op-service/cliapp/lifecycle.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "os" "github.com/urfave/cli/v2" @@ -30,21 +29,22 @@ type Lifecycle interface { // a shutdown when the Stop context is not expired. type LifecycleAction func(ctx *cli.Context, close context.CancelCauseFunc) (Lifecycle, error) +var interruptErr = errors.New("interrupt signal") + // LifecycleCmd turns a LifecycleAction into an CLI action, // by instrumenting it with CLI context and signal based termination. +// The signals are catched with the opio.BlockFn attached to the context, if any. +// If no block function is provided, it adds default interrupt handling. // The app may continue to run post-processing until fully shutting down. // The user can force an early shut-down during post-processing by sending a second interruption signal. func LifecycleCmd(fn LifecycleAction) cli.ActionFunc { - return lifecycleCmd(fn, opio.BlockOnInterruptsContext) -} - -type waitSignalFn func(ctx context.Context, signals ...os.Signal) - -var interruptErr = errors.New("interrupt signal") - -func lifecycleCmd(fn LifecycleAction, blockOnInterrupt waitSignalFn) cli.ActionFunc { return func(ctx *cli.Context) error { hostCtx := ctx.Context + blockOnInterrupt := opio.BlockerFromContext(hostCtx) + if blockOnInterrupt == nil { // add default interrupt blocker to context if none is set. + hostCtx = opio.WithInterruptBlocker(hostCtx) + blockOnInterrupt = opio.BlockerFromContext(hostCtx) + } appCtx, appCancel := context.WithCancelCause(hostCtx) ctx.Context = appCtx diff --git a/op-service/cliapp/lifecycle_test.go b/op-service/cliapp/lifecycle_test.go index 8cb65ee00d40..1a4002729bb5 100644 --- a/op-service/cliapp/lifecycle_test.go +++ b/op-service/cliapp/lifecycle_test.go @@ -3,12 +3,13 @@ package cliapp import ( "context" "errors" - "os" "testing" "time" "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" + + "github.com/ethereum-optimism/optimism/op-service/opio" ) type fakeLifecycle struct { @@ -77,19 +78,19 @@ func TestLifecycleCmd(t *testing.T) { return app, nil } - // puppeteer a system signal waiter with a test signal channel - fakeSignalWaiter := func(ctx context.Context, signals ...os.Signal) { - select { - case <-ctx.Done(): - case <-signalCh: - } - } - // turn our mock app and system signal into a lifecycle-managed command - actionFn := lifecycleCmd(mockAppFn, fakeSignalWaiter) + actionFn := LifecycleCmd(mockAppFn) // try to shut the test down after being locked more than a minute ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + + // puppeteer system signal interrupts by hooking up the test signal channel as "blocker" for the app to use. + ctx = opio.WithBlocker(ctx, func(ctx context.Context) { + select { + case <-ctx.Done(): + case <-signalCh: + } + }) t.Cleanup(cancel) // create a fake CLI context to run our command with diff --git a/op-service/opio/interrupts.go b/op-service/opio/interrupts.go index 1b886c6d9001..cd1b8485791d 100644 --- a/op-service/opio/interrupts.go +++ b/op-service/opio/interrupts.go @@ -41,3 +41,74 @@ func BlockOnInterruptsContext(ctx context.Context, signals ...os.Signal) { signal.Stop(interruptChannel) } } + +type interruptContextKeyType struct{} + +var blockerContextKey = interruptContextKeyType{} + +type interruptCatcher struct { + incoming chan os.Signal +} + +// Block blocks until either an interrupt signal is received, or the context is cancelled. +// No error is returned on interrupt. +func (c *interruptCatcher) Block(ctx context.Context) { + select { + case <-c.incoming: + case <-ctx.Done(): + } +} + +// WithInterruptBlocker attaches an interrupt handler to the context, +// which continues to receive signals after every block. +// This helps functions block on individual consecutive interrupts. +func WithInterruptBlocker(ctx context.Context) context.Context { + if ctx.Value(blockerContextKey) != nil { // already has an interrupt handler + return ctx + } + catcher := &interruptCatcher{ + incoming: make(chan os.Signal, 10), + } + signal.Notify(catcher.incoming, DefaultInterruptSignals...) + + return context.WithValue(ctx, blockerContextKey, BlockFn(catcher.Block)) +} + +// WithBlocker overrides the interrupt blocker value, +// e.g. to insert a block-function for testing CLI shutdown without actual process signals. +func WithBlocker(ctx context.Context, fn BlockFn) context.Context { + return context.WithValue(ctx, blockerContextKey, fn) +} + +// BlockFn simply blocks until the implementation of the blocker interrupts it, or till the given context is cancelled. +type BlockFn func(ctx context.Context) + +// BlockerFromContext returns a BlockFn that blocks on interrupts when called. +func BlockerFromContext(ctx context.Context) BlockFn { + v := ctx.Value(blockerContextKey) + if v == nil { + return nil + } + return v.(BlockFn) +} + +// CancelOnInterrupt cancels the given context on interrupt. +// If a BlockFn is attached to the context, this is used as interrupt-blocking. +// If not, then the context blocks on a manually handled interrupt signal. +func CancelOnInterrupt(ctx context.Context) context.Context { + inner, cancel := context.WithCancel(ctx) + + blockOnInterrupt := BlockerFromContext(ctx) + if blockOnInterrupt == nil { + blockOnInterrupt = func(ctx context.Context) { + BlockOnInterruptsContext(ctx) // default signals + } + } + + go func() { + blockOnInterrupt(ctx) + cancel() + }() + + return inner +} From 972fcabde732c8e98df2b505b88d680360652e47 Mon Sep 17 00:00:00 2001 From: inphi Date: Wed, 1 Nov 2023 12:01:52 -0400 Subject: [PATCH 319/374] ci: ignore code coverage in script contracts --- codecov.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/codecov.yml b/codecov.yml index 6edb2f3e455c..11f6adec1635 100644 --- a/codecov.yml +++ b/codecov.yml @@ -12,6 +12,7 @@ ignore: - "op-bindings/bindings/*.go" - "**/*.t.sol" - "packages/contracts-bedrock/test/**/*.sol" + - "packages/contracts-bedrock/scripts/**/*.sol" - "packages/contracts-bedrock/contracts/vendor/WETH9.sol" - 'packages/contracts-bedrock/contracts/EAS/**/*.sol' coverage: From 46f00fe23e29607d6821d8fb67b8ef8fbd783fe4 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 2 Nov 2023 19:16:48 +0300 Subject: [PATCH 320/374] contracts-bedrock: deal better --- packages/contracts-bedrock/test/OptimismPortal.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol index 66ff26fa71f0..9ef9b8230ae9 100644 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/OptimismPortal.t.sol @@ -30,8 +30,6 @@ contract OptimismPortal_Test is Portal_Initializer { function setUp() public override { super.setUp(); depositor = makeAddr("depositor"); - vm.deal(depositor, type(uint128).max); - vm.deal(address(this), type(uint128).max); } /// @dev Tests that the constructor sets the correct values. @@ -199,6 +197,7 @@ contract OptimismPortal_Test is Portal_Initializer { _data: _data }); + vm.deal(depositor, _mint); vm.prank(depositor, depositor); op.depositTransaction{ value: _mint }({ _to: _to, @@ -237,6 +236,7 @@ contract OptimismPortal_Test is Portal_Initializer { _data: _data }); + vm.deal(address(this), _mint); vm.prank(address(this)); op.depositTransaction{ value: _mint }({ _to: _to, From 43efe7f4b2eec6df0c5299635a95477ce0e565fd Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 2 Nov 2023 17:39:59 +0100 Subject: [PATCH 321/374] op-service: fix typo in comment --- op-service/cliapp/lifecycle.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-service/cliapp/lifecycle.go b/op-service/cliapp/lifecycle.go index cd1c9bfb47c5..2154c025645d 100644 --- a/op-service/cliapp/lifecycle.go +++ b/op-service/cliapp/lifecycle.go @@ -33,7 +33,7 @@ var interruptErr = errors.New("interrupt signal") // LifecycleCmd turns a LifecycleAction into an CLI action, // by instrumenting it with CLI context and signal based termination. -// The signals are catched with the opio.BlockFn attached to the context, if any. +// The signals are caught with the opio.BlockFn attached to the context, if any. // If no block function is provided, it adds default interrupt handling. // The app may continue to run post-processing until fully shutting down. // The user can force an early shut-down during post-processing by sending a second interruption signal. From d04582b556310049b25e2927f81237627aa1a0af Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 2 Nov 2023 19:50:14 +0300 Subject: [PATCH 322/374] contracts-bedrock: gas snapshot --- packages/contracts-bedrock/.gas-snapshot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 09a2e82c1a94..3447d92de242 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -486,7 +486,7 @@ OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayPro OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166699) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154430) OptimismPortal_Test:test_constructor_succeeds() (gas: 28164) -OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14292) +OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14281) OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512200) OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14528) OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127594) From 48962ac92b94babc27d1789088295b602ee745b0 Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 2 Nov 2023 20:21:41 +0100 Subject: [PATCH 323/374] op-node: static-peers list local-peer check and flag description update --- op-node/flags/p2p_flags.go | 5 +++-- op-node/p2p/host.go | 10 +++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/op-node/flags/p2p_flags.go b/op-node/flags/p2p_flags.go index 4f680eae7e8d..34577d831f5b 100644 --- a/op-node/flags/p2p_flags.go +++ b/op-node/flags/p2p_flags.go @@ -189,8 +189,9 @@ func P2PFlags(envPrefix string) []cli.Flag { EnvVars: p2pEnv(envPrefix, "BOOTNODES"), }, &cli.StringFlag{ - Name: StaticPeersName, - Usage: "Comma-separated multiaddr-format peer list. Static connections to make and maintain, these peers will be regarded as trusted.", + Name: StaticPeersName, + Usage: "Comma-separated multiaddr-format peer list. Static connections to make and maintain, these peers will be regarded as trusted. " + + "Addresses of the local peer are ignored. Duplicate/Alternative addresses for the same peer all apply, but only a single connection per peer is maintained.", Required: false, Value: "", EnvVars: p2pEnv(envPrefix, "STATIC"), diff --git a/op-node/p2p/host.go b/op-node/p2p/host.go index 5396bed05d9c..9496d4bf7cc0 100644 --- a/op-node/p2p/host.go +++ b/op-node/p2p/host.go @@ -229,13 +229,17 @@ func (conf *Config) Host(log log.Logger, reporter metrics.Reporter, metrics Host return nil, err } - staticPeers := make([]*peer.AddrInfo, len(conf.StaticPeers)) - for i, peerAddr := range conf.StaticPeers { + staticPeers := make([]*peer.AddrInfo, 0, len(conf.StaticPeers)) + for _, peerAddr := range conf.StaticPeers { addr, err := peer.AddrInfoFromP2pAddr(peerAddr) if err != nil { return nil, fmt.Errorf("bad peer address: %w", err) } - staticPeers[i] = addr + if addr.ID == h.ID() { + log.Info("Static-peer list contains address of local peer, ignoring the address.", "address", addr) + continue + } + staticPeers = append(staticPeers, addr) } out := &extraHost{ From b253cd08c80b92ea5dcb96cae6be46c0a7decf73 Mon Sep 17 00:00:00 2001 From: Danyal Prout Date: Thu, 2 Nov 2023 14:38:04 -0500 Subject: [PATCH 324/374] proxyd: configurable IP rate limit header --- proxyd/config.go | 7 ++++--- proxyd/go.sum | 1 - proxyd/server.go | 10 +++++++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/proxyd/config.go b/proxyd/config.go index fefca9f6e500..63f557c28004 100644 --- a/proxyd/config.go +++ b/proxyd/config.go @@ -22,9 +22,9 @@ type ServerConfig struct { MaxUpstreamBatchSize int `toml:"max_upstream_batch_size"` - EnableRequestLog bool `toml:"enable_request_log"` - MaxRequestBodyLogLen int `toml:"max_request_body_log_len"` - EnablePprof bool `toml:"enable_pprof"` + EnableRequestLog bool `toml:"enable_request_log"` + MaxRequestBodyLogLen int `toml:"max_request_body_log_len"` + EnablePprof bool `toml:"enable_pprof"` EnableXServedByHeader bool `toml:"enable_served_by_header"` } @@ -51,6 +51,7 @@ type RateLimitConfig struct { ExemptUserAgents []string `toml:"exempt_user_agents"` ErrorMessage string `toml:"error_message"` MethodOverrides map[string]*RateLimitMethodOverride `toml:"method_overrides"` + IPHeaderOverride string `toml:"ip_header_override"` } type RateLimitMethodOverride struct { diff --git a/proxyd/go.sum b/proxyd/go.sum index e759ce561aa5..a54ffb592175 100644 --- a/proxyd/go.sum +++ b/proxyd/go.sum @@ -138,7 +138,6 @@ github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= diff --git a/proxyd/server.go b/proxyd/server.go index 2b7a1bd966f6..5d262da40c89 100644 --- a/proxyd/server.go +++ b/proxyd/server.go @@ -44,6 +44,7 @@ const ( defaultWSWriteTimeout = 10 * time.Second maxRequestBodyLogLen = 2000 defaultMaxUpstreamBatchSize = 10 + defaultRateLimitHeader = "X-Forwarded-For" ) var emptyArrayResponse = json.RawMessage("[]") @@ -73,6 +74,7 @@ type Server struct { wsServer *http.Server cache RPCCache srvMu sync.Mutex + rateLimitHeader string } type limiterFunc func(method string) bool @@ -168,6 +170,11 @@ func NewServer( senderLim = limiterFactory(time.Duration(senderRateLimitConfig.Interval), senderRateLimitConfig.Limit, "senders") } + rateLimitHeader := defaultRateLimitHeader + if rateLimitConfig.IPHeaderOverride != "" { + rateLimitHeader = rateLimitConfig.IPHeaderOverride + } + return &Server{ BackendGroups: backendGroups, wsBackendGroup: wsBackendGroup, @@ -192,6 +199,7 @@ func NewServer( allowedChainIds: senderRateLimitConfig.AllowedChainIds, limExemptOrigins: limExemptOrigins, limExemptUserAgents: limExemptUserAgents, + rateLimitHeader: rateLimitHeader, }, nil } @@ -608,7 +616,7 @@ func (s *Server) HandleWS(w http.ResponseWriter, r *http.Request) { func (s *Server) populateContext(w http.ResponseWriter, r *http.Request) context.Context { vars := mux.Vars(r) authorization := vars["authorization"] - xff := r.Header.Get("X-Forwarded-For") + xff := r.Header.Get(s.rateLimitHeader) if xff == "" { ipPort := strings.Split(r.RemoteAddr, ":") if len(ipPort) == 2 { From 14d154d9cd6f552afa8288fe3495d5ffdee2179f Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 2 Nov 2023 20:47:49 +0100 Subject: [PATCH 325/374] op-node: static-peers test --- op-node/p2p/host.go | 2 +- op-node/p2p/host_test.go | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/op-node/p2p/host.go b/op-node/p2p/host.go index 9496d4bf7cc0..6011617f5c78 100644 --- a/op-node/p2p/host.go +++ b/op-node/p2p/host.go @@ -236,7 +236,7 @@ func (conf *Config) Host(log log.Logger, reporter metrics.Reporter, metrics Host return nil, fmt.Errorf("bad peer address: %w", err) } if addr.ID == h.ID() { - log.Info("Static-peer list contains address of local peer, ignoring the address.", "address", addr) + log.Info("Static-peer list contains address of local peer, ignoring the address.", "peer_id", addr.ID, "addrs", addr.Addrs) continue } staticPeers = append(staticPeers, addr) diff --git a/op-node/p2p/host_test.go b/op-node/p2p/host_test.go index 1a44c25664b0..66454c70fe23 100644 --- a/op-node/p2p/host_test.go +++ b/op-node/p2p/host_test.go @@ -15,6 +15,7 @@ import ( "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" + ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" @@ -139,6 +140,13 @@ func TestP2PFull(t *testing.T) { confB.StaticPeers, err = peer.AddrInfoToP2pAddrs(&peer.AddrInfo{ID: hostA.ID(), Addrs: hostA.Addrs()}) require.NoError(t, err) + // Add address of host B itself, it shouldn't connect or cause issues. + idB, err := peer.IDFromPublicKey(confB.Priv.GetPublic()) + require.NoError(t, err) + altAddrB, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/12345/p2p/" + idB.String()) + require.NoError(t, err) + confB.StaticPeers = append(confB.StaticPeers, altAddrB) + logB := testlog.Logger(t, log.LvlError).New("host", "B") nodeB, err := NewNodeP2P(context.Background(), &rollup.Config{}, logB, &confB, &mockGossipIn{}, nil, runCfgB, metrics.NoopMetrics) @@ -146,6 +154,9 @@ func TestP2PFull(t *testing.T) { defer nodeB.Close() hostB := nodeB.Host() + require.True(t, nodeB.IsStatic(hostA.ID()), "node A must be static peer of node B") + require.False(t, nodeB.IsStatic(hostB.ID()), "node B must not be static peer of node B itself") + select { case <-time.After(time.Second): t.Fatal("failed to connect new host") From beea9375e3ea589ef7ee303be07deb95437f9ad6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 20:08:51 +0000 Subject: [PATCH 326/374] build(deps-dev): bump hardhat from 2.18.3 to 2.19.0 Bumps [hardhat](https://github.com/nomiclabs/hardhat) from 2.18.3 to 2.19.0. - [Release notes](https://github.com/nomiclabs/hardhat/releases) - [Commits](https://github.com/nomiclabs/hardhat/compare/hardhat@2.18.3...hardhat@2.19.0) --- updated-dependencies: - dependency-name: hardhat dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/chain-mon/package.json | 2 +- packages/sdk/package.json | 2 +- pnpm-lock.yaml | 36 ++++++++++++++++----------------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/chain-mon/package.json b/packages/chain-mon/package.json index dcd3f4ad8965..19abaad32b49 100644 --- a/packages/chain-mon/package.json +++ b/packages/chain-mon/package.json @@ -59,7 +59,7 @@ "@ethersproject/abstract-provider": "^5.7.0", "@nomiclabs/hardhat-ethers": "^2.2.3", "@nomiclabs/hardhat-waffle": "^2.0.6", - "hardhat": "^2.18.3", + "hardhat": "^2.19.0", "ts-node": "^10.9.1", "tsx": "^3.14.0" } diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 367b5741a393..2cb0150dc957 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -48,7 +48,7 @@ "chai-as-promised": "^7.1.1", "ethereum-waffle": "^4.0.10", "ethers": "^5.7.2", - "hardhat": "^2.18.3", + "hardhat": "^2.19.0", "hardhat-deploy": "^0.11.43", "isomorphic-fetch": "^3.0.0", "mocha": "^10.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 211270d87832..8f221162ecab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -175,13 +175,13 @@ importers: version: 5.7.0 '@nomiclabs/hardhat-ethers': specifier: ^2.2.3 - version: 2.2.3(ethers@5.7.2)(hardhat@2.18.3) + version: 2.2.3(ethers@5.7.2)(hardhat@2.19.0) '@nomiclabs/hardhat-waffle': specifier: ^2.0.6 - version: 2.0.6(@nomiclabs/hardhat-ethers@2.2.3)(@types/sinon-chai@3.2.5)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.18.3) + version: 2.0.6(@nomiclabs/hardhat-ethers@2.2.3)(@types/sinon-chai@3.2.5)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.19.0) hardhat: - specifier: ^2.18.3 - version: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) + specifier: ^2.19.0 + version: 2.19.0(ts-node@10.9.1)(typescript@5.2.2) ts-node: specifier: ^10.9.1 version: 10.9.1(@types/node@20.8.9)(typescript@5.2.2) @@ -479,10 +479,10 @@ importers: version: 5.7.0 '@nomiclabs/hardhat-ethers': specifier: ^2.2.3 - version: 2.2.3(ethers@5.7.2)(hardhat@2.18.3) + version: 2.2.3(ethers@5.7.2)(hardhat@2.19.0) '@nomiclabs/hardhat-waffle': specifier: ^2.0.1 - version: 2.0.1(@nomiclabs/hardhat-ethers@2.2.3)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.18.3) + version: 2.0.1(@nomiclabs/hardhat-ethers@2.2.3)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.19.0) '@types/chai': specifier: ^4.3.8 version: 4.3.8 @@ -505,8 +505,8 @@ importers: specifier: ^5.7.2 version: 5.7.2 hardhat: - specifier: ^2.18.3 - version: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) + specifier: ^2.19.0 + version: 2.19.0(ts-node@10.9.1)(typescript@5.2.2) hardhat-deploy: specifier: ^0.11.43 version: 0.11.43 @@ -2947,17 +2947,17 @@ packages: '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.1 dev: true - /@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.18.3): + /@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.19.0): resolution: {integrity: sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==} peerDependencies: ethers: ^5.0.0 hardhat: ^2.0.0 dependencies: ethers: 5.7.2 - hardhat: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) + hardhat: 2.19.0(ts-node@10.9.1)(typescript@5.2.2) dev: true - /@nomiclabs/hardhat-waffle@2.0.1(@nomiclabs/hardhat-ethers@2.2.3)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.18.3): + /@nomiclabs/hardhat-waffle@2.0.1(@nomiclabs/hardhat-ethers@2.2.3)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.19.0): resolution: {integrity: sha512-2YR2V5zTiztSH9n8BYWgtv3Q+EL0N5Ltm1PAr5z20uAY4SkkfylJ98CIqt18XFvxTD5x4K2wKBzddjV9ViDAZQ==} peerDependencies: '@nomiclabs/hardhat-ethers': ^2.0.0 @@ -2965,15 +2965,15 @@ packages: ethers: ^5.0.0 hardhat: ^2.0.0 dependencies: - '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.18.3) + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.19.0) '@types/sinon-chai': 3.2.5 '@types/web3': 1.0.19 ethereum-waffle: 4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typescript@5.2.2) ethers: 5.7.2 - hardhat: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) + hardhat: 2.19.0(ts-node@10.9.1)(typescript@5.2.2) dev: true - /@nomiclabs/hardhat-waffle@2.0.6(@nomiclabs/hardhat-ethers@2.2.3)(@types/sinon-chai@3.2.5)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.18.3): + /@nomiclabs/hardhat-waffle@2.0.6(@nomiclabs/hardhat-ethers@2.2.3)(@types/sinon-chai@3.2.5)(ethereum-waffle@4.0.10)(ethers@5.7.2)(hardhat@2.19.0): resolution: {integrity: sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg==} peerDependencies: '@nomiclabs/hardhat-ethers': ^2.0.0 @@ -2982,11 +2982,11 @@ packages: ethers: ^5.0.0 hardhat: ^2.0.0 dependencies: - '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.18.3) + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.19.0) '@types/sinon-chai': 3.2.5 ethereum-waffle: 4.0.10(@ensdomains/ens@0.4.5)(@ensdomains/resolver@0.2.4)(@ethersproject/abi@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typescript@5.2.2) ethers: 5.7.2 - hardhat: 2.18.3(ts-node@10.9.1)(typescript@5.2.2) + hardhat: 2.19.0(ts-node@10.9.1)(typescript@5.2.2) dev: true /@nrwl/nx-cloud@16.5.2: @@ -8903,8 +8903,8 @@ packages: - utf-8-validate dev: true - /hardhat@2.18.3(ts-node@10.9.1)(typescript@5.2.2): - resolution: {integrity: sha512-JuYaTG+4ZHVjEHCW5Hn6jCHH3LpO75dtgznZpM/dLv12RcSlw/xHbeQh3FAsGahQr1epKryZcZEMHvztVZHe0g==} + /hardhat@2.19.0(ts-node@10.9.1)(typescript@5.2.2): + resolution: {integrity: sha512-kMpwovOEfrFRQXEopCP+JTcKVwSYVj8rnXE0LynxDqnh06yvyKCQknmXL6IVYTHQL6Csysc/yNbCHQbjSeJGpA==} hasBin: true peerDependencies: ts-node: '*' From 8e7b9f71034e7d6a4439279431cfd96ed7972ba3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 20:10:18 +0000 Subject: [PATCH 327/374] build(deps): bump @ethereumjs/rlp from 5.0.0 to 5.0.1 Bumps [@ethereumjs/rlp](https://github.com/ethereumjs/ethereumjs-monorepo) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/ethereumjs/ethereumjs-monorepo/releases) - [Commits](https://github.com/ethereumjs/ethereumjs-monorepo/compare/@ethereumjs/rlp@5.0.0...@ethereumjs/rlp@5.0.1) --- updated-dependencies: - dependency-name: "@ethereumjs/rlp" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/web3js-plugin/package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/web3js-plugin/package.json b/packages/web3js-plugin/package.json index f80f2dbf2dbc..e23cc3c93996 100644 --- a/packages/web3js-plugin/package.json +++ b/packages/web3js-plugin/package.json @@ -43,7 +43,7 @@ "zod": "^3.22.4" }, "dependencies": { - "@ethereumjs/rlp": "^5.0.0", + "@ethereumjs/rlp": "^5.0.1", "web3-eth": "^4.0.3", "web3-eth-accounts": "^4.0.3" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 211270d87832..3cb2e5a3c67e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -541,8 +541,8 @@ importers: packages/web3js-plugin: dependencies: '@ethereumjs/rlp': - specifier: ^5.0.0 - version: 5.0.0 + specifier: ^5.0.1 + version: 5.0.1 web3: specifier: '>= 4.0.3 < 5.x' version: 4.0.3 @@ -2014,8 +2014,8 @@ packages: engines: {node: '>=14'} hasBin: true - /@ethereumjs/rlp@5.0.0: - resolution: {integrity: sha512-WuS1l7GJmB0n0HsXLozCoEFc9IwYgf3l0gCkKVYgR67puVF1O4OpEaN0hWmm1c+iHUHFCKt1hJrvy5toLg+6ag==} + /@ethereumjs/rlp@5.0.1: + resolution: {integrity: sha512-Ab/Hfzz+T9Zl+65Nkg+9xAmwKPLicsnQ4NW49pgvJp9ovefuic95cgOS9CbPc9izIEgsqm1UitV0uNveCvud9w==} engines: {node: '>=18'} hasBin: true dev: false From c12c9f41eb3f0cd3c99eac96be11eb97d575b939 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 20:11:44 +0000 Subject: [PATCH 328/374] build(deps): bump viem from 1.18.2 to 1.18.3 Bumps [viem](https://github.com/wagmi-dev/viem) from 1.18.2 to 1.18.3. - [Release notes](https://github.com/wagmi-dev/viem/releases) - [Commits](https://github.com/wagmi-dev/viem/compare/viem@1.18.2...viem@1.18.3) --- updated-dependencies: - dependency-name: viem dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/contracts-ts/package.json | 2 +- packages/fee-estimation/package.json | 2 +- packages/sdk/package.json | 2 +- packages/web3js-plugin/package.json | 2 +- pnpm-lock.yaml | 62 ++++++++++++++-------------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/contracts-ts/package.json b/packages/contracts-ts/package.json index 24384796fa19..9b6dfc3db99a 100644 --- a/packages/contracts-ts/package.json +++ b/packages/contracts-ts/package.json @@ -82,6 +82,6 @@ "change-case": "4.1.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "viem": "^1.18.2" + "viem": "^1.18.3" } } diff --git a/packages/fee-estimation/package.json b/packages/fee-estimation/package.json index cd3788ece2f8..e145df500d85 100644 --- a/packages/fee-estimation/package.json +++ b/packages/fee-estimation/package.json @@ -44,7 +44,7 @@ "jsdom": "^22.1.0", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.18.2", + "viem": "^1.18.3", "vite": "^4.5.0", "vitest": "^0.34.2" }, diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 367b5741a393..bdfb42949ef2 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -56,7 +56,7 @@ "ts-node": "^10.9.1", "typedoc": "^0.25.3", "typescript": "^5.2.2", - "viem": "^1.18.2", + "viem": "^1.18.3", "vitest": "^0.34.2", "zod": "^3.22.4" }, diff --git a/packages/web3js-plugin/package.json b/packages/web3js-plugin/package.json index f80f2dbf2dbc..c70cfb39f1d1 100644 --- a/packages/web3js-plugin/package.json +++ b/packages/web3js-plugin/package.json @@ -37,7 +37,7 @@ "@vitest/coverage-istanbul": "^0.34.6", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.18.2", + "viem": "^1.18.3", "vite": "^4.5.0", "vitest": "^0.34.1", "zod": "^3.22.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 211270d87832..bcd8d7a5f54c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -298,11 +298,11 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) viem: - specifier: ^1.18.2 - version: 1.18.2(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.3 + version: 1.18.3(typescript@5.2.2)(zod@3.22.4) wagmi: specifier: '>1.0.0' - version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) + version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) devDependencies: '@eth-optimism/contracts-bedrock': specifier: workspace:* @@ -324,7 +324,7 @@ importers: version: 1.5.2(@wagmi/core@1.4.5)(typescript@5.2.2)(wagmi@1.0.1) '@wagmi/core': specifier: ^1.4.5 - version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) + version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) abitype: specifier: ^0.10.2 version: 0.10.2(typescript@5.2.2) @@ -438,8 +438,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.2 - version: 1.18.2(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.3 + version: 1.18.3(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -529,8 +529,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.2 - version: 1.18.2(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.3 + version: 1.18.3(typescript@5.2.2)(zod@3.22.4) vitest: specifier: ^0.34.2 version: 0.34.2 @@ -569,8 +569,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.2 - version: 1.18.2(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.3 + version: 1.18.3(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -3197,7 +3197,7 @@ packages: resolution: {integrity: sha512-gYw0ki/EAuV1oSyMxpqandHjnthZjYYy+YWpTAzf8BqfXM3ItcZLpjxfg+3+mXW8HIO+3jw6T9iiqEXsqHaMMw==} dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.7.3 - viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - bufferutil - encoding @@ -4562,7 +4562,7 @@ packages: wagmi: optional: true dependencies: - '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) + '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) abort-controller: 3.0.0 bundle-require: 3.1.2(esbuild@0.16.17) @@ -4584,15 +4584,15 @@ packages: picocolors: 1.0.0 prettier: 2.8.8 typescript: 5.2.2 - viem: 1.18.2(typescript@5.2.2)(zod@3.22.3) - wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) + viem: 1.18.3(typescript@5.2.2)(zod@3.22.3) + wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) zod: 3.22.3 transitivePeerDependencies: - bufferutil - utf-8-validate dev: true - /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.2): + /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.3): resolution: {integrity: sha512-fl01vym19DE1uoE+MlASw5zo3Orr/YXlJRjOKLaKYtV+Q7jOLY4TwHgq7sEMs+JYOvFICFBEAlWNNxidr51AqQ==} peerDependencies: '@wagmi/chains': '>=0.2.0' @@ -4615,7 +4615,7 @@ packages: abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil @@ -4627,7 +4627,7 @@ packages: - utf-8-validate - zod - /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.2): + /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.3): resolution: {integrity: sha512-UgwsQKQDFObJVJMf9pDfFoXTv710o4zrTHyhIWKBTMMkLpCMsMxN5+ZaDhBYt/BgoRinfRYQo8uwuwLhxE6Log==} peerDependencies: typescript: '>=5.0.4' @@ -4647,7 +4647,7 @@ packages: abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - '@types/react' @@ -4660,7 +4660,7 @@ packages: - zod dev: true - /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.2): + /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.3): resolution: {integrity: sha512-Zzg4Ob92QMF9NsC+z5/8JZjMn3NCCnwVWGJlv79qRX9mp5Ku40OzJNvqDnjcSGjshe6H0L/KtFZAqTlmu8lT7w==} peerDependencies: typescript: '>=4.9.4' @@ -4670,11 +4670,11 @@ packages: optional: true dependencies: '@wagmi/chains': 0.2.22(typescript@5.2.2) - '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) + '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -4688,7 +4688,7 @@ packages: - utf-8-validate - zod - /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.2): + /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.3): resolution: {integrity: sha512-N9luRb1Uk4tBN9kaYcQSWKE9AsRt/rvZaFt5IZech4JPzNN2sQlfhKd9GEjOXYRDqEPHdDvos7qyBKiDNTz4GA==} peerDependencies: typescript: '>=5.0.4' @@ -4697,11 +4697,11 @@ packages: typescript: optional: true dependencies: - '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) + '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -14292,8 +14292,8 @@ packages: vfile-message: 2.0.4 dev: true - /viem@1.18.2(typescript@5.2.2)(zod@3.22.3): - resolution: {integrity: sha512-ifobXCKwzztmjHbHowAWqTASO6tAqF6udKB9ONXkJQU1cmt830MABiMwJGtTO9Gb9ION1N+324G7nHDbpPn4wg==} + /viem@1.18.3(typescript@5.2.2)(zod@3.22.3): + resolution: {integrity: sha512-r27eb39MHEXul/k2jZnRVNJY8QhoS816Kqh0guaLVLRJkGGIutryh7z5sKIuhKHU1yz2+CoPaiRn08gGKrfskw==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14315,8 +14315,8 @@ packages: - zod dev: true - /viem@1.18.2(typescript@5.2.2)(zod@3.22.4): - resolution: {integrity: sha512-ifobXCKwzztmjHbHowAWqTASO6tAqF6udKB9ONXkJQU1cmt830MABiMwJGtTO9Gb9ION1N+324G7nHDbpPn4wg==} + /viem@1.18.3(typescript@5.2.2)(zod@3.22.4): + resolution: {integrity: sha512-r27eb39MHEXul/k2jZnRVNJY8QhoS816Kqh0guaLVLRJkGGIutryh7z5sKIuhKHU1yz2+CoPaiRn08gGKrfskw==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14809,7 +14809,7 @@ packages: xml-name-validator: 4.0.0 dev: true - /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.2): + /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.3): resolution: {integrity: sha512-+2UkZG9eA3tKqXj1wvlvI8mL0Bcff7Tf5CKfUOyQsdKcY+J5rfwYYya25G+jja57umpHFtfxRaL7xDkNjehrRg==} peerDependencies: react: '>=17.0.0' @@ -14822,12 +14822,12 @@ packages: '@tanstack/query-sync-storage-persister': 4.29.25 '@tanstack/react-query': 4.29.25(react-dom@18.2.0)(react@18.2.0) '@tanstack/react-query-persist-client': 4.29.25(@tanstack/react-query@4.29.25) - '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.2) + '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) abitype: 0.8.1(typescript@5.2.2) react: 18.2.0 typescript: 5.2.2 use-sync-external-store: 1.2.0(react@18.2.0) - viem: 1.18.2(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil From 1c46496d4e7ddc4649804b9dadc3df0f7a087736 Mon Sep 17 00:00:00 2001 From: Will Cory Date: Thu, 2 Nov 2023 14:27:11 -0700 Subject: [PATCH 329/374] chore: Make paths references DRY --- bedrock-devnet/devnet/__init__.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bedrock-devnet/devnet/__init__.py b/bedrock-devnet/devnet/__init__.py index 5e0dcc83f9b7..1f3b91a95a89 100644 --- a/bedrock-devnet/devnet/__init__.py +++ b/bedrock-devnet/devnet/__init__.py @@ -202,13 +202,12 @@ def devnet_deploy(paths): # If someone reads this comment and understands why this is being done, please # update this comment to explain. init_devnet_l1_deploy_config(paths, update_timestamp=True) - outfile_l1 = pjoin(paths.devnet_dir, 'genesis-l1.json') run_command([ 'go', 'run', 'cmd/main.go', 'genesis', 'l1', '--deploy-config', paths.devnet_config_path, '--l1-allocs', paths.allocs_path, '--l1-deployments', paths.addresses_json_path, - '--outfile.l1', outfile_l1, + '--outfile.l1', paths.genesis_l1_path, ], cwd=paths.op_node_dir) log.info('Starting L1.') @@ -227,8 +226,8 @@ def devnet_deploy(paths): '--l1-rpc', 'http://localhost:8545', '--deploy-config', paths.devnet_config_path, '--deployment-dir', paths.deployment_dir, - '--outfile.l2', pjoin(paths.devnet_dir, 'genesis-l2.json'), - '--outfile.rollup', pjoin(paths.devnet_dir, 'rollup.json') + '--outfile.l2', paths.genesis_l2_path, + '--outfile.rollup', paths.rollup_config_path ], cwd=paths.op_node_dir) rollup_config = read_json(paths.rollup_config_path) From a850928f455754956f10463a1d756e452f157af0 Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 2 Nov 2023 23:26:27 +0100 Subject: [PATCH 330/374] specs: clarify span-batch validation rules include upgrade activation check --- specs/span-batches.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/specs/span-batches.md b/specs/span-batches.md index 34cfbd3cd287..63c233fc2e2f 100644 --- a/specs/span-batches.md +++ b/specs/span-batches.md @@ -9,7 +9,7 @@ - [Introduction](#introduction) - [Span batch format](#span-batch-format) -- [Span batch Hard Fork Rule](#span-batch-hard-fork-rule) +- [Span batch Activation Rule](#span-batch-activation-rule) - [Optimization Strategies](#optimization-strategies) - [Truncating information and storing only necessary data](#truncating-information-and-storing-only-necessary-data) - [`tx_data_headers` removal from initial specs](#tx_data_headers-removal-from-initial-specs) @@ -154,13 +154,13 @@ decoding. For example, lets say bad batcher wrote span batch which `block_count the explicit limit, not trying to consume data until EOF is reached. We can also safely preallocate memory for decoding because we know the upper limit of memory usage. -## Span batch Hard Fork Rule +## Span batch Activation Rule -Span batch hard fork is activated based on timestamp. +The span batch upgrade is activated based on timestamp. -Activation Rule: `upgradeNumber != null && x >= upgradeTime` +Activation Rule: `upgradeTime != null && span_start.l1_origin.timestamp >= upgradeTime` -`x == span_start.l1_origin.timestamp`, which is the L1 origin block timestamp of the first block in the span. +`span_start.l1_origin.timestamp` is the L1 origin block timestamp of the first block in the span batch. This rule ensures that every chain activity regarding this span batch is done after the hard fork. i.e. Every block in the span is created, submitted to the L1, and derived from the L1 after the hard fork. @@ -272,6 +272,13 @@ Rules are enforced with the [contextual definitions](./derivation.md#batch-queue Span-batch rules, in validation order: +- `batch_origin` is determined like with singular batches: + - `batch.epoch_num == epoch.number+1`: + - If `next_epoch` is not known -> `undecided`: + i.e. a batch that changes the L1 origin cannot be processed until we have the L1 origin data. + - If known, then define `batch_origin` as `next_epoch` +- `batch_origin.timestamp < span_batch_upgrade_timestamp` -> `drop`: + i.e. enforce the [span batch upgrade activation rule](#span-batch-activation-rule). - `batch.start_timestamp > next_timestamp` -> `future`: i.e. the batch must be ready to process. - `batch.start_timestamp < next_timestamp` -> `drop`: i.e. the batch must not be too old. - `batch.parent_check != safe_l2_head.hash[:20]` -> `drop`: i.e. the checked part of the parent hash must be equal From 6646032d9b656f5842b29a3df2fa622355a27fa5 Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 2 Nov 2023 23:27:40 +0100 Subject: [PATCH 331/374] specs: improve wording of upgrade activation rules --- specs/superchain-upgrades.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/specs/superchain-upgrades.md b/specs/superchain-upgrades.md index d606c7eebfdd..19e241ce06dd 100644 --- a/specs/superchain-upgrades.md +++ b/specs/superchain-upgrades.md @@ -199,7 +199,10 @@ and are then retrieved from the superchain target configuration. ### L2 Block-number based activation (deprecated) -Activation rule: `x != null && x >= upgradeNumber` +Activation rule: `upgradeNumber != null && block.number >= upgradeNumber` + +Starting at, and including, the L2 `block` with `block.number >= upgradeNumber`, the upgrade rules apply. +If the upgrade block-number `upgradeNumber` is not specified in the configuration, the upgrade is ignored. This block number based method has commonly been used in L1 up until the Bellatrix/Paris upgrade, a.k.a. The Merge, which was upgraded through special rules. @@ -207,22 +210,19 @@ which was upgraded through special rules. This method is not superchain-compatible, as the activation-parameter is chain-specific (different chains may have different block-heights at the same moment in time). -Starting at, and including, the L2 `block` with `block.number == x`, the upgrade rules apply. -If the upgrade block-number `x` is not specified in the configuration, the upgrade is ignored. - This applies to the L2 block number, not to the L1-origin block number. This means that an L2 upgrade may be inactive, and then active, without changing the L1-origin. ### L2 Block-timestamp based activation -Activation rule: `x != null && x >= upgradeTime` +Activation rule: `upgradeTime != null && block.timestamp >= upgradeTime` + +Starting at, and including, the L2 `block` with `block.timestamp >= upgradeTime`, the upgrade rules apply. +If the upgrade block-timestamp `upgradeTime` is not specified in the configuration, the upgrade is ignored. This is the preferred superchain upgrade activation-parameter type: it is synchronous between all L2 chains and compatible with post-Merge timestamp-based chain upgrades in L1. -Starting at, and including, the L2 `block` with `block.timestamp == x`, the upgrade rules apply. -If the upgrade block-timestamp `x` is not specified in the configuration, the upgrade is ignored. - This applies to the L2 block timestamp, not to the L1-origin block timestamp. This means that an L2 upgrade may be inactive, and then active, without changing the L1-origin. From d3bf13b266b899efee26008ab992445cad681552 Mon Sep 17 00:00:00 2001 From: protolambda Date: Fri, 3 Nov 2023 00:22:13 +0100 Subject: [PATCH 332/374] op-node: attributes queue reset state for consistency --- op-node/rollup/derive/attributes_queue.go | 1 + 1 file changed, 1 insertion(+) diff --git a/op-node/rollup/derive/attributes_queue.go b/op-node/rollup/derive/attributes_queue.go index c9d3f1bc406e..e923695a6cdf 100644 --- a/op-node/rollup/derive/attributes_queue.go +++ b/op-node/rollup/derive/attributes_queue.go @@ -103,5 +103,6 @@ func (aq *AttributesQueue) createNextAttributes(ctx context.Context, batch *Sing func (aq *AttributesQueue) Reset(ctx context.Context, _ eth.L1BlockRef, _ eth.SystemConfig) error { aq.batch = nil + aq.isLastInSpan = false // overwritten later, but set for consistency return io.EOF } From 90848b23b0fed9d6b4a930bf7a27ee9af27d5e3d Mon Sep 17 00:00:00 2001 From: protolambda Date: Fri, 3 Nov 2023 00:23:16 +0100 Subject: [PATCH 333/374] op-e2e/actions: use interface in batcher for l2 block ref access --- op-e2e/actions/l2_batcher.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/op-e2e/actions/l2_batcher.go b/op-e2e/actions/l2_batcher.go index 8818a42c4194..4ed14c139383 100644 --- a/op-e2e/actions/l2_batcher.go +++ b/op-e2e/actions/l2_batcher.go @@ -20,7 +20,6 @@ import ( "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum-optimism/optimism/op-service/sources" ) type SyncStatusAPI interface { @@ -47,6 +46,10 @@ type BatcherCfg struct { GarbageCfg *GarbageChannelCfg } +type L2BlockRefs interface { + L2BlockRefByHash(ctx context.Context, hash common.Hash) (eth.L2BlockRef, error) +} + // L2Batcher buffers and submits L2 batches to L1. // // TODO: note the batcher shares little logic/state with actual op-batcher, @@ -60,7 +63,7 @@ type L2Batcher struct { syncStatusAPI SyncStatusAPI l2 BlocksAPI l1 L1TxAPI - engCl *sources.EngineClient + engCl L2BlockRefs l1Signer types.Signer @@ -72,7 +75,7 @@ type L2Batcher struct { batcherAddr common.Address } -func NewL2Batcher(log log.Logger, rollupCfg *rollup.Config, batcherCfg *BatcherCfg, api SyncStatusAPI, l1 L1TxAPI, l2 BlocksAPI, engCl *sources.EngineClient) *L2Batcher { +func NewL2Batcher(log log.Logger, rollupCfg *rollup.Config, batcherCfg *BatcherCfg, api SyncStatusAPI, l1 L1TxAPI, l2 BlocksAPI, engCl L2BlockRefs) *L2Batcher { return &L2Batcher{ log: log, rollupCfg: rollupCfg, From ce1b1e3dd5fef4e58d2015db3efce89e686f4c18 Mon Sep 17 00:00:00 2001 From: Aryan Malik Date: Fri, 3 Nov 2023 13:50:35 +0530 Subject: [PATCH 334/374] Usage of 'Immutable' for variables storing keccak hashes --- .../src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol b/packages/contracts-bedrock/src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol index d162b5b2b4ec..115810d9d139 100644 --- a/packages/contracts-bedrock/src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol +++ b/packages/contracts-bedrock/src/periphery/faucet/authmodules/AdminFaucetAuthModule.sol @@ -14,7 +14,7 @@ contract AdminFaucetAuthModule is IFaucetAuthModule, EIP712 { address public immutable ADMIN; /// @notice EIP712 typehash for the Proof type. - bytes32 public constant PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)"); + bytes32 public immutable PROOF_TYPEHASH = keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)"); /// @notice Struct that represents a proof that verifies the admin. /// @custom:field recipient Address that will be receiving the faucet funds. From 3ef2413db6dfb5fb168ee83ae28974b9184375e3 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 16:02:11 +0300 Subject: [PATCH 335/374] contracts-bedrock: lite foundry profile Adds a `lite` profile for foundry that turns off the compiler optimizer. This is suitable for development purposes when the compiler is taking a long time to compile. The developer should be sure to not use this mode when doing contract deployments. To set the profile, set the env var `FOUNDRY_PROFILE=lite`. --- packages/contracts-bedrock/foundry.toml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml index 8c1cc245b681..dddcc64b128e 100644 --- a/packages/contracts-bedrock/foundry.toml +++ b/packages/contracts-bedrock/foundry.toml @@ -52,3 +52,11 @@ ignore = ['src/vendor/WETH9.sol'] [profile.ci.fuzz] runs = 512 + +################################################################ +# PROFILE: LITE # +################################################################ + +[profile.lite] +optimizer = false + From d7051433c7bba99d5382bb44faa37133fa902f44 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 17:10:35 +0300 Subject: [PATCH 336/374] contracts-bedrock: simplify merkle trie setup The `MerkleTrie` tests were using `CommonTest` but do not require anything besides `FFIInterface` so instead of pulling in all of the overhead of `CommonTest`, just deploy `FFIInterface` on its on in the `setUp` function. This should be a slight optimization as it reduces the amount of execution required for setup. Reducing diff from https://github.com/ethereum-optimism/optimism/pull/7928 --- packages/contracts-bedrock/test/MerkleTrie.t.sol | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/MerkleTrie.t.sol b/packages/contracts-bedrock/test/MerkleTrie.t.sol index 59673f06e2ae..1727940eff7c 100644 --- a/packages/contracts-bedrock/test/MerkleTrie.t.sol +++ b/packages/contracts-bedrock/test/MerkleTrie.t.sol @@ -1,10 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; import { MerkleTrie } from "src/libraries/trie/MerkleTrie.sol"; +import { FFIInterface } from "test/setup/FFIInterface.sol"; + +contract MerkleTrie_get_Test is Test { + FFIInterface ffi; + + function setUp() public { + ffi = new FFIInterface(); + } -contract MerkleTrie_get_Test is CommonTest { function test_get_validProof1_succeeds() external { bytes32 root = 0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f; bytes memory key = hex"6b6579326262"; From 6fd31c7798c9ee9268571fe0a3797fd403c821d9 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 17:19:02 +0300 Subject: [PATCH 337/374] contracts-bedrock: migrate ffi interface --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- .../contracts-bedrock/test/CommonTest.t.sol | 235 +---------------- .../test/setup/FFIInterface.sol | 243 ++++++++++++++++++ 4 files changed, 246 insertions(+), 236 deletions(-) create mode 100644 packages/contracts-bedrock/test/setup/FFIInterface.sol diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index e557605acfea..42d41cd47ad9 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:304;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:304;2534:6:135;400:55:304;382:74;;370:2;355:18;2448:99:135;211:251:304;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:304;;;1743:2;1728:18;26025:6379:135;1609:177:304;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:304;19164:28:135;;;2164:21:304;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:304;14107:30:135;;;2511:21:304;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:304;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:304;37406:29:135;;;2860:21:304;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:304;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:304;20288:41:135;;;3208:21:304;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:304;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:304;;;8234:54:135;3601:23:304;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:304;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:304;21415:72:135;;;4259:21:304;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:304;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:304:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:304;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:304;-1:-1:-1;1349:2:304;1334:18;;1321:32;;-1:-1:-1;1365:16:304;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:304;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:304:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:304;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:304:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:305;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:305;2534:6:135;400:55:305;382:74;;370:2;355:18;2448:99:135;211:251:305;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:305;;;1743:2;1728:18;26025:6379:135;1609:177:305;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:305;19164:28:135;;;2164:21:305;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:305;14107:30:135;;;2511:21:305;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:305;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:305;37406:29:135;;;2860:21:305;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:305;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:305;20288:41:135;;;3208:21:305;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:305;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:305;;;8234:54:135;3601:23:305;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:305;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:305;21415:72:135;;;4259:21:305;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:305;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:305:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:305;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:305;-1:-1:-1;1349:2:305;1334:18;;1321:32;;-1:-1:-1;1365:16:305;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:305;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:305:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:305;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:305:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index 52403fe9a12a..d03ea4e51ec2 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:304;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:304;;607:22;589:41;;577:2;562:18;680:66:137;449:187:304;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:304;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:304;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:304;906:62:137;;;2890:21:304;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:304:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:304;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:304:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:304;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:304;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:304;1069:19;1056:33;;-1:-1:-1;641:454:304;-1:-1:-1;641:454:304:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:304;;2017:180;-1:-1:-1;2017:180:304:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:304;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:304;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:305;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:305;;607:22;589:41;;577:2;562:18;680:66:137;449:187:305;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:305;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:305;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:305;906:62:137;;;2890:21:305;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:305:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:305;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:305:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:305;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:305;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:305;1069:19;1056:33;;-1:-1:-1;641:454:305;-1:-1:-1;641:454:305:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:305;;2017:180;-1:-1:-1;2017:180:305:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:305;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:305;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { diff --git a/packages/contracts-bedrock/test/CommonTest.t.sol b/packages/contracts-bedrock/test/CommonTest.t.sol index 6e34ba8007b8..d3f3b16671da 100644 --- a/packages/contracts-bedrock/test/CommonTest.t.sol +++ b/packages/contracts-bedrock/test/CommonTest.t.sol @@ -36,6 +36,7 @@ import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Constants } from "src/libraries/Constants.sol"; +import { FFIInterface } from "test/setup/FFIInterface.sol"; contract CommonTest is Test { address alice = address(128); @@ -497,237 +498,3 @@ contract FeeVault_Initializer is Bridge_Initializer { event Withdrawal(uint256 value, address to, address from, FeeVault.WithdrawalNetwork withdrawalNetwork); } - -contract FFIInterface is Test { - function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx) - external - returns (bytes32, bytes32, bytes32, bytes32, bytes[] memory) - { - string[] memory cmds = new string[](9); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "getProveWithdrawalTransactionInputs"; - cmds[3] = vm.toString(_tx.nonce); - cmds[4] = vm.toString(_tx.sender); - cmds[5] = vm.toString(_tx.target); - cmds[6] = vm.toString(_tx.value); - cmds[7] = vm.toString(_tx.gasLimit); - cmds[8] = vm.toString(_tx.data); - - bytes memory result = vm.ffi(cmds); - ( - bytes32 stateRoot, - bytes32 storageRoot, - bytes32 outputRoot, - bytes32 withdrawalHash, - bytes[] memory withdrawalProof - ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[])); - - return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof); - } - - function hashCrossDomainMessage( - uint256 _nonce, - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes memory _data - ) - external - returns (bytes32) - { - string[] memory cmds = new string[](9); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "hashCrossDomainMessage"; - cmds[3] = vm.toString(_nonce); - cmds[4] = vm.toString(_sender); - cmds[5] = vm.toString(_target); - cmds[6] = vm.toString(_value); - cmds[7] = vm.toString(_gasLimit); - cmds[8] = vm.toString(_data); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes32)); - } - - function hashWithdrawal( - uint256 _nonce, - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes memory _data - ) - external - returns (bytes32) - { - string[] memory cmds = new string[](9); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "hashWithdrawal"; - cmds[3] = vm.toString(_nonce); - cmds[4] = vm.toString(_sender); - cmds[5] = vm.toString(_target); - cmds[6] = vm.toString(_value); - cmds[7] = vm.toString(_gasLimit); - cmds[8] = vm.toString(_data); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes32)); - } - - function hashOutputRootProof( - bytes32 _version, - bytes32 _stateRoot, - bytes32 _messagePasserStorageRoot, - bytes32 _latestBlockhash - ) - external - returns (bytes32) - { - string[] memory cmds = new string[](7); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "hashOutputRootProof"; - cmds[3] = Strings.toHexString(uint256(_version)); - cmds[4] = Strings.toHexString(uint256(_stateRoot)); - cmds[5] = Strings.toHexString(uint256(_messagePasserStorageRoot)); - cmds[6] = Strings.toHexString(uint256(_latestBlockhash)); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes32)); - } - - function hashDepositTransaction( - address _from, - address _to, - uint256 _mint, - uint256 _value, - uint64 _gas, - bytes memory _data, - uint64 _logIndex - ) - external - returns (bytes32) - { - string[] memory cmds = new string[](11); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "hashDepositTransaction"; - cmds[3] = "0x0000000000000000000000000000000000000000000000000000000000000000"; - cmds[4] = vm.toString(_logIndex); - cmds[5] = vm.toString(_from); - cmds[6] = vm.toString(_to); - cmds[7] = vm.toString(_mint); - cmds[8] = vm.toString(_value); - cmds[9] = vm.toString(_gas); - cmds[10] = vm.toString(_data); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes32)); - } - - function encodeDepositTransaction(Types.UserDepositTransaction calldata txn) external returns (bytes memory) { - string[] memory cmds = new string[](12); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "encodeDepositTransaction"; - cmds[3] = vm.toString(txn.from); - cmds[4] = vm.toString(txn.to); - cmds[5] = vm.toString(txn.value); - cmds[6] = vm.toString(txn.mint); - cmds[7] = vm.toString(txn.gasLimit); - cmds[8] = vm.toString(txn.isCreation); - cmds[9] = vm.toString(txn.data); - cmds[10] = vm.toString(txn.l1BlockHash); - cmds[11] = vm.toString(txn.logIndex); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes)); - } - - function encodeCrossDomainMessage( - uint256 _nonce, - address _sender, - address _target, - uint256 _value, - uint256 _gasLimit, - bytes memory _data - ) - external - returns (bytes memory) - { - string[] memory cmds = new string[](9); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "encodeCrossDomainMessage"; - cmds[3] = vm.toString(_nonce); - cmds[4] = vm.toString(_sender); - cmds[5] = vm.toString(_target); - cmds[6] = vm.toString(_value); - cmds[7] = vm.toString(_gasLimit); - cmds[8] = vm.toString(_data); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (bytes)); - } - - function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) { - string[] memory cmds = new string[](4); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "decodeVersionedNonce"; - cmds[3] = vm.toString(nonce); - - bytes memory result = vm.ffi(cmds); - return abi.decode(result, (uint256, uint256)); - } - - function getMerkleTrieFuzzCase(string memory variant) - external - returns (bytes32, bytes memory, bytes memory, bytes[] memory) - { - string[] memory cmds = new string[](6); - cmds[0] = "./scripts/go-ffi/go-ffi"; - cmds[1] = "trie"; - cmds[2] = variant; - - return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[])); - } - - function getCannonMemoryProof(uint32 pc, uint32 insn) external returns (bytes32, bytes memory) { - string[] memory cmds = new string[](5); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "cannonMemoryProof"; - cmds[3] = vm.toString(pc); - cmds[4] = vm.toString(insn); - bytes memory result = vm.ffi(cmds); - (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); - return (memRoot, proof); - } - - function getCannonMemoryProof( - uint32 pc, - uint32 insn, - uint32 memAddr, - uint32 memVal - ) - external - returns (bytes32, bytes memory) - { - string[] memory cmds = new string[](7); - cmds[0] = "scripts/go-ffi/go-ffi"; - cmds[1] = "diff"; - cmds[2] = "cannonMemoryProof"; - cmds[3] = vm.toString(pc); - cmds[4] = vm.toString(insn); - cmds[5] = vm.toString(memAddr); - cmds[6] = vm.toString(memVal); - bytes memory result = vm.ffi(cmds); - (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); - return (memRoot, proof); - } -} diff --git a/packages/contracts-bedrock/test/setup/FFIInterface.sol b/packages/contracts-bedrock/test/setup/FFIInterface.sol new file mode 100644 index 000000000000..93727a035d73 --- /dev/null +++ b/packages/contracts-bedrock/test/setup/FFIInterface.sol @@ -0,0 +1,243 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Types } from "src/libraries/Types.sol"; +import { Vm } from "forge-std/Vm.sol"; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; + +/// @title FFIInterface +contract FFIInterface { + Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + function getProveWithdrawalTransactionInputs(Types.WithdrawalTransaction memory _tx) + external + returns (bytes32, bytes32, bytes32, bytes32, bytes[] memory) + { + string[] memory cmds = new string[](9); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "getProveWithdrawalTransactionInputs"; + cmds[3] = vm.toString(_tx.nonce); + cmds[4] = vm.toString(_tx.sender); + cmds[5] = vm.toString(_tx.target); + cmds[6] = vm.toString(_tx.value); + cmds[7] = vm.toString(_tx.gasLimit); + cmds[8] = vm.toString(_tx.data); + + bytes memory result = vm.ffi(cmds); + ( + bytes32 stateRoot, + bytes32 storageRoot, + bytes32 outputRoot, + bytes32 withdrawalHash, + bytes[] memory withdrawalProof + ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[])); + + return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof); + } + + function hashCrossDomainMessage( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) + external + returns (bytes32) + { + string[] memory cmds = new string[](9); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "hashCrossDomainMessage"; + cmds[3] = vm.toString(_nonce); + cmds[4] = vm.toString(_sender); + cmds[5] = vm.toString(_target); + cmds[6] = vm.toString(_value); + cmds[7] = vm.toString(_gasLimit); + cmds[8] = vm.toString(_data); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes32)); + } + + function hashWithdrawal( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) + external + returns (bytes32) + { + string[] memory cmds = new string[](9); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "hashWithdrawal"; + cmds[3] = vm.toString(_nonce); + cmds[4] = vm.toString(_sender); + cmds[5] = vm.toString(_target); + cmds[6] = vm.toString(_value); + cmds[7] = vm.toString(_gasLimit); + cmds[8] = vm.toString(_data); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes32)); + } + + function hashOutputRootProof( + bytes32 _version, + bytes32 _stateRoot, + bytes32 _messagePasserStorageRoot, + bytes32 _latestBlockhash + ) + external + returns (bytes32) + { + string[] memory cmds = new string[](7); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "hashOutputRootProof"; + cmds[3] = Strings.toHexString(uint256(_version)); + cmds[4] = Strings.toHexString(uint256(_stateRoot)); + cmds[5] = Strings.toHexString(uint256(_messagePasserStorageRoot)); + cmds[6] = Strings.toHexString(uint256(_latestBlockhash)); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes32)); + } + + function hashDepositTransaction( + address _from, + address _to, + uint256 _mint, + uint256 _value, + uint64 _gas, + bytes memory _data, + uint64 _logIndex + ) + external + returns (bytes32) + { + string[] memory cmds = new string[](11); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "hashDepositTransaction"; + cmds[3] = "0x0000000000000000000000000000000000000000000000000000000000000000"; + cmds[4] = vm.toString(_logIndex); + cmds[5] = vm.toString(_from); + cmds[6] = vm.toString(_to); + cmds[7] = vm.toString(_mint); + cmds[8] = vm.toString(_value); + cmds[9] = vm.toString(_gas); + cmds[10] = vm.toString(_data); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes32)); + } + + function encodeDepositTransaction(Types.UserDepositTransaction calldata txn) external returns (bytes memory) { + string[] memory cmds = new string[](12); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "encodeDepositTransaction"; + cmds[3] = vm.toString(txn.from); + cmds[4] = vm.toString(txn.to); + cmds[5] = vm.toString(txn.value); + cmds[6] = vm.toString(txn.mint); + cmds[7] = vm.toString(txn.gasLimit); + cmds[8] = vm.toString(txn.isCreation); + cmds[9] = vm.toString(txn.data); + cmds[10] = vm.toString(txn.l1BlockHash); + cmds[11] = vm.toString(txn.logIndex); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes)); + } + + function encodeCrossDomainMessage( + uint256 _nonce, + address _sender, + address _target, + uint256 _value, + uint256 _gasLimit, + bytes memory _data + ) + external + returns (bytes memory) + { + string[] memory cmds = new string[](9); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "encodeCrossDomainMessage"; + cmds[3] = vm.toString(_nonce); + cmds[4] = vm.toString(_sender); + cmds[5] = vm.toString(_target); + cmds[6] = vm.toString(_value); + cmds[7] = vm.toString(_gasLimit); + cmds[8] = vm.toString(_data); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (bytes)); + } + + function decodeVersionedNonce(uint256 nonce) external returns (uint256, uint256) { + string[] memory cmds = new string[](4); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "decodeVersionedNonce"; + cmds[3] = vm.toString(nonce); + + bytes memory result = vm.ffi(cmds); + return abi.decode(result, (uint256, uint256)); + } + + function getMerkleTrieFuzzCase(string memory variant) + external + returns (bytes32, bytes memory, bytes memory, bytes[] memory) + { + string[] memory cmds = new string[](6); + cmds[0] = "./scripts/go-ffi/go-ffi"; + cmds[1] = "trie"; + cmds[2] = variant; + + return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[])); + } + + function getCannonMemoryProof(uint32 pc, uint32 insn) external returns (bytes32, bytes memory) { + string[] memory cmds = new string[](5); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "cannonMemoryProof"; + cmds[3] = vm.toString(pc); + cmds[4] = vm.toString(insn); + bytes memory result = vm.ffi(cmds); + (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); + return (memRoot, proof); + } + + function getCannonMemoryProof( + uint32 pc, + uint32 insn, + uint32 memAddr, + uint32 memVal + ) + external + returns (bytes32, bytes memory) + { + string[] memory cmds = new string[](7); + cmds[0] = "scripts/go-ffi/go-ffi"; + cmds[1] = "diff"; + cmds[2] = "cannonMemoryProof"; + cmds[3] = vm.toString(pc); + cmds[4] = vm.toString(insn); + cmds[5] = vm.toString(memAddr); + cmds[6] = vm.toString(memVal); + bytes memory result = vm.ffi(cmds); + (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); + return (memRoot, proof); + } +} From 0ea7755501453dfc52759615c02dcf3b7ec49b8c Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 17:30:22 +0300 Subject: [PATCH 338/374] contracts-bedrock: gas-snapshot --- packages/contracts-bedrock/.gas-snapshot | 152 +++++++++++------------ 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index b76982437b87..e5bcfdc0132e 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -329,81 +329,81 @@ LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRece LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 615047) LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1278252) LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954) -MIPS_Test:test_add_succeeds() (gas: 122932) -MIPS_Test:test_addiSign_succeeds() (gas: 122923) -MIPS_Test:test_addi_succeeds() (gas: 123120) -MIPS_Test:test_addu_succeeds() (gas: 122974) -MIPS_Test:test_addui_succeeds() (gas: 123182) -MIPS_Test:test_and_succeeds() (gas: 122993) -MIPS_Test:test_andi_succeeds() (gas: 122926) -MIPS_Test:test_beq_succeeds() (gas: 203359) -MIPS_Test:test_bgez_succeeds() (gas: 122219) -MIPS_Test:test_bgtz_succeeds() (gas: 122140) -MIPS_Test:test_blez_succeeds() (gas: 122096) -MIPS_Test:test_bltz_succeeds() (gas: 122239) -MIPS_Test:test_bne_succeeds() (gas: 122305) -MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86514) -MIPS_Test:test_brk_succeeds() (gas: 122609) -MIPS_Test:test_clo_succeeds() (gas: 122661) -MIPS_Test:test_clone_succeeds() (gas: 122562) -MIPS_Test:test_clz_succeeds() (gas: 123132) -MIPS_Test:test_div_succeeds() (gas: 123111) -MIPS_Test:test_divu_succeeds() (gas: 123096) -MIPS_Test:test_exit_succeeds() (gas: 122611) -MIPS_Test:test_fcntl_succeeds() (gas: 204841) -MIPS_Test:test_illegal_instruction_fails() (gas: 91977) -MIPS_Test:test_invalid_root_fails() (gas: 436151) -MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121249) -MIPS_Test:test_jal_succeeds() (gas: 121238) -MIPS_Test:test_jalr_succeeds() (gas: 122357) -MIPS_Test:test_jr_succeeds() (gas: 122051) -MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85882) -MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120993) -MIPS_Test:test_jump_succeeds() (gas: 120923) -MIPS_Test:test_lb_succeeds() (gas: 128164) -MIPS_Test:test_lbu_succeeds() (gas: 128062) -MIPS_Test:test_lh_succeeds() (gas: 128185) -MIPS_Test:test_lhu_succeeds() (gas: 128102) -MIPS_Test:test_ll_succeeds() (gas: 128324) -MIPS_Test:test_lui_succeeds() (gas: 122205) -MIPS_Test:test_lw_succeeds() (gas: 127953) -MIPS_Test:test_lwl_succeeds() (gas: 243070) -MIPS_Test:test_lwr_succeeds() (gas: 243358) -MIPS_Test:test_mfhi_succeeds() (gas: 122566) -MIPS_Test:test_mflo_succeeds() (gas: 122695) -MIPS_Test:test_mmap_succeeds() (gas: 119529) -MIPS_Test:test_movn_succeeds() (gas: 204031) -MIPS_Test:test_movz_succeeds() (gas: 203899) -MIPS_Test:test_mthi_succeeds() (gas: 122610) -MIPS_Test:test_mtlo_succeeds() (gas: 122718) -MIPS_Test:test_mul_succeeds() (gas: 122210) -MIPS_Test:test_mult_succeeds() (gas: 122914) -MIPS_Test:test_multu_succeeds() (gas: 122951) -MIPS_Test:test_nor_succeeds() (gas: 123043) -MIPS_Test:test_or_succeeds() (gas: 123000) -MIPS_Test:test_ori_succeeds() (gas: 123003) -MIPS_Test:test_preimage_read_succeeds() (gas: 235481) -MIPS_Test:test_preimage_write_succeeds() (gas: 127551) -MIPS_Test:test_prestate_exited_succeeds() (gas: 113792) -MIPS_Test:test_sb_succeeds() (gas: 161501) -MIPS_Test:test_sc_succeeds() (gas: 161684) -MIPS_Test:test_sh_succeeds() (gas: 161538) -MIPS_Test:test_sll_succeeds() (gas: 122171) -MIPS_Test:test_sllv_succeeds() (gas: 122400) -MIPS_Test:test_slt_succeeds() (gas: 205226) -MIPS_Test:test_sltu_succeeds() (gas: 123217) -MIPS_Test:test_sra_succeeds() (gas: 122422) -MIPS_Test:test_srav_succeeds() (gas: 122690) -MIPS_Test:test_srl_succeeds() (gas: 122253) -MIPS_Test:test_srlv_succeeds() (gas: 122418) +MIPS_Test:test_add_succeeds() (gas: 122866) +MIPS_Test:test_addiSign_succeeds() (gas: 122857) +MIPS_Test:test_addi_succeeds() (gas: 123054) +MIPS_Test:test_addu_succeeds() (gas: 122908) +MIPS_Test:test_addui_succeeds() (gas: 123116) +MIPS_Test:test_and_succeeds() (gas: 122927) +MIPS_Test:test_andi_succeeds() (gas: 122860) +MIPS_Test:test_beq_succeeds() (gas: 203293) +MIPS_Test:test_bgez_succeeds() (gas: 122153) +MIPS_Test:test_bgtz_succeeds() (gas: 122074) +MIPS_Test:test_blez_succeeds() (gas: 122030) +MIPS_Test:test_bltz_succeeds() (gas: 122173) +MIPS_Test:test_bne_succeeds() (gas: 122239) +MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86448) +MIPS_Test:test_brk_succeeds() (gas: 122543) +MIPS_Test:test_clo_succeeds() (gas: 122595) +MIPS_Test:test_clone_succeeds() (gas: 122496) +MIPS_Test:test_clz_succeeds() (gas: 123066) +MIPS_Test:test_div_succeeds() (gas: 123045) +MIPS_Test:test_divu_succeeds() (gas: 123030) +MIPS_Test:test_exit_succeeds() (gas: 122545) +MIPS_Test:test_fcntl_succeeds() (gas: 204775) +MIPS_Test:test_illegal_instruction_fails() (gas: 91911) +MIPS_Test:test_invalid_root_fails() (gas: 436085) +MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121183) +MIPS_Test:test_jal_succeeds() (gas: 121172) +MIPS_Test:test_jalr_succeeds() (gas: 122291) +MIPS_Test:test_jr_succeeds() (gas: 121985) +MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85816) +MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120927) +MIPS_Test:test_jump_succeeds() (gas: 120857) +MIPS_Test:test_lb_succeeds() (gas: 128098) +MIPS_Test:test_lbu_succeeds() (gas: 127996) +MIPS_Test:test_lh_succeeds() (gas: 128119) +MIPS_Test:test_lhu_succeeds() (gas: 128036) +MIPS_Test:test_ll_succeeds() (gas: 128258) +MIPS_Test:test_lui_succeeds() (gas: 122139) +MIPS_Test:test_lw_succeeds() (gas: 127887) +MIPS_Test:test_lwl_succeeds() (gas: 242938) +MIPS_Test:test_lwr_succeeds() (gas: 243226) +MIPS_Test:test_mfhi_succeeds() (gas: 122500) +MIPS_Test:test_mflo_succeeds() (gas: 122629) +MIPS_Test:test_mmap_succeeds() (gas: 119528) +MIPS_Test:test_movn_succeeds() (gas: 203965) +MIPS_Test:test_movz_succeeds() (gas: 203833) +MIPS_Test:test_mthi_succeeds() (gas: 122544) +MIPS_Test:test_mtlo_succeeds() (gas: 122652) +MIPS_Test:test_mul_succeeds() (gas: 122144) +MIPS_Test:test_mult_succeeds() (gas: 122848) +MIPS_Test:test_multu_succeeds() (gas: 122885) +MIPS_Test:test_nor_succeeds() (gas: 122977) +MIPS_Test:test_or_succeeds() (gas: 122934) +MIPS_Test:test_ori_succeeds() (gas: 122937) +MIPS_Test:test_preimage_read_succeeds() (gas: 235349) +MIPS_Test:test_preimage_write_succeeds() (gas: 127485) +MIPS_Test:test_prestate_exited_succeeds() (gas: 113726) +MIPS_Test:test_sb_succeeds() (gas: 161369) +MIPS_Test:test_sc_succeeds() (gas: 161552) +MIPS_Test:test_sh_succeeds() (gas: 161406) +MIPS_Test:test_sll_succeeds() (gas: 122105) +MIPS_Test:test_sllv_succeeds() (gas: 122334) +MIPS_Test:test_slt_succeeds() (gas: 205160) +MIPS_Test:test_sltu_succeeds() (gas: 123151) +MIPS_Test:test_sra_succeeds() (gas: 122356) +MIPS_Test:test_srav_succeeds() (gas: 122624) +MIPS_Test:test_srl_succeeds() (gas: 122187) +MIPS_Test:test_srlv_succeeds() (gas: 122352) MIPS_Test:test_step_abi_succeeds() (gas: 58467) -MIPS_Test:test_sub_succeeds() (gas: 123027) -MIPS_Test:test_subu_succeeds() (gas: 123024) -MIPS_Test:test_sw_succeeds() (gas: 161513) -MIPS_Test:test_swl_succeeds() (gas: 161574) -MIPS_Test:test_swr_succeeds() (gas: 161649) -MIPS_Test:test_xor_succeeds() (gas: 123028) -MIPS_Test:test_xori_succeeds() (gas: 123080) +MIPS_Test:test_sub_succeeds() (gas: 122961) +MIPS_Test:test_subu_succeeds() (gas: 122958) +MIPS_Test:test_sw_succeeds() (gas: 161381) +MIPS_Test:test_swl_succeeds() (gas: 161442) +MIPS_Test:test_swr_succeeds() (gas: 161517) +MIPS_Test:test_xor_succeeds() (gas: 122962) +MIPS_Test:test_xori_succeeds() (gas: 123014) MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5733) MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889) MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35845) @@ -469,9 +469,9 @@ OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutp OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 182306) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41780) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 173953) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 181188) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 181161) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 154740) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 219235) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 219208) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 220983) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 38706) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 209679) From 80bbf242247ae841408070b95170338b446a1efc Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 18:17:40 +0300 Subject: [PATCH 339/374] contracts-bedrock: simplify test Simplify the `DeployerWhitelist` tests by using `Test` instead of `CommonTest`. Should slightly reduce the overhead of the tests. --- packages/contracts-bedrock/test/DeployerWhitelist.t.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/contracts-bedrock/test/DeployerWhitelist.t.sol b/packages/contracts-bedrock/test/DeployerWhitelist.t.sol index a3096fd373f8..19dc879d44a2 100644 --- a/packages/contracts-bedrock/test/DeployerWhitelist.t.sol +++ b/packages/contracts-bedrock/test/DeployerWhitelist.t.sol @@ -2,16 +2,16 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; // Target contract import { DeployerWhitelist } from "src/legacy/DeployerWhitelist.sol"; -contract DeployerWhitelist_Test is CommonTest { +contract DeployerWhitelist_Test is Test { DeployerWhitelist list; /// @dev Sets up the test suite. - function setUp() public virtual override { + function setUp() public { list = new DeployerWhitelist(); } From c9412a933c170beef69128bfb1fe4a0545f19c3b Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 18:44:02 +0300 Subject: [PATCH 340/374] contracts-bedrock: simplify rlp tests Migrates the rlp tests to use `Test` instead of `CommonTest`. This will reduce the overhead of running the test slightly. --- packages/contracts-bedrock/.gas-snapshot | 54 +++++++++---------- .../contracts-bedrock/test/RLPReader.t.sol | 6 +-- .../contracts-bedrock/test/RLPWriter.t.sol | 8 +-- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index e5bcfdc0132e..fda4b36ae2c3 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -587,44 +587,44 @@ Proxy_Test:test_upgradeToAndCall_functionDoesNotExist_reverts() (gas: 107980) Proxy_Test:test_upgradeToAndCall_isPayable_succeeds() (gas: 53744) Proxy_Test:test_upgradeToAndCall_succeeds() (gas: 125192) Proxy_Test:test_upgradeTo_clashingFunctionSignatures_succeeds() (gas: 101363) -RLPReader_readBytes_Test:test_readBytes_bytestring00_succeeds() (gas: 1863) -RLPReader_readBytes_Test:test_readBytes_bytestring01_succeeds() (gas: 1840) +RLPReader_readBytes_Test:test_readBytes_bytestring00_succeeds() (gas: 1841) +RLPReader_readBytes_Test:test_readBytes_bytestring01_succeeds() (gas: 1818) RLPReader_readBytes_Test:test_readBytes_bytestring7f_succeeds() (gas: 1861) -RLPReader_readBytes_Test:test_readBytes_invalidListLength_reverts() (gas: 3903) +RLPReader_readBytes_Test:test_readBytes_invalidListLength_reverts() (gas: 3946) RLPReader_readBytes_Test:test_readBytes_invalidPrefix_reverts() (gas: 3961) RLPReader_readBytes_Test:test_readBytes_invalidRemainder_reverts() (gas: 4155) RLPReader_readBytes_Test:test_readBytes_invalidStringLength_reverts() (gas: 3857) RLPReader_readBytes_Test:test_readBytes_revertListItem_reverts() (gas: 3998) RLPReader_readList_Test:test_readList_dictTest1_succeeds() (gas: 23140) RLPReader_readList_Test:test_readList_empty_succeeds() (gas: 4610) -RLPReader_readList_Test:test_readList_incorrectLengthInArray_reverts() (gas: 3976) +RLPReader_readList_Test:test_readList_incorrectLengthInArray_reverts() (gas: 3954) RLPReader_readList_Test:test_readList_int32Overflow2_reverts() (gas: 4139) -RLPReader_readList_Test:test_readList_int32Overflow_reverts() (gas: 4138) +RLPReader_readList_Test:test_readList_int32Overflow_reverts() (gas: 4116) RLPReader_readList_Test:test_readList_invalidRemainder_reverts() (gas: 4114) RLPReader_readList_Test:test_readList_invalidShortList_reverts() (gas: 3967) RLPReader_readList_Test:test_readList_invalidValue_reverts() (gas: 3878) RLPReader_readList_Test:test_readList_leadingZerosInLongLengthArray1_reverts() (gas: 3982) -RLPReader_readList_Test:test_readList_leadingZerosInLongLengthArray2_reverts() (gas: 3945) +RLPReader_readList_Test:test_readList_leadingZerosInLongLengthArray2_reverts() (gas: 3968) RLPReader_readList_Test:test_readList_leadingZerosInLongLengthList1_reverts() (gas: 3984) -RLPReader_readList_Test:test_readList_listLongerThan32Elements_reverts() (gas: 38612) +RLPReader_readList_Test:test_readList_listLongerThan32Elements_reverts() (gas: 38590) RLPReader_readList_Test:test_readList_listOfLists2_succeeds() (gas: 12122) -RLPReader_readList_Test:test_readList_listOfLists_succeeds() (gas: 9472) -RLPReader_readList_Test:test_readList_longList1_succeeds() (gas: 28354) -RLPReader_readList_Test:test_readList_longList2_succeeds() (gas: 196352) -RLPReader_readList_Test:test_readList_longListLessThan56Bytes_reverts() (gas: 4023) -RLPReader_readList_Test:test_readList_longStringLength_reverts() (gas: 3946) +RLPReader_readList_Test:test_readList_listOfLists_succeeds() (gas: 9450) +RLPReader_readList_Test:test_readList_longList1_succeeds() (gas: 28332) +RLPReader_readList_Test:test_readList_longList2_succeeds() (gas: 196395) +RLPReader_readList_Test:test_readList_longListLessThan56Bytes_reverts() (gas: 4046) +RLPReader_readList_Test:test_readList_longStringLength_reverts() (gas: 3924) RLPReader_readList_Test:test_readList_longStringLessThan56Bytes_reverts() (gas: 4009) -RLPReader_readList_Test:test_readList_multiList_succeeds() (gas: 11695) +RLPReader_readList_Test:test_readList_multiList_succeeds() (gas: 11737) RLPReader_readList_Test:test_readList_nonOptimalLongLengthArray1_reverts() (gas: 3999) -RLPReader_readList_Test:test_readList_nonOptimalLongLengthArray2_reverts() (gas: 4044) +RLPReader_readList_Test:test_readList_nonOptimalLongLengthArray2_reverts() (gas: 4022) RLPReader_readList_Test:test_readList_notEnoughContentForList1_reverts() (gas: 4115) -RLPReader_readList_Test:test_readList_notEnoughContentForList2_reverts() (gas: 4117) +RLPReader_readList_Test:test_readList_notEnoughContentForList2_reverts() (gas: 4161) RLPReader_readList_Test:test_readList_notEnoughContentForString1_reverts() (gas: 4072) -RLPReader_readList_Test:test_readList_notEnoughContentForString2_reverts() (gas: 4094) +RLPReader_readList_Test:test_readList_notEnoughContentForString2_reverts() (gas: 4138) RLPReader_readList_Test:test_readList_notLongEnough_reverts() (gas: 3955) -RLPReader_readList_Test:test_readList_shortListMax1_succeeds() (gas: 39602) +RLPReader_readList_Test:test_readList_shortListMax1_succeeds() (gas: 39580) RLPWriter_writeList_Test:test_writeList_dictTest1_succeeds() (gas: 36979) -RLPWriter_writeList_Test:test_writeList_empty_succeeds() (gas: 1711) +RLPWriter_writeList_Test:test_writeList_empty_succeeds() (gas: 1666) RLPWriter_writeList_Test:test_writeList_listoflists2_succeeds() (gas: 16566) RLPWriter_writeList_Test:test_writeList_listoflists_succeeds() (gas: 10841) RLPWriter_writeList_Test:test_writeList_longlist1_succeeds() (gas: 40383) @@ -632,22 +632,22 @@ RLPWriter_writeList_Test:test_writeList_longlist2_succeeds() (gas: 280754) RLPWriter_writeList_Test:test_writeList_multiList_succeeds() (gas: 22446) RLPWriter_writeList_Test:test_writeList_shortListMax1_succeeds() (gas: 36793) RLPWriter_writeList_Test:test_writeList_stringList_succeeds() (gas: 10697) -RLPWriter_writeString_Test:test_writeString_bytestring00_succeeds() (gas: 951) -RLPWriter_writeString_Test:test_writeString_bytestring01_succeeds() (gas: 951) +RLPWriter_writeString_Test:test_writeString_bytestring00_succeeds() (gas: 929) +RLPWriter_writeString_Test:test_writeString_bytestring01_succeeds() (gas: 906) RLPWriter_writeString_Test:test_writeString_bytestring7f_succeeds() (gas: 972) -RLPWriter_writeString_Test:test_writeString_empty_succeeds() (gas: 1633) +RLPWriter_writeString_Test:test_writeString_empty_succeeds() (gas: 1611) RLPWriter_writeString_Test:test_writeString_longstring2_succeeds() (gas: 258768) -RLPWriter_writeString_Test:test_writeString_longstring_succeeds() (gas: 16961) +RLPWriter_writeString_Test:test_writeString_longstring_succeeds() (gas: 16939) RLPWriter_writeString_Test:test_writeString_shortstring2_succeeds() (gas: 15376) RLPWriter_writeString_Test:test_writeString_shortstring_succeeds() (gas: 2470) -RLPWriter_writeUint_Test:test_writeUint_mediumint2_succeeds() (gas: 8721) +RLPWriter_writeUint_Test:test_writeUint_mediumint2_succeeds() (gas: 8699) RLPWriter_writeUint_Test:test_writeUint_mediumint3_succeeds() (gas: 9098) -RLPWriter_writeUint_Test:test_writeUint_mediumint_succeeds() (gas: 8357) +RLPWriter_writeUint_Test:test_writeUint_mediumint_succeeds() (gas: 8380) RLPWriter_writeUint_Test:test_writeUint_smallint2_succeeds() (gas: 7249) RLPWriter_writeUint_Test:test_writeUint_smallint3_succeeds() (gas: 7271) -RLPWriter_writeUint_Test:test_writeUint_smallint4_succeeds() (gas: 7272) -RLPWriter_writeUint_Test:test_writeUint_smallint_succeeds() (gas: 7250) -RLPWriter_writeUint_Test:test_writeUint_zero_succeeds() (gas: 7734) +RLPWriter_writeUint_Test:test_writeUint_smallint4_succeeds() (gas: 7250) +RLPWriter_writeUint_Test:test_writeUint_smallint_succeeds() (gas: 7294) +RLPWriter_writeUint_Test:test_writeUint_zero_succeeds() (gas: 7777) ResolvedDelegateProxy_Test:test_fallback_addressManagerNotSet_reverts() (gas: 605906) ResolvedDelegateProxy_Test:test_fallback_delegateCallBar_reverts() (gas: 24783) ResourceMetering_Test:test_meter_denominatorEq1_reverts() (gas: 20024064) diff --git a/packages/contracts-bedrock/test/RLPReader.t.sol b/packages/contracts-bedrock/test/RLPReader.t.sol index 17fe69c817c0..7d4cf189fbe9 100644 --- a/packages/contracts-bedrock/test/RLPReader.t.sol +++ b/packages/contracts-bedrock/test/RLPReader.t.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.15; import { stdError } from "forge-std/Test.sol"; -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; import { RLPReader } from "src/libraries/rlp/RLPReader.sol"; -contract RLPReader_readBytes_Test is CommonTest { +contract RLPReader_readBytes_Test is Test { function test_readBytes_bytestring00_succeeds() external { assertEq(RLPReader.readBytes(hex"00"), hex"00"); } @@ -44,7 +44,7 @@ contract RLPReader_readBytes_Test is CommonTest { } } -contract RLPReader_readList_Test is CommonTest { +contract RLPReader_readList_Test is Test { function test_readList_empty_succeeds() external { RLPReader.RLPItem[] memory list = RLPReader.readList(hex"c0"); assertEq(list.length, 0); diff --git a/packages/contracts-bedrock/test/RLPWriter.t.sol b/packages/contracts-bedrock/test/RLPWriter.t.sol index b1735578ad44..86faffd05fc5 100644 --- a/packages/contracts-bedrock/test/RLPWriter.t.sol +++ b/packages/contracts-bedrock/test/RLPWriter.t.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.15; import { RLPWriter } from "src/libraries/rlp/RLPWriter.sol"; -import { CommonTest } from "test/CommonTest.t.sol"; +import { Test } from "forge-std/Test.sol"; -contract RLPWriter_writeString_Test is CommonTest { +contract RLPWriter_writeString_Test is Test { function test_writeString_empty_succeeds() external { assertEq(RLPWriter.writeString(""), hex"80"); } @@ -49,7 +49,7 @@ contract RLPWriter_writeString_Test is CommonTest { } } -contract RLPWriter_writeUint_Test is CommonTest { +contract RLPWriter_writeUint_Test is Test { function test_writeUint_zero_succeeds() external { assertEq(RLPWriter.writeUint(0x0), hex"80"); } @@ -83,7 +83,7 @@ contract RLPWriter_writeUint_Test is CommonTest { } } -contract RLPWriter_writeList_Test is CommonTest { +contract RLPWriter_writeList_Test is Test { function test_writeList_empty_succeeds() external { assertEq(RLPWriter.writeList(new bytes[](0)), hex"c0"); } From 9d8678f190c33fa5c3b293ded144948194f51212 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 18:47:10 +0300 Subject: [PATCH 341/374] contracts-bedrock: 1967 helper version Use a more relaxed version for the `EIP1967Helper` contract. This will make it much more portable. Part of https://github.com/ethereum-optimism/optimism/pull/7928 --- packages/contracts-bedrock/test/mocks/EIP1967Helper.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol b/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol index ade87a814640..31002b65517a 100644 --- a/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol +++ b/packages/contracts-bedrock/test/mocks/EIP1967Helper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity ^0.8.0; import { Vm } from "forge-std/Vm.sol"; import { Constants } from "src/libraries/Constants.sol"; From 0205424f6b8c01dca1015c97677b877940699058 Mon Sep 17 00:00:00 2001 From: Will Cory Date: Mon, 30 Oct 2023 10:39:11 -0700 Subject: [PATCH 342/374] fix(fm-test-services): Use lockfile in docker test --- ufm-test-services/metamask/Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ufm-test-services/metamask/Dockerfile b/ufm-test-services/metamask/Dockerfile index 1e9631470ab0..b09e7bc3912f 100644 --- a/ufm-test-services/metamask/Dockerfile +++ b/ufm-test-services/metamask/Dockerfile @@ -7,6 +7,8 @@ WORKDIR /app # Update PATH ENV PATH /app/node_modules/.bin:$PATH +RUN npm i -g pnpm + RUN if [ "$METAMASK_PLAYWRIGHT_RUN_HEADLESS" != "false" ]; then \ apt-get update && \ apt-get install -y xvfb && \ @@ -14,8 +16,8 @@ RUN if [ "$METAMASK_PLAYWRIGHT_RUN_HEADLESS" != "false" ]; then \ fi # Copy necessary files and directories -COPY package.json /app/ -RUN npm install +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml /app/ +RUN pnpm install --frozen-lockfile COPY tests /app/tests/ COPY playwright.config.ts /app/ COPY start.sh /app/ From 6441c445f0df0a6cfea31a87acc387c125b1f52c Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 18:51:13 +0300 Subject: [PATCH 343/374] contracts-bedrock: simplify CrossDomainOwnable test Removes usage of `CommonTest` that are not required. Also canonicalize the import paths. This should help to speed up the tests slightly by reducing the amount of execution required to run the tests. --- packages/contracts-bedrock/test/CrossDomainOwnable.t.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol index 27c8757066f7..a539bbd91004 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol @@ -2,17 +2,18 @@ pragma solidity 0.8.15; // Testing utilities -import { Vm, VmSafe } from "forge-std/Vm.sol"; +import { VmSafe } from "forge-std/Vm.sol"; +import { Test } from "forge-std/Test.sol"; import { CommonTest, Portal_Initializer } from "test/CommonTest.t.sol"; // Libraries import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; // Target contract dependencies -import { AddressAliasHelper } from "../src/vendor/AddressAliasHelper.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; // Target contract -import { CrossDomainOwnable } from "../src/L2/CrossDomainOwnable.sol"; +import { CrossDomainOwnable } from "src/L2/CrossDomainOwnable.sol"; contract XDomainSetter is CrossDomainOwnable { uint256 public value; @@ -22,7 +23,7 @@ contract XDomainSetter is CrossDomainOwnable { } } -contract CrossDomainOwnable_Test is CommonTest { +contract CrossDomainOwnable_Test is Test { XDomainSetter setter; function setUp() public override { From 52ab3673602ab34d4966fea35bab148f1953f13b Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 18:57:09 +0300 Subject: [PATCH 344/374] contracts-bedrock: fix --- packages/contracts-bedrock/test/CrossDomainOwnable.t.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol index a539bbd91004..63f09d552d5c 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol @@ -26,8 +26,7 @@ contract XDomainSetter is CrossDomainOwnable { contract CrossDomainOwnable_Test is Test { XDomainSetter setter; - function setUp() public override { - super.setUp(); + function setUp() public { setter = new XDomainSetter(); } From ec7b2cff9b0e112c795669c89458420453964c6f Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 20:22:01 +0300 Subject: [PATCH 345/374] contracts-bedrock: cleanup --- packages/contracts-bedrock/test/CrossDomainOwnable.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol index 63f09d552d5c..34330b23542c 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; // Testing utilities import { VmSafe } from "forge-std/Vm.sol"; import { Test } from "forge-std/Test.sol"; -import { CommonTest, Portal_Initializer } from "test/CommonTest.t.sol"; +import { Portal_Initializer } from "test/CommonTest.t.sol"; // Libraries import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; From d911a8c4929131d7d4e71b8f1fd1a63da8ceed83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 20:49:01 +0000 Subject: [PATCH 346/374] build(deps): bump viem from 1.18.3 to 1.18.4 Bumps [viem](https://github.com/wagmi-dev/viem) from 1.18.3 to 1.18.4. - [Release notes](https://github.com/wagmi-dev/viem/releases) - [Commits](https://github.com/wagmi-dev/viem/compare/viem@1.18.3...viem@1.18.4) --- updated-dependencies: - dependency-name: viem dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/contracts-ts/package.json | 2 +- packages/fee-estimation/package.json | 2 +- packages/sdk/package.json | 2 +- packages/web3js-plugin/package.json | 2 +- pnpm-lock.yaml | 62 ++++++++++++++-------------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/contracts-ts/package.json b/packages/contracts-ts/package.json index 9b6dfc3db99a..0873431b421d 100644 --- a/packages/contracts-ts/package.json +++ b/packages/contracts-ts/package.json @@ -82,6 +82,6 @@ "change-case": "4.1.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "viem": "^1.18.3" + "viem": "^1.18.4" } } diff --git a/packages/fee-estimation/package.json b/packages/fee-estimation/package.json index e145df500d85..25d229db84a6 100644 --- a/packages/fee-estimation/package.json +++ b/packages/fee-estimation/package.json @@ -44,7 +44,7 @@ "jsdom": "^22.1.0", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.18.3", + "viem": "^1.18.4", "vite": "^4.5.0", "vitest": "^0.34.2" }, diff --git a/packages/sdk/package.json b/packages/sdk/package.json index ef3575524f24..b1cd2122d1ce 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -56,7 +56,7 @@ "ts-node": "^10.9.1", "typedoc": "^0.25.3", "typescript": "^5.2.2", - "viem": "^1.18.3", + "viem": "^1.18.4", "vitest": "^0.34.2", "zod": "^3.22.4" }, diff --git a/packages/web3js-plugin/package.json b/packages/web3js-plugin/package.json index 1a7c950131e0..5743c09969ab 100644 --- a/packages/web3js-plugin/package.json +++ b/packages/web3js-plugin/package.json @@ -37,7 +37,7 @@ "@vitest/coverage-istanbul": "^0.34.6", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.18.3", + "viem": "^1.18.4", "vite": "^4.5.0", "vitest": "^0.34.1", "zod": "^3.22.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 06a3c535ec36..d0895ffb6807 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -298,11 +298,11 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) viem: - specifier: ^1.18.3 - version: 1.18.3(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.4 + version: 1.18.4(typescript@5.2.2)(zod@3.22.4) wagmi: specifier: '>1.0.0' - version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) + version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) devDependencies: '@eth-optimism/contracts-bedrock': specifier: workspace:* @@ -324,7 +324,7 @@ importers: version: 1.5.2(@wagmi/core@1.4.5)(typescript@5.2.2)(wagmi@1.0.1) '@wagmi/core': specifier: ^1.4.5 - version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) + version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) abitype: specifier: ^0.10.2 version: 0.10.2(typescript@5.2.2) @@ -438,8 +438,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.3 - version: 1.18.3(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.4 + version: 1.18.4(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -529,8 +529,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.3 - version: 1.18.3(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.4 + version: 1.18.4(typescript@5.2.2)(zod@3.22.4) vitest: specifier: ^0.34.2 version: 0.34.2 @@ -569,8 +569,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.3 - version: 1.18.3(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.4 + version: 1.18.4(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -3197,7 +3197,7 @@ packages: resolution: {integrity: sha512-gYw0ki/EAuV1oSyMxpqandHjnthZjYYy+YWpTAzf8BqfXM3ItcZLpjxfg+3+mXW8HIO+3jw6T9iiqEXsqHaMMw==} dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.7.3 - viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - bufferutil - encoding @@ -4562,7 +4562,7 @@ packages: wagmi: optional: true dependencies: - '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) + '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) abort-controller: 3.0.0 bundle-require: 3.1.2(esbuild@0.16.17) @@ -4584,15 +4584,15 @@ packages: picocolors: 1.0.0 prettier: 2.8.8 typescript: 5.2.2 - viem: 1.18.3(typescript@5.2.2)(zod@3.22.3) - wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) + viem: 1.18.4(typescript@5.2.2)(zod@3.22.3) + wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) zod: 3.22.3 transitivePeerDependencies: - bufferutil - utf-8-validate dev: true - /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.3): + /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4): resolution: {integrity: sha512-fl01vym19DE1uoE+MlASw5zo3Orr/YXlJRjOKLaKYtV+Q7jOLY4TwHgq7sEMs+JYOvFICFBEAlWNNxidr51AqQ==} peerDependencies: '@wagmi/chains': '>=0.2.0' @@ -4615,7 +4615,7 @@ packages: abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil @@ -4627,7 +4627,7 @@ packages: - utf-8-validate - zod - /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.3): + /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.4): resolution: {integrity: sha512-UgwsQKQDFObJVJMf9pDfFoXTv710o4zrTHyhIWKBTMMkLpCMsMxN5+ZaDhBYt/BgoRinfRYQo8uwuwLhxE6Log==} peerDependencies: typescript: '>=5.0.4' @@ -4647,7 +4647,7 @@ packages: abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - '@types/react' @@ -4660,7 +4660,7 @@ packages: - zod dev: true - /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.3): + /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.4): resolution: {integrity: sha512-Zzg4Ob92QMF9NsC+z5/8JZjMn3NCCnwVWGJlv79qRX9mp5Ku40OzJNvqDnjcSGjshe6H0L/KtFZAqTlmu8lT7w==} peerDependencies: typescript: '>=4.9.4' @@ -4670,11 +4670,11 @@ packages: optional: true dependencies: '@wagmi/chains': 0.2.22(typescript@5.2.2) - '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) + '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -4688,7 +4688,7 @@ packages: - utf-8-validate - zod - /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.3): + /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.4): resolution: {integrity: sha512-N9luRb1Uk4tBN9kaYcQSWKE9AsRt/rvZaFt5IZech4JPzNN2sQlfhKd9GEjOXYRDqEPHdDvos7qyBKiDNTz4GA==} peerDependencies: typescript: '>=5.0.4' @@ -4697,11 +4697,11 @@ packages: typescript: optional: true dependencies: - '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) + '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -14292,8 +14292,8 @@ packages: vfile-message: 2.0.4 dev: true - /viem@1.18.3(typescript@5.2.2)(zod@3.22.3): - resolution: {integrity: sha512-r27eb39MHEXul/k2jZnRVNJY8QhoS816Kqh0guaLVLRJkGGIutryh7z5sKIuhKHU1yz2+CoPaiRn08gGKrfskw==} + /viem@1.18.4(typescript@5.2.2)(zod@3.22.3): + resolution: {integrity: sha512-im+y30k+IGT6VtfD/q1V0RX5PaiHPsFTHkKqvTjTqV+ZT8RgJXzOGPXr5E0uPIm2cbJAJp6A9nR9BCHY7BKR2Q==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14315,8 +14315,8 @@ packages: - zod dev: true - /viem@1.18.3(typescript@5.2.2)(zod@3.22.4): - resolution: {integrity: sha512-r27eb39MHEXul/k2jZnRVNJY8QhoS816Kqh0guaLVLRJkGGIutryh7z5sKIuhKHU1yz2+CoPaiRn08gGKrfskw==} + /viem@1.18.4(typescript@5.2.2)(zod@3.22.4): + resolution: {integrity: sha512-im+y30k+IGT6VtfD/q1V0RX5PaiHPsFTHkKqvTjTqV+ZT8RgJXzOGPXr5E0uPIm2cbJAJp6A9nR9BCHY7BKR2Q==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14809,7 +14809,7 @@ packages: xml-name-validator: 4.0.0 dev: true - /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.3): + /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4): resolution: {integrity: sha512-+2UkZG9eA3tKqXj1wvlvI8mL0Bcff7Tf5CKfUOyQsdKcY+J5rfwYYya25G+jja57umpHFtfxRaL7xDkNjehrRg==} peerDependencies: react: '>=17.0.0' @@ -14822,12 +14822,12 @@ packages: '@tanstack/query-sync-storage-persister': 4.29.25 '@tanstack/react-query': 4.29.25(react-dom@18.2.0)(react@18.2.0) '@tanstack/react-query-persist-client': 4.29.25(@tanstack/react-query@4.29.25) - '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.3) + '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) abitype: 0.8.1(typescript@5.2.2) react: 18.2.0 typescript: 5.2.2 use-sync-external-store: 1.2.0(react@18.2.0) - viem: 1.18.3(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil From 126e8adc6ba30359bb4228ed526cd8582e97ea1f Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 6 Nov 2023 10:15:47 +1000 Subject: [PATCH 347/374] op-challenger: Remove AbsolutePreState from TraceProvider Nothing actually uses it - only AbsolutePreStateCommitment so we can narrow the interface. --- .../game/fault/trace/alphabet/provider.go | 20 ++++--------------- .../game/fault/trace/cannon/provider.go | 6 +++--- .../game/fault/trace/cannon/provider_test.go | 12 ++++++----- .../game/fault/trace/split/provider.go | 5 ----- .../game/fault/trace/split/provider_test.go | 18 ----------------- op-challenger/game/fault/types/types.go | 3 --- 6 files changed, 14 insertions(+), 50 deletions(-) diff --git a/op-challenger/game/fault/trace/alphabet/provider.go b/op-challenger/game/fault/trace/alphabet/provider.go index 929764250736..ac64a6da6639 100644 --- a/op-challenger/game/fault/trace/alphabet/provider.go +++ b/op-challenger/game/fault/trace/alphabet/provider.go @@ -14,6 +14,7 @@ import ( var ( ErrIndexTooLarge = errors.New("index is larger than the maximum index") + absolutePrestate = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000060") ) // AlphabetTraceProvider is a [TraceProvider] that provides claims for specific @@ -36,11 +37,7 @@ func NewTraceProvider(state string, depth uint64) *AlphabetTraceProvider { func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, i types.Position) ([]byte, []byte, *types.PreimageOracleData, error) { traceIndex := i.TraceIndex(int(ap.depth)) if traceIndex.Cmp(common.Big0) == 0 { - prestate, err := ap.AbsolutePreState(ctx) - if err != nil { - return nil, nil, nil, err - } - return prestate, []byte{}, nil, nil + return absolutePrestate, []byte{}, nil, nil } // We want the pre-state which is the value prior to the one requested traceIndex = traceIndex.Sub(traceIndex, big.NewInt(1)) @@ -67,17 +64,8 @@ func (ap *AlphabetTraceProvider) Get(ctx context.Context, i types.Position) (com return alphabetStateHash(claimBytes), nil } -// AbsolutePreState returns the absolute pre-state for the alphabet trace. -func (ap *AlphabetTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, error) { - return common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000060"), nil -} - -func (ap *AlphabetTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (common.Hash, error) { - prestate, err := ap.AbsolutePreState(ctx) - if err != nil { - return common.Hash{}, err - } - hash := common.BytesToHash(crypto.Keccak256(prestate)) +func (ap *AlphabetTraceProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { + hash := common.BytesToHash(crypto.Keccak256(absolutePrestate)) hash[0] = mipsevm.VMStatusUnfinished return hash, nil } diff --git a/op-challenger/game/fault/trace/cannon/provider.go b/op-challenger/game/fault/trace/cannon/provider.go index 1a2832baf020..c2c7e9c4b0a6 100644 --- a/op-challenger/game/fault/trace/cannon/provider.go +++ b/op-challenger/game/fault/trace/cannon/provider.go @@ -129,7 +129,7 @@ func (p *CannonTraceProvider) GetStepData(ctx context.Context, pos types.Positio return value, data, oracleData, nil } -func (p *CannonTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, error) { +func (p *CannonTraceProvider) absolutePreState() ([]byte, error) { state, err := parseState(p.prestate) if err != nil { return nil, fmt.Errorf("cannot load absolute pre-state: %w", err) @@ -137,8 +137,8 @@ func (p *CannonTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, err return state.EncodeWitness(), nil } -func (p *CannonTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (common.Hash, error) { - state, err := p.AbsolutePreState(ctx) +func (p *CannonTraceProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { + state, err := p.absolutePreState() if err != nil { return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) } diff --git a/op-challenger/game/fault/trace/cannon/provider_test.go b/op-challenger/game/fault/trace/cannon/provider_test.go index 30f926bf0ca3..fdf969345e29 100644 --- a/op-challenger/game/fault/trace/cannon/provider_test.go +++ b/op-challenger/game/fault/trace/cannon/provider_test.go @@ -216,28 +216,28 @@ func TestGetStepData(t *testing.T) { }) } -func TestAbsolutePreState(t *testing.T) { +func TestAbsolutePreStateCommitment(t *testing.T) { dataDir := t.TempDir() prestate := "state.json" t.Run("StateUnavailable", func(t *testing.T) { provider, _ := setupWithTestData(t, "/dir/does/not/exist", prestate) - _, err := provider.AbsolutePreState(context.Background()) + _, err := provider.AbsolutePreStateCommitment(context.Background()) require.ErrorIs(t, err, os.ErrNotExist) }) t.Run("InvalidStateFile", func(t *testing.T) { setupPreState(t, dataDir, "invalid.json") provider, _ := setupWithTestData(t, dataDir, prestate) - _, err := provider.AbsolutePreState(context.Background()) + _, err := provider.AbsolutePreStateCommitment(context.Background()) require.ErrorContains(t, err, "invalid mipsevm state") }) t.Run("ExpectedAbsolutePreState", func(t *testing.T) { setupPreState(t, dataDir, "state.json") provider, _ := setupWithTestData(t, dataDir, prestate) - preState, err := provider.AbsolutePreState(context.Background()) + actual, err := provider.AbsolutePreStateCommitment(context.Background()) require.NoError(t, err) state := mipsevm.State{ Memory: mipsevm.NewMemory(), @@ -253,7 +253,9 @@ func TestAbsolutePreState(t *testing.T) { Step: 0, Registers: [32]uint32{}, } - require.Equal(t, []byte(state.EncodeWitness()), preState) + expected, err := state.EncodeWitness().StateHash() + require.NoError(t, err) + require.Equal(t, expected, actual) }) } diff --git a/op-challenger/game/fault/trace/split/provider.go b/op-challenger/game/fault/trace/split/provider.go index 6d61c8ab9a13..eb77f198116c 100644 --- a/op-challenger/game/fault/trace/split/provider.go +++ b/op-challenger/game/fault/trace/split/provider.go @@ -56,11 +56,6 @@ func (s *SplitTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (ha return s.bottomProvider.AbsolutePreStateCommitment(ctx) } -// AbsolutePreState routes the AbsolutePreState request to the lowest internal [types.TraceProvider]. -func (s *SplitTraceProvider) AbsolutePreState(ctx context.Context) (preimage []byte, err error) { - return s.bottomProvider.AbsolutePreState(ctx) -} - // GetStepData routes the GetStepData request to the lowest internal [types.TraceProvider]. func (s *SplitTraceProvider) GetStepData(ctx context.Context, pos types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) { ancestorDepth, provider := s.providerForDepth(uint64(pos.Depth())) diff --git a/op-challenger/game/fault/trace/split/provider_test.go b/op-challenger/game/fault/trace/split/provider_test.go index 2845bfc66cb4..b63ab6d93349 100644 --- a/op-challenger/game/fault/trace/split/provider_test.go +++ b/op-challenger/game/fault/trace/split/provider_test.go @@ -64,24 +64,6 @@ func TestAbsolutePreStateCommitment(t *testing.T) { }) } -func TestAbsolutePreState(t *testing.T) { - t.Run("ErrorBubblesUp", func(t *testing.T) { - mockOutputProvider := mockTraceProvider{absolutePreStateError: mockGetError} - splitProvider := newSplitTraceProvider(t, nil, &mockOutputProvider, 40) - _, err := splitProvider.AbsolutePreState(context.Background()) - require.ErrorIs(t, err, mockGetError) - }) - - t.Run("ReturnsCorrectPreimageData", func(t *testing.T) { - expectedPreimage := []byte{1, 2, 3, 4} - mockOutputProvider := mockTraceProvider{preImageData: expectedPreimage} - splitProvider := newSplitTraceProvider(t, nil, &mockOutputProvider, 40) - output, err := splitProvider.AbsolutePreState(context.Background()) - require.NoError(t, err) - require.Equal(t, expectedPreimage, output) - }) -} - func TestGetStepData(t *testing.T) { t.Run("ErrorBubblesUp", func(t *testing.T) { mockOutputProvider := mockTraceProvider{getStepDataError: mockGetError} diff --git a/op-challenger/game/fault/types/types.go b/op-challenger/game/fault/types/types.go index 68497a377e66..12eb5c416300 100644 --- a/op-challenger/game/fault/types/types.go +++ b/op-challenger/game/fault/types/types.go @@ -69,9 +69,6 @@ type TraceProvider interface { // The prestate returned from GetStepData for trace 10 should be the pre-image of the claim from trace 9 GetStepData(ctx context.Context, i Position) (prestate []byte, proofData []byte, preimageData *PreimageOracleData, err error) - // AbsolutePreState is the pre-image value of the trace that transitions to the trace value at index 0 - AbsolutePreState(ctx context.Context) (preimage []byte, err error) - // AbsolutePreStateCommitment is the commitment of the pre-image value of the trace that transitions to the trace value at index 0 AbsolutePreStateCommitment(ctx context.Context) (hash common.Hash, err error) } From fe5f61e921224ad7f9b3a137ec9f9be629408787 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Mon, 6 Nov 2023 12:00:58 +1000 Subject: [PATCH 348/374] op-challenger: Remove claim loader It was only used in an unused e2e helper method. --- op-challenger/game/fault/loader.go | 141 ----------- op-challenger/game/fault/loader_test.go | 266 --------------------- op-e2e/e2eutils/disputegame/game_helper.go | 20 -- 3 files changed, 427 deletions(-) delete mode 100644 op-challenger/game/fault/loader.go delete mode 100644 op-challenger/game/fault/loader_test.go diff --git a/op-challenger/game/fault/loader.go b/op-challenger/game/fault/loader.go deleted file mode 100644 index 55bfbae90b5f..000000000000 --- a/op-challenger/game/fault/loader.go +++ /dev/null @@ -1,141 +0,0 @@ -package fault - -import ( - "context" - "math/big" - - "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" -) - -// MinimalFaultDisputeGameCaller is a minimal interface around [bindings.FaultDisputeGameCaller]. -// This needs to be updated if the [bindings.FaultDisputeGameCaller] interface changes. -type MinimalFaultDisputeGameCaller interface { - ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int - }, error) - Status(opts *bind.CallOpts) (uint8, error) - ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) - MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error) - ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) -} - -// loader pulls in fault dispute game claim data periodically and over subscriptions. -type loader struct { - caller MinimalFaultDisputeGameCaller -} - -// NewLoader creates a new [loader]. -func NewLoader(caller MinimalFaultDisputeGameCaller) *loader { - return &loader{ - caller: caller, - } -} - -// NewLoaderFromBindings creates a new [loader] from a [bindings.FaultDisputeGameCaller]. -func NewLoaderFromBindings(fdgAddr common.Address, client bind.ContractCaller) (*loader, error) { - caller, err := bindings.NewFaultDisputeGameCaller(fdgAddr, client) - if err != nil { - return nil, err - } - return NewLoader(caller), nil -} - -// GetGameStatus returns the current game status. -func (l *loader) GetGameStatus(ctx context.Context) (gameTypes.GameStatus, error) { - status, err := l.caller.Status(&bind.CallOpts{Context: ctx}) - return gameTypes.GameStatus(status), err -} - -// GetClaimCount returns the number of claims in the game. -func (l *loader) GetClaimCount(ctx context.Context) (uint64, error) { - count, err := l.caller.ClaimDataLen(&bind.CallOpts{Context: ctx}) - if err != nil { - return 0, err - } - return count.Uint64(), nil -} - -// FetchGameDepth fetches the game depth from the fault dispute game. -func (l *loader) FetchGameDepth(ctx context.Context) (uint64, error) { - callOpts := bind.CallOpts{ - Context: ctx, - } - - gameDepth, err := l.caller.MAXGAMEDEPTH(&callOpts) - if err != nil { - return 0, err - } - - return gameDepth.Uint64(), nil -} - -// fetchClaim fetches a single [Claim] with a hydrated parent. -func (l *loader) fetchClaim(ctx context.Context, arrIndex uint64) (types.Claim, error) { - callOpts := bind.CallOpts{ - Context: ctx, - } - - fetchedClaim, err := l.caller.ClaimData(&callOpts, new(big.Int).SetUint64(arrIndex)) - if err != nil { - return types.Claim{}, err - } - - claim := types.Claim{ - ClaimData: types.ClaimData{ - Value: fetchedClaim.Claim, - Position: types.NewPositionFromGIndex(fetchedClaim.Position), - }, - Countered: fetchedClaim.Countered, - Clock: fetchedClaim.Clock.Uint64(), - ContractIndex: int(arrIndex), - ParentContractIndex: int(fetchedClaim.ParentIndex), - } - - return claim, nil -} - -// FetchClaims fetches all claims from the fault dispute game. -func (l *loader) FetchClaims(ctx context.Context) ([]types.Claim, error) { - // Get the current claim count. - claimCount, err := l.caller.ClaimDataLen(&bind.CallOpts{ - Context: ctx, - }) - if err != nil { - return nil, err - } - - // Fetch each claim and build a list. - claimList := make([]types.Claim, claimCount.Uint64()) - for i := uint64(0); i < claimCount.Uint64(); i++ { - claim, err := l.fetchClaim(ctx, i) - if err != nil { - return nil, err - } - claimList[i] = claim - } - - return claimList, nil -} - -// FetchAbsolutePrestateHash fetches the hashed absolute prestate from the fault dispute game. -func (l *loader) FetchAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { - callOpts := bind.CallOpts{ - Context: ctx, - } - - absolutePrestate, err := l.caller.ABSOLUTEPRESTATE(&callOpts) - if err != nil { - return common.Hash{}, err - } - - return absolutePrestate, nil -} diff --git a/op-challenger/game/fault/loader_test.go b/op-challenger/game/fault/loader_test.go deleted file mode 100644 index 886076373432..000000000000 --- a/op-challenger/game/fault/loader_test.go +++ /dev/null @@ -1,266 +0,0 @@ -package fault - -import ( - "context" - "fmt" - "math/big" - "testing" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" -) - -var ( - mockClaimDataError = fmt.Errorf("claim data errored") - mockClaimLenError = fmt.Errorf("claim len errored") - mockMaxGameDepthError = fmt.Errorf("max game depth errored") - mockPrestateError = fmt.Errorf("prestate errored") - mockStatusError = fmt.Errorf("status errored") -) - -// TestLoader_GetGameStatus tests fetching the game status. -func TestLoader_GetGameStatus(t *testing.T) { - tests := []struct { - name string - status uint8 - expectedError bool - }{ - { - name: "challenger won status", - status: uint8(gameTypes.GameStatusChallengerWon), - }, - { - name: "defender won status", - status: uint8(gameTypes.GameStatusDefenderWon), - }, - { - name: "in progress status", - status: uint8(gameTypes.GameStatusInProgress), - }, - { - name: "error bubbled up", - expectedError: true, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.status = test.status - mockCaller.statusError = test.expectedError - loader := NewLoader(mockCaller) - status, err := loader.GetGameStatus(context.Background()) - if test.expectedError { - require.ErrorIs(t, err, mockStatusError) - } else { - require.NoError(t, err) - require.Equal(t, gameTypes.GameStatus(test.status), status) - } - }) - } -} - -// TestLoader_FetchGameDepth tests fetching the game depth. -func TestLoader_FetchGameDepth(t *testing.T) { - t.Run("Succeeds", func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.maxGameDepth = 10 - loader := NewLoader(mockCaller) - depth, err := loader.FetchGameDepth(context.Background()) - require.NoError(t, err) - require.Equal(t, uint64(10), depth) - }) - - t.Run("Errors", func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.maxGameDepthError = true - loader := NewLoader(mockCaller) - depth, err := loader.FetchGameDepth(context.Background()) - require.ErrorIs(t, mockMaxGameDepthError, err) - require.Equal(t, depth, uint64(0)) - }) -} - -// TestLoader_FetchAbsolutePrestateHash tests fetching the absolute prestate hash. -func TestLoader_FetchAbsolutePrestateHash(t *testing.T) { - t.Run("Succeeds", func(t *testing.T) { - mockCaller := newMockCaller() - loader := NewLoader(mockCaller) - prestate, err := loader.FetchAbsolutePrestateHash(context.Background()) - require.NoError(t, err) - require.ElementsMatch(t, common.HexToHash("0xdEad"), prestate) - }) - - t.Run("Errors", func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.prestateError = true - loader := NewLoader(mockCaller) - prestate, err := loader.FetchAbsolutePrestateHash(context.Background()) - require.Error(t, err) - require.ElementsMatch(t, common.Hash{}, prestate) - }) -} - -// TestLoader_FetchClaims tests fetching claims. -func TestLoader_FetchClaims(t *testing.T) { - t.Run("Succeeds", func(t *testing.T) { - mockCaller := newMockCaller() - expectedClaims := mockCaller.returnClaims - loader := NewLoader(mockCaller) - claims, err := loader.FetchClaims(context.Background()) - require.NoError(t, err) - require.ElementsMatch(t, []types.Claim{ - { - ClaimData: types.ClaimData{ - Value: expectedClaims[0].Claim, - Position: types.NewPositionFromGIndex(expectedClaims[0].Position), - }, - Countered: false, - Clock: uint64(0), - ContractIndex: 0, - }, - { - ClaimData: types.ClaimData{ - Value: expectedClaims[1].Claim, - Position: types.NewPositionFromGIndex(expectedClaims[1].Position), - }, - Countered: false, - Clock: uint64(0), - ContractIndex: 1, - ParentContractIndex: 0, - }, - { - ClaimData: types.ClaimData{ - Value: expectedClaims[2].Claim, - Position: types.NewPositionFromGIndex(expectedClaims[2].Position), - }, - Countered: false, - Clock: uint64(0), - ContractIndex: 2, - ParentContractIndex: 1, - }, - }, claims) - }) - - t.Run("Claim Data Errors", func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.claimDataError = true - loader := NewLoader(mockCaller) - claims, err := loader.FetchClaims(context.Background()) - require.ErrorIs(t, err, mockClaimDataError) - require.Empty(t, claims) - }) - - t.Run("Claim Len Errors", func(t *testing.T) { - mockCaller := newMockCaller() - mockCaller.claimLenError = true - loader := NewLoader(mockCaller) - claims, err := loader.FetchClaims(context.Background()) - require.ErrorIs(t, err, mockClaimLenError) - require.Empty(t, claims) - }) -} - -type mockCaller struct { - claimDataError bool - claimLenError bool - maxGameDepthError bool - prestateError bool - statusError bool - maxGameDepth uint64 - currentIndex uint64 - status uint8 - returnClaims []struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int - } -} - -func newMockCaller() *mockCaller { - return &mockCaller{ - returnClaims: []struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int - }{ - { - Claim: [32]byte{0x00}, - Position: big.NewInt(1), - Countered: false, - Clock: big.NewInt(0), - }, - { - Claim: [32]byte{0x01}, - Position: big.NewInt(2), - Countered: false, - Clock: big.NewInt(0), - ParentIndex: 0, - }, - { - Claim: [32]byte{0x02}, - Position: big.NewInt(3), - Countered: false, - Clock: big.NewInt(0), - ParentIndex: 1, - }, - }, - } -} - -func (m *mockCaller) ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int -}, error) { - if m.claimDataError { - return struct { - ParentIndex uint32 - Countered bool - Claim [32]byte - Position *big.Int - Clock *big.Int - }{}, mockClaimDataError - } - returnClaim := m.returnClaims[arg0.Uint64()] - m.currentIndex++ - return returnClaim, nil -} - -func (m *mockCaller) Status(opts *bind.CallOpts) (uint8, error) { - if m.statusError { - return 0, mockStatusError - } - return m.status, nil -} - -func (m *mockCaller) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) { - if m.claimLenError { - return big.NewInt(0), mockClaimLenError - } - return big.NewInt(int64(len(m.returnClaims))), nil -} - -func (m *mockCaller) MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error) { - if m.maxGameDepthError { - return nil, mockMaxGameDepthError - } - return big.NewInt(int64(m.maxGameDepth)), nil -} - -func (m *mockCaller) ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) { - if m.prestateError { - return [32]byte{}, mockPrestateError - } - return common.HexToHash("0xdEad"), nil -} diff --git a/op-e2e/e2eutils/disputegame/game_helper.go b/op-e2e/e2eutils/disputegame/game_helper.go index 6ce31f2f9c76..5e8a1fcb1a00 100644 --- a/op-e2e/e2eutils/disputegame/game_helper.go +++ b/op-e2e/e2eutils/disputegame/game_helper.go @@ -8,7 +8,6 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-bindings/bindings" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -356,25 +355,6 @@ func (g *FaultGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) { g.require.NoError(err, "ResolveClaim transaction was not OK") } -// ResolveAllClaims resolves all subgames -// This function does not resolve the game. That's the responsibility of challengers -func (g *FaultGameHelper) ResolveAllClaims(ctx context.Context) { - loader := fault.NewLoader(g.game) - claims, err := loader.FetchClaims(ctx) - g.require.NoError(err, "Failed to fetch claims") - subgames := make(map[int]bool) - for i := len(claims) - 1; i > 0; i-- { - subgames[claims[i].ParentContractIndex] = true - // Subgames containing only one node are implicitly resolved - // i.e. uncountered and claims at MAX_DEPTH - if !subgames[i] { - continue - } - g.ResolveClaim(ctx, int64(i)) - } - g.ResolveClaim(ctx, 0) -} - func (g *FaultGameHelper) gameData(ctx context.Context) string { opts := &bind.CallOpts{Context: ctx} maxDepth := int(g.MaxDepth(ctx)) From 4cddf82caab7579d5c96132da922bb83ebd755ea Mon Sep 17 00:00:00 2001 From: Tei Im Date: Mon, 6 Nov 2023 11:15:03 +0900 Subject: [PATCH 349/374] Parameterize span batch related test cases --- op-e2e/actions/blocktime_test.go | 36 +++++++++++++++-- op-e2e/actions/l2_batcher_test.go | 58 +++++++++++++++++++++------ op-e2e/actions/l2_proposer_test.go | 28 ++++++++++++- op-e2e/actions/reorg_test.go | 59 ++++++++++++++++++++++------ op-e2e/actions/sync_test.go | 31 ++++++++++++++- op-e2e/actions/system_config_test.go | 42 +++++++++++++++++--- op-e2e/actions/user_test.go | 30 +++++++++----- op-e2e/setup.go | 2 +- op-e2e/system_fpp_test.go | 43 +++++++++++++++++--- op-e2e/system_test.go | 28 ++++++++++++- 10 files changed, 302 insertions(+), 55 deletions(-) diff --git a/op-e2e/actions/blocktime_test.go b/op-e2e/actions/blocktime_test.go index 2f3cf8d46381..440b982a72ae 100644 --- a/op-e2e/actions/blocktime_test.go +++ b/op-e2e/actions/blocktime_test.go @@ -6,20 +6,47 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-service/testlog" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" ) -// TestBatchInLastPossibleBlocks tests that the derivation pipeline +// TestBlockTimeBatchType run each blocktime-related test case in singular batch mode and span batch mode. +func TestBlockTimeBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) + }{ + {"BatchInLastPossibleBlocks", BatchInLastPossibleBlocks}, + {"LargeL1Gaps", LargeL1Gaps}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + spanBatchTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &spanBatchTimeOffset) + }) + } +} + +// BatchInLastPossibleBlocks tests that the derivation pipeline // accepts a batch that is included in the last possible L1 block // where there are also no other batches included in the sequence // window. // This is a regression test against the bug fixed in PR #4566 -func TestBatchInLastPossibleBlocks(gt *testing.T) { +func BatchInLastPossibleBlocks(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset dp.DeployConfig.SequencerWindowSize = 4 dp.DeployConfig.L2BlockTime = 2 @@ -116,7 +143,7 @@ func TestBatchInLastPossibleBlocks(gt *testing.T) { verifyChainStateOnSequencer(12, 23, 11, 17, 8) } -// TestLargeL1Gaps tests the case that there is a gap between two L1 blocks which +// LargeL1Gaps tests the case that there is a gap between two L1 blocks which // is larger than the sequencer drift. // This test has the following parameters: // L1 Block time: 4s. L2 Block time: 2s. Sequencer Drift: 32s @@ -127,13 +154,14 @@ func TestBatchInLastPossibleBlocks(gt *testing.T) { // Then it generates 3 more L1 blocks. // At this point it can verify that the batches where properly generated. // Note: It batches submits when possible. -func TestLargeL1Gaps(gt *testing.T) { +func LargeL1Gaps(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp.DeployConfig.L1BlockTime = 4 dp.DeployConfig.L2BlockTime = 2 dp.DeployConfig.SequencerWindowSize = 4 dp.DeployConfig.MaxSequencerDrift = 32 + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) diff --git a/op-e2e/actions/l2_batcher_test.go b/op-e2e/actions/l2_batcher_test.go index bc467f0f7b1d..a9ecbc322995 100644 --- a/op-e2e/actions/l2_batcher_test.go +++ b/op-e2e/actions/l2_batcher_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" @@ -20,7 +21,36 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func TestBatcher(gt *testing.T) { +// TestL2BatcherBatchType run each batcher-related test case in singular batch mode and span batch mode. +func TestL2BatcherBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) + }{ + {"NormalBatcher", NormalBatcher}, + {"L2Finalization", L2Finalization}, + {"L2FinalizationWithSparseL1", L2FinalizationWithSparseL1}, + {"GarbageBatch", GarbageBatch}, + {"ExtendedTimeWithoutL1Batches", ExtendedTimeWithoutL1Batches}, + {"BigL2Txs", BigL2Txs}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + spanBatchTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &spanBatchTimeOffset) + }) + } +} + +func NormalBatcher(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) @@ -29,6 +59,7 @@ func TestBatcher(gt *testing.T) { L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) @@ -55,7 +86,7 @@ func TestBatcher(gt *testing.T) { To: &dp.Addresses.Bob, Value: e2eutils.Ether(2), }) - require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + require.NoError(t, cl.SendTransaction(t.Ctx(), tx)) sequencer.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t) @@ -97,9 +128,10 @@ func TestBatcher(gt *testing.T) { require.NotNil(t, vTx) } -func TestL2Finalization(gt *testing.T) { +func L2Finalization(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) miner, engine, sequencer := setupSequencerTest(t, sd, log) @@ -202,10 +234,11 @@ func TestL2Finalization(gt *testing.T) { require.Equal(t, heightToSubmit, sequencer.SyncStatus().FinalizedL2.Number, "unknown/bad finalized L1 blocks are ignored") } -// TestL2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal -func TestL2FinalizationWithSparseL1(gt *testing.T) { +// L2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal +func L2FinalizationWithSparseL1(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) miner, engine, sequencer := setupSequencerTest(t, sd, log) @@ -258,13 +291,14 @@ func TestL2FinalizationWithSparseL1(gt *testing.T) { require.Equal(t, finalStatus.FinalizedL2.Number, finalStatus.UnsafeL2.Number, "sequencer submitted its L2 block and it finalized") } -// TestGarbageBatch tests the behavior of an invalid/malformed output channel frame containing +// GarbageBatch tests the behavior of an invalid/malformed output channel frame containing // valid batches being submitted to the batch inbox. These batches should always be rejected // and the safe L2 head should remain unaltered. -func TestGarbageBatch(gt *testing.T) { +func GarbageBatch(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) p := defaultRollupTestParams dp := e2eutils.MakeDeployParams(t, p) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset for _, garbageKind := range GarbageKinds { sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlError) @@ -340,7 +374,7 @@ func TestGarbageBatch(gt *testing.T) { } } -func TestExtendedTimeWithoutL1Batches(gt *testing.T) { +func ExtendedTimeWithoutL1Batches(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) @@ -349,6 +383,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) { L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlError) miner, engine, sequencer := setupSequencerTest(t, sd, log) @@ -386,7 +421,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) { require.Equal(t, sequencer.L2Unsafe(), sequencer.L2Safe(), "same for sequencer") } -// TestBigL2Txs tests a high-throughput case with constrained batcher: +// BigL2Txs tests a high-throughput case with constrained batcher: // - Fill 40 L2 blocks to near max-capacity, with txs of 120 KB each // - Buffer the L2 blocks into channels together as much as possible, submit data-txs only when necessary // (just before crossing the max RLP channel size) @@ -398,7 +433,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) { // The goal of this test is to quickly run through an otherwise very slow process of submitting and including lots of data. // This does not test the batcher code, but is really focused at testing the batcher utils // and channel-decoding verifier code in the derive package. -func TestBigL2Txs(gt *testing.T) { +func BigL2Txs(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) p := &e2eutils.TestParams{ MaxSequencerDrift: 100, @@ -407,6 +442,7 @@ func TestBigL2Txs(gt *testing.T) { L1BlockTime: 12, } dp := e2eutils.MakeDeployParams(t, p) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlInfo) miner, engine, sequencer := setupSequencerTest(t, sd, log) @@ -464,7 +500,7 @@ func TestBigL2Txs(gt *testing.T) { Value: big.NewInt(0), Data: data, }) - require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) + require.NoError(t, cl.SendTransaction(t.Ctx(), tx)) engine.ActL2IncludeTx(dp.Addresses.Alice)(t) } sequencer.ActL2EndBlock(t) diff --git a/op-e2e/actions/l2_proposer_test.go b/op-e2e/actions/l2_proposer_test.go index d16d610978ed..44654ebd9769 100644 --- a/op-e2e/actions/l2_proposer_test.go +++ b/op-e2e/actions/l2_proposer_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" @@ -14,9 +15,34 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func TestProposer(gt *testing.T) { +// TestProposerBatchType run each proposer-related test case in singular batch mode and span batch mode. +func TestProposerBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) + }{ + {"RunProposerTest", RunProposerTest}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + spanBatchTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &spanBatchTimeOffset) + }) + } +} + +func RunProposerTest(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) diff --git a/op-e2e/actions/reorg_test.go b/op-e2e/actions/reorg_test.go index a50dacc17f8e..df88568356e4 100644 --- a/op-e2e/actions/reorg_test.go +++ b/op-e2e/actions/reorg_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/log" @@ -21,8 +22,9 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -func setupReorgTest(t Testing, config *e2eutils.TestParams) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) { +func setupReorgTest(t Testing, config *e2eutils.TestParams, spanBatchTimeOffset *hexutil.Uint64) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) { dp := e2eutils.MakeDeployParams(t, config) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) @@ -44,9 +46,38 @@ func setupReorgTestActors(t Testing, dp *e2eutils.DeployParams, sd *e2eutils.Set return sd, dp, miner, sequencer, seqEngine, verifier, verifEngine, batcher } -func TestReorgOrphanBlock(gt *testing.T) { +// TestReorgBatchType run each reorg-related test case in singular batch mode and span batch mode. +func TestReorgBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) + }{ + {"ReorgOrphanBlock", ReorgOrphanBlock}, + {"ReorgFlipFlop", ReorgFlipFlop}, + {"DeepReorg", DeepReorg}, + {"RestartOpGeth", RestartOpGeth}, + {"ConflictingL2Blocks", ConflictingL2Blocks}, + {"SyncAfterReorg", SyncAfterReorg}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + spanBatchTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &spanBatchTimeOffset) + }) + } +} + +func ReorgOrphanBlock(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams) + sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams, spanBatchTimeOffset) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) sequencer.ActL2PipelineFull(t) @@ -112,9 +143,9 @@ func TestReorgOrphanBlock(gt *testing.T) { require.Equal(t, verifier.L2Safe(), sequencer.L2Safe(), "verifier and sequencer see same safe L2 block, while only verifier dealt with the orphan and replay") } -func TestReorgFlipFlop(gt *testing.T) { +func ReorgFlipFlop(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) - sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams) + sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams, spanBatchTimeOffset) minerCl := miner.L1Client(t, sd.RollupCfg) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) checkVerifEngine := func() { @@ -333,7 +364,7 @@ func TestReorgFlipFlop(gt *testing.T) { // Verifier // - Unsafe head is 62 // - Safe head is 42 -func TestDeepReorg(gt *testing.T) { +func DeepReorg(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) // Create actor and verification engine client @@ -342,7 +373,7 @@ func TestDeepReorg(gt *testing.T) { SequencerWindowSize: 20, ChannelTimeout: 120, L1BlockTime: 4, - }) + }, spanBatchTimeOffset) minerCl := miner.L1Client(t, sd.RollupCfg) l2Client := seqEngine.EthClient() verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) @@ -566,9 +597,9 @@ type rpcWrapper struct { client.RPC } -// TestRestartOpGeth tests that the sequencer can restart its execution engine without rollup-node restart, +// RestartOpGeth tests that the sequencer can restart its execution engine without rollup-node restart, // including recovering the finalized/safe state of L2 chain without reorging. -func TestRestartOpGeth(gt *testing.T) { +func RestartOpGeth(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dbPath := path.Join(t.TempDir(), "testdb") dbOption := func(_ *ethconfig.Config, nodeCfg *node.Config) error { @@ -576,6 +607,7 @@ func TestRestartOpGeth(gt *testing.T) { return nil } dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) jwtPath := e2eutils.WriteDefaultJWT(t) @@ -660,12 +692,13 @@ func TestRestartOpGeth(gt *testing.T) { require.Equal(t, statusBeforeRestart.SafeL2, sequencer.L2Safe(), "expecting the safe block to catch up to what it was before shutdown after syncing from L1, and not be stuck at the finalized block") } -// TestConflictingL2Blocks tests that a second copy of the sequencer stack cannot introduce an alternative +// ConflictingL2Blocks tests that a second copy of the sequencer stack cannot introduce an alternative // L2 block (compared to something already secured by the first sequencer): // the alt block is not synced by the verifier, in unsafe and safe sync modes. -func TestConflictingL2Blocks(gt *testing.T) { +func ConflictingL2Blocks(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) @@ -772,7 +805,7 @@ func TestConflictingL2Blocks(gt *testing.T) { require.Equal(t, sequencer.L2Unsafe(), altSequencer.L2Unsafe(), "and gets back in harmony with original sequencer") } -func TestSyncAfterReorg(gt *testing.T) { +func SyncAfterReorg(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) testingParams := e2eutils.TestParams{ MaxSequencerDrift: 60, @@ -780,7 +813,7 @@ func TestSyncAfterReorg(gt *testing.T) { ChannelTimeout: 2, L1BlockTime: 12, } - sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := setupReorgTest(t, &testingParams) + sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := setupReorgTest(t, &testingParams, spanBatchTimeOffset) l2Client := seqEngine.EthClient() log := testlog.Logger(t, log.LvlDebug) addresses := e2eutils.CollectAddresses(sd, dp) diff --git a/op-e2e/actions/sync_test.go b/op-e2e/actions/sync_test.go index 57f8564f7a98..387daf343dc8 100644 --- a/op-e2e/actions/sync_test.go +++ b/op-e2e/actions/sync_test.go @@ -23,9 +23,35 @@ import ( "github.com/stretchr/testify/require" ) -func TestDerivationWithFlakyL1RPC(gt *testing.T) { +// TestSyncBatchType run each sync test case in singular batch mode and span batch mode. +func TestSyncBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) + }{ + {"DerivationWithFlakyL1RPC", DerivationWithFlakyL1RPC}, + {"FinalizeWhileSyncing", FinalizeWhileSyncing}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + spanBatchTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &spanBatchTimeOffset) + }) + } +} + +func DerivationWithFlakyL1RPC(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) @@ -62,9 +88,10 @@ func TestDerivationWithFlakyL1RPC(gt *testing.T) { require.Equal(t, sequencer.L2Unsafe(), verifier.L2Safe(), "verifier is synced") } -func TestFinalizeWhileSyncing(gt *testing.T) { +func FinalizeWhileSyncing(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) diff --git a/op-e2e/actions/system_config_test.go b/op-e2e/actions/system_config_test.go index 59cbc57729ba..6d0e24bf6c2f 100644 --- a/op-e2e/actions/system_config_test.go +++ b/op-e2e/actions/system_config_test.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" @@ -19,13 +20,40 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -// TestBatcherKeyRotation tests that batcher A can operate, then be replaced with batcher B, then ignore old batcher A, +// TestSystemConfigBatchType run each system config-related test case in singular batch mode and span batch mode. +func TestSystemConfigBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) + }{ + {"BatcherKeyRotation", BatcherKeyRotation}, + {"GPOParamsChange", GPOParamsChange}, + {"GasLimitChange", GasLimitChange}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + spanBatchTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &spanBatchTimeOffset) + }) + } +} + +// BatcherKeyRotation tests that batcher A can operate, then be replaced with batcher B, then ignore old batcher A, // and that the change to batcher B is reverted properly upon reorg of L1. -func TestBatcherKeyRotation(gt *testing.T) { +func BatcherKeyRotation(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp.DeployConfig.L2BlockTime = 2 + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) @@ -198,11 +226,12 @@ func TestBatcherKeyRotation(gt *testing.T) { require.Equal(t, sequencer.L2Unsafe(), verifier.L2Unsafe(), "verifier synced") } -// TestGPOParamsChange tests that the GPO params can be updated to adjust fees of L2 transactions, +// GPOParamsChange tests that the GPO params can be updated to adjust fees of L2 transactions, // and that the L1 data fees to the L2 transaction are applied correctly before, during and after the GPO update in L2. -func TestGPOParamsChange(gt *testing.T) { +func GPOParamsChange(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) @@ -326,12 +355,13 @@ func TestGPOParamsChange(gt *testing.T) { require.Equal(t, "2.3", receipt.FeeScalar.String(), "2_300_000 divided by 6 decimals = float(2.3)") } -// TestGasLimitChange tests that the gas limit can be configured to L1, +// GasLimitChange tests that the gas limit can be configured to L1, // and that the L2 changes the gas limit instantly at the exact block that adopts the L1 origin with // the gas limit change event. And checks if a verifier node can reproduce the same gas limit change. -func TestGasLimitChange(gt *testing.T) { +func GasLimitChange(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) diff --git a/op-e2e/actions/user_test.go b/op-e2e/actions/user_test.go index 5e0a88eb683c..34171696f72a 100644 --- a/op-e2e/actions/user_test.go +++ b/op-e2e/actions/user_test.go @@ -13,10 +13,12 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) -type regolithScheduledTest struct { - name string - regolithTime *hexutil.Uint64 - activateRegolith bool +type hardforkScheduledTest struct { + name string + regolithTime *hexutil.Uint64 + spanBatchTime *hexutil.Uint64 + activateRegolith bool + activateSpanBatch bool } // TestCrossLayerUser tests that common actions of the CrossLayerUser actor work in various regolith configurations: @@ -31,11 +33,18 @@ func TestCrossLayerUser(t *testing.T) { zeroTime := hexutil.Uint64(0) futureTime := hexutil.Uint64(20) farFutureTime := hexutil.Uint64(2000) - tests := []regolithScheduledTest{ - {name: "NoRegolith", regolithTime: nil, activateRegolith: false}, - {name: "NotYetRegolith", regolithTime: &farFutureTime, activateRegolith: false}, - {name: "RegolithAtGenesis", regolithTime: &zeroTime, activateRegolith: true}, - {name: "RegolithAfterGenesis", regolithTime: &futureTime, activateRegolith: true}, + tests := []hardforkScheduledTest{ + {name: "NoRegolith", regolithTime: nil, activateRegolith: false, spanBatchTime: nil, activateSpanBatch: false}, + {name: "NotYetRegolith", regolithTime: &farFutureTime, activateRegolith: false, spanBatchTime: nil, activateSpanBatch: false}, + {name: "RegolithAtGenesis", regolithTime: &zeroTime, activateRegolith: true, spanBatchTime: nil, activateSpanBatch: false}, + {name: "RegolithAfterGenesis", regolithTime: &futureTime, activateRegolith: true, spanBatchTime: nil, activateSpanBatch: false}, + {name: "NoSpanBatch", regolithTime: &zeroTime, activateRegolith: true, spanBatchTime: nil, activateSpanBatch: false}, + {name: "NotYetSpanBatch", regolithTime: &zeroTime, activateRegolith: true, + spanBatchTime: &farFutureTime, activateSpanBatch: false}, + {name: "SpanBatchAtGenesis", regolithTime: &zeroTime, activateRegolith: true, + spanBatchTime: &zeroTime, activateSpanBatch: true}, + {name: "SpanBatchAfterGenesis", regolithTime: &zeroTime, activateRegolith: true, + spanBatchTime: &futureTime, activateSpanBatch: true}, } for _, test := range tests { test := test // Use a fixed reference as the tests run in parallel @@ -45,10 +54,11 @@ func TestCrossLayerUser(t *testing.T) { } } -func runCrossLayerUserTest(gt *testing.T, test regolithScheduledTest) { +func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp.DeployConfig.L2GenesisRegolithTimeOffset = test.regolithTime + dp.DeployConfig.L2GenesisSpanBatchTimeOffset = test.spanBatchTime sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LvlDebug) diff --git a/op-e2e/setup.go b/op-e2e/setup.go index ab873b1b3a7a..291c71a5b8c4 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -684,7 +684,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste } var batchType uint = derive.SingularBatchType - if os.Getenv("OP_E2E_USE_SPAN_BATCH") == "true" { + if cfg.DeployConfig.L2GenesisSpanBatchTimeOffset != nil && *cfg.DeployConfig.L2GenesisSpanBatchTimeOffset == hexutil.Uint64(0) { batchType = derive.SpanBatchType } batcherMaxL1TxSizeBytes := cfg.BatcherMaxL1TxSizeBytes diff --git a/op-e2e/system_fpp_test.go b/op-e2e/system_fpp_test.go index b4a20bc086e1..5c4d3376c040 100644 --- a/op-e2e/system_fpp_test.go +++ b/op-e2e/system_fpp_test.go @@ -15,25 +15,42 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" "github.com/stretchr/testify/require" ) func TestVerifyL2OutputRoot(t *testing.T) { - testVerifyL2OutputRoot(t, false) + testVerifyL2OutputRoot(t, false, false) +} + +func TestVerifyL2OutputRootSpanBatch(t *testing.T) { + testVerifyL2OutputRoot(t, false, true) } func TestVerifyL2OutputRootDetached(t *testing.T) { - testVerifyL2OutputRoot(t, true) + testVerifyL2OutputRoot(t, true, false) +} + +func TestVerifyL2OutputRootDetachedSpanBatch(t *testing.T) { + testVerifyL2OutputRoot(t, true, true) } func TestVerifyL2OutputRootEmptyBlock(t *testing.T) { - testVerifyL2OutputRootEmptyBlock(t, false) + testVerifyL2OutputRootEmptyBlock(t, false, false) +} + +func TestVerifyL2OutputRootEmptyBlockSpanBatch(t *testing.T) { + testVerifyL2OutputRootEmptyBlock(t, false, true) } func TestVerifyL2OutputRootEmptyBlockDetached(t *testing.T) { - testVerifyL2OutputRootEmptyBlock(t, true) + testVerifyL2OutputRootEmptyBlock(t, true, false) +} + +func TestVerifyL2OutputRootEmptyBlockDetachedSpanBatch(t *testing.T) { + testVerifyL2OutputRootEmptyBlock(t, true, true) } // TestVerifyL2OutputRootEmptyBlock asserts that the program can verify the output root of an empty block @@ -46,7 +63,7 @@ func TestVerifyL2OutputRootEmptyBlockDetached(t *testing.T) { // - reboot the batch submitter // - update the state root via a tx // - run program -func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) { +func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActivated bool) { InitParallel(t) ctx := context.Background() @@ -56,6 +73,13 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) { // Use a small sequencer window size to avoid test timeout while waiting for empty blocks // But not too small to ensure that our claim and subsequent state change is published cfg.DeployConfig.SequencerWindowSize = 16 + if spanBatchActivated { + // Activate span batch hard fork + minTs := hexutil.Uint64(0) + cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs + } else { + cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = nil + } sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") @@ -147,13 +171,20 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) { }) } -func testVerifyL2OutputRoot(t *testing.T, detached bool) { +func testVerifyL2OutputRoot(t *testing.T, detached bool, spanBatchActivated bool) { InitParallel(t) ctx := context.Background() cfg := DefaultSystemConfig(t) // We don't need a verifier - just the sequencer is enough delete(cfg.Nodes, "verifier") + if spanBatchActivated { + // Activate span batch hard fork + minTs := hexutil.Uint64(0) + cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs + } else { + cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = nil + } sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") diff --git a/op-e2e/system_test.go b/op-e2e/system_test.go index dcc4d57f0790..7c850b9d9d5f 100644 --- a/op-e2e/system_test.go +++ b/op-e2e/system_test.go @@ -45,6 +45,31 @@ import ( "github.com/ethereum-optimism/optimism/op-service/testlog" ) +// TestSystemBatchType run each system e2e test case in singular batch mode and span batch mode. +// If the test case tests batch submission and advancing safe head, it should be tested in both singular and span batch mode. +func TestSystemBatchType(t *testing.T) { + tests := []struct { + name string + f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) + }{ + {"StopStartBatcher", StopStartBatcher}, + } + for _, test := range tests { + test := test + t.Run(test.name+"_SingularBatch", func(t *testing.T) { + test.f(t, nil) + }) + } + + spanBatchTimeOffset := hexutil.Uint64(0) + for _, test := range tests { + test := test + t.Run(test.name+"_SpanBatch", func(t *testing.T) { + test.f(t, &spanBatchTimeOffset) + }) + } +} + func TestMain(m *testing.M) { if config.ExternalL2Shim != "" { fmt.Println("Running tests with external L2 process adapter at ", config.ExternalL2Shim) @@ -1222,10 +1247,11 @@ func TestFees(t *testing.T) { require.Equal(t, balanceDiff, totalFee, "balances should add up") } -func TestStopStartBatcher(t *testing.T) { +func StopStartBatcher(t *testing.T, spanBatchTimeOffset *hexutil.Uint64) { InitParallel(t) cfg := DefaultSystemConfig(t) + cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset sys, err := cfg.Start(t) require.Nil(t, err, "Error starting up system") defer sys.Close() From bc7398ca8b20e22280a1da7e87cd6b4f98a142a2 Mon Sep 17 00:00:00 2001 From: Tei Im Date: Mon, 6 Nov 2023 14:14:15 +0900 Subject: [PATCH 350/374] Remove OP_E2E_USE_SPAN_BATCH env usage --- .circleci/config.yml | 7 ------- op-e2e/Makefile | 4 ---- op-e2e/e2eutils/setup.go | 9 --------- op-e2e/setup.go | 1 - 4 files changed, 21 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9d54acd98f80..9804389292ee 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1418,13 +1418,6 @@ workflows: - op-stack-go-lint - devnet-allocs - l1-geth-version-check - - go-e2e-test: - name: op-e2e-span-batch-tests - module: op-e2e - target: test-span-batch - requires: - - op-stack-go-lint - - devnet-allocs - op-program-compat: requires: - op-program-tests diff --git a/op-e2e/Makefile b/op-e2e/Makefile index 8f53508e9ffd..1f880be22503 100644 --- a/op-e2e/Makefile +++ b/op-e2e/Makefile @@ -23,10 +23,6 @@ test-http: pre-test OP_E2E_USE_HTTP=true $(go_test) $(go_test_flags) ./... .PHONY: test-http -test-span-batch: pre-test - OP_E2E_USE_SPAN_BATCH=true $(go_test) $(go_test_flags) ./... -.PHONY: test-span-batch - cannon-prestate: make -C .. cannon-prestate .PHONY: cannon-prestate diff --git a/op-e2e/e2eutils/setup.go b/op-e2e/e2eutils/setup.go index bf6cea93e52a..050cde7983fc 100644 --- a/op-e2e/e2eutils/setup.go +++ b/op-e2e/e2eutils/setup.go @@ -59,7 +59,6 @@ func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams { deployConfig.L1BlockTime = tp.L1BlockTime deployConfig.L2GenesisRegolithTimeOffset = nil deployConfig.L2GenesisCanyonTimeOffset = CanyonTimeOffset() - deployConfig.L2GenesisSpanBatchTimeOffset = SpanBatchTimeOffset() require.NoError(t, deployConfig.Check()) require.Equal(t, addresses.Batcher, deployConfig.BatchSenderAddress) @@ -186,14 +185,6 @@ func SystemConfigFromDeployConfig(deployConfig *genesis.DeployConfig) eth.System } } -func SpanBatchTimeOffset() *hexutil.Uint64 { - if os.Getenv("OP_E2E_USE_SPAN_BATCH") == "true" { - offset := hexutil.Uint64(0) - return &offset - } - return nil -} - func CanyonTimeOffset() *hexutil.Uint64 { if os.Getenv("OP_E2E_USE_CANYON") == "true" { offset := hexutil.Uint64(0) diff --git a/op-e2e/setup.go b/op-e2e/setup.go index 291c71a5b8c4..0acd3c67b77f 100644 --- a/op-e2e/setup.go +++ b/op-e2e/setup.go @@ -88,7 +88,6 @@ func DefaultSystemConfig(t *testing.T) SystemConfig { deployConfig := config.DeployConfig.Copy() deployConfig.L1GenesisBlockTimestamp = hexutil.Uint64(time.Now().Unix()) deployConfig.L2GenesisCanyonTimeOffset = e2eutils.CanyonTimeOffset() - deployConfig.L2GenesisSpanBatchTimeOffset = e2eutils.SpanBatchTimeOffset() require.NoError(t, deployConfig.Check(), "Deploy config is invalid, do you need to run make devnet-allocs?") l1Deployments := config.L1Deployments.Copy() require.NoError(t, l1Deployments.Check()) From 09b509c839311b002fa774f1e0120119aa157d49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 07:29:05 +0000 Subject: [PATCH 351/374] build(deps): bump github.com/jackc/pgx/v5 from 5.4.3 to 5.5.0 Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.4.3 to 5.5.0. - [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md) - [Commits](https://github.com/jackc/pgx/compare/v5.4.3...v5.5.0) --- updated-dependencies: - dependency-name: github.com/jackc/pgx/v5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 3 ++- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0905c0fea4fb..585600874eca 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-ds-leveldb v0.5.0 github.com/jackc/pgtype v1.14.0 - github.com/jackc/pgx/v5 v5.4.3 + github.com/jackc/pgx/v5 v5.5.0 github.com/libp2p/go-libp2p v0.31.0 github.com/libp2p/go-libp2p-mplex v0.9.0 github.com/libp2p/go-libp2p-pubsub v0.9.3 @@ -118,6 +118,7 @@ require ( github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect diff --git a/go.sum b/go.sum index 14269d6d3ab7..c15908abd339 100644 --- a/go.sum +++ b/go.sum @@ -368,11 +368,13 @@ github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9 github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c h1:Dznn52SgVIVst9UyOT9brctYUgxs+CvVfPaC3jKrA50= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= -github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +github.com/jackc/pgx/v5 v5.5.0 h1:NxstgwndsTRy7eq9/kqYc/BZh5w2hHJV86wjvO+1xPw= +github.com/jackc/pgx/v5 v5.5.0/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= From 586f7f42c6c42d6a42f1e673dfdbf705a25df3ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 07:29:14 +0000 Subject: [PATCH 352/374] build(deps): bump golang.org/x/sync from 0.4.0 to 0.5.0 Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.4.0 to 0.5.0. - [Commits](https://github.com/golang/sync/compare/v0.4.0...v0.5.0) --- updated-dependencies: - dependency-name: golang.org/x/sync dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0905c0fea4fb..06c37593c579 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/urfave/cli/v2 v2.25.7 golang.org/x/crypto v0.14.0 golang.org/x/exp v0.0.0-20230905200255-921286631fa9 - golang.org/x/sync v0.4.0 + golang.org/x/sync v0.5.0 golang.org/x/term v0.13.0 golang.org/x/time v0.3.0 gorm.io/driver/postgres v1.5.4 diff --git a/go.sum b/go.sum index 14269d6d3ab7..5f3e9b26556a 100644 --- a/go.sum +++ b/go.sum @@ -827,8 +827,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 5c21b792e8fb3744d7dc2bbd0d552dcb9d05886e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 10:33:37 +0000 Subject: [PATCH 353/374] build(deps): bump golang.org/x/time from 0.3.0 to 0.4.0 Bumps [golang.org/x/time](https://github.com/golang/time) from 0.3.0 to 0.4.0. - [Commits](https://github.com/golang/time/compare/v0.3.0...v0.4.0) --- updated-dependencies: - dependency-name: golang.org/x/time dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 06c37593c579..0e6ec10ec6c1 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( golang.org/x/exp v0.0.0-20230905200255-921286631fa9 golang.org/x/sync v0.5.0 golang.org/x/term v0.13.0 - golang.org/x/time v0.3.0 + golang.org/x/time v0.4.0 gorm.io/driver/postgres v1.5.4 gorm.io/gorm v1.25.5 ) diff --git a/go.sum b/go.sum index 5f3e9b26556a..7f45dded0950 100644 --- a/go.sum +++ b/go.sum @@ -899,8 +899,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY= +golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From 7bc7ce309ccab43e672d48ef4395ab6804377b10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 11:42:45 +0000 Subject: [PATCH 354/374] build(deps): bump github.com/libp2p/go-libp2p-pubsub Bumps [github.com/libp2p/go-libp2p-pubsub](https://github.com/libp2p/go-libp2p-pubsub) from 0.9.3 to 0.10.0. - [Release notes](https://github.com/libp2p/go-libp2p-pubsub/releases) - [Commits](https://github.com/libp2p/go-libp2p-pubsub/compare/v0.9.3...v0.10.0) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p-pubsub dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 32 ++++++++++++++--------------- go.sum | 65 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 48 insertions(+), 49 deletions(-) diff --git a/go.mod b/go.mod index 9e12a331eff6..6980236fb99c 100644 --- a/go.mod +++ b/go.mod @@ -24,9 +24,9 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/jackc/pgtype v1.14.0 github.com/jackc/pgx/v5 v5.5.0 - github.com/libp2p/go-libp2p v0.31.0 + github.com/libp2p/go-libp2p v0.32.0 github.com/libp2p/go-libp2p-mplex v0.9.0 - github.com/libp2p/go-libp2p-pubsub v0.9.3 + github.com/libp2p/go-libp2p-pubsub v0.10.0 github.com/libp2p/go-libp2p-testing v0.12.0 github.com/mattn/go-isatty v0.0.20 github.com/multiformats/go-base32 v0.1.0 @@ -40,7 +40,7 @@ require ( github.com/stretchr/testify v1.8.4 github.com/urfave/cli/v2 v2.25.7 golang.org/x/crypto v0.14.0 - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 + golang.org/x/exp v0.0.0-20231006140011-7918f672742d golang.org/x/sync v0.5.0 golang.org/x/term v0.13.0 golang.org/x/time v0.4.0 @@ -98,10 +98,9 @@ require ( github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect + github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -126,7 +125,7 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -146,7 +145,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.55 // indirect + github.com/miekg/dns v1.1.56 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -159,7 +158,7 @@ require ( github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect - github.com/multiformats/go-multistream v0.4.1 // indirect + github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 // indirect @@ -173,9 +172,9 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - github.com/quic-go/quic-go v0.38.1 // indirect - github.com/quic-go/webtransport-go v0.5.3 // indirect + github.com/quic-go/qtls-go1-20 v0.3.4 // indirect + github.com/quic-go/quic-go v0.39.3 // indirect + github.com/quic-go/webtransport-go v0.6.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rivo/uniseg v0.4.3 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect @@ -193,15 +192,16 @@ require ( github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect go.uber.org/automaxprocs v1.5.2 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.20.0 // indirect + go.uber.org/dig v1.17.1 // indirect + go.uber.org/fx v1.20.1 // indirect + go.uber.org/mock v0.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.25.0 // indirect - golang.org/x/mod v0.12.0 // indirect + go.uber.org/zap v1.26.0 // indirect + golang.org/x/mod v0.13.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 7f59c4d97811..969419f38dd8 100644 --- a/go.sum +++ b/go.sum @@ -226,8 +226,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -265,8 +263,8 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -402,8 +400,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -440,14 +438,14 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= -github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= +github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM= +github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-mplex v0.9.0 h1:R58pDRAmuBXkYugbSSXR9wrTX3+1pFM1xP2bLuodIq8= github.com/libp2p/go-libp2p-mplex v0.9.0/go.mod h1:ro1i4kuwiFT+uMPbIDIFkcLs1KRbNp0QwnUXM+P64Og= -github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= -github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= +github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= +github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= @@ -495,8 +493,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -539,8 +537,8 @@ github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI1 github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= +github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= @@ -610,12 +608,12 @@ github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwa github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= -github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= +github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= +github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -729,13 +727,15 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= -go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= +go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= +go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -747,8 +747,8 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -772,8 +772,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -785,8 +785,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -922,11 +922,10 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 9b9310164c5e56f260360b842574ba416d0b92fd Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 6 Nov 2023 16:03:45 +0300 Subject: [PATCH 355/374] op-node: remove deprecated `Pretty()` call Use `String()` over `Pretty()` - https://github.com/libp2p/go-libp2p/pull/2563 - https://github.com/libp2p/go-libp2p-pubsub/issues/547 --- op-node/p2p/node.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-node/p2p/node.go b/op-node/p2p/node.go index 7279f63e6a8c..9c4d3f4da082 100644 --- a/op-node/p2p/node.go +++ b/op-node/p2p/node.go @@ -142,7 +142,7 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l if err != nil { return fmt.Errorf("failed to join blocks gossip topic: %w", err) } - log.Info("started p2p host", "addrs", n.host.Addrs(), "peerID", n.host.ID().Pretty()) + log.Info("started p2p host", "addrs", n.host.Addrs(), "peerID", n.host.ID().String()) tcpPort, err := FindActiveTCPPort(n.host) if err != nil { From 0ccf39b51834fe2788f39633145305b37cd7ec05 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 6 Nov 2023 16:56:07 +0300 Subject: [PATCH 356/374] contracts-bedrock: foundry d85718785859dc0b5a095d2302d1a20ec06ab77a Updates foundry to a version that contains the `loadAllocs` cheatcode - https://github.com/foundry-rs/foundry/pull/6207 This will unblock work on implementing test coverage against the L2 genesis generation script --- .foundryrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.foundryrc b/.foundryrc index 0a8ddf64ab6e..90fe0bd77b75 100644 --- a/.foundryrc +++ b/.foundryrc @@ -1 +1 @@ -ee5d02c3ef5f55a06b069e4a70a820661a9130c8 +d85718785859dc0b5a095d2302d1a20ec06ab77a From 081eebd9122ea648e9f8de5082a4760b44e3e73e Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 6 Nov 2023 18:21:40 +0300 Subject: [PATCH 357/374] contracts-bedrock: decouple magic number in test Remove the magic number `1800` in favor of a generic submission interval. Based on the test's comment, this is the expected input. Breaking this into its own test from https://github.com/ethereum-optimism/optimism/pull/7928 to show that without the rest of the diff, the test still passes to ensure that a bug doesn't sneak in. fwiw this test will likely be modified with the next release of the fault proof. --- packages/contracts-bedrock/.gas-snapshot | 2 +- packages/contracts-bedrock/test/FaultDisputeGame.t.sol | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index fda4b36ae2c3..0943c5f3c598 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -105,7 +105,7 @@ FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32328) FaultDisputeGame_Test:test_gameData_succeeds() (gas: 32777) FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8265) FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57646) -FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 210650) +FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 213808) FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228466) FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594025) FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23175) diff --git a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol index 2dc3d6e7d656..eccf19f08950 100644 --- a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol @@ -139,8 +139,9 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { /// For now, it is critical that the first proposed output root of an OP stack /// chain is done so by an honest party. function test_initialize_firstOutput_reverts() public { + uint256 submissionInterval = oracle.SUBMISSION_INTERVAL(); vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x11)); - factory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(1800, block.number - 1)); + factory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(submissionInterval, block.number - 1)); } /// @dev Tests that the `create` function reverts when the rootClaim does not disagree with the outcome. From 6e890fafb6c531b837c176cd2234651ac95fd752 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 25 Oct 2023 14:32:17 -0600 Subject: [PATCH 358/374] contracts-bedrock: test deploy script This updates the tests to use the deploy script to set up the L1 contracts. This ensures that the tests are testing a setup as close as possible as to what ends up in production. The L2 contracts are setup in a unified place but as not set up behind proxies yet. This has been an issue but should be addressed when we have the ability to import the output of the L2 genesis generation script. Any circleci machines that run `forge build` oom when the machine is not an xlarge. This means that many jobs need to be bumped up to that size for them to run until the end. `CommonTest` is heavily modified and cleaned up. A lot of code was deleted and a good amount of the code that was added is from moving things to kwargs sytax from not. Some tests were converted from being regular tests into fuzz tests. --- packages/contracts-bedrock/.gas-snapshot | 804 +++++++++--------- .../invariant-docs/OptimismPortal.md | 8 +- .../test/BenchmarkTest.t.sol | 76 +- .../contracts-bedrock/test/CommonTest.t.sol | 428 ++++------ .../test/CrossDomainMessenger.t.sol | 45 +- .../test/CrossDomainOwnable.t.sol | 2 +- .../test/CrossDomainOwnable2.t.sol | 14 +- .../test/CrossDomainOwnable3.t.sol | 16 +- .../test/DelayedVetoable.t.sol | 2 +- .../test/FaultDisputeGame.t.sol | 17 +- .../contracts-bedrock/test/FeeVault.t.sol | 43 +- .../test/GasPriceOracle.t.sol | 35 +- .../test/GovernanceToken.t.sol | 96 +-- .../test/Initializable.t.sol | 15 +- packages/contracts-bedrock/test/L1Block.t.sol | 40 +- .../test/L1CrossDomainMessenger.t.sol | 177 ++-- .../test/L1ERC721Bridge.t.sol | 104 +-- .../test/L1StandardBridge.t.sol | 342 ++++---- .../test/L2CrossDomainMessenger.t.sol | 92 +- .../test/L2ERC721Bridge.t.sol | 102 +-- .../test/L2OutputOracle.t.sol | 287 ++++--- .../test/L2StandardBridge.t.sol | 239 +++--- .../test/L2ToL1MessagePasser.t.sol | 48 +- .../test/LegacyMessagePasser.t.sol | 18 +- .../test/OptimismMintableERC20.t.sol | 16 +- .../test/OptimismMintableERC20Factory.t.sol | 22 +- .../test/OptimismMintableERC721.t.sol | 20 +- .../test/OptimismMintableERC721Factory.t.sol | 12 +- .../test/OptimismPortal.t.sol | 385 +++++---- .../test/ProtocolVersions.t.sol | 37 +- .../test/SequencerFeeVault.t.sol | 102 ++- .../contracts-bedrock/test/SystemConfig.t.sol | 259 +++--- .../invariants/CrossDomainMessenger.t.sol | 12 +- .../test/invariants/L2OutputOracle.t.sol | 4 +- .../test/invariants/OptimismPortal.t.sol | 49 +- 35 files changed, 1986 insertions(+), 1982 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 0943c5f3c598..0f5e6129bcd2 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -26,36 +26,36 @@ Bytes_toNibbles_Test:test_toNibbles_expectedResult128Bytes_works() (gas: 78882) Bytes_toNibbles_Test:test_toNibbles_expectedResult5Bytes_works() (gas: 3992) Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 823) Constants_Test:test_eip1967Constants_succeeds() (gas: 453) -CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20435) -CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8461) -CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57494) -CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16610) -CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73522) -CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10554) -CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28289) -CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 73970) -CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32000) -CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91527) -CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13215) -CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35242) -CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52084) -CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48610) -CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12037) -CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13437) -CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12081) -CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81417) +CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20525) +CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8528) +CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57518) +CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16655) +CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73597) +CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10605) +CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28378) +CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 74058) +CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32111) +CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91600) +CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13260) +CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35271) +CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52158) +CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48706) +CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12112) +CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13460) +CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12177) +CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81600) CrossDomainOwnable_Test:test_onlyOwner_notOwner_reverts() (gas: 10597) CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34883) -DelayedVetoable_Getters_Test:test_getters() (gas: 24466) -DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 36220) -DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 21867) +DelayedVetoable_Getters_Test:test_getters() (gas: 24671) +DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 36263) +DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 15190) DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582) DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395) -DisputeGameFactory_Owner_Test:test_owner_succeeds() (gas: 12581) -DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16042) -DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44301) -DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950) -DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642) +DisputeGameFactory_Owner_Test:test_owner_succeeds() (gas: 12611) +DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16067) +DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44346) +DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15974) +DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18738) Drippie_Test:test_create_calledTwice_reverts() (gas: 168953) Drippie_Test:test_create_succeeds() (gas: 183401) Drippie_Test:test_drip_amount_succeeds() (gas: 285353) @@ -89,218 +89,218 @@ FaucetTest:test_nonAdmin_drip_fails() (gas: 262520) FaucetTest:test_receive_succeeds() (gas: 17401) FaucetTest:test_withdraw_nonAdmin_reverts() (gas: 13145) FaucetTest:test_withdraw_succeeds() (gas: 78359) -FaultDisputeGame_ResolvesCorrectly_CorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 660000) -FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 666860) -FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 663563) -FaultDisputeGame_ResolvesCorrectly_CorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 666736) -FaultDisputeGame_ResolvesCorrectly_CorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 666049) -FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 652764) -FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 658252) -FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 655614) -FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 656552) -FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 656003) -FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 642642) -FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10409) -FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32328) -FaultDisputeGame_Test:test_gameData_succeeds() (gas: 32777) +FaultDisputeGame_ResolvesCorrectly_CorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 660030) +FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 666890) +FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 663593) +FaultDisputeGame_ResolvesCorrectly_CorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 666766) +FaultDisputeGame_ResolvesCorrectly_CorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 666079) +FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 652788) +FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 658276) +FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 655638) +FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 656576) +FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 656027) +FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 642366) +FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10439) +FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32385) +FaultDisputeGame_Test:test_gameData_succeeds() (gas: 32857) FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8265) -FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57646) -FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 213808) -FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228466) -FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594025) -FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23175) -FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13300) -FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 147367) -FaultDisputeGame_Test:test_move_duplicateClaimsDifferentSubgames_succeeds() (gas: 556831) +FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57761) +FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228488) +FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594267) +FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23197) +FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13322) +FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 147390) +FaultDisputeGame_Test:test_move_duplicateClaimsDifferentSubgames_succeeds() (gas: 556832) FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 585853) -FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10980) -FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24644) -FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 151915) -FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 269432) +FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 11010) +FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24668) +FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 152008) +FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 269473) FaultDisputeGame_Test:test_resolve_claimAlreadyResolved_reverts() (gas: 272334) FaultDisputeGame_Test:test_resolve_claimAtMaxDepthAlreadyResolved_reverts() (gas: 586606) -FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9754) -FaultDisputeGame_Test:test_resolve_outOfOrderResolution_reverts() (gas: 309015) -FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 139090) -FaultDisputeGame_Test:test_resolve_rootUncontestedButUnresolved_reverts() (gas: 15884) +FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9776) +FaultDisputeGame_Test:test_resolve_outOfOrderResolution_reverts() (gas: 308993) +FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 139119) +FaultDisputeGame_Test:test_resolve_rootUncontestedButUnresolved_reverts() (gas: 15980) FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 18428) -FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 51410) -FaultDisputeGame_Test:test_resolve_stepReached_succeeds() (gas: 498406) -FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 443357) +FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 51484) +FaultDisputeGame_Test:test_resolve_stepReached_succeeds() (gas: 498483) +FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 443381) FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8232) -FeeVault_Test:test_constructor_succeeds() (gas: 18185) -GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354421) -GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952628) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 542325) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4054518) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 443561) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3489288) -GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 42714) -GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 90658) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 75076) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 75697) -GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143181) -GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8325) -GasPriceOracle_Test:test_decimals_succeeds() (gas: 6167) -GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8294) -GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10656) -GasPriceOracle_Test:test_overhead_succeeds() (gas: 10636) -GasPriceOracle_Test:test_scalar_succeeds() (gas: 10677) -GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5910) -GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5911) -GovernanceToken_Test:test_approve_succeeds() (gas: 133293) -GovernanceToken_Test:test_burnFrom_succeeds() (gas: 122733) -GovernanceToken_Test:test_burn_succeeds() (gas: 114588) -GovernanceToken_Test:test_constructor_succeeds() (gas: 21298) -GovernanceToken_Test:test_decreaseAllowance_succeeds() (gas: 137008) -GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 137118) -GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 17030) -GovernanceToken_Test:test_mint_fromOwner_succeeds() (gas: 108592) -GovernanceToken_Test:test_transferFrom_succeeds() (gas: 146273) -GovernanceToken_Test:test_transfer_succeeds() (gas: 138108) -Hashing_hashDepositSource_Test:test_hashDepositSource_succeeds() (gas: 633) -Initializer_Test:test_cannotReinitializeL1_succeeds() (gas: 98390) +FeeVault_Test:test_constructor_baseFeeVault_succeeds() (gas: 17428) +FeeVault_Test:test_constructor_l1FeeVault_succeeds() (gas: 17396) +GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354398) +GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952696) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 544879) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4057119) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 446307) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3491910) +GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 45340) +GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 88797) +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68343) +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68922) +GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143347) +GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8392) +GasPriceOracle_Test:test_decimals_succeeds() (gas: 6234) +GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8340) +GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10657) +GasPriceOracle_Test:test_overhead_succeeds() (gas: 10637) +GasPriceOracle_Test:test_scalar_succeeds() (gas: 10722) +GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5956) +GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5976) +GovernanceToken_Test:test_approve_succeeds() (gas: 138023) +GovernanceToken_Test:test_burnFrom_succeeds() (gas: 127582) +GovernanceToken_Test:test_burn_succeeds() (gas: 119070) +GovernanceToken_Test:test_constructor_succeeds() (gas: 23693) +GovernanceToken_Test:test_decreaseAllowance_succeeds() (gas: 141912) +GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 142022) +GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 21355) +GovernanceToken_Test:test_mint_fromOwner_succeeds() (gas: 110895) +GovernanceToken_Test:test_transferFrom_succeeds() (gas: 151340) +GovernanceToken_Test:test_transfer_succeeds() (gas: 142867) +Hashing_hashDepositSource_Test:test_hashDepositSource_succeeds() (gas: 700) +Initializer_Test:test_cannotReinitializeL1_succeeds() (gas: 101013) L1BlockNumberTest:test_fallback_succeeds() (gas: 18655) L1BlockNumberTest:test_getL1BlockNumber_succeeds() (gas: 10625) L1BlockNumberTest:test_receive_succeeds() (gas: 25384) -L1BlockTest:test_basefee_succeeds() (gas: 7554) -L1BlockTest:test_hash_succeeds() (gas: 7576) -L1BlockTest:test_number_succeeds() (gas: 7629) -L1BlockTest:test_sequenceNumber_succeeds() (gas: 7630) -L1BlockTest:test_timestamp_succeeds() (gas: 7640) -L1BlockTest:test_updateValues_succeeds() (gas: 60482) -L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24781) -L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49384) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 239657) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 233416) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 126344) -L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 79599) -L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 227456) -L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 76590) -L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 60779) -L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12343) -L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 33133) -L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 392933) -L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1669172) -L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 87853) -L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24253) -L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62686) -L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37285) -L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 455269) -L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 70997) -L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35681) -L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60561) -L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35204) -L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 454966) -L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70823) -L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 18861) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 29475) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27220) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23241) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 24990) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 425245) -L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 514756) -L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 501934) -L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 720272) -L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 717849) -L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 22276) -L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 514789) -L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 502006) -L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 40759) -L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 54102) -L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 36551) -L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 36738) -L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 36623) -L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 498144) -L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 33452) -L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 34118) -L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 64673) -L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 28383) -L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 27239) -L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 615130) -L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8477) -L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 191078) -L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48913) -L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 31136) -L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11689) -L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 123957) -L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135812) -L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 49230) -L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10590) -L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 31453) -L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 26854) -L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 157156) -L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 34489) -L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 27183) -L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 29305) -L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 24641) -L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 154746) -L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 34271) -L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 21004) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 38661) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 246925) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27208) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23274) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 27124) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 179976) -L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 23902) -L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 46800) -L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 15216) -L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 20216) -L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 187875) -L2OutputOracle_constructor_Test:test_constructor_l2BlockTimeZero_reverts() (gas: 39022) -L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 39032) -L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 51777) -L2OutputOracle_constructor_Test:test_initialize_badTimestamp_reverts() (gas: 12353) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 217031) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 113258) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 21018) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_nonExistent_reverts() (gas: 111651) -L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 307411) -L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 185564) -L2OutputOracle_getter_Test:test_computeL2Timestamp_succeeds() (gas: 38198) -L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 269700) -L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17892) -L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 98188) -L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 98096) -L2OutputOracle_getter_Test:test_getL2Output_succeeds() (gas: 104600) -L2OutputOracle_getter_Test:test_latestBlockNumber_succeeds() (gas: 99129) -L2OutputOracle_getter_Test:test_nextBlockNumber_succeeds() (gas: 17447) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 28812) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_futureTimetamp_reverts() (gas: 30792) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_notProposer_reverts() (gas: 27928) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 103242) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unexpectedBlockNumber_reverts() (gas: 30526) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 31526) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_wrongFork_reverts() (gas: 31129) -L2OutputOracle_proposeL2Output_Test:test_proposeWithBlockhashAndHeight_succeeds() (gas: 97442) -L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 392297) -L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 392530) -L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 387821) -L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 396094) -L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 396456) -L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251807) -L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 388103) -L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 26132) -L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 26400) -L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 26159) -L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 96091) -L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 94945) -L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 45528) -L2StandardBridge_Test:test_initialize_succeeds() (gas: 26316) -L2StandardBridge_Test:test_receive_succeeds() (gas: 177125) -L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 143366) -L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16552) -LegacyERC20ETH_Test:test_approve_doesNotExist_reverts() (gas: 10702) -LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10637) -LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6341) -LegacyERC20ETH_Test:test_decreaseAllowance_doesNotExist_reverts() (gas: 10724) -LegacyERC20ETH_Test:test_increaseAllowance_doesNotExist_reverts() (gas: 10690) -LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15420) -LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10627) -LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12957) -LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10755) -LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34524) +L1BlockTest:test_basefee_succeeds() (gas: 7576) +L1BlockTest:test_hash_succeeds() (gas: 7671) +L1BlockTest:test_number_succeeds() (gas: 7651) +L1BlockTest:test_sequenceNumber_succeeds() (gas: 7676) +L1BlockTest:test_timestamp_succeeds() (gas: 7685) +L1BlockTest:test_updateValues_succeeds() (gas: 60549) +L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24803) +L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49430) +L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 239747) +L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 233439) +L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 126367) +L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 79600) +L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 227457) +L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 76613) +L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 60802) +L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12410) +L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 33134) +L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 392982) +L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1669266) +L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 87934) +L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24282) +L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62734) +L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37330) +L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 455331) +L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 71019) +L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35761) +L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60608) +L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35185) +L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 455030) +L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70867) +L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 18927) +L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 29495) +L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27242) +L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23283) +L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 25013) +L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 425310) +L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 517246) +L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 504475) +L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 723482) +L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 721016) +L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 24968) +L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 517343) +L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 504614) +L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 43427) +L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 57852) +L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 40313) +L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 40464) +L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 40350) +L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 503477) +L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 37194) +L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 37883) +L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 70086) +L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 32693) +L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 30416) +L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 617714) +L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8521) +L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 191123) +L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48936) +L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 31159) +L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11712) +L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 124025) +L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135857) +L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 49311) +L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10686) +L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 26476) +L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 21837) +L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 152170) +L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 29472) +L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 22228) +L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 24332) +L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 19674) +L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 149761) +L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 29304) +L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 14638) +L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 33650) +L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 241398) +L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 22196) +L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 18260) +L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 22091) +L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 174492) +L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 32612) +L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 56622) +L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 24804) +L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 26357) +L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 191207) +L2OutputOracle_constructor_Test:test_constructor_l2BlockTimeZero_reverts() (gas: 44322) +L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 44398) +L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 61377) +L2OutputOracle_constructor_Test:test_initialize_badTimestamp_reverts() (gas: 12388) +L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 226802) +L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 118576) +L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 21030) +L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_nonExistent_reverts() (gas: 117047) +L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 318177) +L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 193280) +L2OutputOracle_getter_Test:test_computeL2Timestamp_succeeds() (gas: 44531) +L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 277477) +L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17960) +L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 103519) +L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 103427) +L2OutputOracle_getter_Test:test_getL2Output_succeeds() (gas: 109954) +L2OutputOracle_getter_Test:test_latestBlockNumber_succeeds() (gas: 104504) +L2OutputOracle_getter_Test:test_nextBlockNumber_succeeds() (gas: 17492) +L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 34143) +L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_futureTimetamp_reverts() (gas: 34240) +L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_notProposer_reverts() (gas: 26076) +L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 109323) +L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unexpectedBlockNumber_reverts() (gas: 33945) +L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 34946) +L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_wrongFork_reverts() (gas: 34466) +L2OutputOracle_proposeL2Output_Test:test_proposeWithBlockhashAndHeight_succeeds() (gas: 100845) +L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 392348) +L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 392599) +L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 387993) +L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 396266) +L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 396611) +L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251910) +L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 388275) +L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 26215) +L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 26425) +L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 26230) +L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 96161) +L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 95024) +L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 45613) +L2StandardBridge_Test:test_initialize_succeeds() (gas: 28938) +L2StandardBridge_Test:test_receive_succeeds() (gas: 177159) +L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 143423) +L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16587) +LegacyERC20ETH_Test:test_approve_doesNotExist_reverts() (gas: 10804) +LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10676) +LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6422) +LegacyERC20ETH_Test:test_decreaseAllowance_doesNotExist_reverts() (gas: 10739) +LegacyERC20ETH_Test:test_increaseAllowance_doesNotExist_reverts() (gas: 10749) +LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15773) +LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10709) +LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12970) +LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10793) +LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34629) LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689) LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8531) LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 233535) @@ -329,81 +329,81 @@ LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRece LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 615047) LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1278252) LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954) -MIPS_Test:test_add_succeeds() (gas: 122866) -MIPS_Test:test_addiSign_succeeds() (gas: 122857) -MIPS_Test:test_addi_succeeds() (gas: 123054) -MIPS_Test:test_addu_succeeds() (gas: 122908) -MIPS_Test:test_addui_succeeds() (gas: 123116) -MIPS_Test:test_and_succeeds() (gas: 122927) -MIPS_Test:test_andi_succeeds() (gas: 122860) -MIPS_Test:test_beq_succeeds() (gas: 203293) -MIPS_Test:test_bgez_succeeds() (gas: 122153) -MIPS_Test:test_bgtz_succeeds() (gas: 122074) -MIPS_Test:test_blez_succeeds() (gas: 122030) -MIPS_Test:test_bltz_succeeds() (gas: 122173) -MIPS_Test:test_bne_succeeds() (gas: 122239) -MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86448) -MIPS_Test:test_brk_succeeds() (gas: 122543) -MIPS_Test:test_clo_succeeds() (gas: 122595) -MIPS_Test:test_clone_succeeds() (gas: 122496) -MIPS_Test:test_clz_succeeds() (gas: 123066) -MIPS_Test:test_div_succeeds() (gas: 123045) -MIPS_Test:test_divu_succeeds() (gas: 123030) -MIPS_Test:test_exit_succeeds() (gas: 122545) -MIPS_Test:test_fcntl_succeeds() (gas: 204775) -MIPS_Test:test_illegal_instruction_fails() (gas: 91911) -MIPS_Test:test_invalid_root_fails() (gas: 436085) -MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121183) -MIPS_Test:test_jal_succeeds() (gas: 121172) -MIPS_Test:test_jalr_succeeds() (gas: 122291) -MIPS_Test:test_jr_succeeds() (gas: 121985) -MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85816) -MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120927) -MIPS_Test:test_jump_succeeds() (gas: 120857) -MIPS_Test:test_lb_succeeds() (gas: 128098) -MIPS_Test:test_lbu_succeeds() (gas: 127996) -MIPS_Test:test_lh_succeeds() (gas: 128119) -MIPS_Test:test_lhu_succeeds() (gas: 128036) -MIPS_Test:test_ll_succeeds() (gas: 128258) -MIPS_Test:test_lui_succeeds() (gas: 122139) -MIPS_Test:test_lw_succeeds() (gas: 127887) -MIPS_Test:test_lwl_succeeds() (gas: 242938) -MIPS_Test:test_lwr_succeeds() (gas: 243226) -MIPS_Test:test_mfhi_succeeds() (gas: 122500) -MIPS_Test:test_mflo_succeeds() (gas: 122629) -MIPS_Test:test_mmap_succeeds() (gas: 119528) -MIPS_Test:test_movn_succeeds() (gas: 203965) -MIPS_Test:test_movz_succeeds() (gas: 203833) -MIPS_Test:test_mthi_succeeds() (gas: 122544) -MIPS_Test:test_mtlo_succeeds() (gas: 122652) -MIPS_Test:test_mul_succeeds() (gas: 122144) -MIPS_Test:test_mult_succeeds() (gas: 122848) -MIPS_Test:test_multu_succeeds() (gas: 122885) -MIPS_Test:test_nor_succeeds() (gas: 122977) -MIPS_Test:test_or_succeeds() (gas: 122934) -MIPS_Test:test_ori_succeeds() (gas: 122937) -MIPS_Test:test_preimage_read_succeeds() (gas: 235349) -MIPS_Test:test_preimage_write_succeeds() (gas: 127485) -MIPS_Test:test_prestate_exited_succeeds() (gas: 113726) -MIPS_Test:test_sb_succeeds() (gas: 161369) -MIPS_Test:test_sc_succeeds() (gas: 161552) -MIPS_Test:test_sh_succeeds() (gas: 161406) -MIPS_Test:test_sll_succeeds() (gas: 122105) -MIPS_Test:test_sllv_succeeds() (gas: 122334) -MIPS_Test:test_slt_succeeds() (gas: 205160) -MIPS_Test:test_sltu_succeeds() (gas: 123151) -MIPS_Test:test_sra_succeeds() (gas: 122356) -MIPS_Test:test_srav_succeeds() (gas: 122624) -MIPS_Test:test_srl_succeeds() (gas: 122187) -MIPS_Test:test_srlv_succeeds() (gas: 122352) -MIPS_Test:test_step_abi_succeeds() (gas: 58467) -MIPS_Test:test_sub_succeeds() (gas: 122961) -MIPS_Test:test_subu_succeeds() (gas: 122958) -MIPS_Test:test_sw_succeeds() (gas: 161381) -MIPS_Test:test_swl_succeeds() (gas: 161442) -MIPS_Test:test_swr_succeeds() (gas: 161517) -MIPS_Test:test_xor_succeeds() (gas: 122962) -MIPS_Test:test_xori_succeeds() (gas: 123014) +MIPS_Test:test_add_succeeds() (gas: 123021) +MIPS_Test:test_addiSign_succeeds() (gas: 122946) +MIPS_Test:test_addi_succeeds() (gas: 123144) +MIPS_Test:test_addu_succeeds() (gas: 122975) +MIPS_Test:test_addui_succeeds() (gas: 123206) +MIPS_Test:test_and_succeeds() (gas: 122994) +MIPS_Test:test_andi_succeeds() (gas: 122971) +MIPS_Test:test_beq_succeeds() (gas: 203427) +MIPS_Test:test_bgez_succeeds() (gas: 122287) +MIPS_Test:test_bgtz_succeeds() (gas: 122164) +MIPS_Test:test_blez_succeeds() (gas: 122186) +MIPS_Test:test_bltz_succeeds() (gas: 122284) +MIPS_Test:test_bne_succeeds() (gas: 122329) +MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86558) +MIPS_Test:test_brk_succeeds() (gas: 122588) +MIPS_Test:test_clo_succeeds() (gas: 122707) +MIPS_Test:test_clone_succeeds() (gas: 122563) +MIPS_Test:test_clz_succeeds() (gas: 123199) +MIPS_Test:test_div_succeeds() (gas: 123134) +MIPS_Test:test_divu_succeeds() (gas: 123164) +MIPS_Test:test_exit_succeeds() (gas: 122634) +MIPS_Test:test_fcntl_succeeds() (gas: 204864) +MIPS_Test:test_illegal_instruction_fails() (gas: 91978) +MIPS_Test:test_invalid_root_fails() (gas: 436238) +MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121250) +MIPS_Test:test_jal_succeeds() (gas: 121239) +MIPS_Test:test_jalr_succeeds() (gas: 122425) +MIPS_Test:test_jr_succeeds() (gas: 122140) +MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85861) +MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120994) +MIPS_Test:test_jump_succeeds() (gas: 120991) +MIPS_Test:test_lb_succeeds() (gas: 128187) +MIPS_Test:test_lbu_succeeds() (gas: 128107) +MIPS_Test:test_lh_succeeds() (gas: 128251) +MIPS_Test:test_lhu_succeeds() (gas: 128125) +MIPS_Test:test_ll_succeeds() (gas: 128347) +MIPS_Test:test_lui_succeeds() (gas: 122228) +MIPS_Test:test_lw_succeeds() (gas: 127976) +MIPS_Test:test_lwl_succeeds() (gas: 243138) +MIPS_Test:test_lwr_succeeds() (gas: 243427) +MIPS_Test:test_mfhi_succeeds() (gas: 122634) +MIPS_Test:test_mflo_succeeds() (gas: 122718) +MIPS_Test:test_mmap_succeeds() (gas: 119636) +MIPS_Test:test_movn_succeeds() (gas: 204054) +MIPS_Test:test_movz_succeeds() (gas: 203900) +MIPS_Test:test_mthi_succeeds() (gas: 122634) +MIPS_Test:test_mtlo_succeeds() (gas: 122741) +MIPS_Test:test_mul_succeeds() (gas: 122278) +MIPS_Test:test_mult_succeeds() (gas: 122915) +MIPS_Test:test_multu_succeeds() (gas: 122995) +MIPS_Test:test_nor_succeeds() (gas: 123087) +MIPS_Test:test_or_succeeds() (gas: 123046) +MIPS_Test:test_ori_succeeds() (gas: 123026) +MIPS_Test:test_preimage_read_succeeds() (gas: 235502) +MIPS_Test:test_preimage_write_succeeds() (gas: 127574) +MIPS_Test:test_prestate_exited_succeeds() (gas: 113834) +MIPS_Test:test_sb_succeeds() (gas: 161547) +MIPS_Test:test_sc_succeeds() (gas: 161752) +MIPS_Test:test_sh_succeeds() (gas: 161628) +MIPS_Test:test_sll_succeeds() (gas: 122260) +MIPS_Test:test_sllv_succeeds() (gas: 122424) +MIPS_Test:test_slt_succeeds() (gas: 205272) +MIPS_Test:test_sltu_succeeds() (gas: 123285) +MIPS_Test:test_sra_succeeds() (gas: 122490) +MIPS_Test:test_srav_succeeds() (gas: 122758) +MIPS_Test:test_srl_succeeds() (gas: 122276) +MIPS_Test:test_srlv_succeeds() (gas: 122506) +MIPS_Test:test_step_abi_succeeds() (gas: 58532) +MIPS_Test:test_sub_succeeds() (gas: 123029) +MIPS_Test:test_subu_succeeds() (gas: 123092) +MIPS_Test:test_sw_succeeds() (gas: 161626) +MIPS_Test:test_swl_succeeds() (gas: 161643) +MIPS_Test:test_swr_succeeds() (gas: 161718) +MIPS_Test:test_xor_succeeds() (gas: 123029) +MIPS_Test:test_xori_succeeds() (gas: 123082) MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5733) MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889) MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35845) @@ -425,77 +425,77 @@ MerkleTrie_get_Test:test_get_validProof9_succeeds() (gas: 48802) MerkleTrie_get_Test:test_get_wrongKeyProof_reverts() (gas: 50730) MerkleTrie_get_Test:test_get_zeroBranchValueLength_reverts() (gas: 41684) MerkleTrie_get_Test:test_get_zeroLengthKey_reverts() (gas: 3632) -MintManager_constructor_Test:test_constructor_succeeds() (gas: 10579) -MintManager_mint_Test:test_mint_afterPeriodElapsed_succeeds() (gas: 148117) -MintManager_mint_Test:test_mint_beforePeriodElapsed_reverts() (gas: 140433) -MintManager_mint_Test:test_mint_fromNotOwner_reverts() (gas: 10987) -MintManager_mint_Test:test_mint_fromOwner_succeeds() (gas: 137219) -MintManager_mint_Test:test_mint_moreThanCap_reverts() (gas: 142523) -MintManager_upgrade_Test:test_upgrade_fromNotOwner_reverts() (gas: 10974) -MintManager_upgrade_Test:test_upgrade_fromOwner_succeeds() (gas: 23434) -MintManager_upgrade_Test:test_upgrade_toZeroAddress_reverts() (gas: 11003) +MintManager_constructor_Test:test_constructor_succeeds() (gas: 10645) +MintManager_mint_Test:test_mint_afterPeriodElapsed_succeeds() (gas: 148140) +MintManager_mint_Test:test_mint_beforePeriodElapsed_reverts() (gas: 140523) +MintManager_mint_Test:test_mint_fromNotOwner_reverts() (gas: 11010) +MintManager_mint_Test:test_mint_fromOwner_succeeds() (gas: 137330) +MintManager_mint_Test:test_mint_moreThanCap_reverts() (gas: 142590) +MintManager_upgrade_Test:test_upgrade_fromNotOwner_reverts() (gas: 11041) +MintManager_upgrade_Test:test_upgrade_fromOwner_succeeds() (gas: 23509) +MintManager_upgrade_Test:test_upgrade_toZeroAddress_reverts() (gas: 11070) Multichain:test_script_succeeds() (gas: 3078) -OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7621) -OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11164) -OptimismMintableERC20_Test:test_burn_succeeds() (gas: 50996) -OptimismMintableERC20_Test:test_erc165_supportsInterface_succeeds() (gas: 7787) -OptimismMintableERC20_Test:test_l1Token_succeeds() (gas: 7621) -OptimismMintableERC20_Test:test_l2Bridge_succeeds() (gas: 7621) -OptimismMintableERC20_Test:test_legacy_succeeds() (gas: 14322) -OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11165) -OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63544) -OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7667) -OptimismMintableERC721Factory_Test:test_constructor_succeeds() (gas: 8381) -OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_sameTwice_reverts() (gas: 8937393460516800045) -OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316169) -OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_zeroRemoteToken_reverts() (gas: 9493) -OptimismMintableERC721_Test:test_burn_notBridge_reverts() (gas: 136966) -OptimismMintableERC721_Test:test_burn_succeeds() (gas: 118832) -OptimismMintableERC721_Test:test_constructor_succeeds() (gas: 24162) -OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11121) -OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140547) -OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9005) -OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163441) -OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 9760) -OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1142536) -OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9570) -OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516764385) -OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1142527) -OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 11178) -OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16111) -OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26781) -OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 191521) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178667) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 182306) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41780) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 173953) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 181161) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 154740) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 219208) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 220983) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 38706) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 209679) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696162676) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 171302) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85805) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111317) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52973) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 58846) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 297494) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227596) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166699) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154430) -OptimismPortal_Test:test_constructor_succeeds() (gas: 28164) -OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14281) -OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512200) -OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14528) -OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127594) -OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17597) +OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7717) +OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11180) +OptimismMintableERC20_Test:test_burn_succeeds() (gas: 51074) +OptimismMintableERC20_Test:test_erc165_supportsInterface_succeeds() (gas: 7832) +OptimismMintableERC20_Test:test_l1Token_succeeds() (gas: 7717) +OptimismMintableERC20_Test:test_l2Bridge_succeeds() (gas: 7672) +OptimismMintableERC20_Test:test_legacy_succeeds() (gas: 14518) +OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11224) +OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63604) +OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7740) +OptimismMintableERC721Factory_Test:test_constructor_succeeds() (gas: 8402) +OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_sameTwice_reverts() (gas: 8937393460516800078) +OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316545) +OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_zeroRemoteToken_reverts() (gas: 9542) +OptimismMintableERC721_Test:test_burn_notBridge_reverts() (gas: 136997) +OptimismMintableERC721_Test:test_burn_succeeds() (gas: 118933) +OptimismMintableERC721_Test:test_constructor_succeeds() (gas: 24516) +OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11224) +OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140614) +OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9050) +OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163620) +OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 9812) +OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1142649) +OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9621) +OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516764416) +OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1142596) +OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 14593) +OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16211) +OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26775) +OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 186062) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178756) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 182285) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41781) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 173977) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 181245) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 154807) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 219305) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 220984) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 38751) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 209680) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696162678) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 171324) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85828) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111318) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52951) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 58892) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 297539) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227597) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166744) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154431) +OptimismPortal_Test:test_constructor_succeeds() (gas: 33454) +OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14283) +OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512202) +OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14550) +OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127617) +OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17643) OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 24487) -OptimismPortal_Test:test_pause_succeeds() (gas: 27344) -OptimismPortal_Test:test_receive_succeeds() (gas: 127564) -OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31514) -OptimismPortal_Test:test_unpause_succeeds() (gas: 27451) +OptimismPortal_Test:test_pause_succeeds() (gas: 27329) +OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 40906) +OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31558) +OptimismPortal_Test:test_unpause_succeeds() (gas: 27372) OptimistAllowlistTest:test_constructor_succeeds() (gas: 16407) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49650) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49254) @@ -549,10 +549,10 @@ PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 76076) PreimageOracle_Test:test_loadLocalData_multipleContexts_succeeds() (gas: 147718) PreimageOracle_Test:test_loadLocalData_onePart_succeeds() (gas: 75905) PreimageOracle_Test:test_loadLocalData_outOfBoundsOffset_reverts() (gas: 8882) -ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 52181) -ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 32301) -ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15508) -ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15520) +ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 41635) +ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 45046) +ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15553) +ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15565) ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 36440) ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15675) ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51084) @@ -661,33 +661,33 @@ ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20020816) ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 19549) SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1021670598) SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1095190688) -SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 78333) -SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 46791) -SequencerFeeVault_Test:test_constructor_succeeds() (gas: 5526) -SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 5464) -SequencerFeeVault_Test:test_receive_succeeds() (gas: 17373) -SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9332) -SequencerFeeVault_Test:test_withdraw_toL1_succeeds() (gas: 171675) -SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11549) -StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 49936) -StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33072) -Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31821, ~: 31821) +SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 80640) +SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 48926) +SequencerFeeVault_Test:test_constructor_succeeds() (gas: 7705) +SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 12816) +SequencerFeeVault_Test:test_receive_succeeds() (gas: 17395) +SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9399) +SequencerFeeVault_Test:test_withdraw_toL1_succeeds() (gas: 618343) +SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11595) +StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 50168) +StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33117) +Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31510, ~: 31821) Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31598, ~: 31598) Storage_Roundtrip_Test:test_setGetUint_succeeds(bytes32,uint256) (runs: 64, μ: 30731, ~: 31664) -SystemConfig_Initialize_Test:test_initialize_events_succeeds() (gas: 71972) -SystemConfig_Initialize_Test:test_initialize_startBlockNoop_reverts() (gas: 81247) -SystemConfig_Initialize_Test:test_initialize_startBlockOverride_succeeds() (gas: 65143) -SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 64968) -SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 57177) -SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 15607) -SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 15577) -SystemConfig_Setters_TestFail:test_setGasLimit_notOwner_reverts() (gas: 15676) -SystemConfig_Setters_TestFail:test_setResourceConfig_badMinMax_reverts() (gas: 18541) -SystemConfig_Setters_TestFail:test_setResourceConfig_badPrecision_reverts() (gas: 21142) -SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas: 22146) -SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 16799) -SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 18578) -SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 15590) +SystemConfig_Initialize_Test:test_initialize_events_succeeds() (gas: 88186) +SystemConfig_Initialize_Test:test_initialize_startBlockNoop_reverts() (gas: 77159) +SystemConfig_Initialize_Test:test_initialize_startBlockOverride_succeeds() (gas: 81116) +SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 88523) +SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 59900) +SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 15652) +SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 15644) +SystemConfig_Setters_TestFail:test_setGasLimit_notOwner_reverts() (gas: 15743) +SystemConfig_Setters_TestFail:test_setResourceConfig_badMinMax_reverts() (gas: 18614) +SystemConfig_Setters_TestFail:test_setResourceConfig_badPrecision_reverts() (gas: 21194) +SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas: 22242) +SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 16844) +SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 18629) +SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 15657) TransactorTest:test_call_succeeds() (gas: 26709) TransactorTest:test_call_unauthorized_reverts() (gas: 18117) TransactorTest:test_constructor_succeeds() (gas: 9739) diff --git a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md index c13d0212128d..b1b2c38cb278 100644 --- a/packages/contracts-bedrock/invariant-docs/OptimismPortal.md +++ b/packages/contracts-bedrock/invariant-docs/OptimismPortal.md @@ -1,21 +1,21 @@ # `OptimismPortal` Invariants ## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. -**Test:** [`OptimismPortal.t.sol#L148`](../test/invariants/OptimismPortal.t.sol#L148) +**Test:** [`OptimismPortal.t.sol#L151`](../test/invariants/OptimismPortal.t.sol#L151) All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. ## `finalizeWithdrawalTransaction` should revert if the finalization period has not elapsed. -**Test:** [`OptimismPortal.t.sol#L171`](../test/invariants/OptimismPortal.t.sol#L171) +**Test:** [`OptimismPortal.t.sol#L174`](../test/invariants/OptimismPortal.t.sol#L174) A withdrawal that has been proven should not be able to be finalized until after the finalization period has elapsed. ## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. -**Test:** [`OptimismPortal.t.sol#L201`](../test/invariants/OptimismPortal.t.sol#L201) +**Test:** [`OptimismPortal.t.sol#L204`](../test/invariants/OptimismPortal.t.sol#L204) Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice. ## A withdrawal should **always** be able to be finalized `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. -**Test:** [`OptimismPortal.t.sol#L230`](../test/invariants/OptimismPortal.t.sol#L230) +**Test:** [`OptimismPortal.t.sol#L233`](../test/invariants/OptimismPortal.t.sol#L233) This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. \ No newline at end of file diff --git a/packages/contracts-bedrock/test/BenchmarkTest.t.sol b/packages/contracts-bedrock/test/BenchmarkTest.t.sol index 780162b66b0d..dfe0d9f180db 100644 --- a/packages/contracts-bedrock/test/BenchmarkTest.t.sol +++ b/packages/contracts-bedrock/test/BenchmarkTest.t.sol @@ -15,8 +15,8 @@ function setPrevBaseFee(Vm _vm, address _op, uint128 _prevBaseFee) { contract SetPrevBaseFee_Test is Portal_Initializer { function test_setPrevBaseFee_succeeds() external { - setPrevBaseFee(vm, address(op), 100 gwei); - (uint128 prevBaseFee,, uint64 prevBlockNum) = op.params(); + setPrevBaseFee(vm, address(optimismPortal), 100 gwei); + (uint128 prevBaseFee,, uint64 prevBlockNum) = optimismPortal.params(); assertEq(uint256(prevBaseFee), 100 gwei); assertEq(uint256(prevBlockNum), block.number); } @@ -61,61 +61,64 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer { messagePasserStorageRoot: _storageRoot, latestBlockhash: bytes32(uint256(0)) }); - _proposedBlockNumber = oracle.nextBlockNumber(); - _proposedOutputIndex = oracle.nextOutputIndex(); + _proposedBlockNumber = l2OutputOracle.nextBlockNumber(); + _proposedOutputIndex = l2OutputOracle.nextOutputIndex(); } // Get the system into a nice ready-to-use state. function setUp() public virtual override { // Configure the oracle to return the output root we've prepared. - vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1); - vm.prank(oracle.PROPOSER()); - oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); + vm.warp(l2OutputOracle.computeL2Timestamp(_proposedBlockNumber) + 1); + vm.prank(l2OutputOracle.PROPOSER()); + l2OutputOracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); // Warp beyond the finalization period for the block we've proposed. - vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp( + l2OutputOracle.getL2Output(_proposedOutputIndex).timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + + 1 + ); // Fund the portal so that we can withdraw ETH. - vm.deal(address(op), 0xFFFFFFFF); + vm.deal(address(optimismPortal), 0xFFFFFFFF); } function test_depositTransaction_benchmark() external { - op.depositTransaction{ value: NON_ZERO_VALUE }( - NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA + optimismPortal.depositTransaction{ value: 100 }( + address(1), 0, 50000, false, hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000" ); } function test_depositTransaction_benchmark_1() external { - setPrevBaseFee(vm, address(op), 1 gwei); - op.depositTransaction{ value: NON_ZERO_VALUE }( - NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA + setPrevBaseFee(vm, address(optimismPortal), 1 gwei); + optimismPortal.depositTransaction{ value: 100 }( + address(1), 0, 50000, false, hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000" ); } function test_proveWithdrawalTransaction_benchmark() external { - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); } } contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer { function test_sendMessage_benchmark_0() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 1 gwei); + setPrevBaseFee(vm, address(optimismPortal), 1 gwei); // The amount of data typically sent during a bridge deposit. bytes memory data = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; vm.resumeGasMetering(); - L1Messenger.sendMessage(bob, data, uint32(100)); + l1CrossDomainMessenger.sendMessage(bob, data, uint32(100)); } function test_sendMessage_benchmark_1() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 10 gwei); + setPrevBaseFee(vm, address(optimismPortal), 10 gwei); // The amount of data typically sent during a bridge deposit. bytes memory data = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; vm.resumeGasMetering(); - L1Messenger.sendMessage(bob, data, uint32(100)); + l1CrossDomainMessenger.sendMessage(bob, data, uint32(100)); } } @@ -124,28 +127,28 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer { super.setUp(); deal(address(L1Token), alice, 100000, true); vm.startPrank(alice, alice); - L1Token.approve(address(L1Bridge), type(uint256).max); + L1Token.approve(address(l1StandardBridge), type(uint256).max); } function test_depositETH_benchmark_0() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 1 gwei); + setPrevBaseFee(vm, address(optimismPortal), 1 gwei); vm.resumeGasMetering(); - L1Bridge.depositETH{ value: 500 }(50000, hex""); + l1StandardBridge.depositETH{ value: 500 }(50000, hex""); } function test_depositETH_benchmark_1() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 10 gwei); + setPrevBaseFee(vm, address(optimismPortal), 10 gwei); vm.resumeGasMetering(); - L1Bridge.depositETH{ value: 500 }(50000, hex""); + l1StandardBridge.depositETH{ value: 500 }(50000, hex""); } function test_depositERC20_benchmark_0() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 1 gwei); + setPrevBaseFee(vm, address(optimismPortal), 1 gwei); vm.resumeGasMetering(); - L1Bridge.bridgeERC20({ + l1StandardBridge.bridgeERC20({ _localToken: address(L1Token), _remoteToken: address(L2Token), _amount: 100, @@ -156,9 +159,9 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer { function test_depositERC20_benchmark_1() external { vm.pauseGasMetering(); - setPrevBaseFee(vm, address(op), 10 gwei); + setPrevBaseFee(vm, address(optimismPortal), 10 gwei); vm.resumeGasMetering(); - L1Bridge.bridgeERC20({ + l1StandardBridge.bridgeERC20({ _localToken: address(L1Token), _remoteToken: address(L2Token), _amount: 100, @@ -171,21 +174,21 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer { contract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer { function setUp() public virtual override { super.setUp(); - deal(address(L1Token), address(L1Bridge), 100, true); + deal(address(L1Token), address(l1StandardBridge), 100, true); vm.mockCall( - address(L1Bridge.messenger()), + address(l1StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); - vm.startPrank(address(L1Bridge.messenger())); - vm.deal(address(L1Bridge.messenger()), 100); + vm.startPrank(address(l1StandardBridge.messenger())); + vm.deal(address(l1StandardBridge.messenger()), 100); } function test_finalizeETHWithdrawal_benchmark() external { // TODO: Make this more accurate. It is underestimating the cost because it pranks // the call coming from the messenger, which bypasses the portal // and oracle. - L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex""); + l1StandardBridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex""); } } @@ -194,12 +197,13 @@ contract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer { function setUp() public override { super.setUp(); - nextBlockNumber = oracle.nextBlockNumber(); + nextBlockNumber = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber); + address proposer = cfg.l2OutputOracleProposer(); vm.startPrank(proposer); } function test_proposeL2Output_benchmark() external { - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); } } diff --git a/packages/contracts-bedrock/test/CommonTest.t.sol b/packages/contracts-bedrock/test/CommonTest.t.sol index d3f3b16671da..5484c514ebb7 100644 --- a/packages/contracts-bedrock/test/CommonTest.t.sol +++ b/packages/contracts-bedrock/test/CommonTest.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.15; // Testing utilities import { Test, StdUtils } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; @@ -18,6 +17,12 @@ import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; +import { L1FeeVault } from "src/L2/L1FeeVault.sol"; +import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; +import { FeeVault } from "src/universal/FeeVault.sol"; +import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; +import { L1Block } from "src/L2/L1Block.sol"; +import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; import { FeeVault } from "src/universal/FeeVault.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { LegacyERC20ETH } from "src/legacy/LegacyERC20ETH.sol"; @@ -25,53 +30,191 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { Types } from "src/libraries/Types.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { Proxy } from "src/universal/Proxy.sol"; -import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; import { AddressManager } from "src/legacy/AddressManager.sol"; import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; import { IL1ChugSplashDeployer } from "src/legacy/L1ChugSplashProxy.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; +import { GovernanceToken } from "src/governance/GovernanceToken.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol"; +import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { Constants } from "src/libraries/Constants.sol"; +import { Deploy } from "scripts/Deploy.s.sol"; import { FFIInterface } from "test/setup/FFIInterface.sol"; -contract CommonTest is Test { +contract CommonTest is Deploy, Test { address alice = address(128); address bob = address(256); - address multisig = address(512); - address immutable ZERO_ADDRESS = address(0); - address immutable NON_ZERO_ADDRESS = address(1); - uint256 immutable NON_ZERO_VALUE = 100; - uint256 immutable ZERO_VALUE = 0; - uint64 immutable NON_ZERO_GASLIMIT = 50000; - bytes32 nonZeroHash = keccak256(abi.encode("NON_ZERO")); - bytes NON_ZERO_DATA = hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000"; + bytes32 constant nonZeroHash = keccak256(abi.encode("NON_ZERO")); event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); /// @dev OpenZeppelin Ownable.sol transferOwnership event event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + OptimismPortal optimismPortal; + L2OutputOracle l2OutputOracle; + SystemConfig systemConfig; + L1StandardBridge l1StandardBridge; + L1CrossDomainMessenger l1CrossDomainMessenger; + AddressManager addressManager; + L1ERC721Bridge l1ERC721Bridge; + OptimismMintableERC20Factory l1OptimismMintableERC20Factory; + ProtocolVersions protocolVersions; + + L2CrossDomainMessenger l2CrossDomainMessenger; + L2StandardBridge l2StandardBridge; + L2ToL1MessagePasser l2ToL1MessagePasser; + OptimismMintableERC20Factory l2OptimismMintableERC20Factory; + L2ERC721Bridge l2ERC721Bridge; + BaseFeeVault baseFeeVault; + SequencerFeeVault sequencerFeeVault; + L1FeeVault l1FeeVault; + GasPriceOracle gasPriceOracle; + L1Block l1Block; + LegacyMessagePasser legacyMessagePasser; + GovernanceToken governanceToken; + FFIInterface ffi; - function setUp() public virtual { + function setUp() public virtual override { // Give alice and bob some ETH vm.deal(alice, 1 << 16); vm.deal(bob, 1 << 16); - vm.deal(multisig, 1 << 16); vm.label(alice, "alice"); vm.label(bob, "bob"); - vm.label(multisig, "multisig"); // Make sure we have a non-zero base fee vm.fee(1000000000); + // Set the deterministic deployer in state + vm.etch( + 0x4e59b44847b379578588920cA78FbF26c0B4956C, + hex"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" + ); + ffi = new FFIInterface(); + + Deploy.setUp(); + Deploy.run(); + + // Set up L1 + optimismPortal = OptimismPortal(mustGetAddress("OptimismPortalProxy")); + l2OutputOracle = L2OutputOracle(mustGetAddress("L2OutputOracleProxy")); + systemConfig = SystemConfig(mustGetAddress("SystemConfigProxy")); + l1StandardBridge = L1StandardBridge(mustGetAddress("L1StandardBridgeProxy")); + l1CrossDomainMessenger = L1CrossDomainMessenger(mustGetAddress("L1CrossDomainMessengerProxy")); + addressManager = AddressManager(mustGetAddress("AddressManager")); + l1ERC721Bridge = L1ERC721Bridge(mustGetAddress("L1ERC721BridgeProxy")); + l1OptimismMintableERC20Factory = + OptimismMintableERC20Factory(mustGetAddress("OptimismMintableERC20FactoryProxy")); + protocolVersions = ProtocolVersions(mustGetAddress("ProtocolVersionsProxy")); + + vm.label(address(l2OutputOracle), "L2OutputOracle"); + vm.label(address(optimismPortal), "OptimismPortal"); + vm.label(address(systemConfig), "SystemConfig"); + vm.label(address(l1StandardBridge), "L1StandardBridge"); + vm.label(address(l1CrossDomainMessenger), "L1CrossDomainMessenger"); + vm.label(address(addressManager), "AddressManager"); + vm.label(address(l1ERC721Bridge), "L1ERC721Bridge"); + vm.label(address(l1OptimismMintableERC20Factory), "OptimismMintableERC20Factory"); + vm.label(address(protocolVersions), "ProtocolVersions"); + + // Set up L2. There are currently no proxies set in the L2 initialization. + vm.etch( + Predeploys.L2_CROSS_DOMAIN_MESSENGER, + address(new L2CrossDomainMessenger(address(l1CrossDomainMessenger))).code + ); + l2CrossDomainMessenger = L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); + l2CrossDomainMessenger.initialize(); + + vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code); + l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); + + vm.etch( + Predeploys.L2_STANDARD_BRIDGE, address(new L2StandardBridge(StandardBridge(payable(l1StandardBridge)))).code + ); + l2StandardBridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)); + l2StandardBridge.initialize(); + + vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(new OptimismMintableERC20Factory()).code); + l2OptimismMintableERC20Factory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); + l2OptimismMintableERC20Factory.initialize(Predeploys.L2_STANDARD_BRIDGE); + + vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code); + + vm.etch(Predeploys.L2_ERC721_BRIDGE, address(new L2ERC721Bridge(address(l1ERC721Bridge))).code); + l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); + l2ERC721Bridge.initialize(); + + vm.etch( + Predeploys.SEQUENCER_FEE_WALLET, + address( + new SequencerFeeVault(cfg.sequencerFeeVaultRecipient(), cfg.sequencerFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2) + ).code + ); + vm.etch( + Predeploys.BASE_FEE_VAULT, + address( + new BaseFeeVault(cfg.baseFeeVaultRecipient(), cfg.baseFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L1) + ).code + ); + vm.etch( + Predeploys.L1_FEE_VAULT, + address( + new L1FeeVault(cfg.l1FeeVaultRecipient(), cfg.l1FeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2) + ).code + ); + + sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); + baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); + l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); + + vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code); + l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); + + vm.etch(Predeploys.GAS_PRICE_ORACLE, address(new GasPriceOracle()).code); + gasPriceOracle = GasPriceOracle(Predeploys.GAS_PRICE_ORACLE); + + vm.etch(Predeploys.LEGACY_MESSAGE_PASSER, address(new LegacyMessagePasser()).code); + legacyMessagePasser = LegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); + + vm.etch(Predeploys.GOVERNANCE_TOKEN, address(new GovernanceToken()).code); + governanceToken = GovernanceToken(Predeploys.GOVERNANCE_TOKEN); + vm.store( + Predeploys.GOVERNANCE_TOKEN, + bytes32(uint256(3)), + bytes32(0x4f7074696d69736d000000000000000000000000000000000000000000000010) + ); + vm.store( + Predeploys.GOVERNANCE_TOKEN, + bytes32(uint256(4)), + bytes32(0x4f50000000000000000000000000000000000000000000000000000000000004) + ); + + // Set the governance token's owner to be the final system owner + address finalSystemOwner = cfg.finalSystemOwner(); + vm.prank(governanceToken.owner()); + governanceToken.transferOwnership(finalSystemOwner); + + vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, "OptimismMintableERC20Factory"); + vm.label(Predeploys.LEGACY_ERC20_ETH, "LegacyERC20ETH"); + vm.label(Predeploys.L2_STANDARD_BRIDGE, "L2StandardBridge"); + vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger"); + vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, "L2ToL1MessagePasser"); + vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault"); + vm.label(Predeploys.L2_ERC721_BRIDGE, "L2ERC721Bridge"); + vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault"); + vm.label(Predeploys.L1_FEE_VAULT, "L1FeeVault"); + vm.label(Predeploys.L1_BLOCK_ATTRIBUTES, "L1Block"); + vm.label(Predeploys.GAS_PRICE_ORACLE, "GasPriceOracle"); + vm.label(Predeploys.LEGACY_MESSAGE_PASSER, "LegacyMessagePasser"); + vm.label(Predeploys.GOVERNANCE_TOKEN, "GovernanceToken"); + vm.label(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), "L1CrossDomainMessenger_aliased"); } function emitTransactionDeposited( @@ -90,44 +233,26 @@ contract CommonTest is Test { } contract L2OutputOracle_Initializer is CommonTest { - // Test target - L2OutputOracle oracle; - L2OutputOracle oracleImpl; - - L2ToL1MessagePasser messagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); - - // Constructor arguments - address internal proposer = 0x000000000000000000000000000000000000AbBa; - address internal owner = 0x000000000000000000000000000000000000ACDC; - uint256 internal submissionInterval = 1800; - uint256 internal l2BlockTime = 2; - uint256 internal startingBlockNumber = 200; - uint256 internal startingTimestamp = 1000; - uint256 internal finalizationPeriodSeconds = 7 days; - address guardian; - - // Test data - uint256 initL1Time; - event OutputProposed( bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp ); event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); - // Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output + // @dev Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output function warpToProposeTime(uint256 _nextBlockNumber) public { - vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1); + vm.warp(l2OutputOracle.computeL2Timestamp(_nextBlockNumber) + 1); } /// @dev Helper function to propose an output. function proposeAnotherOutput() public { bytes32 proposedOutput2 = keccak256(abi.encode()); - uint256 nextBlockNumber = oracle.nextBlockNumber(); - uint256 nextOutputIndex = oracle.nextOutputIndex(); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex(); warpToProposeTime(nextBlockNumber); - uint256 proposedNumber = oracle.latestBlockNumber(); + uint256 proposedNumber = l2OutputOracle.latestBlockNumber(); + uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval(); // Ensure the submissionInterval is enforced assertEq(nextBlockNumber, proposedNumber + submissionInterval); @@ -136,107 +261,29 @@ contract L2OutputOracle_Initializer is CommonTest { vm.expectEmit(true, true, true, true); emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp); + address proposer = cfg.l2OutputOracleProposer(); vm.prank(proposer); - oracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0); + l2OutputOracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0); } function setUp() public virtual override { super.setUp(); - guardian = makeAddr("guardian"); // By default the first block has timestamp and number zero, which will cause underflows in the // tests, so we'll move forward to these block values. - initL1Time = startingTimestamp + 1; - vm.warp(initL1Time); - vm.roll(startingBlockNumber); - // Deploy the L2OutputOracle and transfer owernship to the proposer - oracleImpl = new L2OutputOracle({ - _submissionInterval: submissionInterval, - _l2BlockTime: l2BlockTime, - _finalizationPeriodSeconds: finalizationPeriodSeconds - }); - Proxy proxy = new Proxy(multisig); - vm.prank(multisig); - proxy.upgradeToAndCall( - address(oracleImpl), - abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp, proposer, owner)) - ); - oracle = L2OutputOracle(address(proxy)); - vm.label(address(oracle), "L2OutputOracle"); - - // Set the L2ToL1MessagePasser at the correct address - vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code); - - vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, "L2ToL1MessagePasser"); + vm.warp(cfg.l2OutputOracleStartingTimestamp() + 1); + vm.roll(cfg.l2OutputOracleStartingBlockNumber() + 1); } } contract Portal_Initializer is L2OutputOracle_Initializer { - // Test target - OptimismPortal internal opImpl; - OptimismPortal internal op; - SystemConfig systemConfig; - event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to); - - function setUp() public virtual override { - super.setUp(); - - Proxy systemConfigProxy = new Proxy(multisig); - - SystemConfig systemConfigImpl = new SystemConfig(); - - vm.prank(multisig); - systemConfigProxy.upgradeToAndCall( - address(systemConfigImpl), - abi.encodeCall( - SystemConfig.initialize, - ( - address(1), //_owner, - 0, //_overhead, - 10000, //_scalar, - bytes32(0), //_batcherHash, - 30_000_000, //_gasLimit, - address(0), //_unsafeBlockSigner, - Constants.DEFAULT_RESOURCE_CONFIG(), //_config, - 0, //_startBlock - address(0xff), // _batchInbox - SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: address(0), - l1ERC721Bridge: address(0), - l1StandardBridge: address(0), - l2OutputOracle: address(oracle), - optimismPortal: address(op), - optimismMintableERC20Factory: address(0) - }) - ) - ) - ); - - systemConfig = SystemConfig(address(systemConfigProxy)); - - opImpl = new OptimismPortal(); - - Proxy proxy = new Proxy(multisig); - vm.prank(multisig); - proxy.upgradeToAndCall( - address(opImpl), abi.encodeCall(OptimismPortal.initialize, (oracle, guardian, systemConfig, false)) - ); - op = OptimismPortal(payable(address(proxy))); - vm.label(address(op), "OptimismPortal"); - } } contract Messenger_Initializer is Portal_Initializer { - AddressManager internal addressManager; - L1CrossDomainMessenger internal L1Messenger; - L2CrossDomainMessenger internal L2Messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER); - event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); - event SentMessageExtension1(address indexed sender, uint256 value); - event MessagePassed( uint256 indexed nonce, address indexed sender, @@ -246,10 +293,8 @@ contract Messenger_Initializer is Portal_Initializer { bytes data, bytes32 withdrawalHash ); - event RelayedMessage(bytes32 indexed msgHash); event FailedRelayedMessage(bytes32 indexed msgHash); - event TransactionDeposited( address indexed from, address indexed to, @@ -259,49 +304,10 @@ contract Messenger_Initializer is Portal_Initializer { bool isCreation, bytes data ); - event WhatHappened(bool success, bytes returndata); - - function setUp() public virtual override { - super.setUp(); - - // Deploy the address manager - vm.prank(multisig); - addressManager = new AddressManager(); - - // Setup implementation - L1CrossDomainMessenger L1MessengerImpl = new L1CrossDomainMessenger(); - - // Setup the address manager and proxy - vm.prank(multisig); - addressManager.setAddress("OVM_L1CrossDomainMessenger", address(L1MessengerImpl)); - ResolvedDelegateProxy proxy = new ResolvedDelegateProxy( - addressManager, - "OVM_L1CrossDomainMessenger" - ); - L1Messenger = L1CrossDomainMessenger(address(proxy)); - L1Messenger.initialize(op); - - vm.etch(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(new L2CrossDomainMessenger(address(L1Messenger))).code); - - L2Messenger.initialize(); - - // Label addresses - vm.label(address(addressManager), "AddressManager"); - vm.label(address(L1MessengerImpl), "L1CrossDomainMessenger_Impl"); - vm.label(address(L1Messenger), "L1CrossDomainMessenger_Proxy"); - vm.label(Predeploys.LEGACY_ERC20_ETH, "LegacyERC20ETH"); - vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger"); - - vm.label(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)), "L1CrossDomainMessenger_aliased"); - } } contract Bridge_Initializer is Messenger_Initializer { - L1StandardBridge L1Bridge; - L2StandardBridge L2Bridge; - OptimismMintableERC20Factory L2TokenFactory; - OptimismMintableERC20Factory L1TokenFactory; ERC20 L1Token; ERC20 BadL1Token; OptimismMintableERC20 L2Token; @@ -359,44 +365,10 @@ contract Bridge_Initializer is Messenger_Initializer { function setUp() public virtual override { super.setUp(); - vm.label(Predeploys.L2_STANDARD_BRIDGE, "L2StandardBridge"); - vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, "OptimismMintableERC20Factory"); - - // Deploy the L1 bridge and initialize it with the address of the - // L1CrossDomainMessenger - L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig); - vm.mockCall(multisig, abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector), abi.encode(true)); - vm.startPrank(multisig); - proxy.setCode(address(new L1StandardBridge()).code); - vm.clearMockedCalls(); - address L1Bridge_Impl = proxy.getImplementation(); - vm.stopPrank(); - - L1Bridge = L1StandardBridge(payable(address(proxy))); - L1Bridge.initialize({ _messenger: L1Messenger }); - - vm.label(address(proxy), "L1StandardBridge_Proxy"); - vm.label(address(L1Bridge_Impl), "L1StandardBridge_Impl"); - - // Deploy the L2StandardBridge, move it to the correct predeploy - // address and then initialize it. It is safe to call initialize directly - // on the proxy because the bytecode was set in state with `etch`. - vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(new L2StandardBridge(StandardBridge(payable(proxy)))).code); - L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)); - L2Bridge.initialize(); - - // Set up the L2 mintable token factory - OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory(); - vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code); - L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); - L2TokenFactory.initialize(Predeploys.L2_STANDARD_BRIDGE); - - vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code); - L1Token = new ERC20("Native L1 Token", "L1T"); LegacyL2Token = new LegacyMintableERC20({ - _l2Bridge: address(L2Bridge), + _l2Bridge: address(l2StandardBridge), _l1Token: address(L1Token), _name: string.concat("LegacyL2-", L1Token.name()), _symbol: string.concat("LegacyL2-", L1Token.symbol()) @@ -405,7 +377,7 @@ contract Bridge_Initializer is Messenger_Initializer { // Deploy the L2 ERC20 now L2Token = OptimismMintableERC20( - L2TokenFactory.createStandardL2Token( + l2OptimismMintableERC20Factory.createStandardL2Token( address(L1Token), string(abi.encodePacked("L2-", L1Token.name())), string(abi.encodePacked("L2-", L1Token.symbol())) @@ -413,7 +385,7 @@ contract Bridge_Initializer is Messenger_Initializer { ); BadL2Token = OptimismMintableERC20( - L2TokenFactory.createStandardL2Token( + l2OptimismMintableERC20Factory.createStandardL2Token( address(1), string(abi.encodePacked("L2-", L1Token.name())), string(abi.encodePacked("L2-", L1Token.symbol())) @@ -421,18 +393,9 @@ contract Bridge_Initializer is Messenger_Initializer { ); NativeL2Token = new ERC20("Native L2 Token", "L2T"); - Proxy factoryProxy = new Proxy(multisig); - OptimismMintableERC20Factory L1TokenFactoryImpl = new OptimismMintableERC20Factory(); - - vm.prank(multisig); - factoryProxy.upgradeToAndCall( - address(L1TokenFactoryImpl), abi.encodeCall(OptimismMintableERC20Factory.initialize, address(L1Bridge)) - ); - - L1TokenFactory = OptimismMintableERC20Factory(address(factoryProxy)); RemoteL1Token = OptimismMintableERC20( - L1TokenFactory.createStandardL2Token( + l1OptimismMintableERC20Factory.createStandardL2Token( address(NativeL2Token), string(abi.encodePacked("L1-", NativeL2Token.name())), string(abi.encodePacked("L1-", NativeL2Token.symbol())) @@ -440,7 +403,7 @@ contract Bridge_Initializer is Messenger_Initializer { ); BadL1Token = OptimismMintableERC20( - L1TokenFactory.createStandardL2Token( + l1OptimismMintableERC20Factory.createStandardL2Token( address(1), string(abi.encodePacked("L1-", NativeL2Token.name())), string(abi.encodePacked("L1-", NativeL2Token.symbol())) @@ -449,52 +412,7 @@ contract Bridge_Initializer is Messenger_Initializer { } } -contract ERC721Bridge_Initializer is Bridge_Initializer { - L1ERC721Bridge L1NFTBridge; - L2ERC721Bridge L2NFTBridge; - - function setUp() public virtual override { - super.setUp(); - - // Deploy the L1ERC721Bridge. - L1ERC721Bridge l1BridgeImpl = new L1ERC721Bridge(); - Proxy l1BridgeProxy = new Proxy(multisig); - - vm.prank(multisig); - l1BridgeProxy.upgradeToAndCall( - address(l1BridgeImpl), abi.encodeCall(L1ERC721Bridge.initialize, (CrossDomainMessenger(L1Messenger))) - ); - - L1NFTBridge = L1ERC721Bridge(address(l1BridgeProxy)); - - // Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address. - L2ERC721Bridge l2BridgeImpl = new L2ERC721Bridge(address(L1NFTBridge)); - Proxy l2BridgeProxy = new Proxy(multisig); - vm.etch(Predeploys.L2_ERC721_BRIDGE, address(l2BridgeProxy).code); - - // set the storage slot for admin - bytes32 OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - vm.store(Predeploys.L2_ERC721_BRIDGE, OWNER_KEY, bytes32(uint256(uint160(multisig)))); - - vm.prank(multisig); - Proxy(payable(Predeploys.L2_ERC721_BRIDGE)).upgradeToAndCall( - address(l2BridgeImpl), abi.encodeCall(L2ERC721Bridge.initialize, ()) - ); - - // Set up a reference to the L2ERC721Bridge. - L2NFTBridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); - - // Label the L1 and L2 bridges. - vm.label(address(L1NFTBridge), "L1ERC721Bridge"); - vm.label(address(L2NFTBridge), "L2ERC721Bridge"); - } -} - contract FeeVault_Initializer is Bridge_Initializer { - SequencerFeeVault vault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); - address constant recipient = address(1024); - event Withdrawal(uint256 value, address to, address from); - event Withdrawal(uint256 value, address to, address from, FeeVault.WithdrawalNetwork withdrawalNetwork); } diff --git a/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol index df0e34a5f7e6..8aa4c697ca14 100644 --- a/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol @@ -1,30 +1,31 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; + // Testing utilities import { Test } from "forge-std/Test.sol"; -import { Messenger_Initializer, Test } from "test/CommonTest.t.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; - -import { Reverter, CallerCaller } from "test/mocks/Callers.sol"; +import { Messenger_Initializer } from "test/CommonTest.t.sol"; +import { CallerCaller, Reverter } from "test/mocks/Callers.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { Encoding } from "src/libraries/Encoding.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; + // CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2 // CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract. contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { /// @dev Ensure that baseGas passes for the max value of _minGasLimit, /// this is about 4 Billion. function test_baseGas_succeeds() external view { - L1Messenger.baseGas(hex"ff", type(uint32).max); + l1CrossDomainMessenger.baseGas(hex"ff", type(uint32).max); } /// @dev Fuzz for other values which might cause a revert in baseGas. function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view { - L1Messenger.baseGas(hex"ff", _minGasLimit); + l1CrossDomainMessenger.baseGas(hex"ff", _minGasLimit); } /// @notice The baseGas function should always return a value greater than @@ -33,8 +34,8 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { /// gas to the OptimismPortal. function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit) external { vm.assume(_data.length <= type(uint64).max); - uint64 baseGas = L1Messenger.baseGas(_data, _minGasLimit); - uint64 minGasLimit = op.minimumGasLimit(uint64(_data.length)); + uint64 baseGas = l1CrossDomainMessenger.baseGas(_data, _minGasLimit); + uint64 minGasLimit = optimismPortal.minimumGasLimit(uint64(_data.length)); assertTrue(baseGas >= minGasLimit); } } @@ -45,18 +46,18 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { contract ExternalRelay is Test { address internal op; address internal fuzzedSender; - L1CrossDomainMessenger internal L1Messenger; + L1CrossDomainMessenger internal l1CrossDomainMessenger; event FailedRelayedMessage(bytes32 indexed msgHash); constructor(L1CrossDomainMessenger _l1Messenger, address _op) { - L1Messenger = _l1Messenger; + l1CrossDomainMessenger = _l1Messenger; op = _op; } /// @notice Internal helper function to relay a message and perform assertions. function _internalRelay(address _innerSender) internal { - address initialSender = L1Messenger.xDomainMessageSender(); + address initialSender = l1CrossDomainMessenger.xDomainMessageSender(); bytes memory callMessage = getCallData(); @@ -73,7 +74,7 @@ contract ExternalRelay is Test { emit FailedRelayedMessage(hash); vm.prank(address(op)); - L1Messenger.relayMessage({ + l1CrossDomainMessenger.relayMessage({ _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), _sender: _innerSender, _target: address(this), @@ -82,9 +83,9 @@ contract ExternalRelay is Test { _message: callMessage }); - assertTrue(L1Messenger.failedMessages(hash)); - assertFalse(L1Messenger.successfulMessages(hash)); - assertEq(initialSender, L1Messenger.xDomainMessageSender()); + assertTrue(l1CrossDomainMessenger.failedMessages(hash)); + assertFalse(l1CrossDomainMessenger.successfulMessages(hash)); + assertEq(initialSender, l1CrossDomainMessenger.xDomainMessageSender()); } /// @notice externalCallWithMinGas is called by the CrossDomainMessenger. @@ -119,7 +120,7 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { function setUp() public override { super.setUp(); - er = new ExternalRelay(L1Messenger, address(op)); + er = new ExternalRelay(l1CrossDomainMessenger, address(optimismPortal)); } /// @dev This test mocks an OptimismPortal call to the L1CrossDomainMessenger via @@ -151,9 +152,9 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { }); // set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - vm.prank(address(op)); - L1Messenger.relayMessage({ + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage({ _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), _sender: sender, _target: target, @@ -162,11 +163,11 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { _message: callMessage }); - assertTrue(L1Messenger.successfulMessages(hash)); - assertEq(L1Messenger.failedMessages(hash), false); + assertTrue(l1CrossDomainMessenger.successfulMessages(hash)); + assertEq(l1CrossDomainMessenger.failedMessages(hash), false); // Ensures that the `xDomainMsgSender` is set back to `Predeploys.L2_CROSS_DOMAIN_MESSENGER` vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L1Messenger.xDomainMessageSender(); + l1CrossDomainMessenger.xDomainMessageSender(); } } diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol index 34330b23542c..bc7b06f8c9ac 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol @@ -63,7 +63,7 @@ contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer { vm.recordLogs(); vm.prank(alice); - op.depositTransaction({ + optimismPortal.depositTransaction({ _to: address(setter), _value: 0, _gasLimit: 30_000, diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol index c059872c784a..6eb095cd216f 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol @@ -44,9 +44,9 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { // set the xDomainMsgSender storage slot bytes32 key = bytes32(uint256(204)); bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice)); - vm.store(address(L2Messenger), key, value); + vm.store(address(l2CrossDomainMessenger), key, value); - vm.prank(address(L2Messenger)); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("CrossDomainOwnable2: caller is not the owner"); setter.set(1); } @@ -69,8 +69,10 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { vm.expectEmit(true, true, true, true); emit FailedRelayedMessage(hash); - vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); - L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message); + vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger))); + l2CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message + ); assertEq(setter.value(), 0); } @@ -81,8 +83,8 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { // Simulate the L2 execution where the call is coming from // the L1CrossDomainMessenger - vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); - L2Messenger.relayMessage( + vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger))); + l2CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce(1, 1), owner, address(setter), diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol index dbe2c9af3b4c..f770ae7d2bed 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol @@ -73,9 +73,9 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { // set the xDomainMsgSender storage slot bytes32 key = bytes32(uint256(204)); bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob); - vm.store(address(L2Messenger), key, value); + vm.store(address(l2CrossDomainMessenger), key, value); - vm.prank(address(L2Messenger)); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("CrossDomainOwnable3: caller is not the owner"); setter.set(1); } @@ -109,11 +109,13 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { // It should be a failed message. The revert is caught, // so we cannot expectRevert here. - vm.expectEmit(true, true, true, true, address(L2Messenger)); + vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger)); emit FailedRelayedMessage(hash); - vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); - L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message); + vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger))); + l2CrossDomainMessenger.relayMessage( + Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message + ); assertEq(setter.value(), 0); } @@ -212,8 +214,8 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { // Simulate the L2 execution where the call is coming from // the L1CrossDomainMessenger - vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); - L2Messenger.relayMessage( + vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger))); + l2CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce(1, 1), bob, address(setter), diff --git a/packages/contracts-bedrock/test/DelayedVetoable.t.sol b/packages/contracts-bedrock/test/DelayedVetoable.t.sol index 27d0670a5875..90a259786585 100644 --- a/packages/contracts-bedrock/test/DelayedVetoable.t.sol +++ b/packages/contracts-bedrock/test/DelayedVetoable.t.sol @@ -146,7 +146,7 @@ contract DelayedVetoable_HandleCall_TestFail is DelayedVetoable_Init { /// @dev Only the initiator can initiate a call. function test_handleCall_unauthorizedInitiation_reverts() external { vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, initiator, address(this))); - (bool success,) = address(delayedVetoable).call(NON_ZERO_DATA); + (bool success,) = address(delayedVetoable).call(hex"00001234"); assertTrue(success); } diff --git a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol index eccf19f08950..02b8cab16fee 100644 --- a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol @@ -37,9 +37,9 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init { vm.warp(1690906994); // Propose 2 mock outputs - vm.startPrank(oracle.PROPOSER()); + vm.startPrank(l2OutputOracle.PROPOSER()); for (uint256 i; i < 2; i++) { - oracle.proposeL2Output(bytes32(i + 1), oracle.nextBlockNumber(), blockhash(i), i); + l2OutputOracle.proposeL2Output(bytes32(i + 1), l2OutputOracle.nextBlockNumber(), blockhash(i), i); // Advance 1 block vm.roll(block.number + 1); @@ -52,7 +52,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init { blockOracle.checkpoint(); // Set the extra data for the game creation - extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, block.number - 1); + extraData = abi.encode(l2OutputOracle.SUBMISSION_INTERVAL() * 2, block.number - 1); // Deploy an implementation of the fault game gameImpl = new FaultDisputeGame( @@ -61,7 +61,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init { 4, Duration.wrap(7 days), new AlphabetVM(absolutePrestate), - oracle, + l2OutputOracle, blockOracle ); // Register the game implementation with the factory. @@ -127,7 +127,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { function test_initialize_l1HeadTooOld_reverts() public { // Store a mock block hash for the genesis block. The timestamp will default to 0. vm.store(address(gameImpl.BLOCK_ORACLE()), keccak256(abi.encode(0, 0)), bytes32(uint256(1))); - bytes memory _extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, 0); + bytes memory _extraData = abi.encode(l2OutputOracle.SUBMISSION_INTERVAL() * 2, 0); vm.expectRevert(L1HeadTooOld.selector); factory.create(GAME_TYPE, ROOT_CLAIM, _extraData); @@ -138,11 +138,14 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { /// to dispute the first output root by using genesis as the starting point. /// For now, it is critical that the first proposed output root of an OP stack /// chain is done so by an honest party. + + /* function test_initialize_firstOutput_reverts() public { uint256 submissionInterval = oracle.SUBMISSION_INTERVAL(); vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x11)); factory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(submissionInterval, block.number - 1)); } + */ /// @dev Tests that the `create` function reverts when the rootClaim does not disagree with the outcome. function testFuzz_initialize_badRootStatus_reverts(Claim rootClaim, bytes calldata extraData) public { @@ -160,12 +163,12 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { // Starting (FaultDisputeGame.OutputProposal memory startingProp, FaultDisputeGame.OutputProposal memory disputedProp) = gameProxy.proposals(); - Types.OutputProposal memory starting = oracle.getL2Output(startingProp.index); + Types.OutputProposal memory starting = l2OutputOracle.getL2Output(startingProp.index); assertEq(startingProp.index, 0); assertEq(startingProp.l2BlockNumber, starting.l2BlockNumber); assertEq(Hash.unwrap(startingProp.outputRoot), starting.outputRoot); // Disputed - Types.OutputProposal memory disputed = oracle.getL2Output(disputedProp.index); + Types.OutputProposal memory disputed = l2OutputOracle.getL2Output(disputedProp.index); assertEq(disputedProp.index, 1); assertEq(disputedProp.l2BlockNumber, disputed.l2BlockNumber); assertEq(Hash.unwrap(disputedProp.outputRoot), disputed.outputRoot); diff --git a/packages/contracts-bedrock/test/FeeVault.t.sol b/packages/contracts-bedrock/test/FeeVault.t.sol index 3b877840935c..bbfa3792443a 100644 --- a/packages/contracts-bedrock/test/FeeVault.t.sol +++ b/packages/contracts-bedrock/test/FeeVault.t.sol @@ -3,48 +3,23 @@ pragma solidity 0.8.15; // Testing utilities import { Bridge_Initializer } from "test/CommonTest.t.sol"; -import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; - -// Libraries -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract dependencies -import { FeeVault } from "src/universal/FeeVault.sol"; // Target contract -import { L1FeeVault } from "src/L2/L1FeeVault.sol"; +import { FeeVault } from "src/universal/FeeVault.sol"; // Test the implementations of the FeeVault contract FeeVault_Test is Bridge_Initializer { - BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); - L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); - - uint256 constant otherMinimumWithdrawalAmount = 10 ether; - - /// @dev Sets up the test suite. - function setUp() public override { - super.setUp(); - vm.etch( - Predeploys.BASE_FEE_VAULT, - address(new BaseFeeVault(alice, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1)).code - ); - vm.etch( - Predeploys.L1_FEE_VAULT, - address(new L1FeeVault(bob, otherMinimumWithdrawalAmount, FeeVault.WithdrawalNetwork.L2)).code - ); - - vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault"); - vm.label(Predeploys.L1_FEE_VAULT, "L1FeeVault"); + /// @dev Tests that the constructor sets the correct values. + function test_constructor_l1FeeVault_succeeds() external { + assertEq(l1FeeVault.RECIPIENT(), cfg.l1FeeVaultRecipient()); + assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.l1FeeVaultMinimumWithdrawalAmount()); + assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L2)); } /// @dev Tests that the constructor sets the correct values. - function test_constructor_succeeds() external { - assertEq(baseFeeVault.RECIPIENT(), alice); - assertEq(l1FeeVault.RECIPIENT(), bob); - assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), NON_ZERO_VALUE); - assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), otherMinimumWithdrawalAmount); + function test_constructor_baseFeeVault_succeeds() external { + assertEq(baseFeeVault.RECIPIENT(), cfg.baseFeeVaultRecipient()); + assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.baseFeeVaultMinimumWithdrawalAmount()); assertEq(uint8(baseFeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L1)); - assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L2)); } } diff --git a/packages/contracts-bedrock/test/GasPriceOracle.t.sol b/packages/contracts-bedrock/test/GasPriceOracle.t.sol index 26e571ecb550..cee8c888f795 100644 --- a/packages/contracts-bedrock/test/GasPriceOracle.t.sol +++ b/packages/contracts-bedrock/test/GasPriceOracle.t.sol @@ -4,20 +4,11 @@ pragma solidity 0.8.15; // Testing utilities import { CommonTest } from "test/CommonTest.t.sol"; -// Target contract dependencies -import { L1Block } from "src/L2/L1Block.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract -import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; - contract GasPriceOracle_Test is CommonTest { event OverheadUpdated(uint256); event ScalarUpdated(uint256); event DecimalsUpdated(uint256); - GasPriceOracle gasOracle; - L1Block l1Block; address depositor; // The initial L1 context values @@ -33,17 +24,9 @@ contract GasPriceOracle_Test is CommonTest { /// @dev Sets up the test suite. function setUp() public virtual override { super.setUp(); - // place the L1Block contract at the predeploy address - vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code); - l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); depositor = l1Block.DEPOSITOR_ACCOUNT(); - // We are not setting the gas oracle at its predeploy - // address for simplicity purposes. Nothing in this test - // requires it to be at a particular address - gasOracle = new GasPriceOracle(); - vm.prank(depositor); l1Block.setL1BlockValues({ _number: number, @@ -59,43 +42,43 @@ contract GasPriceOracle_Test is CommonTest { /// @dev Tests that `l1BaseFee` is set correctly. function test_l1BaseFee_succeeds() external { - assertEq(gasOracle.l1BaseFee(), basefee); + assertEq(gasPriceOracle.l1BaseFee(), basefee); } /// @dev Tests that `gasPrice` is set correctly. function test_gasPrice_succeeds() external { vm.fee(100); - uint256 gasPrice = gasOracle.gasPrice(); + uint256 gasPrice = gasPriceOracle.gasPrice(); assertEq(gasPrice, 100); } /// @dev Tests that `baseFee` is set correctly. function test_baseFee_succeeds() external { vm.fee(64); - uint256 gasPrice = gasOracle.baseFee(); + uint256 gasPrice = gasPriceOracle.baseFee(); assertEq(gasPrice, 64); } /// @dev Tests that `scalar` is set correctly. function test_scalar_succeeds() external { - assertEq(gasOracle.scalar(), l1FeeScalar); + assertEq(gasPriceOracle.scalar(), l1FeeScalar); } /// @dev Tests that `overhead` is set correctly. function test_overhead_succeeds() external { - assertEq(gasOracle.overhead(), l1FeeOverhead); + assertEq(gasPriceOracle.overhead(), l1FeeOverhead); } /// @dev Tests that `decimals` is set correctly. function test_decimals_succeeds() external { - assertEq(gasOracle.decimals(), 6); - assertEq(gasOracle.DECIMALS(), 6); + assertEq(gasPriceOracle.decimals(), 6); + assertEq(gasPriceOracle.DECIMALS(), 6); } /// @dev Tests that `setGasPrice` reverts since it was removed in bedrock. function test_setGasPrice_doesNotExist_reverts() external { (bool success, bytes memory returndata) = - address(gasOracle).call(abi.encodeWithSignature("setGasPrice(uint256)", 1)); + address(gasPriceOracle).call(abi.encodeWithSignature("setGasPrice(uint256)", 1)); assertEq(success, false); assertEq(returndata, hex""); @@ -104,7 +87,7 @@ contract GasPriceOracle_Test is CommonTest { /// @dev Tests that `setL1BaseFee` reverts since it was removed in bedrock. function test_setL1BaseFee_doesNotExist_reverts() external { (bool success, bytes memory returndata) = - address(gasOracle).call(abi.encodeWithSignature("setL1BaseFee(uint256)", 1)); + address(gasPriceOracle).call(abi.encodeWithSignature("setL1BaseFee(uint256)", 1)); assertEq(success, false); assertEq(returndata, hex""); diff --git a/packages/contracts-bedrock/test/GovernanceToken.t.sol b/packages/contracts-bedrock/test/GovernanceToken.t.sol index ec3c7902af7e..1b9f5edca4e0 100644 --- a/packages/contracts-bedrock/test/GovernanceToken.t.sol +++ b/packages/contracts-bedrock/test/GovernanceToken.t.sol @@ -4,39 +4,35 @@ pragma solidity 0.8.15; // Testing utilities import { CommonTest } from "test/CommonTest.t.sol"; -// Target contract -import { GovernanceToken } from "src/governance/GovernanceToken.sol"; - contract GovernanceToken_Test is CommonTest { - address constant owner = address(0x1234); - address constant rando = address(0x5678); - GovernanceToken internal gov; + address owner; + address rando; /// @dev Sets up the test suite. function setUp() public virtual override { super.setUp(); - vm.prank(owner); - gov = new GovernanceToken(); + owner = governanceToken.owner(); + rando = makeAddr("rando"); } /// @dev Tests that the constructor sets the correct initial state. function test_constructor_succeeds() external { - assertEq(gov.owner(), owner); - assertEq(gov.name(), "Optimism"); - assertEq(gov.symbol(), "OP"); - assertEq(gov.decimals(), 18); - assertEq(gov.totalSupply(), 0); + assertEq(governanceToken.owner(), owner); + assertEq(governanceToken.name(), "Optimism"); + assertEq(governanceToken.symbol(), "OP"); + assertEq(governanceToken.decimals(), 18); + assertEq(governanceToken.totalSupply(), 0); } /// @dev Tests that the owner can successfully call `mint`. function test_mint_fromOwner_succeeds() external { // Mint 100 tokens. vm.prank(owner); - gov.mint(owner, 100); + governanceToken.mint(owner, 100); // Balances have updated correctly. - assertEq(gov.balanceOf(owner), 100); - assertEq(gov.totalSupply(), 100); + assertEq(governanceToken.balanceOf(owner), 100); + assertEq(governanceToken.totalSupply(), 100); } /// @dev Tests that `mint` reverts when called by a non-owner. @@ -44,130 +40,130 @@ contract GovernanceToken_Test is CommonTest { // Mint 100 tokens as rando. vm.prank(rando); vm.expectRevert("Ownable: caller is not the owner"); - gov.mint(owner, 100); + governanceToken.mint(owner, 100); // Balance does not update. - assertEq(gov.balanceOf(owner), 0); - assertEq(gov.totalSupply(), 0); + assertEq(governanceToken.balanceOf(owner), 0); + assertEq(governanceToken.totalSupply(), 0); } /// @dev Tests that the owner can successfully call `burn`. function test_burn_succeeds() external { // Mint 100 tokens to rando. vm.prank(owner); - gov.mint(rando, 100); + governanceToken.mint(rando, 100); // Rando burns their tokens. vm.prank(rando); - gov.burn(50); + governanceToken.burn(50); // Balances have updated correctly. - assertEq(gov.balanceOf(rando), 50); - assertEq(gov.totalSupply(), 50); + assertEq(governanceToken.balanceOf(rando), 50); + assertEq(governanceToken.totalSupply(), 50); } /// @dev Tests that the owner can successfully call `burnFrom`. function test_burnFrom_succeeds() external { // Mint 100 tokens to rando. vm.prank(owner); - gov.mint(rando, 100); + governanceToken.mint(rando, 100); // Rando approves owner to burn 50 tokens. vm.prank(rando); - gov.approve(owner, 50); + governanceToken.approve(owner, 50); // Owner burns 50 tokens from rando. vm.prank(owner); - gov.burnFrom(rando, 50); + governanceToken.burnFrom(rando, 50); // Balances have updated correctly. - assertEq(gov.balanceOf(rando), 50); - assertEq(gov.totalSupply(), 50); + assertEq(governanceToken.balanceOf(rando), 50); + assertEq(governanceToken.totalSupply(), 50); } /// @dev Tests that `transfer` correctly transfers tokens. function test_transfer_succeeds() external { // Mint 100 tokens to rando. vm.prank(owner); - gov.mint(rando, 100); + governanceToken.mint(rando, 100); // Rando transfers 50 tokens to owner. vm.prank(rando); - gov.transfer(owner, 50); + governanceToken.transfer(owner, 50); // Balances have updated correctly. - assertEq(gov.balanceOf(owner), 50); - assertEq(gov.balanceOf(rando), 50); - assertEq(gov.totalSupply(), 100); + assertEq(governanceToken.balanceOf(owner), 50); + assertEq(governanceToken.balanceOf(rando), 50); + assertEq(governanceToken.totalSupply(), 100); } /// @dev Tests that `approve` correctly sets allowances. function test_approve_succeeds() external { // Mint 100 tokens to rando. vm.prank(owner); - gov.mint(rando, 100); + governanceToken.mint(rando, 100); // Rando approves owner to spend 50 tokens. vm.prank(rando); - gov.approve(owner, 50); + governanceToken.approve(owner, 50); // Allowances have updated. - assertEq(gov.allowance(rando, owner), 50); + assertEq(governanceToken.allowance(rando, owner), 50); } /// @dev Tests that `transferFrom` correctly transfers tokens. function test_transferFrom_succeeds() external { // Mint 100 tokens to rando. vm.prank(owner); - gov.mint(rando, 100); + governanceToken.mint(rando, 100); // Rando approves owner to spend 50 tokens. vm.prank(rando); - gov.approve(owner, 50); + governanceToken.approve(owner, 50); // Owner transfers 50 tokens from rando to owner. vm.prank(owner); - gov.transferFrom(rando, owner, 50); + governanceToken.transferFrom(rando, owner, 50); // Balances have updated correctly. - assertEq(gov.balanceOf(owner), 50); - assertEq(gov.balanceOf(rando), 50); - assertEq(gov.totalSupply(), 100); + assertEq(governanceToken.balanceOf(owner), 50); + assertEq(governanceToken.balanceOf(rando), 50); + assertEq(governanceToken.totalSupply(), 100); } /// @dev Tests that `increaseAllowance` correctly increases allowances. function test_increaseAllowance_succeeds() external { // Mint 100 tokens to rando. vm.prank(owner); - gov.mint(rando, 100); + governanceToken.mint(rando, 100); // Rando approves owner to spend 50 tokens. vm.prank(rando); - gov.approve(owner, 50); + governanceToken.approve(owner, 50); // Rando increases allowance by 50 tokens. vm.prank(rando); - gov.increaseAllowance(owner, 50); + governanceToken.increaseAllowance(owner, 50); // Allowances have updated. - assertEq(gov.allowance(rando, owner), 100); + assertEq(governanceToken.allowance(rando, owner), 100); } /// @dev Tests that `decreaseAllowance` correctly decreases allowances. function test_decreaseAllowance_succeeds() external { // Mint 100 tokens to rando. vm.prank(owner); - gov.mint(rando, 100); + governanceToken.mint(rando, 100); // Rando approves owner to spend 100 tokens. vm.prank(rando); - gov.approve(owner, 100); + governanceToken.approve(owner, 100); // Rando decreases allowance by 50 tokens. vm.prank(rando); - gov.decreaseAllowance(owner, 50); + governanceToken.decreaseAllowance(owner, 50); // Allowances have updated. - assertEq(gov.allowance(rando, owner), 50); + assertEq(governanceToken.allowance(rando, owner), 50); } } diff --git a/packages/contracts-bedrock/test/Initializable.t.sol b/packages/contracts-bedrock/test/Initializable.t.sol index e96989d8f680..47b4a2dd96c1 100644 --- a/packages/contracts-bedrock/test/Initializable.t.sol +++ b/packages/contracts-bedrock/test/Initializable.t.sol @@ -1,8 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; -import { console } from "forge-std/console.sol"; +import { Bridge_Initializer } from "test/CommonTest.t.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; @@ -13,19 +12,19 @@ import { OptimismPortal } from "src/L1/OptimismPortal.sol"; /// @dev Ensures that the `initialize()` function on contracts cannot be called more than /// once. This contract inherits from `ERC721Bridge_Initializer` because it is the /// deepest contract in the inheritance chain for setting up the system contracts. -contract Initializer_Test is ERC721Bridge_Initializer { +contract Initializer_Test is Bridge_Initializer { function test_cannotReinitializeL1_succeeds() public { vm.expectRevert("Initializable: contract is already initialized"); - L1Messenger.initialize(OptimismPortal(payable(address(0)))); + l1CrossDomainMessenger.initialize(OptimismPortal(payable(address(0)))); vm.expectRevert("Initializable: contract is already initialized"); - L1Bridge.initialize(CrossDomainMessenger(address(0))); + l1StandardBridge.initialize(CrossDomainMessenger(address(0))); vm.expectRevert("Initializable: contract is already initialized"); - oracle.initialize(0, 0, address(0), address(0)); + l2OutputOracle.initialize(0, 0, address(0), address(0)); vm.expectRevert("Initializable: contract is already initialized"); - op.initialize(L2OutputOracle(address(0)), address(0), SystemConfig(address(0)), false); + optimismPortal.initialize(L2OutputOracle(address(0)), address(0), SystemConfig(address(0)), false); vm.expectRevert("Initializable: contract is already initialized"); systemConfig.initialize({ @@ -56,6 +55,6 @@ contract Initializer_Test is ERC721Bridge_Initializer { }); vm.expectRevert("Initializable: contract is already initialized"); - L1NFTBridge.initialize(CrossDomainMessenger(address(0))); + l1ERC721Bridge.initialize(CrossDomainMessenger(address(0))); } } diff --git a/packages/contracts-bedrock/test/L1Block.t.sol b/packages/contracts-bedrock/test/L1Block.t.sol index f44f606a6270..bdc3623faacd 100644 --- a/packages/contracts-bedrock/test/L1Block.t.sol +++ b/packages/contracts-bedrock/test/L1Block.t.sol @@ -8,21 +8,19 @@ import { CommonTest } from "test/CommonTest.t.sol"; import { L1Block } from "src/L2/L1Block.sol"; contract L1BlockTest is CommonTest { - L1Block lb; address depositor; - bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1)); /// @dev Sets up the test suite. function setUp() public virtual override { super.setUp(); - lb = new L1Block(); - depositor = lb.DEPOSITOR_ACCOUNT(); + + depositor = l1Block.DEPOSITOR_ACCOUNT(); vm.prank(depositor); - lb.setL1BlockValues({ + l1Block.setL1BlockValues({ _number: uint64(1), _timestamp: uint64(2), _basefee: 3, - _hash: NON_ZERO_HASH, + _hash: keccak256(abi.encode(block.number)), _sequenceNumber: uint64(4), _batcherHash: bytes32(0), _l1FeeOverhead: 2, @@ -44,46 +42,46 @@ contract L1BlockTest is CommonTest { external { vm.prank(depositor); - lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs); - assertEq(lb.number(), n); - assertEq(lb.timestamp(), t); - assertEq(lb.basefee(), b); - assertEq(lb.hash(), h); - assertEq(lb.sequenceNumber(), s); - assertEq(lb.batcherHash(), bt); - assertEq(lb.l1FeeOverhead(), fo); - assertEq(lb.l1FeeScalar(), fs); + l1Block.setL1BlockValues(n, t, b, h, s, bt, fo, fs); + assertEq(l1Block.number(), n); + assertEq(l1Block.timestamp(), t); + assertEq(l1Block.basefee(), b); + assertEq(l1Block.hash(), h); + assertEq(l1Block.sequenceNumber(), s); + assertEq(l1Block.batcherHash(), bt); + assertEq(l1Block.l1FeeOverhead(), fo); + assertEq(l1Block.l1FeeScalar(), fs); } /// @dev Tests that `number` returns the correct value. function test_number_succeeds() external { - assertEq(lb.number(), uint64(1)); + assertEq(l1Block.number(), uint64(1)); } /// @dev Tests that `timestamp` returns the correct value. function test_timestamp_succeeds() external { - assertEq(lb.timestamp(), uint64(2)); + assertEq(l1Block.timestamp(), uint64(2)); } /// @dev Tests that `basefee` returns the correct value. function test_basefee_succeeds() external { - assertEq(lb.basefee(), 3); + assertEq(l1Block.basefee(), 3); } /// @dev Tests that `hash` returns the correct value. function test_hash_succeeds() external { - assertEq(lb.hash(), NON_ZERO_HASH); + assertEq(l1Block.hash(), keccak256(abi.encode(block.number))); } /// @dev Tests that `sequenceNumber` returns the correct value. function test_sequenceNumber_succeeds() external { - assertEq(lb.sequenceNumber(), uint64(4)); + assertEq(l1Block.sequenceNumber(), uint64(4)); } /// @dev Tests that `setL1BlockValues` can set max values. function test_updateValues_succeeds() external { vm.prank(depositor); - lb.setL1BlockValues({ + l1Block.setL1BlockValues({ _number: type(uint64).max, _timestamp: type(uint64).max, _basefee: type(uint256).max, diff --git a/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol index 8f2f4401378e..4d05977ff53b 100644 --- a/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol @@ -24,8 +24,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { /// @dev Tests that the version can be decoded from the message nonce. function test_messageVersion_succeeds() external { - (, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce()); - assertEq(version, L1Messenger.MESSAGE_VERSION()); + (, uint16 version) = Encoding.decodeVersionedNonce(l1CrossDomainMessenger.messageNonce()); + assertEq(version, l1CrossDomainMessenger.MESSAGE_VERSION()); } /// @dev Tests that the sendMessage function is able to send a single message. @@ -34,55 +34,57 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { function test_sendMessage_succeeds() external { // deposit transaction on the optimism portal should be called vm.expectCall( - address(op), + address(optimismPortal), abi.encodeWithSelector( OptimismPortal.depositTransaction.selector, Predeploys.L2_CROSS_DOMAIN_MESSENGER, 0, - L1Messenger.baseGas(hex"ff", 100), + l1CrossDomainMessenger.baseGas(hex"ff", 100), false, - Encoding.encodeCrossDomainMessage(L1Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff") + Encoding.encodeCrossDomainMessage( + l1CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff" + ) ) ); // TransactionDeposited event vm.expectEmit(true, true, true, true); emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)), + AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), Predeploys.L2_CROSS_DOMAIN_MESSENGER, 0, 0, - L1Messenger.baseGas(hex"ff", 100), + l1CrossDomainMessenger.baseGas(hex"ff", 100), false, - Encoding.encodeCrossDomainMessage(L1Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff") + Encoding.encodeCrossDomainMessage(l1CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff") ); // SentMessage event vm.expectEmit(true, true, true, true); - emit SentMessage(recipient, alice, hex"ff", L1Messenger.messageNonce(), 100); + emit SentMessage(recipient, alice, hex"ff", l1CrossDomainMessenger.messageNonce(), 100); // SentMessageExtension1 event vm.expectEmit(true, true, true, true); emit SentMessageExtension1(alice, 0); vm.prank(alice); - L1Messenger.sendMessage(recipient, hex"ff", uint32(100)); + l1CrossDomainMessenger.sendMessage(recipient, hex"ff", uint32(100)); } /// @dev Tests that the sendMessage function is able to send /// the same message twice. function test_sendMessage_twice_succeeds() external { - uint256 nonce = L1Messenger.messageNonce(); - L1Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); - L1Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); + uint256 nonce = l1CrossDomainMessenger.messageNonce(); + l1CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000)); + l1CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000)); // the nonce increments for each message sent - assertEq(nonce + 2, L1Messenger.messageNonce()); + assertEq(nonce + 2, l1CrossDomainMessenger.messageNonce()); } /// @dev Tests that the xDomainMessageSender reverts when not set. function test_xDomainSender_notSet_reverts() external { vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L1Messenger.xDomainMessageSender(); + l1CrossDomainMessenger.xDomainMessageSender(); } /// @dev Tests that the relayMessage function reverts when @@ -92,14 +94,14 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); // Expect a revert. vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time"); // Try to relay a v2 message. - vm.prank(address(op)); - L2Messenger.relayMessage( + vm.prank(address(optimismPortal)); + l2CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce sender, target, @@ -118,8 +120,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { vm.expectCall(target, hex"1111"); // set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - vm.prank(address(op)); + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.prank(address(optimismPortal)); vm.expectEmit(true, true, true, true); @@ -129,7 +131,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { emit RelayedMessage(hash); - L1Messenger.relayMessage( + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce sender, target, @@ -139,28 +141,28 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // the message hash is in the successfulMessages mapping - assert(L1Messenger.successfulMessages(hash)); + assert(l1CrossDomainMessenger.successfulMessages(hash)); // it is not in the received messages mapping - assertEq(L1Messenger.failedMessages(hash), false); + assertEq(l1CrossDomainMessenger.failedMessages(hash), false); } /// @dev Tests that relayMessage reverts if attempting to relay a message /// sent to an L1 system contract. function test_relayMessage_toSystemContract_reverts() external { // set the target to be the OptimismPortal - address target = address(op); + address target = address(optimismPortal); address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; bytes memory message = hex"1111"; - vm.prank(address(op)); + vm.prank(address(optimismPortal)); vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); - L1Messenger.relayMessage( + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message ); - vm.store(address(op), 0, bytes32(abi.encode(sender))); + vm.store(address(optimismPortal), 0, bytes32(abi.encode(sender))); vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); - L1Messenger.relayMessage( + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message ); } @@ -173,7 +175,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { bytes memory message = hex"1111"; vm.expectRevert("CrossDomainMessenger: value must be zero unless message is from a system address"); - L1Messenger.relayMessage{ value: 100 }( + l1CrossDomainMessenger.relayMessage{ value: 100 }( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message ); } @@ -182,18 +184,18 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { /// after a message is relayed. function test_xDomainMessageSender_reset_succeeds() external { vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L1Messenger.xDomainMessageSender(); + l1CrossDomainMessenger.xDomainMessageSender(); address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - vm.prank(address(op)); - L1Messenger.relayMessage( + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), address(0), address(0), 0, 0, hex"" ); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L1Messenger.xDomainMessageSender(); + l1CrossDomainMessenger.xDomainMessageSender(); } /// @dev Tests that relayMessage should successfully call the target contract after @@ -210,11 +212,11 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, value, 0, hex"1111" ); - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.etch(target, address(new Reverter()).code); - vm.deal(address(op), value); - vm.prank(address(op)); - L1Messenger.relayMessage{ value: value }( + vm.deal(address(optimismPortal), value); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage{ value: value }( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce sender, target, @@ -223,10 +225,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { hex"1111" ); - assertEq(address(L1Messenger).balance, value); + assertEq(address(l1CrossDomainMessenger).balance, value); assertEq(address(target).balance, 0); - assertEq(L1Messenger.successfulMessages(hash), false); - assertEq(L1Messenger.failedMessages(hash), true); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), false); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); vm.expectEmit(true, true, true, true); @@ -234,7 +236,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { vm.etch(target, address(0).code); vm.prank(address(sender)); - L1Messenger.relayMessage( + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce sender, target, @@ -243,10 +245,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { hex"1111" ); - assertEq(address(L1Messenger).balance, 0); + assertEq(address(l1CrossDomainMessenger).balance, 0); assertEq(address(target).balance, value); - assertEq(L1Messenger.successfulMessages(hash), true); - assertEq(L1Messenger.failedMessages(hash), true); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); } /// @dev Tests that relayMessage should successfully call the target contract after @@ -268,7 +270,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); // Target should be called with expected data. vm.expectCall(target, hex"1111"); @@ -278,8 +280,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { emit RelayedMessage(hash); // Relay the message. - vm.prank(address(op)); - L1Messenger.relayMessage( + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce sender, target, @@ -289,8 +291,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Message was successfully relayed. - assertEq(L1Messenger.successfulMessages(hash), true); - assertEq(L1Messenger.failedMessages(hash), false); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l1CrossDomainMessenger.failedMessages(hash), false); } /// @dev Tests that relayMessage should revert if the message is already replayed. @@ -310,20 +312,19 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); // Mark legacy message as already relayed. uint256 successfulMessagesSlot = 203; bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex"1111", 0); bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot)); - vm.store(address(L1Messenger), slot, bytes32(uint256(1))); + vm.store(address(l1CrossDomainMessenger), slot, bytes32(uint256(1))); // Expect revert. vm.expectRevert("CrossDomainMessenger: legacy withdrawal already relayed"); // Relay the message. - vm.prank(address(op)); - L1Messenger.relayMessage( + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce sender, target, @@ -333,8 +334,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Message was not relayed. - assertEq(L1Messenger.successfulMessages(hash), false); - assertEq(L1Messenger.failedMessages(hash), false); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), false); + assertEq(l1CrossDomainMessenger.failedMessages(hash), false); } /// @dev Tests that relayMessage can be retried after a failure with a legacy message. @@ -355,7 +356,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); // Turn the target into a Reverter. vm.etch(target, address(new Reverter()).code); @@ -368,9 +369,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { emit FailedRelayedMessage(hash); // Relay the message. - vm.deal(address(op), value); - vm.prank(address(op)); - L1Messenger.relayMessage{ value: value }( + vm.deal(address(optimismPortal), value); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage{ value: value }( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce sender, target, @@ -380,10 +381,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Message failed. - assertEq(address(L1Messenger).balance, value); + assertEq(address(l1CrossDomainMessenger).balance, value); assertEq(address(target).balance, 0); - assertEq(L1Messenger.successfulMessages(hash), false); - assertEq(L1Messenger.failedMessages(hash), true); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), false); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); // Make the target not revert anymore. vm.etch(target, address(0).code); @@ -397,7 +398,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { // Retry the message. vm.prank(address(sender)); - L1Messenger.relayMessage( + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce sender, target, @@ -407,10 +408,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Message was successfully relayed. - assertEq(address(L1Messenger).balance, 0); + assertEq(address(l1CrossDomainMessenger).balance, 0); assertEq(address(target).balance, value); - assertEq(L1Messenger.successfulMessages(hash), true); - assertEq(L1Messenger.failedMessages(hash), true); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); } /// @dev Tests that relayMessage cannot be retried after success with a legacy message. @@ -431,7 +432,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); // Target should be called with expected data. vm.expectCall(target, hex"1111"); @@ -441,9 +442,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { emit RelayedMessage(hash); // Relay the message. - vm.deal(address(op), value); - vm.prank(address(op)); - L1Messenger.relayMessage{ value: value }( + vm.deal(address(optimismPortal), value); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage{ value: value }( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce sender, target, @@ -453,17 +454,17 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Message was successfully relayed. - assertEq(address(L1Messenger).balance, 0); + assertEq(address(l1CrossDomainMessenger).balance, 0); assertEq(address(target).balance, value); - assertEq(L1Messenger.successfulMessages(hash), true); - assertEq(L1Messenger.failedMessages(hash), false); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l1CrossDomainMessenger.failedMessages(hash), false); // Expect a revert. vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); // Retry the message. vm.prank(address(sender)); - L1Messenger.relayMessage( + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce sender, target, @@ -491,7 +492,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); + vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); // Turn the target into a Reverter. vm.etch(target, address(new Reverter()).code); @@ -500,9 +501,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { vm.expectCall(target, hex"1111"); // Relay the message. - vm.deal(address(op), value); - vm.prank(address(op)); - L1Messenger.relayMessage{ value: value }( + vm.deal(address(optimismPortal), value); + vm.prank(address(optimismPortal)); + l1CrossDomainMessenger.relayMessage{ value: value }( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce sender, target, @@ -512,10 +513,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Message failed. - assertEq(address(L1Messenger).balance, value); + assertEq(address(l1CrossDomainMessenger).balance, value); assertEq(address(target).balance, 0); - assertEq(L1Messenger.successfulMessages(hash), false); - assertEq(L1Messenger.failedMessages(hash), true); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), false); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); // Make the target not revert anymore. vm.etch(target, address(0).code); @@ -529,7 +530,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { // Retry the message vm.prank(address(sender)); - L1Messenger.relayMessage( + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce sender, target, @@ -539,17 +540,17 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ); // Message was successfully relayed. - assertEq(address(L1Messenger).balance, 0); + assertEq(address(l1CrossDomainMessenger).balance, 0); assertEq(address(target).balance, value); - assertEq(L1Messenger.successfulMessages(hash), true); - assertEq(L1Messenger.failedMessages(hash), true); + assertEq(l1CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l1CrossDomainMessenger.failedMessages(hash), true); // Expect a revert. vm.expectRevert("CrossDomainMessenger: message has already been relayed"); // Retry the message again. vm.prank(address(sender)); - L1Messenger.relayMessage( + l1CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce sender, target, diff --git a/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol index b57c8b7ef70d..ac18fc7983f5 100644 --- a/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/CommonTest.t.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; // Target contract dependencies @@ -21,7 +21,7 @@ contract TestERC721 is ERC721 { } } -contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { +contract L1ERC721Bridge_Test is Bridge_Initializer { TestERC721 internal localToken; TestERC721 internal remoteToken; uint256 internal constant tokenId = 1; @@ -56,26 +56,26 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Approve the bridge to transfer the token. vm.prank(alice); - localToken.approve(address(L1NFTBridge), tokenId); + localToken.approve(address(l1ERC721Bridge), tokenId); } /// @dev Tests that the constructor sets the correct values. function test_constructor_succeeds() public { - assertEq(address(L1NFTBridge.MESSENGER()), address(L1Messenger)); - assertEq(address(L1NFTBridge.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE); - assertEq(address(L1NFTBridge.messenger()), address(L1Messenger)); - assertEq(address(L1NFTBridge.otherBridge()), Predeploys.L2_ERC721_BRIDGE); + assertEq(address(l1ERC721Bridge.MESSENGER()), address(l1CrossDomainMessenger)); + assertEq(address(l1ERC721Bridge.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE); + assertEq(address(l1ERC721Bridge.messenger()), address(l1CrossDomainMessenger)); + assertEq(address(l1ERC721Bridge.otherBridge()), Predeploys.L2_ERC721_BRIDGE); } /// @dev Tests that the ERC721 can be bridged successfully. function test_bridgeERC721_succeeds() public { // Expect a call to the messenger. vm.expectCall( - address(L1Messenger), + address(l1CrossDomainMessenger), abi.encodeCall( - L1Messenger.sendMessage, + l1CrossDomainMessenger.sendMessage, ( - address(L2NFTBridge), + address(l2ERC721Bridge), abi.encodeCall( L2ERC721Bridge.finalizeBridgeERC721, (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678") @@ -91,11 +91,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); - L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); // Token is locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), true); - assertEq(localToken.ownerOf(tokenId), address(L1NFTBridge)); + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), true); + assertEq(localToken.ownerOf(tokenId), address(l1ERC721Bridge)); } /// @dev Tests that the ERC721 bridge reverts for non externally owned accounts. @@ -104,10 +104,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { vm.etch(alice, hex"01"); vm.prank(alice); vm.expectRevert("ERC721Bridge: account is not externally owned"); - L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(localToken.ownerOf(tokenId), alice); } @@ -116,10 +116,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); vm.expectRevert(); - L1NFTBridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678"); + l1ERC721Bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678"); // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(localToken.ownerOf(tokenId), alice); } @@ -128,10 +128,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)"); - L1NFTBridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678"); + l1ERC721Bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678"); // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(localToken.ownerOf(tokenId), alice); } @@ -140,10 +140,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(bob); vm.expectRevert("ERC721: transfer from incorrect owner"); - L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(localToken.ownerOf(tokenId), alice); } @@ -152,9 +152,9 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { function test_bridgeERC721To_succeeds() external { // Expect a call to the messenger. vm.expectCall( - address(L1Messenger), + address(l1CrossDomainMessenger), abi.encodeCall( - L1Messenger.sendMessage, + l1CrossDomainMessenger.sendMessage, ( address(Predeploys.L2_ERC721_BRIDGE), abi.encodeCall( @@ -172,11 +172,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); - L1NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); + l1ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); // Token is locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), true); - assertEq(localToken.ownerOf(tokenId), address(L1NFTBridge)); + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), true); + assertEq(localToken.ownerOf(tokenId), address(l1ERC721Bridge)); } /// @dev Tests that the ERC721 bridge reverts for non externally owned accounts @@ -185,10 +185,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); vm.expectRevert(); - L1NFTBridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678"); + l1ERC721Bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678"); // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(localToken.ownerOf(tokenId), alice); } @@ -198,10 +198,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)"); - L1NFTBridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678"); + l1ERC721Bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678"); // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(localToken.ownerOf(tokenId), alice); } @@ -211,10 +211,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(bob); vm.expectRevert("ERC721: transfer from incorrect owner"); - L1NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); + l1ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(localToken.ownerOf(tokenId), alice); } @@ -222,7 +222,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { function test_finalizeBridgeERC721_succeeds() external { // Bridge the token. vm.prank(alice); - L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); // Expect an event to be emitted. vm.expectEmit(true, true, true, true); @@ -230,15 +230,15 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Finalize a withdrawal. vm.mockCall( - address(L1Messenger), - abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), + address(l1CrossDomainMessenger), + abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector), abi.encode(Predeploys.L2_ERC721_BRIDGE) ); - vm.prank(address(L1Messenger)); - L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + vm.prank(address(l1CrossDomainMessenger)); + l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); // Token is not locked in the bridge. - assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); + assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(localToken.ownerOf(tokenId), alice); } @@ -248,7 +248,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { // Finalize a withdrawal. vm.prank(alice); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); - L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); } /// @dev Tests that the ERC721 bridge finalize reverts when not called @@ -256,11 +256,13 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { // Finalize a withdrawal. vm.mockCall( - address(L1Messenger), abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), abi.encode(alice) + address(l1CrossDomainMessenger), + abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(alice) ); - vm.prank(address(L1Messenger)); + vm.prank(address(l1CrossDomainMessenger)); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); - L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); } /// @dev Tests that the ERC721 bridge finalize reverts when the local token @@ -268,13 +270,15 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { function test_finalizeBridgeERC721_selfToken_reverts() external { // Finalize a withdrawal. vm.mockCall( - address(L1Messenger), - abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), + address(l1CrossDomainMessenger), + abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector), abi.encode(Predeploys.L2_ERC721_BRIDGE) ); - vm.prank(address(L1Messenger)); + vm.prank(address(l1CrossDomainMessenger)); vm.expectRevert("L1ERC721Bridge: local token cannot be self"); - L1NFTBridge.finalizeBridgeERC721(address(L1NFTBridge), address(remoteToken), alice, alice, tokenId, hex"5678"); + l1ERC721Bridge.finalizeBridgeERC721( + address(l1ERC721Bridge), address(remoteToken), alice, alice, tokenId, hex"5678" + ); } /// @dev Tests that the ERC721 bridge finalize reverts when the remote token @@ -282,12 +286,12 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { function test_finalizeBridgeERC721_notEscrowed_reverts() external { // Finalize a withdrawal. vm.mockCall( - address(L1Messenger), - abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), + address(l1CrossDomainMessenger), + abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector), abi.encode(Predeploys.L2_ERC721_BRIDGE) ); - vm.prank(address(L1Messenger)); + vm.prank(address(l1CrossDomainMessenger)); vm.expectRevert("L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge"); - L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); } } diff --git a/packages/contracts-bedrock/test/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1StandardBridge.t.sol index c8966dd8b62f..4f8f5e15e7ba 100644 --- a/packages/contracts-bedrock/test/L1StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L1StandardBridge.t.sol @@ -22,20 +22,20 @@ import { OptimismPortal } from "src/L1/OptimismPortal.sol"; contract L1StandardBridge_Getter_Test is Bridge_Initializer { /// @dev Test that the accessors return the correct initialized values. function test_getters_succeeds() external view { - assert(L1Bridge.l2TokenBridge() == address(L2Bridge)); - assert(L1Bridge.OTHER_BRIDGE() == L2Bridge); - assert(L1Bridge.messenger() == L1Messenger); - assert(L1Bridge.MESSENGER() == L1Messenger); + assert(l1StandardBridge.l2TokenBridge() == address(l2StandardBridge)); + assert(l1StandardBridge.OTHER_BRIDGE() == l2StandardBridge); + assert(l1StandardBridge.messenger() == l1CrossDomainMessenger); + assert(l1StandardBridge.MESSENGER() == l1CrossDomainMessenger); } } contract L1StandardBridge_Initialize_Test is Bridge_Initializer { /// @dev Test that the initialize function sets the correct values. function test_initialize_succeeds() external { - assertEq(address(L1Bridge.messenger()), address(L1Messenger)); - assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE); - assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE); - bytes32 slot0 = vm.load(address(L1Bridge), bytes32(uint256(0))); + assertEq(address(l1StandardBridge.messenger()), address(l1CrossDomainMessenger)); + assertEq(address(l1StandardBridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE); + assertEq(address(l2StandardBridge), Predeploys.L2_STANDARD_BRIDGE); + bytes32 slot0 = vm.load(address(l1StandardBridge), bytes32(uint256(0))); assertEq(slot0, bytes32(uint256(Constants.INITIALIZER))); } } @@ -45,29 +45,29 @@ contract L1StandardBridge_Initialize_TestFail is Bridge_Initializer { } contract L1StandardBridge_Receive_Test is Bridge_Initializer { /// @dev Tests receive bridges ETH successfully. function test_receive_succeeds() external { - assertEq(address(op).balance, 0); + assertEq(address(optimismPortal).balance, 0); // The legacy event must be emitted for backwards compatibility - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ETHDepositInitiated(alice, alice, 100, hex""); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ETHBridgeInitiated(alice, alice, 100, hex""); vm.expectCall( - address(L1Messenger), + address(l1CrossDomainMessenger), abi.encodeWithSelector( CrossDomainMessenger.sendMessage.selector, - address(L2Bridge), + address(l2StandardBridge), abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""), 200_000 ) ); vm.prank(alice, alice); - (bool success,) = address(L1Bridge).call{ value: 100 }(hex""); + (bool success,) = address(l1StandardBridge).call{ value: 100 }(hex""); assertEq(success, true); - assertEq(address(op).balance, 100); + assertEq(address(optimismPortal).balance, 100); } } @@ -77,59 +77,76 @@ contract PreBridgeETH is Bridge_Initializer { /// @dev Asserts the expected calls and events for bridging ETH depending /// on whether the bridge call is legacy or not. function _preBridgeETH(bool isLegacy) internal { - assertEq(address(op).balance, 0); - uint256 nonce = L1Messenger.messageNonce(); + assertEq(address(optimismPortal).balance, 0); + uint256 nonce = l1CrossDomainMessenger.messageNonce(); uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION - address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); + address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); bytes memory message = abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 500, hex"dead"); if (isLegacy) { vm.expectCall( - address(L1Bridge), 500, abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex"dead") + address(l1StandardBridge), + 500, + abi.encodeWithSelector(l1StandardBridge.depositETH.selector, 50000, hex"dead") ); } else { - vm.expectCall(address(L1Bridge), 500, abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex"dead")); + vm.expectCall( + address(l1StandardBridge), + 500, + abi.encodeWithSelector(l1StandardBridge.bridgeETH.selector, 50000, hex"dead") + ); } vm.expectCall( - address(L1Messenger), + address(l1CrossDomainMessenger), 500, - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 50000) + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 50000) ); bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 500, 50000, message + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l1StandardBridge), + address(l2StandardBridge), + 500, + 50000, + message ); - uint64 baseGas = L1Messenger.baseGas(message, 50000); + uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 50000); vm.expectCall( - address(op), + address(optimismPortal), 500, abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, address(L2Messenger), 500, baseGas, false, innerMessage + OptimismPortal.depositTransaction.selector, + address(l2CrossDomainMessenger), + 500, + baseGas, + false, + innerMessage ) ); bytes memory opaqueData = abi.encodePacked(uint256(500), uint256(500), baseGas, false, innerMessage); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ETHDepositInitiated(alice, alice, 500, hex"dead"); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ETHBridgeInitiated(alice, alice, 500, hex"dead"); // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call - vm.expectEmit(true, true, true, true, address(op)); - emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); + vm.expectEmit(true, true, true, true, address(optimismPortal)); + emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData); // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 50000); + vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger)); + emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 50000); // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessageExtension1(address(L1Bridge), 500); + vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger)); + emit SentMessageExtension1(address(l1StandardBridge), 500); vm.prank(alice, alice); } @@ -143,8 +160,8 @@ contract L1StandardBridge_DepositETH_Test is PreBridgeETH { /// ETH ends up in the optimismPortal. function test_depositETH_succeeds() external { _preBridgeETH({ isLegacy: true }); - L1Bridge.depositETH{ value: 500 }(50000, hex"dead"); - assertEq(address(op).balance, 500); + l1StandardBridge.depositETH{ value: 500 }(50000, hex"dead"); + assertEq(address(optimismPortal).balance, 500); } } @@ -156,8 +173,8 @@ contract L1StandardBridge_BridgeETH_Test is PreBridgeETH { /// ETH ends up in the optimismPortal. function test_bridgeETH_succeeds() external { _preBridgeETH({ isLegacy: false }); - L1Bridge.bridgeETH{ value: 500 }(50000, hex"dead"); - assertEq(address(op).balance, 500); + l1StandardBridge.bridgeETH{ value: 500 }(50000, hex"dead"); + assertEq(address(optimismPortal).balance, 500); } } @@ -167,7 +184,7 @@ contract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer { vm.etch(alice, address(L1Token).code); vm.expectRevert("StandardBridge: function can only be called from an EOA"); vm.prank(alice); - L1Bridge.depositETH{ value: 1 }(300, hex""); + l1StandardBridge.depositETH{ value: 1 }(300, hex""); } } @@ -175,18 +192,22 @@ contract PreBridgeETHTo is Bridge_Initializer { /// @dev Asserts the expected calls and events for bridging ETH to a different /// address depending on whether the bridge call is legacy or not. function _preBridgeETHTo(bool isLegacy) internal { - assertEq(address(op).balance, 0); - uint256 nonce = L1Messenger.messageNonce(); + assertEq(address(optimismPortal).balance, 0); + uint256 nonce = l1CrossDomainMessenger.messageNonce(); uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION - address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); + address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); if (isLegacy) { vm.expectCall( - address(L1Bridge), 600, abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex"dead") + address(l1StandardBridge), + 600, + abi.encodeWithSelector(l1StandardBridge.depositETHTo.selector, bob, 60000, hex"dead") ); } else { vm.expectCall( - address(L1Bridge), 600, abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex"dead") + address(l1StandardBridge), + 600, + abi.encodeWithSelector(l1StandardBridge.bridgeETHTo.selector, bob, 60000, hex"dead") ); } @@ -196,41 +217,52 @@ contract PreBridgeETHTo is Bridge_Initializer { // the L1 bridge should call // L1CrossDomainMessenger.sendMessage vm.expectCall( - address(L1Messenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 60000) + address(l1CrossDomainMessenger), + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 60000) ); bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 600, 60000, message + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l1StandardBridge), + address(l2StandardBridge), + 600, + 60000, + message ); - uint64 baseGas = L1Messenger.baseGas(message, 60000); + uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 60000); vm.expectCall( - address(op), + address(optimismPortal), abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, address(L2Messenger), 600, baseGas, false, innerMessage + OptimismPortal.depositTransaction.selector, + address(l2CrossDomainMessenger), + 600, + baseGas, + false, + innerMessage ) ); bytes memory opaqueData = abi.encodePacked(uint256(600), uint256(600), baseGas, false, innerMessage); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ETHDepositInitiated(alice, bob, 600, hex"dead"); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ETHBridgeInitiated(alice, bob, 600, hex"dead"); // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call - vm.expectEmit(true, true, true, true, address(op)); - emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); + vm.expectEmit(true, true, true, true, address(optimismPortal)); + emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData); // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 60000); + vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger)); + emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 60000); // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessageExtension1(address(L1Bridge), 600); + vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger)); + emit SentMessageExtension1(address(l1StandardBridge), 600); // deposit eth to bob vm.prank(alice, alice); @@ -245,8 +277,8 @@ contract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo { /// ETH ends up in the optimismPortal. function test_depositETHTo_succeeds() external { _preBridgeETHTo({ isLegacy: true }); - L1Bridge.depositETHTo{ value: 600 }(bob, 60000, hex"dead"); - assertEq(address(op).balance, 600); + l1StandardBridge.depositETHTo{ value: 600 }(bob, 60000, hex"dead"); + assertEq(address(optimismPortal).balance, 600); } } @@ -258,8 +290,8 @@ contract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo { /// ETH ends up in the optimismPortal. function test_bridgeETHTo_succeeds() external { _preBridgeETHTo({ isLegacy: false }); - L1Bridge.bridgeETHTo{ value: 600 }(bob, 60000, hex"dead"); - assertEq(address(op).balance, 600); + l1StandardBridge.bridgeETHTo{ value: 600 }(bob, 60000, hex"dead"); + assertEq(address(optimismPortal).balance, 600); } } @@ -280,18 +312,18 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer { /// Calls depositTransaction on the OptimismPortal. /// Only EOA can call depositERC20. function test_depositERC20_succeeds() external { - uint256 nonce = L1Messenger.messageNonce(); + uint256 nonce = l1CrossDomainMessenger.messageNonce(); uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION - address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); + address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); // Deal Alice's ERC20 State deal(address(L1Token), alice, 100000, true); vm.prank(alice); - L1Token.approve(address(L1Bridge), type(uint256).max); + L1Token.approve(address(l1StandardBridge), type(uint256).max); - // The L1Bridge should transfer alice's tokens to itself + // The l1StandardBridge should transfer alice's tokens to itself vm.expectCall( - address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100) + address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(l1StandardBridge), 100) ); bytes memory message = abi.encodeWithSelector( @@ -300,46 +332,57 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer { // the L1 bridge should call L1CrossDomainMessenger.sendMessage vm.expectCall( - address(L1Messenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 10000) + address(l1CrossDomainMessenger), + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 10000) ); bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 0, 10000, message + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l1StandardBridge), + address(l2StandardBridge), + 0, + 10000, + message ); - uint64 baseGas = L1Messenger.baseGas(message, 10000); + uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 10000); vm.expectCall( - address(op), + address(optimismPortal), abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, address(L2Messenger), 0, baseGas, false, innerMessage + OptimismPortal.depositTransaction.selector, + address(l2CrossDomainMessenger), + 0, + baseGas, + false, + innerMessage ) ); bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage); // Should emit both the bedrock and legacy events - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex""); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex""); // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call - vm.expectEmit(true, true, true, true, address(op)); - emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); + vm.expectEmit(true, true, true, true, address(optimismPortal)); + emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData); // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000); + vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger)); + emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 10000); // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessageExtension1(address(L1Bridge), 0); + vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger)); + emit SentMessageExtension1(address(l1StandardBridge), 0); vm.prank(alice); - L1Bridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex""); - assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100); + l1StandardBridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex""); + assertEq(l1StandardBridge.deposits(address(L1Token), address(L2Token)), 100); } } @@ -352,7 +395,7 @@ contract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer { vm.expectRevert("StandardBridge: function can only be called from an EOA"); vm.prank(alice, alice); - L1Bridge.depositERC20(address(0), address(0), 100, 100, hex""); + l1StandardBridge.depositERC20(address(0), address(0), 100, 100, hex""); } } @@ -364,65 +407,77 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer { /// Calls depositTransaction on the OptimismPortal. /// Contracts can call depositERC20. function test_depositERC20To_succeeds() external { - uint256 nonce = L1Messenger.messageNonce(); + uint256 nonce = l1CrossDomainMessenger.messageNonce(); uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION - address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); + address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); bytes memory message = abi.encodeWithSelector( StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, bob, 1000, hex"" ); bytes memory innerMessage = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 0, 10000, message + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l1StandardBridge), + address(l2StandardBridge), + 0, + 10000, + message ); - uint64 baseGas = L1Messenger.baseGas(message, 10000); + uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 10000); bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage); deal(address(L1Token), alice, 100000, true); vm.prank(alice); - L1Token.approve(address(L1Bridge), type(uint256).max); + L1Token.approve(address(l1StandardBridge), type(uint256).max); // Should emit both the bedrock and legacy events - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex""); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex""); // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call - vm.expectEmit(true, true, true, true, address(op)); - emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); + vm.expectEmit(true, true, true, true, address(optimismPortal)); + emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData); // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000); + vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger)); + emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 10000); // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L1Messenger)); - emit SentMessageExtension1(address(L1Bridge), 0); + vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger)); + emit SentMessageExtension1(address(l1StandardBridge), 0); // the L1 bridge should call L1CrossDomainMessenger.sendMessage vm.expectCall( - address(L1Messenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 10000) + address(l1CrossDomainMessenger), + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 10000) ); // The L1 XDM should call OptimismPortal.depositTransaction vm.expectCall( - address(op), + address(optimismPortal), abi.encodeWithSelector( - OptimismPortal.depositTransaction.selector, address(L2Messenger), 0, baseGas, false, innerMessage + OptimismPortal.depositTransaction.selector, + address(l2CrossDomainMessenger), + 0, + baseGas, + false, + innerMessage ) ); vm.expectCall( - address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000) + address(L1Token), + abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(l1StandardBridge), 1000) ); vm.prank(alice); - L1Bridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex""); + l1StandardBridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex""); - assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 1000); + assertEq(l1StandardBridge.deposits(address(L1Token), address(L2Token)), 1000); } } @@ -435,25 +490,25 @@ contract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer { function test_finalizeETHWithdrawal_succeeds() external { uint256 aliceBalance = alice.balance; - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ETHWithdrawalFinalized(alice, alice, 100, hex""); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ETHBridgeFinalized(alice, alice, 100, hex""); vm.expectCall(alice, hex""); vm.mockCall( - address(L1Bridge.messenger()), + address(l1StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); // ensure that the messenger has ETH to call with - vm.deal(address(L1Bridge.messenger()), 100); - vm.prank(address(L1Bridge.messenger())); - L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex""); + vm.deal(address(l1StandardBridge.messenger()), 100); + vm.prank(address(l1StandardBridge.messenger())); + l1StandardBridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex""); - assertEq(address(L1Bridge.messenger()).balance, 0); + assertEq(address(l1StandardBridge.messenger()).balance, 0); assertEq(aliceBalance + 100, alice.balance); } } @@ -468,32 +523,33 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer { /// Emits ERC20WithdrawalFinalized event. /// Only callable by the L2 bridge. function test_finalizeERC20Withdrawal_succeeds() external { - deal(address(L1Token), address(L1Bridge), 100, true); + deal(address(L1Token), address(l1StandardBridge), 100, true); - uint256 slot = stdstore.target(address(L1Bridge)).sig("deposits(address,address)").with_key(address(L1Token)) - .with_key(address(L2Token)).find(); + uint256 slot = stdstore.target(address(l1StandardBridge)).sig("deposits(address,address)").with_key( + address(L1Token) + ).with_key(address(L2Token)).find(); // Give the L1 bridge some ERC20 tokens - vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100))); - assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100); + vm.store(address(l1StandardBridge), bytes32(slot), bytes32(uint256(100))); + assertEq(l1StandardBridge.deposits(address(L1Token), address(L2Token)), 100); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); vm.expectCall(address(L1Token), abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)); vm.mockCall( - address(L1Bridge.messenger()), + address(l1StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); - vm.prank(address(L1Bridge.messenger())); - L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); + vm.prank(address(l1StandardBridge.messenger())); + l1StandardBridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); - assertEq(L1Token.balanceOf(address(L1Bridge)), 0); + assertEq(L1Token.balanceOf(address(l1StandardBridge)), 0); assertEq(L1Token.balanceOf(address(alice)), 100); } } @@ -502,87 +558,87 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer /// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge. function test_finalizeERC20Withdrawal_notMessenger_reverts() external { vm.mockCall( - address(L1Bridge.messenger()), + address(l1StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.prank(address(28)); vm.expectRevert("StandardBridge: function can only be called from the other bridge"); - L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); + l1StandardBridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); } /// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge. function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external { vm.mockCall( - address(L1Bridge.messenger()), + address(l1StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encode(address(address(0))) ); - vm.prank(address(L1Bridge.messenger())); + vm.prank(address(l1StandardBridge.messenger())); vm.expectRevert("StandardBridge: function can only be called from the other bridge"); - L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); + l1StandardBridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); } } contract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { /// @dev Tests that finalizing bridged ETH succeeds. function test_finalizeBridgeETH_succeeds() external { - address messenger = address(L1Bridge.messenger()); + address messenger = address(l1StandardBridge.messenger()); vm.mockCall( messenger, abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.deal(messenger, 100); vm.prank(messenger); - vm.expectEmit(true, true, true, true, address(L1Bridge)); + vm.expectEmit(true, true, true, true, address(l1StandardBridge)); emit ETHBridgeFinalized(alice, alice, 100, hex""); - L1Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); + l1StandardBridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); } } contract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer { /// @dev Tests that finalizing bridged ETH reverts if the amount is incorrect. function test_finalizeBridgeETH_incorrectValue_reverts() external { - address messenger = address(L1Bridge.messenger()); + address messenger = address(l1StandardBridge.messenger()); vm.mockCall( messenger, abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.deal(messenger, 100); vm.prank(messenger); vm.expectRevert("StandardBridge: amount sent does not match amount required"); - L1Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex""); + l1StandardBridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex""); } /// @dev Tests that finalizing bridged ETH reverts if the destination is the L1 bridge. function test_finalizeBridgeETH_sendToSelf_reverts() external { - address messenger = address(L1Bridge.messenger()); + address messenger = address(l1StandardBridge.messenger()); vm.mockCall( messenger, abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.deal(messenger, 100); vm.prank(messenger); vm.expectRevert("StandardBridge: cannot send to self"); - L1Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L1Bridge), 100, hex""); + l1StandardBridge.finalizeBridgeETH{ value: 100 }(alice, address(l1StandardBridge), 100, hex""); } /// @dev Tests that finalizing bridged ETH reverts if the destination is the messenger. function test_finalizeBridgeETH_sendToMessenger_reverts() external { - address messenger = address(L1Bridge.messenger()); + address messenger = address(l1StandardBridge.messenger()); vm.mockCall( messenger, abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L1Bridge.OTHER_BRIDGE())) + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) ); vm.deal(messenger, 100); vm.prank(messenger); vm.expectRevert("StandardBridge: cannot send to messenger"); - L1Bridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex""); + l1StandardBridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex""); } } diff --git a/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol index 9066397dcfec..0a9c5602813e 100644 --- a/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol @@ -20,20 +20,20 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { /// @dev Tests that `messageNonce` can be decoded correctly. function test_messageVersion_succeeds() external { - (, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce()); - assertEq(version, L2Messenger.MESSAGE_VERSION()); + (, uint16 version) = Encoding.decodeVersionedNonce(l2CrossDomainMessenger.messageNonce()); + assertEq(version, l2CrossDomainMessenger.MESSAGE_VERSION()); } /// @dev Tests that `sendMessage` executes successfully. function test_sendMessage_succeeds() external { bytes memory xDomainCallData = - Encoding.encodeCrossDomainMessage(L2Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff"); + Encoding.encodeCrossDomainMessage(l2CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff"); vm.expectCall( - address(messagePasser), + address(l2ToL1MessagePasser), abi.encodeWithSelector( L2ToL1MessagePasser.initiateWithdrawal.selector, - address(L1Messenger), - L2Messenger.baseGas(hex"ff", 100), + address(l1CrossDomainMessenger), + l2CrossDomainMessenger.baseGas(hex"ff", 100), xDomainCallData ) ); @@ -41,56 +41,56 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { // MessagePassed event vm.expectEmit(true, true, true, true); emit MessagePassed( - messagePasser.messageNonce(), - address(L2Messenger), - address(L1Messenger), + l2ToL1MessagePasser.messageNonce(), + address(l2CrossDomainMessenger), + address(l1CrossDomainMessenger), 0, - L2Messenger.baseGas(hex"ff", 100), + l2CrossDomainMessenger.baseGas(hex"ff", 100), xDomainCallData, Hashing.hashWithdrawal( Types.WithdrawalTransaction({ - nonce: messagePasser.messageNonce(), - sender: address(L2Messenger), - target: address(L1Messenger), + nonce: l2ToL1MessagePasser.messageNonce(), + sender: address(l2CrossDomainMessenger), + target: address(l1CrossDomainMessenger), value: 0, - gasLimit: L2Messenger.baseGas(hex"ff", 100), + gasLimit: l2CrossDomainMessenger.baseGas(hex"ff", 100), data: xDomainCallData }) ) ); vm.prank(alice); - L2Messenger.sendMessage(recipient, hex"ff", uint32(100)); + l2CrossDomainMessenger.sendMessage(recipient, hex"ff", uint32(100)); } /// @dev Tests that `sendMessage` can be called twice and that /// the nonce increments correctly. function test_sendMessage_twice_succeeds() external { - uint256 nonce = L2Messenger.messageNonce(); - L2Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); - L2Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); + uint256 nonce = l2CrossDomainMessenger.messageNonce(); + l2CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000)); + l2CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000)); // the nonce increments for each message sent - assertEq(nonce + 2, L2Messenger.messageNonce()); + assertEq(nonce + 2, l2CrossDomainMessenger.messageNonce()); } /// @dev Tests that `sendMessage` reverts if the recipient is the zero address. function test_xDomainSender_senderNotSet_reverts() external { vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L2Messenger.xDomainMessageSender(); + l2CrossDomainMessenger.xDomainMessageSender(); } /// @dev Tests that `sendMessage` reverts if the message version is not supported. function test_relayMessage_v2_reverts() external { address target = address(0xabcd); - address sender = address(L1Messenger); - address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); + address sender = address(l1CrossDomainMessenger); + address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); // Expect a revert. vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time"); // Try to relay a v2 message. vm.prank(caller); - L2Messenger.relayMessage( + l2CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce(0, 2), // nonce sender, target, @@ -103,8 +103,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { /// @dev Tests that `relayMessage` executes successfully. function test_relayMessage_succeeds() external { address target = address(0xabcd); - address sender = address(L1Messenger); - address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); + address sender = address(l1CrossDomainMessenger); + address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); vm.expectCall(target, hex"1111"); @@ -117,7 +117,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { emit RelayedMessage(hash); - L2Messenger.relayMessage( + l2CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce(0, 1), // nonce sender, target, @@ -127,36 +127,36 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ); // the message hash is in the successfulMessages mapping - assert(L2Messenger.successfulMessages(hash)); + assert(l2CrossDomainMessenger.successfulMessages(hash)); // it is not in the received messages mapping - assertEq(L2Messenger.failedMessages(hash), false); + assertEq(l2CrossDomainMessenger.failedMessages(hash), false); } /// @dev Tests that `relayMessage` reverts if attempting to relay /// a message sent to an L1 system contract. function test_relayMessage_toSystemContract_reverts() external { - address target = address(messagePasser); - address sender = address(L1Messenger); - address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); + address target = address(l2ToL1MessagePasser); + address sender = address(l1CrossDomainMessenger); + address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); bytes memory message = hex"1111"; vm.prank(caller); vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); - L1Messenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, message); + l1CrossDomainMessenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, message); } /// @dev Tests that `relayMessage` correctly resets the `xDomainMessageSender` /// to the original value after a message is relayed. function test_xDomainMessageSender_reset_succeeds() external { vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L2Messenger.xDomainMessageSender(); + l2CrossDomainMessenger.xDomainMessageSender(); - address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); + address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); vm.prank(caller); - L2Messenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), address(0), address(0), 0, 0, hex""); + l2CrossDomainMessenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), address(0), address(0), 0, 0, hex""); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); - L2Messenger.xDomainMessageSender(); + l2CrossDomainMessenger.xDomainMessageSender(); } /// @dev Tests that `relayMessage` is able to send a successful call @@ -164,8 +164,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { /// gets stuck, but the second message succeeds. function test_relayMessage_retry_succeeds() external { address target = address(0xabcd); - address sender = address(L1Messenger); - address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); + address sender = address(l1CrossDomainMessenger); + address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)); uint256 value = 100; bytes32 hash = @@ -174,7 +174,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { vm.etch(target, address(new Reverter()).code); vm.deal(address(caller), value); vm.prank(caller); - L2Messenger.relayMessage{ value: value }( + l2CrossDomainMessenger.relayMessage{ value: value }( Encoding.encodeVersionedNonce(0, 1), // nonce sender, target, @@ -183,10 +183,10 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { hex"1111" ); - assertEq(address(L2Messenger).balance, value); + assertEq(address(l2CrossDomainMessenger).balance, value); assertEq(address(target).balance, 0); - assertEq(L2Messenger.successfulMessages(hash), false); - assertEq(L2Messenger.failedMessages(hash), true); + assertEq(l2CrossDomainMessenger.successfulMessages(hash), false); + assertEq(l2CrossDomainMessenger.failedMessages(hash), true); vm.expectEmit(true, true, true, true); @@ -194,7 +194,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { vm.etch(target, address(0).code); vm.prank(address(sender)); - L2Messenger.relayMessage( + l2CrossDomainMessenger.relayMessage( Encoding.encodeVersionedNonce(0, 1), // nonce sender, target, @@ -203,9 +203,9 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { hex"1111" ); - assertEq(address(L2Messenger).balance, 0); + assertEq(address(l2CrossDomainMessenger).balance, 0); assertEq(address(target).balance, value); - assertEq(L2Messenger.successfulMessages(hash), true); - assertEq(L2Messenger.failedMessages(hash), true); + assertEq(l2CrossDomainMessenger.successfulMessages(hash), true); + assertEq(l2CrossDomainMessenger.failedMessages(hash), true); } } diff --git a/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol index 03567f3beae1..43989983a39a 100644 --- a/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/CommonTest.t.sol"; // Target contract dependencies import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; @@ -33,7 +33,7 @@ contract TestMintableERC721 is OptimismMintableERC721 { } } -contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { +contract L2ERC721Bridge_Test is Bridge_Initializer { TestMintableERC721 internal localToken; TestERC721 internal remoteToken; uint256 internal constant tokenId = 1; @@ -61,22 +61,22 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { super.setUp(); remoteToken = new TestERC721(); - localToken = new TestMintableERC721(address(L2NFTBridge), address(remoteToken)); + localToken = new TestMintableERC721(address(l2ERC721Bridge), address(remoteToken)); // Mint alice a token. localToken.mint(alice, tokenId); // Approve the bridge to transfer the token. vm.prank(alice); - localToken.approve(address(L2NFTBridge), tokenId); + localToken.approve(address(l2ERC721Bridge), tokenId); } /// @dev Tests that the constructor sets the correct variables. function test_constructor_succeeds() public { - assertEq(address(L2NFTBridge.MESSENGER()), address(L2Messenger)); - assertEq(address(L2NFTBridge.OTHER_BRIDGE()), address(L1NFTBridge)); - assertEq(address(L2NFTBridge.messenger()), address(L2Messenger)); - assertEq(address(L2NFTBridge.otherBridge()), address(L1NFTBridge)); + assertEq(address(l2ERC721Bridge.MESSENGER()), address(l2CrossDomainMessenger)); + assertEq(address(l2ERC721Bridge.OTHER_BRIDGE()), address(l1ERC721Bridge)); + assertEq(address(l2ERC721Bridge.messenger()), address(l2CrossDomainMessenger)); + assertEq(address(l2ERC721Bridge.otherBridge()), address(l1ERC721Bridge)); } /// @dev Tests that `bridgeERC721` correctly bridges a token and @@ -84,11 +84,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { function test_bridgeERC721_succeeds() public { // Expect a call to the messenger. vm.expectCall( - address(L2Messenger), + address(l2CrossDomainMessenger), abi.encodeCall( - L2Messenger.sendMessage, + l2CrossDomainMessenger.sendMessage, ( - address(L1NFTBridge), + address(l1ERC721Bridge), abi.encodeCall( L2ERC721Bridge.finalizeBridgeERC721, (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678") @@ -104,7 +104,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); - L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); // Token is burned. vm.expectRevert("ERC721: invalid token ID"); @@ -117,7 +117,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { vm.etch(alice, hex"01"); vm.prank(alice); vm.expectRevert("ERC721Bridge: account is not externally owned"); - L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); // Token is not locked in the bridge. assertEq(localToken.ownerOf(tokenId), alice); @@ -128,7 +128,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); vm.expectRevert(); - L2NFTBridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678"); // Token is not locked in the bridge. assertEq(localToken.ownerOf(tokenId), alice); @@ -139,7 +139,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)"); - L2NFTBridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678"); // Token is not locked in the bridge. assertEq(localToken.ownerOf(tokenId), alice); @@ -150,7 +150,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(bob); vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner"); - L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); // Token is not locked in the bridge. assertEq(localToken.ownerOf(tokenId), alice); @@ -161,11 +161,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { function test_bridgeERC721To_succeeds() external { // Expect a call to the messenger. vm.expectCall( - address(L2Messenger), + address(l2CrossDomainMessenger), abi.encodeCall( - L2Messenger.sendMessage, + l2CrossDomainMessenger.sendMessage, ( - address(L1NFTBridge), + address(l1ERC721Bridge), abi.encodeCall( L1ERC721Bridge.finalizeBridgeERC721, (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") @@ -181,7 +181,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); - L2NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); // Token is burned. vm.expectRevert("ERC721: invalid token ID"); @@ -193,7 +193,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); vm.expectRevert(); - L2NFTBridge.bridgeERC721To(address(0), address(L1NFTBridge), bob, tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721To(address(0), address(l1ERC721Bridge), bob, tokenId, 1234, hex"5678"); // Token is not locked in the bridge. assertEq(localToken.ownerOf(tokenId), alice); @@ -204,7 +204,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(alice); vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)"); - L2NFTBridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678"); // Token is not locked in the bridge. assertEq(localToken.ownerOf(tokenId), alice); @@ -215,7 +215,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the token. vm.prank(bob); vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner"); - L2NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); // Token is not locked in the bridge. assertEq(localToken.ownerOf(tokenId), alice); @@ -225,7 +225,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { function test_finalizeBridgeERC721_succeeds() external { // Bridge the token. vm.prank(alice); - L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); // Expect an event to be emitted. vm.expectEmit(true, true, true, true); @@ -233,12 +233,12 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Finalize a withdrawal. vm.mockCall( - address(L2Messenger), - abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), - abi.encode(L1NFTBridge) + address(l2CrossDomainMessenger), + abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(l1ERC721Bridge) ); - vm.prank(address(L2Messenger)); - L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + vm.prank(address(l2CrossDomainMessenger)); + l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); // Token is not locked in the bridge. assertEq(localToken.ownerOf(tokenId), alice); @@ -252,18 +252,18 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Bridge the non-compliant token. vm.prank(alice); - L2NFTBridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex"5678"); + l2ERC721Bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex"5678"); // Attempt to finalize the withdrawal. Should revert because the token does not claim // to be compliant with the `IOptimismMintableERC721` interface. vm.mockCall( - address(L2Messenger), - abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), - abi.encode(L1NFTBridge) + address(l2CrossDomainMessenger), + abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(l1ERC721Bridge) ); - vm.prank(address(L2Messenger)); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("L2ERC721Bridge: local token interface is not compliant"); - L2NFTBridge.finalizeBridgeERC721( + l2ERC721Bridge.finalizeBridgeERC721( address(address(nonCompliantToken)), address(address(0x01)), alice, alice, tokenId, hex"5678" ); } @@ -273,18 +273,20 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { // Finalize a withdrawal. vm.prank(alice); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); - L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); } /// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge. function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { // Finalize a withdrawal. vm.mockCall( - address(L2Messenger), abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), abi.encode(alice) + address(l2CrossDomainMessenger), + abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(alice) ); - vm.prank(address(L2Messenger)); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); - L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); } /// @dev Tests that `finalizeBridgeERC721` reverts when the local token is the @@ -292,26 +294,28 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { function test_finalizeBridgeERC721_selfToken_reverts() external { // Finalize a withdrawal. vm.mockCall( - address(L2Messenger), - abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), - abi.encode(address(L1NFTBridge)) + address(l2CrossDomainMessenger), + abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1ERC721Bridge)) ); - vm.prank(address(L2Messenger)); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("L2ERC721Bridge: local token cannot be self"); - L2NFTBridge.finalizeBridgeERC721(address(L2NFTBridge), address(remoteToken), alice, alice, tokenId, hex"5678"); + l2ERC721Bridge.finalizeBridgeERC721( + address(l2ERC721Bridge), address(remoteToken), alice, alice, tokenId, hex"5678" + ); } /// @dev Tests that `finalizeBridgeERC721` reverts when already finalized. function test_finalizeBridgeERC721_alreadyExists_reverts() external { // Finalize a withdrawal. vm.mockCall( - address(L2Messenger), - abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), - abi.encode(address(L1NFTBridge)) + address(l2CrossDomainMessenger), + abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector), + abi.encode(address(l1ERC721Bridge)) ); - vm.prank(address(L2Messenger)); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("ERC721: token already minted"); - L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); + l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); } } diff --git a/packages/contracts-bedrock/test/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/L2OutputOracle.t.sol index 4a052ee29cdf..6a7bb0c76469 100644 --- a/packages/contracts-bedrock/test/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/L2OutputOracle.t.sol @@ -20,23 +20,32 @@ import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { /// @dev Tests that constructor sets the initial values correctly. function test_constructor_succeeds() external { - assertEq(oracle.PROPOSER(), proposer); - assertEq(oracle.proposer(), proposer); - assertEq(oracle.CHALLENGER(), owner); - assertEq(oracle.challenger(), owner); - assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval); - assertEq(oracle.submissionInterval(), submissionInterval); - assertEq(oracle.latestBlockNumber(), startingBlockNumber); - assertEq(oracle.startingBlockNumber(), startingBlockNumber); - assertEq(oracle.startingTimestamp(), startingTimestamp); - assertEq(oracle.L2_BLOCK_TIME(), l2BlockTime); - assertEq(oracle.l2BlockTime(), l2BlockTime); - assertEq(oracle.finalizationPeriodSeconds(), finalizationPeriodSeconds); - assertEq(oracle.FINALIZATION_PERIOD_SECONDS(), finalizationPeriodSeconds); + address proposer = cfg.l2OutputOracleProposer(); + address challenger = cfg.l2OutputOracleChallenger(); + uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval(); + uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber(); + uint256 startingTimestamp = cfg.l2OutputOracleStartingTimestamp(); + uint256 l2BlockTime = cfg.l2BlockTime(); + uint256 finalizationPeriodSeconds = cfg.finalizationPeriodSeconds(); + + assertEq(l2OutputOracle.PROPOSER(), proposer); + assertEq(l2OutputOracle.proposer(), proposer); + assertEq(l2OutputOracle.CHALLENGER(), challenger); + assertEq(l2OutputOracle.challenger(), challenger); + assertEq(l2OutputOracle.SUBMISSION_INTERVAL(), submissionInterval); + assertEq(l2OutputOracle.submissionInterval(), submissionInterval); + assertEq(l2OutputOracle.latestBlockNumber(), startingBlockNumber); + assertEq(l2OutputOracle.startingBlockNumber(), startingBlockNumber); + assertEq(l2OutputOracle.startingTimestamp(), startingTimestamp); + assertEq(l2OutputOracle.L2_BLOCK_TIME(), l2BlockTime); + assertEq(l2OutputOracle.l2BlockTime(), l2BlockTime); + assertEq(l2OutputOracle.finalizationPeriodSeconds(), finalizationPeriodSeconds); + assertEq(l2OutputOracle.FINALIZATION_PERIOD_SECONDS(), finalizationPeriodSeconds); } /// @dev Tests that the constructor reverts if the l2BlockTime is invalid. function test_constructor_l2BlockTimeZero_reverts() external { + uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval(); vm.expectRevert("L2OutputOracle: L2 block time must be greater than 0"); new L2OutputOracle({ _submissionInterval: submissionInterval, @@ -47,6 +56,7 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { /// @dev Tests that the constructor reverts if the submissionInterval is zero. function test_constructor_submissionInterval_reverts() external { + uint256 l2BlockTime = cfg.l2BlockTime(); vm.expectRevert("L2OutputOracle: submission interval must be greater than 0"); new L2OutputOracle({ _submissionInterval: 0, @@ -59,9 +69,9 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { function test_initialize_badTimestamp_reverts() external { // Reset the initialized field in the 0th storage slot // so that initialize can be called again. - vm.store(address(oracle), bytes32(uint256(0)), bytes32(uint256(0))); + vm.store(address(l2OutputOracle), bytes32(uint256(0)), bytes32(uint256(0))); vm.expectRevert("L2OutputOracle: starting L2 timestamp must be less than current time"); - oracle.initialize({ + l2OutputOracle.initialize({ _startingBlockNumber: 0, _startingTimestamp: block.timestamp + 1, _proposer: address(0), @@ -75,43 +85,43 @@ contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer { /// @dev Tests that `latestBlockNumber` returns the correct value. function test_latestBlockNumber_succeeds() external { - uint256 proposedNumber = oracle.nextBlockNumber(); + uint256 proposedNumber = l2OutputOracle.nextBlockNumber(); // Roll to after the block number we'll propose warpToProposeTime(proposedNumber); - vm.prank(proposer); - oracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0); - assertEq(oracle.latestBlockNumber(), proposedNumber); + vm.prank(cfg.l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0); + assertEq(l2OutputOracle.latestBlockNumber(), proposedNumber); } /// @dev Tests that `getL2Output` returns the correct value. function test_getL2Output_succeeds() external { - uint256 nextBlockNumber = oracle.nextBlockNumber(); - uint256 nextOutputIndex = oracle.nextOutputIndex(); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex(); warpToProposeTime(nextBlockNumber); - vm.prank(proposer); - oracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0); + vm.prank(cfg.l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0); - Types.OutputProposal memory proposal = oracle.getL2Output(nextOutputIndex); + Types.OutputProposal memory proposal = l2OutputOracle.getL2Output(nextOutputIndex); assertEq(proposal.outputRoot, proposedOutput1); assertEq(proposal.timestamp, block.timestamp); // The block number is larger than the latest proposed output: vm.expectRevert(stdError.indexOOBError); - oracle.getL2Output(nextOutputIndex + 1); + l2OutputOracle.getL2Output(nextOutputIndex + 1); } /// @dev Tests that `getL2OutputIndexAfter` returns the correct value /// when the input is the exact block number of the proposal. function test_getL2OutputIndexAfter_sameBlock_succeeds() external { bytes32 output1 = keccak256(abi.encode(1)); - uint256 nextBlockNumber1 = oracle.nextBlockNumber(); + uint256 nextBlockNumber1 = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber1); - vm.prank(proposer); - oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); + vm.prank(cfg.l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); // Querying with exact same block as proposed returns the proposal. - uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1); + uint256 index1 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber1); assertEq(index1, 0); } @@ -119,84 +129,90 @@ contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer { /// when the input is the previous block number of the proposal. function test_getL2OutputIndexAfter_previousBlock_succeeds() external { bytes32 output1 = keccak256(abi.encode(1)); - uint256 nextBlockNumber1 = oracle.nextBlockNumber(); + uint256 nextBlockNumber1 = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber1); - vm.prank(proposer); - oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); + vm.prank(cfg.l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); // Querying with previous block returns the proposal too. - uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 - 1); + uint256 index1 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber1 - 1); assertEq(index1, 0); } /// @dev Tests that `getL2OutputIndexAfter` returns the correct value. function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external { bytes32 output1 = keccak256(abi.encode(1)); - uint256 nextBlockNumber1 = oracle.nextBlockNumber(); + uint256 nextBlockNumber1 = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber1); - vm.prank(proposer); - oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); + vm.prank(cfg.l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); bytes32 output2 = keccak256(abi.encode(2)); - uint256 nextBlockNumber2 = oracle.nextBlockNumber(); + uint256 nextBlockNumber2 = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber2); - vm.prank(proposer); - oracle.proposeL2Output(output2, nextBlockNumber2, 0, 0); + vm.prank(cfg.l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output2, nextBlockNumber2, 0, 0); bytes32 output3 = keccak256(abi.encode(3)); - uint256 nextBlockNumber3 = oracle.nextBlockNumber(); + uint256 nextBlockNumber3 = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber3); - vm.prank(proposer); - oracle.proposeL2Output(output3, nextBlockNumber3, 0, 0); + vm.prank(cfg.l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output3, nextBlockNumber3, 0, 0); bytes32 output4 = keccak256(abi.encode(4)); - uint256 nextBlockNumber4 = oracle.nextBlockNumber(); + uint256 nextBlockNumber4 = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber4); - vm.prank(proposer); - oracle.proposeL2Output(output4, nextBlockNumber4, 0, 0); + vm.prank(cfg.l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(output4, nextBlockNumber4, 0, 0); // Querying with a block number between the first and second proposal - uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 + 1); + uint256 index1 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber1 + 1); assertEq(index1, 1); // Querying with a block number between the second and third proposal - uint256 index2 = oracle.getL2OutputIndexAfter(nextBlockNumber2 + 1); + uint256 index2 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber2 + 1); assertEq(index2, 2); // Querying with a block number between the third and fourth proposal - uint256 index3 = oracle.getL2OutputIndexAfter(nextBlockNumber3 + 1); + uint256 index3 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber3 + 1); assertEq(index3, 3); } /// @dev Tests that `getL2OutputIndexAfter` reverts when no output exists. function test_getL2OutputIndexAfter_noOutputsExis_reverts() external { vm.expectRevert("L2OutputOracle: cannot get output as no outputs have been proposed yet"); - oracle.getL2OutputIndexAfter(0); + l2OutputOracle.getL2OutputIndexAfter(0); } /// @dev Tests that `nextBlockNumber` returns the correct value. function test_nextBlockNumber_succeeds() external { assertEq( - oracle.nextBlockNumber(), + l2OutputOracle.nextBlockNumber(), // The return value should match this arithmetic - oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL() + l2OutputOracle.latestBlockNumber() + l2OutputOracle.SUBMISSION_INTERVAL() ); } /// @dev Tests that `computeL2Timestamp` returns the correct value. function test_computeL2Timestamp_succeeds() external { + uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber(); + uint256 startingTimestamp = cfg.l2OutputOracleStartingTimestamp(); + uint256 l2BlockTime = cfg.l2BlockTime(); + // reverts if timestamp is too low vm.expectRevert(stdError.arithmeticError); - oracle.computeL2Timestamp(startingBlockNumber - 1); + l2OutputOracle.computeL2Timestamp(startingBlockNumber - 1); // check timestamp for the very first block - assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp); + assertEq(l2OutputOracle.computeL2Timestamp(startingBlockNumber), startingTimestamp); // check timestamp for the first block after the starting block - assertEq(oracle.computeL2Timestamp(startingBlockNumber + 1), startingTimestamp + l2BlockTime); + assertEq(l2OutputOracle.computeL2Timestamp(startingBlockNumber + 1), startingTimestamp + l2BlockTime); // check timestamp for some other block number - assertEq(oracle.computeL2Timestamp(startingBlockNumber + 96024), startingTimestamp + l2BlockTime * 96024); + assertEq( + l2OutputOracle.computeL2Timestamp(startingBlockNumber + 96024), startingTimestamp + l2BlockTime * 96024 + ); } } @@ -214,62 +230,62 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer { uint256 prevL1BlockNumber = block.number - 1; bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber); - uint256 nextBlockNumber = oracle.nextBlockNumber(); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber); - vm.prank(proposer); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber); + vm.prank(cfg.l2OutputOracleProposer()); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber); } /// @dev Tests that `proposeL2Output` reverts when called by a party /// that is not the proposer. function test_proposeL2Output_notProposer_reverts() external { - uint256 nextBlockNumber = oracle.nextBlockNumber(); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber); vm.prank(address(128)); vm.expectRevert("L2OutputOracle: only the proposer address can propose new outputs"); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); } /// @dev Tests that `proposeL2Output` reverts when given a zero blockhash. function test_proposeL2Output_emptyOutput_reverts() external { bytes32 outputToPropose = bytes32(0); - uint256 nextBlockNumber = oracle.nextBlockNumber(); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber); - vm.prank(proposer); + vm.prank(cfg.l2OutputOracleProposer()); vm.expectRevert("L2OutputOracle: L2 output proposal cannot be the zero hash"); - oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0); + l2OutputOracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0); } /// @dev Tests that `proposeL2Output` reverts when given a block number /// that does not match the next expected block number. function test_proposeL2Output_unexpectedBlockNumber_reverts() external { - uint256 nextBlockNumber = oracle.nextBlockNumber(); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber); - vm.prank(proposer); + vm.prank(cfg.l2OutputOracleProposer()); vm.expectRevert("L2OutputOracle: block number must be equal to next expected block number"); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0); } /// @dev Tests that `proposeL2Output` reverts when given a block number /// that has a timestamp in the future. function test_proposeL2Output_futureTimetamp_reverts() external { - uint256 nextBlockNumber = oracle.nextBlockNumber(); - uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + uint256 nextTimestamp = l2OutputOracle.computeL2Timestamp(nextBlockNumber); vm.warp(nextTimestamp); - vm.prank(proposer); + vm.prank(cfg.l2OutputOracleProposer()); vm.expectRevert("L2OutputOracle: cannot propose L2 output in the future"); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); } /// @dev Tests that `proposeL2Output` reverts when given a block number /// whose hash does not match the given block hash. function test_proposeL2Output_wrongFork_reverts() external { - uint256 nextBlockNumber = oracle.nextBlockNumber(); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber); - vm.prank(proposer); + vm.prank(cfg.l2OutputOracleProposer()); vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height"); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, bytes32(uint256(0x01)), block.number - 1); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, bytes32(uint256(0x01)), block.number); } /// @dev Tests that `proposeL2Output` reverts when given a block number @@ -282,13 +298,13 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer { uint256 l1BlockNumber = block.number - 1; bytes32 l1BlockHash = blockhash(l1BlockNumber); - uint256 nextBlockNumber = oracle.nextBlockNumber(); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); warpToProposeTime(nextBlockNumber); - vm.prank(proposer); + vm.prank(cfg.l2OutputOracleProposer()); // This will fail when foundry no longer returns zerod block hashes vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height"); - oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1); + l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1); } } @@ -298,22 +314,23 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { proposeAnotherOutput(); proposeAnotherOutput(); - uint256 latestBlockNumber = oracle.latestBlockNumber(); - uint256 latestOutputIndex = oracle.latestOutputIndex(); - Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 1); + uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber(); + uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex(); + Types.OutputProposal memory newLatestOutput = l2OutputOracle.getL2Output(latestOutputIndex - 1); - vm.prank(owner); + vm.prank(l2OutputOracle.challenger()); vm.expectEmit(true, true, false, false); emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex); - oracle.deleteL2Outputs(latestOutputIndex); + l2OutputOracle.deleteL2Outputs(latestOutputIndex); // validate latestBlockNumber has been reduced - uint256 latestBlockNumberAfter = oracle.latestBlockNumber(); - uint256 latestOutputIndexAfter = oracle.latestOutputIndex(); + uint256 latestBlockNumberAfter = l2OutputOracle.latestBlockNumber(); + uint256 latestOutputIndexAfter = l2OutputOracle.latestOutputIndex(); + uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval(); assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter); // validate that the new latest output is as expected. - Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter); + Types.OutputProposal memory proposal = l2OutputOracle.getL2Output(latestOutputIndexAfter); assertEq(newLatestOutput.outputRoot, proposal.outputRoot); assertEq(newLatestOutput.timestamp, proposal.timestamp); } @@ -325,43 +342,44 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { proposeAnotherOutput(); proposeAnotherOutput(); - uint256 latestBlockNumber = oracle.latestBlockNumber(); - uint256 latestOutputIndex = oracle.latestOutputIndex(); - Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 3); + uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber(); + uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex(); + Types.OutputProposal memory newLatestOutput = l2OutputOracle.getL2Output(latestOutputIndex - 3); - vm.prank(owner); + vm.prank(l2OutputOracle.challenger()); vm.expectEmit(true, true, false, false); emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2); - oracle.deleteL2Outputs(latestOutputIndex - 2); + l2OutputOracle.deleteL2Outputs(latestOutputIndex - 2); // validate latestBlockNumber has been reduced - uint256 latestBlockNumberAfter = oracle.latestBlockNumber(); - uint256 latestOutputIndexAfter = oracle.latestOutputIndex(); + uint256 latestBlockNumberAfter = l2OutputOracle.latestBlockNumber(); + uint256 latestOutputIndexAfter = l2OutputOracle.latestOutputIndex(); + uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval(); assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter); // validate that the new latest output is as expected. - Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter); + Types.OutputProposal memory proposal = l2OutputOracle.getL2Output(latestOutputIndexAfter); assertEq(newLatestOutput.outputRoot, proposal.outputRoot); assertEq(newLatestOutput.timestamp, proposal.timestamp); } /// @dev Tests that `deleteL2Outputs` reverts when not called by the challenger. function test_deleteL2Outputs_ifNotChallenger_reverts() external { - uint256 latestBlockNumber = oracle.latestBlockNumber(); + uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber(); vm.expectRevert("L2OutputOracle: only the challenger address can delete outputs"); - oracle.deleteL2Outputs(latestBlockNumber); + l2OutputOracle.deleteL2Outputs(latestBlockNumber); } /// @dev Tests that `deleteL2Outputs` reverts for a non-existant output index. function test_deleteL2Outputs_nonExistent_reverts() external { proposeAnotherOutput(); - uint256 latestBlockNumber = oracle.latestBlockNumber(); + uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber(); - vm.prank(owner); + vm.prank(l2OutputOracle.challenger()); vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index"); - oracle.deleteL2Outputs(latestBlockNumber + 1); + l2OutputOracle.deleteL2Outputs(latestBlockNumber + 1); } /// @dev Tests that `deleteL2Outputs` reverts when trying to delete outputs @@ -372,14 +390,14 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { proposeAnotherOutput(); // Delete the latest two outputs - uint256 latestOutputIndex = oracle.latestOutputIndex(); - vm.prank(owner); - oracle.deleteL2Outputs(latestOutputIndex - 2); + uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex(); + vm.prank(l2OutputOracle.challenger()); + l2OutputOracle.deleteL2Outputs(latestOutputIndex - 2); // Now try to delete the same output again - vm.prank(owner); + vm.prank(l2OutputOracle.challenger()); vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index"); - oracle.deleteL2Outputs(latestOutputIndex - 2); + l2OutputOracle.deleteL2Outputs(latestOutputIndex - 2); } /// @dev Tests that `deleteL2Outputs` reverts for finalized outputs. @@ -387,43 +405,48 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { proposeAnotherOutput(); // Warp past the finalization period + 1 second - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); - uint256 latestOutputIndex = oracle.latestOutputIndex(); + uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex(); // Try to delete a finalized output - vm.prank(owner); + vm.prank(l2OutputOracle.challenger()); vm.expectRevert("L2OutputOracle: cannot delete outputs that have already been finalized"); - oracle.deleteL2Outputs(latestOutputIndex); + l2OutputOracle.deleteL2Outputs(latestOutputIndex); } } contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { - Proxy internal proxy; - - function setUp() public override { - super.setUp(); - proxy = Proxy(payable(address(oracle))); - } - /// @dev Tests that the proxy is initialized with the correct values. function test_initValuesOnProxy_succeeds() external { - assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval); - assertEq(oracle.submissionInterval(), submissionInterval); - assertEq(oracle.L2_BLOCK_TIME(), l2BlockTime); - assertEq(oracle.l2BlockTime(), l2BlockTime); - assertEq(oracle.startingBlockNumber(), startingBlockNumber); - assertEq(oracle.startingTimestamp(), startingTimestamp); - assertEq(oracle.finalizationPeriodSeconds(), finalizationPeriodSeconds); - assertEq(oracle.PROPOSER(), proposer); - assertEq(oracle.proposer(), proposer); - assertEq(oracle.CHALLENGER(), owner); - assertEq(oracle.challenger(), owner); + address proposer = cfg.l2OutputOracleProposer(); + address challenger = cfg.l2OutputOracleChallenger(); + uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval(); + uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber(); + uint256 startingTimestamp = cfg.l2OutputOracleStartingTimestamp(); + uint256 l2BlockTime = cfg.l2BlockTime(); + uint256 finalizationPeriodSeconds = cfg.finalizationPeriodSeconds(); + + assertEq(l2OutputOracle.SUBMISSION_INTERVAL(), submissionInterval); + assertEq(l2OutputOracle.submissionInterval(), submissionInterval); + assertEq(l2OutputOracle.L2_BLOCK_TIME(), l2BlockTime); + assertEq(l2OutputOracle.l2BlockTime(), l2BlockTime); + assertEq(l2OutputOracle.startingBlockNumber(), startingBlockNumber); + assertEq(l2OutputOracle.startingTimestamp(), startingTimestamp); + assertEq(l2OutputOracle.finalizationPeriodSeconds(), finalizationPeriodSeconds); + assertEq(l2OutputOracle.PROPOSER(), proposer); + assertEq(l2OutputOracle.proposer(), proposer); + assertEq(l2OutputOracle.CHALLENGER(), challenger); + assertEq(l2OutputOracle.challenger(), challenger); } /// @dev Tests that the impl is created with the correct values. function test_initValuesOnImpl_succeeds() external { + L2OutputOracle oracleImpl = L2OutputOracle(mustGetAddress("L2OutputOracle")); + + uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval(); assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL()); + uint256 l2BlockTime = cfg.l2BlockTime(); assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME()); // The values that are set in the initialize function should be all @@ -438,8 +461,10 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { /// @dev Tests that the proxy cannot be initialized twice. function test_initializeProxy_alreadyInitialized_reverts() external { + uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber(); + uint256 startingTimestamp = cfg.l2OutputOracleStartingTimestamp(); vm.expectRevert("Initializable: contract is already initialized"); - L2OutputOracle(payable(proxy)).initialize({ + l2OutputOracle.initialize({ _startingBlockNumber: startingBlockNumber, _startingTimestamp: startingTimestamp, _proposer: address(1), @@ -449,8 +474,11 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { /// @dev Tests that the implementation contract cannot be initialized twice. function test_initializeImpl_alreadyInitialized_reverts() external { + L2OutputOracle oracleImpl = L2OutputOracle(mustGetAddress("L2OutputOracle")); + uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber(); + uint256 startingTimestamp = cfg.l2OutputOracleStartingTimestamp(); vm.expectRevert("Initializable: contract is already initialized"); - L2OutputOracle(oracleImpl).initialize({ + oracleImpl.initialize({ _startingBlockNumber: startingBlockNumber, _startingTimestamp: startingTimestamp, _proposer: address(1), @@ -460,8 +488,9 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { /// @dev Tests that the proxy can be successfully upgraded. function test_upgrading_succeeds() external { + Proxy proxy = Proxy(mustGetAddress("L2OutputOracleProxy")); // Check an unused slot before upgrading. - bytes32 slot21Before = vm.load(address(oracle), bytes32(uint256(21))); + bytes32 slot21Before = vm.load(address(l2OutputOracle), bytes32(uint256(21))); assertEq(bytes32(0), slot21Before); NextImpl nextImpl = new NextImpl(); @@ -472,8 +501,8 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { assertEq(proxy.implementation(), address(nextImpl)); // Verify that the NextImpl contract initialized its values according as expected - bytes32 slot21After = vm.load(address(oracle), bytes32(uint256(21))); - bytes32 slot21Expected = NextImpl(address(oracle)).slot21Init(); + bytes32 slot21After = vm.load(address(l2OutputOracle), bytes32(uint256(21))); + bytes32 slot21Expected = NextImpl(address(l2OutputOracle)).slot21Init(); assertEq(slot21Expected, slot21After); } } diff --git a/packages/contracts-bedrock/test/L2StandardBridge.t.sol b/packages/contracts-bedrock/test/L2StandardBridge.t.sol index be7dd6ff639c..1053c09d2c15 100644 --- a/packages/contracts-bedrock/test/L2StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L2StandardBridge.t.sol @@ -23,24 +23,24 @@ contract L2StandardBridge_Test is Bridge_Initializer { /// @dev Tests that the bridge is initialized correctly. function test_initialize_succeeds() external { - assertEq(address(L2Bridge.messenger()), address(L2Messenger)); - assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge)); - assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge)); + assertEq(address(l2StandardBridge.messenger()), address(l2CrossDomainMessenger)); + assertEq(l1StandardBridge.l2TokenBridge(), address(l2StandardBridge)); + assertEq(address(l2StandardBridge.OTHER_BRIDGE()), address(l1StandardBridge)); } /// @dev Tests that the bridge receives ETH and successfully initiates a withdrawal. function test_receive_succeeds() external { - assertEq(address(messagePasser).balance, 0); - uint256 nonce = L2Messenger.messageNonce(); + assertEq(address(l2ToL1MessagePasser).balance, 0); + uint256 nonce = l2CrossDomainMessenger.messageNonce(); bytes memory message = abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""); - uint64 baseGas = L2Messenger.baseGas(message, 200_000); + uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 200_000); bytes memory withdrawalData = abi.encodeWithSelector( CrossDomainMessenger.relayMessage.selector, nonce, - address(L2Bridge), - address(L1Bridge), + address(l2StandardBridge), + address(l1StandardBridge), 100, 200_000, message @@ -48,8 +48,8 @@ contract L2StandardBridge_Test is Bridge_Initializer { bytes32 withdrawalHash = Hashing.hashWithdrawal( Types.WithdrawalTransaction({ nonce: nonce, - sender: address(L2Messenger), - target: address(L1Messenger), + sender: address(l2CrossDomainMessenger), + target: address(l1CrossDomainMessenger), value: 100, gasLimit: baseGas, data: withdrawalData @@ -63,24 +63,30 @@ contract L2StandardBridge_Test is Bridge_Initializer { emit ETHBridgeInitiated(alice, alice, 100, hex""); // L2ToL1MessagePasser will emit a MessagePassed event - vm.expectEmit(true, true, true, true, address(messagePasser)); + vm.expectEmit(true, true, true, true, address(l2ToL1MessagePasser)); emit MessagePassed( - nonce, address(L2Messenger), address(L1Messenger), 100, baseGas, withdrawalData, withdrawalHash + nonce, + address(l2CrossDomainMessenger), + address(l1CrossDomainMessenger), + 100, + baseGas, + withdrawalData, + withdrawalHash ); // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L2Messenger)); - emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 200_000); + vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger)); + emit SentMessage(address(l1StandardBridge), address(l2StandardBridge), message, nonce, 200_000); // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L2Messenger)); - emit SentMessageExtension1(address(L2Bridge), 100); + vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger)); + emit SentMessageExtension1(address(l2StandardBridge), 100); vm.expectCall( - address(L2Messenger), + address(l2CrossDomainMessenger), abi.encodeWithSelector( CrossDomainMessenger.sendMessage.selector, - address(L1Bridge), + address(l1StandardBridge), message, 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT ) @@ -89,23 +95,26 @@ contract L2StandardBridge_Test is Bridge_Initializer { vm.expectCall( Predeploys.L2_TO_L1_MESSAGE_PASSER, abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData + L2ToL1MessagePasser.initiateWithdrawal.selector, + address(l1CrossDomainMessenger), + baseGas, + withdrawalData ) ); vm.prank(alice, alice); - (bool success,) = address(L2Bridge).call{ value: 100 }(hex""); + (bool success,) = address(l2StandardBridge).call{ value: 100 }(hex""); assertEq(success, true); - assertEq(address(messagePasser).balance, 100); + assertEq(address(l2ToL1MessagePasser).balance, 100); } /// @dev Tests that `withdraw` reverts if the amount is not equal to the value sent. function test_withdraw_insufficientValue_reverts() external { - assertEq(address(messagePasser).balance, 0); + assertEq(address(l2ToL1MessagePasser).balance, 0); vm.expectRevert("StandardBridge: bridging ETH must include sufficient ETH value"); vm.prank(alice, alice); - L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex""); + l2StandardBridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex""); } /// @dev Tests that the legacy `withdraw` interface on the L2StandardBridge @@ -114,7 +123,7 @@ contract L2StandardBridge_Test is Bridge_Initializer { assertTrue(alice.balance >= 100); assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0); - vm.expectEmit(true, true, true, true, address(L2Bridge)); + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); emit WithdrawalInitiated({ l1Token: address(0), l2Token: Predeploys.LEGACY_ERC20_ETH, @@ -124,11 +133,11 @@ contract L2StandardBridge_Test is Bridge_Initializer { data: hex"" }); - vm.expectEmit(true, true, true, true, address(L2Bridge)); + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex"" }); vm.prank(alice, alice); - L2Bridge.withdraw{ value: 100 }({ + l2StandardBridge.withdraw{ value: 100 }({ _l2Token: Predeploys.LEGACY_ERC20_ETH, _amount: 100, _minGasLimit: 1000, @@ -145,19 +154,25 @@ contract PreBridgeERC20 is Bridge_Initializer { // Alice has 100 L2Token deal(_l2Token, alice, 100, true); assertEq(ERC20(_l2Token).balanceOf(alice), 100); - uint256 nonce = L2Messenger.messageNonce(); + uint256 nonce = l2CrossDomainMessenger.messageNonce(); bytes memory message = abi.encodeWithSelector( StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, alice, 100, hex"" ); - uint64 baseGas = L2Messenger.baseGas(message, 1000); + uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 1000); bytes memory withdrawalData = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L2Bridge), address(L1Bridge), 0, 1000, message + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l2StandardBridge), + address(l1StandardBridge), + 0, + 1000, + message ); bytes32 withdrawalHash = Hashing.hashWithdrawal( Types.WithdrawalTransaction({ nonce: nonce, - sender: address(L2Messenger), - target: address(L1Messenger), + sender: address(l2CrossDomainMessenger), + target: address(l1CrossDomainMessenger), value: 0, gasLimit: baseGas, data: withdrawalData @@ -166,28 +181,34 @@ contract PreBridgeERC20 is Bridge_Initializer { if (_isLegacy) { vm.expectCall( - address(L2Bridge), abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex"") + address(l2StandardBridge), + abi.encodeWithSelector(l2StandardBridge.withdraw.selector, _l2Token, 100, 1000, hex"") ); } else { vm.expectCall( - address(L2Bridge), - abi.encodeWithSelector(L2Bridge.bridgeERC20.selector, _l2Token, address(L1Token), 100, 1000, hex"") + address(l2StandardBridge), + abi.encodeWithSelector( + l2StandardBridge.bridgeERC20.selector, _l2Token, address(L1Token), 100, 1000, hex"" + ) ); } vm.expectCall( - address(L2Messenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L1Bridge), message, 1000) + address(l2CrossDomainMessenger), + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 1000) ); vm.expectCall( Predeploys.L2_TO_L1_MESSAGE_PASSER, abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData + L2ToL1MessagePasser.initiateWithdrawal.selector, + address(l1CrossDomainMessenger), + baseGas, + withdrawalData ) ); - // The L2Bridge should burn the tokens + // The l2StandardBridge should burn the tokens vm.expectCall(_l2Token, abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)); vm.expectEmit(true, true, true, true); @@ -198,16 +219,22 @@ contract PreBridgeERC20 is Bridge_Initializer { vm.expectEmit(true, true, true, true); emit MessagePassed( - nonce, address(L2Messenger), address(L1Messenger), 0, baseGas, withdrawalData, withdrawalHash + nonce, + address(l2CrossDomainMessenger), + address(l1CrossDomainMessenger), + 0, + baseGas, + withdrawalData, + withdrawalHash ); // SentMessage event emitted by the CrossDomainMessenger vm.expectEmit(true, true, true, true); - emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000); + emit SentMessage(address(l1StandardBridge), address(l2StandardBridge), message, nonce, 1000); // SentMessageExtension1 event emitted by the CrossDomainMessenger vm.expectEmit(true, true, true, true); - emit SentMessageExtension1(address(L2Bridge), 0); + emit SentMessageExtension1(address(l2StandardBridge), 0); vm.prank(alice, alice); } @@ -220,7 +247,7 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 { // - calls Withdrawer.initiateWithdrawal function test_withdraw_withdrawingERC20_succeeds() external { _preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) }); - L2Bridge.withdraw(address(L2Token), 100, 1000, hex""); + l2StandardBridge.withdraw(address(L2Token), 100, 1000, hex""); assertEq(L2Token.balanceOf(alice), 0); } @@ -231,21 +258,21 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 { // - calls Withdrawer.initiateWithdrawal function test_bridgeERC20_succeeds() external { _preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) }); - L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex""); + l2StandardBridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex""); assertEq(L2Token.balanceOf(alice), 0); } function test_withdrawLegacyERC20_succeeds() external { _preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) }); - L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex""); + l2StandardBridge.withdraw(address(LegacyL2Token), 100, 1000, hex""); assertEq(L2Token.balanceOf(alice), 0); } function test_bridgeLegacyERC20_succeeds() external { _preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) }); - L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex""); + l2StandardBridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex""); assertEq(L2Token.balanceOf(alice), 0); } @@ -255,7 +282,7 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 { deal(address(L2Token), address(this), 100, true); vm.expectRevert("StandardBridge: function can only be called from an EOA"); - L2Bridge.withdraw(address(L2Token), 100, 1000, hex""); + l2StandardBridge.withdraw(address(L2Token), 100, 1000, hex""); } } @@ -265,70 +292,86 @@ contract PreBridgeERC20To is Bridge_Initializer { function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal { deal(_l2Token, alice, 100, true); assertEq(ERC20(L2Token).balanceOf(alice), 100); - uint256 nonce = L2Messenger.messageNonce(); + uint256 nonce = l2CrossDomainMessenger.messageNonce(); bytes memory message = abi.encodeWithSelector( StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, bob, 100, hex"" ); - uint64 baseGas = L2Messenger.baseGas(message, 1000); + uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 1000); bytes memory withdrawalData = abi.encodeWithSelector( - CrossDomainMessenger.relayMessage.selector, nonce, address(L2Bridge), address(L1Bridge), 0, 1000, message + CrossDomainMessenger.relayMessage.selector, + nonce, + address(l2StandardBridge), + address(l1StandardBridge), + 0, + 1000, + message ); bytes32 withdrawalHash = Hashing.hashWithdrawal( Types.WithdrawalTransaction({ nonce: nonce, - sender: address(L2Messenger), - target: address(L1Messenger), + sender: address(l2CrossDomainMessenger), + target: address(l1CrossDomainMessenger), value: 0, gasLimit: baseGas, data: withdrawalData }) ); - vm.expectEmit(true, true, true, true, address(L2Bridge)); + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex""); - vm.expectEmit(true, true, true, true, address(L2Bridge)); + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex""); - vm.expectEmit(true, true, true, true, address(messagePasser)); + vm.expectEmit(true, true, true, true, address(l2ToL1MessagePasser)); emit MessagePassed( - nonce, address(L2Messenger), address(L1Messenger), 0, baseGas, withdrawalData, withdrawalHash + nonce, + address(l2CrossDomainMessenger), + address(l1CrossDomainMessenger), + 0, + baseGas, + withdrawalData, + withdrawalHash ); // SentMessage event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L2Messenger)); - emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000); + vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger)); + emit SentMessage(address(l1StandardBridge), address(l2StandardBridge), message, nonce, 1000); // SentMessageExtension1 event emitted by the CrossDomainMessenger - vm.expectEmit(true, true, true, true, address(L2Messenger)); - emit SentMessageExtension1(address(L2Bridge), 0); + vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger)); + emit SentMessageExtension1(address(l2StandardBridge), 0); if (_isLegacy) { vm.expectCall( - address(L2Bridge), abi.encodeWithSelector(L2Bridge.withdrawTo.selector, _l2Token, bob, 100, 1000, hex"") + address(l2StandardBridge), + abi.encodeWithSelector(l2StandardBridge.withdrawTo.selector, _l2Token, bob, 100, 1000, hex"") ); } else { vm.expectCall( - address(L2Bridge), + address(l2StandardBridge), abi.encodeWithSelector( - L2Bridge.bridgeERC20To.selector, _l2Token, address(L1Token), bob, 100, 1000, hex"" + l2StandardBridge.bridgeERC20To.selector, _l2Token, address(L1Token), bob, 100, 1000, hex"" ) ); } vm.expectCall( - address(L2Messenger), - abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L1Bridge), message, 1000) + address(l2CrossDomainMessenger), + abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 1000) ); vm.expectCall( Predeploys.L2_TO_L1_MESSAGE_PASSER, abi.encodeWithSelector( - L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData + L2ToL1MessagePasser.initiateWithdrawal.selector, + address(l1CrossDomainMessenger), + baseGas, + withdrawalData ) ); - // The L2Bridge should burn the tokens + // The l2StandardBridge should burn the tokens vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)); vm.prank(alice, alice); @@ -340,7 +383,7 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To { /// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`. function test_withdrawTo_withdrawingERC20_succeeds() external { _preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) }); - L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex""); + l2StandardBridge.withdrawTo(address(L2Token), bob, 100, 1000, hex""); assertEq(L2Token.balanceOf(alice), 0); } @@ -349,7 +392,7 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To { /// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`. function test_bridgeERC20To_succeeds() external { _preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) }); - L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex""); + l2StandardBridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex""); assertEq(L2Token.balanceOf(alice), 0); } } @@ -361,37 +404,37 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { /// - call `Withdrawer.initiateWithdrawal` if the token pair is not supported function test_finalizeDeposit_depositingERC20_succeeds() external { vm.mockCall( - address(L2Bridge.messenger()), + address(l2StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) ); vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)); // Should emit both the bedrock and legacy events - vm.expectEmit(true, true, true, true, address(L2Bridge)); + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); - vm.expectEmit(true, true, true, true, address(L2Bridge)); + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex""); - vm.prank(address(L2Messenger)); - L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex""); + vm.prank(address(l2CrossDomainMessenger)); + l2StandardBridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex""); } /// @dev Tests that `finalizeDeposit` succeeds when depositing ETH. function test_finalizeDeposit_depositingETH_succeeds() external { vm.mockCall( - address(L2Bridge.messenger()), + address(l2StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) ); // Should emit both the bedrock and legacy events - vm.expectEmit(true, true, true, true, address(L2Bridge)); + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); - vm.expectEmit(true, true, true, true, address(L2Bridge)); + vm.expectEmit(true, true, true, true, address(l2StandardBridge)); emit ERC20BridgeFinalized( address(L2Token), // localToken address(L1Token), // remoteToken @@ -401,58 +444,58 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { hex"" ); - vm.prank(address(L2Messenger)); - L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex""); + vm.prank(address(l2CrossDomainMessenger)); + l2StandardBridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex""); } /// @dev Tests that `finalizeDeposit` reverts if the amounts do not match. function test_finalizeBridgeETH_incorrectValue_reverts() external { vm.mockCall( - address(L2Bridge.messenger()), + address(l2StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) ); - vm.deal(address(L2Messenger), 100); - vm.prank(address(L2Messenger)); + vm.deal(address(l2CrossDomainMessenger), 100); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("StandardBridge: amount sent does not match amount required"); - L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex""); + l2StandardBridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex""); } /// @dev Tests that `finalizeDeposit` reverts if the receipient is the other bridge. function test_finalizeBridgeETH_sendToSelf_reverts() external { vm.mockCall( - address(L2Bridge.messenger()), + address(l2StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) ); - vm.deal(address(L2Messenger), 100); - vm.prank(address(L2Messenger)); + vm.deal(address(l2CrossDomainMessenger), 100); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("StandardBridge: cannot send to self"); - L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex""); + l2StandardBridge.finalizeBridgeETH{ value: 100 }(alice, address(l2StandardBridge), 100, hex""); } /// @dev Tests that `finalizeDeposit` reverts if the receipient is the messenger. function test_finalizeBridgeETH_sendToMessenger_reverts() external { vm.mockCall( - address(L2Bridge.messenger()), + address(l2StandardBridge.messenger()), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) ); - vm.deal(address(L2Messenger), 100); - vm.prank(address(L2Messenger)); + vm.deal(address(l2CrossDomainMessenger), 100); + vm.prank(address(l2CrossDomainMessenger)); vm.expectRevert("StandardBridge: cannot send to messenger"); - L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Messenger), 100, hex""); + l2StandardBridge.finalizeBridgeETH{ value: 100 }(alice, address(l2CrossDomainMessenger), 100, hex""); } } contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { /// @dev Tests that `finalizeBridgeETH` succeeds. function test_finalizeBridgeETH_succeeds() external { - address messenger = address(L2Bridge.messenger()); + address messenger = address(l2StandardBridge.messenger()); vm.mockCall( messenger, abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), - abi.encode(address(L2Bridge.OTHER_BRIDGE())) + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) ); vm.deal(messenger, 100); vm.prank(messenger); @@ -463,6 +506,6 @@ contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { vm.expectEmit(true, true, true, true); emit ETHBridgeFinalized(alice, alice, 100, hex""); - L2Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); + l2StandardBridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); } } diff --git a/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol b/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol index 82ee90454b6c..7ee5a43f9ad1 100644 --- a/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol +++ b/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol @@ -8,12 +8,7 @@ import { CommonTest } from "test/CommonTest.t.sol"; import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; -// Target contract -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; - contract L2ToL1MessagePasserTest is CommonTest { - L2ToL1MessagePasser messagePasser; - event MessagePassed( uint256 indexed nonce, address indexed sender, @@ -26,12 +21,6 @@ contract L2ToL1MessagePasserTest is CommonTest { event WithdrawerBalanceBurnt(uint256 indexed amount); - /// @dev Sets up the test suite. - function setUp() public virtual override { - super.setUp(); - messagePasser = new L2ToL1MessagePasser(); - } - /// @dev Tests that `initiateWithdrawal` succeeds and correctly sets the state /// of the message passer for the withdrawal hash. function testFuzz_initiateWithdrawal_succeeds( @@ -43,7 +32,7 @@ contract L2ToL1MessagePasserTest is CommonTest { ) external { - uint256 nonce = messagePasser.messageNonce(); + uint256 nonce = l2ToL1MessagePasser.messageNonce(); bytes32 withdrawalHash = Hashing.hashWithdrawal( Types.WithdrawalTransaction({ @@ -56,18 +45,18 @@ contract L2ToL1MessagePasserTest is CommonTest { }) ); - vm.expectEmit(true, true, true, true); + vm.expectEmit(address(l2ToL1MessagePasser)); emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash); vm.deal(_sender, _value); vm.prank(_sender); - messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data); + l2ToL1MessagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data); - assertEq(messagePasser.sentMessages(withdrawalHash), true); + assertEq(l2ToL1MessagePasser.sentMessages(withdrawalHash), true); bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0))); - assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1))); + assertEq(vm.load(address(l2ToL1MessagePasser), slot), bytes32(uint256(1))); } /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed @@ -82,7 +71,7 @@ contract L2ToL1MessagePasserTest is CommonTest { { bytes32 withdrawalHash = Hashing.hashWithdrawal( Types.WithdrawalTransaction({ - nonce: messagePasser.messageNonce(), + nonce: l2ToL1MessagePasser.messageNonce(), sender: address(this), target: _target, value: _value, @@ -91,13 +80,13 @@ contract L2ToL1MessagePasserTest is CommonTest { }) ); - vm.expectEmit(address(messagePasser)); + vm.expectEmit(address(l2ToL1MessagePasser)); emit MessagePassed( - messagePasser.messageNonce(), address(this), _target, _value, _gasLimit, _data, withdrawalHash + l2ToL1MessagePasser.messageNonce(), address(this), _target, _value, _gasLimit, _data, withdrawalHash ); vm.deal(address(this), _value); - messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data); + l2ToL1MessagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data); } /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed @@ -110,7 +99,7 @@ contract L2ToL1MessagePasserTest is CommonTest { ) external { - uint256 nonce = messagePasser.messageNonce(); + uint256 nonce = l2ToL1MessagePasser.messageNonce(); // EOA emulation vm.prank(alice, alice); @@ -118,29 +107,28 @@ contract L2ToL1MessagePasserTest is CommonTest { bytes32 withdrawalHash = Hashing.hashWithdrawal(Types.WithdrawalTransaction(nonce, alice, _target, _value, _gasLimit, _data)); - vm.expectEmit(address(messagePasser)); + vm.expectEmit(address(l2ToL1MessagePasser)); emit MessagePassed(nonce, alice, _target, _value, _gasLimit, _data, withdrawalHash); - messagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); + l2ToL1MessagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); // the sent messages mapping is filled - assertEq(messagePasser.sentMessages(withdrawalHash), true); + assertEq(l2ToL1MessagePasser.sentMessages(withdrawalHash), true); // the nonce increments - assertEq(nonce + 1, messagePasser.messageNonce()); + assertEq(nonce + 1, l2ToL1MessagePasser.messageNonce()); } /// @dev Tests that `burn` succeeds and destroys the ETH held in the contract. function testFuzz_burn_succeeds(uint256 _value, address _target, uint256 _gasLimit, bytes memory _data) external { vm.deal(address(this), _value); - messagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); + l2ToL1MessagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); - assertEq(address(messagePasser).balance, _value); - vm.expectEmit(true, false, false, false); + assertEq(address(l2ToL1MessagePasser).balance, _value); emit WithdrawerBalanceBurnt(_value); - messagePasser.burn(); + l2ToL1MessagePasser.burn(); // The Withdrawer should have no balance - assertEq(address(messagePasser).balance, 0); + assertEq(address(l2ToL1MessagePasser).balance, 0); } } diff --git a/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol b/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol index abf841e3e79e..d31e04720771 100644 --- a/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol +++ b/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol @@ -4,25 +4,11 @@ pragma solidity 0.8.15; // Testing utilities import { CommonTest } from "test/CommonTest.t.sol"; -// Testing contract dependencies -import { Predeploys } from "src/libraries/Predeploys.sol"; - -// Target contract -import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; - contract LegacyMessagePasser_Test is CommonTest { - LegacyMessagePasser messagePasser; - - /// @dev Sets up the test suite. - function setUp() public virtual override { - super.setUp(); - messagePasser = new LegacyMessagePasser(); - } - /// @dev Tests that `passMessageToL1` succeeds. function test_passMessageToL1_succeeds() external { vm.prank(alice); - messagePasser.passMessageToL1(hex"ff"); - assert(messagePasser.sentMessages(keccak256(abi.encodePacked(hex"ff", alice)))); + legacyMessagePasser.passMessageToL1(hex"ff"); + assert(legacyMessagePasser.sentMessages(keccak256(abi.encodePacked(hex"ff", alice)))); } } diff --git a/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol index 40233eded0f8..5bda37ef875b 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol @@ -14,7 +14,7 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { } function test_bridge_succeeds() external { - assertEq(L2Token.bridge(), address(L2Bridge)); + assertEq(L2Token.bridge(), address(l2StandardBridge)); } function test_l1Token_succeeds() external { @@ -22,7 +22,7 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { } function test_l2Bridge_succeeds() external { - assertEq(L2Token.l2Bridge(), address(L2Bridge)); + assertEq(L2Token.l2Bridge(), address(l2StandardBridge)); } function test_legacy_succeeds() external { @@ -31,16 +31,16 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { assertEq(L2Token.remoteToken(), address(L1Token)); assertEq(L2Token.l1Token(), address(L1Token)); // Getters for the bridge - assertEq(L2Token.BRIDGE(), address(L2Bridge)); - assertEq(L2Token.bridge(), address(L2Bridge)); - assertEq(L2Token.l2Bridge(), address(L2Bridge)); + assertEq(L2Token.BRIDGE(), address(l2StandardBridge)); + assertEq(L2Token.bridge(), address(l2StandardBridge)); + assertEq(L2Token.l2Bridge(), address(l2StandardBridge)); } function test_mint_succeeds() external { vm.expectEmit(true, true, true, true); emit Mint(alice, 100); - vm.prank(address(L2Bridge)); + vm.prank(address(l2StandardBridge)); L2Token.mint(alice, 100); assertEq(L2Token.balanceOf(alice), 100); @@ -54,13 +54,13 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { } function test_burn_succeeds() external { - vm.prank(address(L2Bridge)); + vm.prank(address(l2StandardBridge)); L2Token.mint(alice, 100); vm.expectEmit(true, true, true, true); emit Burn(alice, 100); - vm.prank(address(L2Bridge)); + vm.prank(address(l2StandardBridge)); L2Token.burn(alice, 100); assertEq(L2Token.balanceOf(alice), 0); diff --git a/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol index a09ea0f94df7..82fb9c332e25 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol @@ -8,12 +8,8 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); - function setUp() public override { - super.setUp(); - } - function test_bridge_succeeds() external { - assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge)); + assertEq(address(l2OptimismMintableERC20Factory.BRIDGE()), address(l2StandardBridge)); } function test_createStandardL2Token_succeeds() external { @@ -29,7 +25,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { emit OptimismMintableERC20Created(local, remote, alice); vm.prank(alice); - address addr = L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); + address addr = l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP"); assertTrue(addr == local); assertTrue(OptimismMintableERC20(local).decimals() == 18); } @@ -45,7 +41,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { emit OptimismMintableERC20Created(local, remote, alice); vm.prank(alice); - address addr = L2TokenFactory.createOptimismMintableERC20WithDecimals(remote, "Beep", "BOOP", 6); + address addr = l2OptimismMintableERC20Factory.createOptimismMintableERC20WithDecimals(remote, "Beep", "BOOP", 6); assertTrue(addr == local); assertTrue(OptimismMintableERC20(local).decimals() == 6); @@ -55,18 +51,18 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { address remote = address(4); vm.prank(alice); - L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); + l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP"); vm.expectRevert(); vm.prank(alice); - L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); + l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP"); } function test_createStandardL2Token_remoteIsZero_reverts() external { address remote = address(0); vm.expectRevert("OptimismMintableERC20Factory: must provide remote token address"); - L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); + l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP"); } function calculateTokenAddress( @@ -79,10 +75,12 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { view returns (address) { - bytes memory constructorArgs = abi.encode(address(L2Bridge), _remote, _name, _symbol, _decimals); + bytes memory constructorArgs = abi.encode(address(l2StandardBridge), _remote, _name, _symbol, _decimals); bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC20).creationCode, constructorArgs); bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol, _decimals)); - bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(L2TokenFactory), salt, keccak256(bytecode))); + bytes32 hash = keccak256( + abi.encodePacked(bytes1(0xff), address(l2OptimismMintableERC20Factory), salt, keccak256(bytecode)) + ); return address(uint160(uint256(hash))); } } diff --git a/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol index 5aac93b2eb4c..a5ceade22cac 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol @@ -5,10 +5,10 @@ import { ERC721, IERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/CommonTest.t.sol"; import { OptimismMintableERC721, IOptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; -contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { +contract OptimismMintableERC721_Test is Bridge_Initializer { ERC721 internal L1NFT; OptimismMintableERC721 internal L2NFT; @@ -24,7 +24,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { // Set up the token pair. L1NFT = new ERC721("L1NFT", "L1T"); L2NFT = new OptimismMintableERC721( - address(L2NFTBridge), + address(l2ERC721Bridge), 1, address(L1NFT), "L2NFT", @@ -40,10 +40,10 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { assertEq(L2NFT.name(), "L2NFT"); assertEq(L2NFT.symbol(), "L2T"); assertEq(L2NFT.remoteToken(), address(L1NFT)); - assertEq(L2NFT.bridge(), address(L2NFTBridge)); + assertEq(L2NFT.bridge(), address(l2ERC721Bridge)); assertEq(L2NFT.remoteChainId(), 1); assertEq(L2NFT.REMOTE_TOKEN(), address(L1NFT)); - assertEq(L2NFT.BRIDGE(), address(L2NFTBridge)); + assertEq(L2NFT.BRIDGE(), address(l2ERC721Bridge)); assertEq(L2NFT.REMOTE_CHAIN_ID(), 1); } @@ -69,7 +69,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { emit Mint(alice, 1); // Mint the token. - vm.prank(address(L2NFTBridge)); + vm.prank(address(l2ERC721Bridge)); L2NFT.safeMint(alice, 1); // Token should be owned by alice. @@ -85,7 +85,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { function test_burn_succeeds() external { // Mint the token first. - vm.prank(address(L2NFTBridge)); + vm.prank(address(l2ERC721Bridge)); L2NFT.safeMint(alice, 1); // Expect a transfer event. @@ -97,7 +97,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { emit Burn(alice, 1); // Burn the token. - vm.prank(address(L2NFTBridge)); + vm.prank(address(l2ERC721Bridge)); L2NFT.burn(alice, 1); // Token should be owned by address(0). @@ -107,7 +107,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { function test_burn_notBridge_reverts() external { // Mint the token first. - vm.prank(address(L2NFTBridge)); + vm.prank(address(l2ERC721Bridge)); L2NFT.safeMint(alice, 1); // Try to burn the token. @@ -118,7 +118,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { function test_tokenURI_succeeds() external { // Mint the token first. - vm.prank(address(L2NFTBridge)); + vm.prank(address(l2ERC721Bridge)); L2NFT.safeMint(alice, 1); // Token URI should be correct. diff --git a/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol index ee70e3ff9f3b..75f4d94167dd 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol @@ -2,11 +2,11 @@ pragma solidity 0.8.15; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/CommonTest.t.sol"; import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; -contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { +contract OptimismMintableERC721Factory_Test is Bridge_Initializer { OptimismMintableERC721Factory internal factory; event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer); @@ -15,14 +15,14 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { super.setUp(); // Set up the token pair. - factory = new OptimismMintableERC721Factory(address(L2NFTBridge), 1); + factory = new OptimismMintableERC721Factory(address(l2ERC721Bridge), 1); // Label the addresses for nice traces. vm.label(address(factory), "OptimismMintableERC721Factory"); } function test_constructor_succeeds() external { - assertEq(factory.BRIDGE(), address(L2NFTBridge)); + assertEq(factory.BRIDGE(), address(l2ERC721Bridge)); assertEq(factory.REMOTE_CHAIN_ID(), 1); } @@ -49,7 +49,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { assertEq(created.name(), "L2Token"); assertEq(created.symbol(), "L2T"); assertEq(created.REMOTE_TOKEN(), remote); - assertEq(created.BRIDGE(), address(L2NFTBridge)); + assertEq(created.BRIDGE(), address(l2ERC721Bridge)); assertEq(created.REMOTE_CHAIN_ID(), 1); } @@ -80,7 +80,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { view returns (address) { - bytes memory constructorArgs = abi.encode(address(L2NFTBridge), 1, _remote, _name, _symbol); + bytes memory constructorArgs = abi.encode(address(l2ERC721Bridge), 1, _remote, _name, _symbol); bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC721).creationCode, constructorArgs); bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol)); bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(factory), salt, keccak256(bytecode))); diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol index 9ef9b8230ae9..bb68a0b4f5c9 100644 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/OptimismPortal.t.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.15; import { stdError } from "forge-std/Test.sol"; import { Portal_Initializer } from "test/CommonTest.t.sol"; import { NextImpl } from "test/mocks/NextImpl.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; @@ -17,8 +18,6 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; - -// Target contract import { OptimismPortal } from "src/L1/OptimismPortal.sol"; contract OptimismPortal_Test is Portal_Initializer { @@ -34,87 +33,96 @@ contract OptimismPortal_Test is Portal_Initializer { /// @dev Tests that the constructor sets the correct values. function test_constructor_succeeds() external { - assertEq(address(op.L2_ORACLE()), address(oracle)); - assertEq(address(op.l2Oracle()), address(oracle)); - assertEq(op.GUARDIAN(), guardian); - assertEq(op.guardian(), guardian); - assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD); - assertEq(op.paused(), false); + address guardian = cfg.portalGuardian(); + assertEq(address(optimismPortal.L2_ORACLE()), address(l2OutputOracle)); + assertEq(address(optimismPortal.l2Oracle()), address(l2OutputOracle)); + assertEq(optimismPortal.GUARDIAN(), guardian); + assertEq(optimismPortal.guardian(), guardian); + assertEq(optimismPortal.l2Sender(), 0x000000000000000000000000000000000000dEaD); + assertEq(optimismPortal.paused(), false); } /// @dev Tests that `pause` successfully pauses /// when called by the GUARDIAN. function test_pause_succeeds() external { - address guardian = op.GUARDIAN(); + address guardian = optimismPortal.GUARDIAN(); - assertEq(op.paused(), false); + assertEq(optimismPortal.paused(), false); - vm.expectEmit(true, true, true, true, address(op)); + vm.expectEmit(address(optimismPortal)); emit Paused(guardian); vm.prank(guardian); - op.pause(); + optimismPortal.pause(); - assertEq(op.paused(), true); + assertEq(optimismPortal.paused(), true); } /// @dev Tests that `pause` reverts when called by a non-GUARDIAN. function test_pause_onlyGuardian_reverts() external { - assertEq(op.paused(), false); + assertEq(optimismPortal.paused(), false); - assertTrue(op.GUARDIAN() != alice); + assertTrue(optimismPortal.GUARDIAN() != alice); vm.expectRevert("OptimismPortal: only guardian can pause"); vm.prank(alice); - op.pause(); + optimismPortal.pause(); - assertEq(op.paused(), false); + assertEq(optimismPortal.paused(), false); } /// @dev Tests that `unpause` successfully unpauses /// when called by the GUARDIAN. function test_unpause_succeeds() external { - address guardian = op.GUARDIAN(); + address guardian = optimismPortal.GUARDIAN(); vm.prank(guardian); - op.pause(); - assertEq(op.paused(), true); + optimismPortal.pause(); + assertEq(optimismPortal.paused(), true); - vm.expectEmit(true, true, true, true, address(op)); + vm.expectEmit(address(optimismPortal)); emit Unpaused(guardian); vm.prank(guardian); - op.unpause(); + optimismPortal.unpause(); - assertEq(op.paused(), false); + assertEq(optimismPortal.paused(), false); } /// @dev Tests that `unpause` reverts when called by a non-GUARDIAN. function test_unpause_onlyGuardian_reverts() external { - address guardian = op.GUARDIAN(); + address guardian = optimismPortal.GUARDIAN(); vm.prank(guardian); - op.pause(); - assertEq(op.paused(), true); + optimismPortal.pause(); + assertEq(optimismPortal.paused(), true); - assertTrue(op.GUARDIAN() != alice); + assertTrue(optimismPortal.GUARDIAN() != alice); vm.expectRevert("OptimismPortal: only guardian can unpause"); vm.prank(alice); - op.unpause(); + optimismPortal.unpause(); - assertEq(op.paused(), true); + assertEq(optimismPortal.paused(), true); } /// @dev Tests that `receive` successdully deposits ETH. - function test_receive_succeeds() external { - vm.expectEmit(true, true, false, true); - emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex""); + function testFuzz_receive_succeeds(uint256 _value) external { + vm.expectEmit(address(optimismPortal)); + emitTransactionDeposited({ + _from: alice, + _to: alice, + _value: _value, + _mint: _value, + _gasLimit: 100_000, + _isCreation: false, + _data: hex"" + }); // give alice money and send as an eoa - vm.deal(alice, 2 ** 64); + vm.deal(alice, _value); vm.prank(alice, alice); - (bool s,) = address(op).call{ value: 100 }(hex""); + (bool s,) = address(optimismPortal).call{ value: _value }(hex""); - assert(s); - assertEq(address(op).balance, 100); + assertTrue(s); + assertEq(address(optimismPortal).balance, _value); } /// @dev Tests that `depositTransaction` reverts when the destination address is non-zero @@ -122,16 +130,16 @@ contract OptimismPortal_Test is Portal_Initializer { function test_depositTransaction_contractCreation_reverts() external { // contract creation must have a target of address(0) vm.expectRevert("OptimismPortal: must send to address(0) when creating a contract"); - op.depositTransaction(address(1), 1, 0, true, hex""); + optimismPortal.depositTransaction(address(1), 1, 0, true, hex""); } /// @dev Tests that `depositTransaction` reverts when the data is too large. /// This places an upper bound on unsafe blocks sent over p2p. function test_depositTransaction_largeData_reverts() external { uint256 size = 120_001; - uint64 gasLimit = op.minimumGasLimit(uint64(size)); + uint64 gasLimit = optimismPortal.minimumGasLimit(uint64(size)); vm.expectRevert("OptimismPortal: data too large"); - op.depositTransaction({ + optimismPortal.depositTransaction({ _to: address(0), _value: 0, _gasLimit: gasLimit, @@ -143,30 +151,34 @@ contract OptimismPortal_Test is Portal_Initializer { /// @dev Tests that `depositTransaction` reverts when the gas limit is too small. function test_depositTransaction_smallGasLimit_reverts() external { vm.expectRevert("OptimismPortal: gas limit too small"); - op.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" }); + optimismPortal.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" }); } /// @dev Tests that `depositTransaction` succeeds for small, /// but sufficient, gas limits. function testFuzz_depositTransaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external { - vm.assume(_data.length <= type(uint64).max); - - uint64 gasLimit = op.minimumGasLimit(uint64(_data.length)); + uint64 gasLimit = optimismPortal.minimumGasLimit(uint64(_data.length)); if (_shouldFail) { gasLimit = uint64(bound(gasLimit, 0, gasLimit - 1)); vm.expectRevert("OptimismPortal: gas limit too small"); } - op.depositTransaction({ _to: address(0x40), _value: 0, _gasLimit: gasLimit, _isCreation: false, _data: _data }); + optimismPortal.depositTransaction({ + _to: address(0x40), + _value: 0, + _gasLimit: gasLimit, + _isCreation: false, + _data: _data + }); } /// @dev Tests that `minimumGasLimit` succeeds for small calldata sizes. /// The gas limit should be 21k for 0 calldata and increase linearly /// for larger calldata sizes. function test_minimumGasLimit_succeeds() external { - assertEq(op.minimumGasLimit(0), 21_000); - assertTrue(op.minimumGasLimit(2) > op.minimumGasLimit(1)); - assertTrue(op.minimumGasLimit(3) > op.minimumGasLimit(2)); + assertEq(optimismPortal.minimumGasLimit(0), 21_000); + assertTrue(optimismPortal.minimumGasLimit(2) > optimismPortal.minimumGasLimit(1)); + assertTrue(optimismPortal.minimumGasLimit(3) > optimismPortal.minimumGasLimit(2)); } /// @dev Tests that `depositTransaction` succeeds for an EOA. @@ -181,12 +193,12 @@ contract OptimismPortal_Test is Portal_Initializer { external { _gasLimit = uint64( - bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) + bound(_gasLimit, optimismPortal.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) ); if (_isCreation) _to = address(0); // EOA emulation - vm.expectEmit(address(op)); + vm.expectEmit(address(optimismPortal)); emitTransactionDeposited({ _from: depositor, _to: _to, @@ -199,14 +211,14 @@ contract OptimismPortal_Test is Portal_Initializer { vm.deal(depositor, _mint); vm.prank(depositor, depositor); - op.depositTransaction{ value: _mint }({ + optimismPortal.depositTransaction{ value: _mint }({ _to: _to, _value: _value, _gasLimit: _gasLimit, _isCreation: _isCreation, _data: _data }); - assertEq(address(op).balance, _mint); + assertEq(address(optimismPortal).balance, _mint); } /// @dev Tests that `depositTransaction` succeeds for a contract. @@ -220,12 +232,10 @@ contract OptimismPortal_Test is Portal_Initializer { ) external { - _gasLimit = uint64( - bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) - ); + _gasLimit = uint64(bound(_gasLimit, optimismPortal.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit)); if (_isCreation) _to = address(0); - vm.expectEmit(address(op)); + vm.expectEmit(address(optimismPortal)); emitTransactionDeposited({ _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), _to: _to, @@ -236,43 +246,63 @@ contract OptimismPortal_Test is Portal_Initializer { _data: _data }); + vm.deal(address(this), _mint); vm.prank(address(this)); - op.depositTransaction{ value: _mint }({ + optimismPortal.depositTransaction{ value: _mint }({ _to: _to, _value: _value, _gasLimit: _gasLimit, _isCreation: _isCreation, _data: _data }); - assertEq(address(op).balance, _mint); + assertEq(address(optimismPortal).balance, _mint); + } + + /// @dev Tests that `isOutputFinalized` succeeds for an EOA depositing a tx with ETH and data. + function test_simple_isOutputFinalized_succeeds() external { + uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber(); + + uint256 ts = block.timestamp; + vm.mockCall( + address(optimismPortal.L2_ORACLE()), + abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), + abi.encode(Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber))) + ); + + // warp to the finalization period + vm.warp(ts + l2OutputOracle.FINALIZATION_PERIOD_SECONDS()); + assertEq(optimismPortal.isOutputFinalized(0), false); + + // warp past the finalization period + vm.warp(ts + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); + assertEq(optimismPortal.isOutputFinalized(0), true); } /// @dev Tests `isOutputFinalized` for a finalized output. function test_isOutputFinalized_succeeds() external { - uint256 checkpoint = oracle.nextBlockNumber(); - uint256 nextOutputIndex = oracle.nextOutputIndex(); + uint256 checkpoint = l2OutputOracle.nextBlockNumber(); + uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex(); vm.roll(checkpoint); - vm.warp(oracle.computeL2Timestamp(checkpoint) + 1); - vm.prank(oracle.PROPOSER()); - oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0); + vm.warp(l2OutputOracle.computeL2Timestamp(checkpoint) + 1); + vm.prank(l2OutputOracle.PROPOSER()); + l2OutputOracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0); // warp to the final second of the finalization period - uint256 finalizationHorizon = block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS(); + uint256 finalizationHorizon = block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS(); vm.warp(finalizationHorizon); // The checkpointed block should not be finalized until 1 second from now. - assertEq(op.isOutputFinalized(nextOutputIndex), false); + assertEq(optimismPortal.isOutputFinalized(nextOutputIndex), false); // Nor should a block after it vm.expectRevert(stdError.indexOOBError); - assertEq(op.isOutputFinalized(nextOutputIndex + 1), false); - + assertEq(optimismPortal.isOutputFinalized(nextOutputIndex + 1), false); // warp past the finalization period vm.warp(finalizationHorizon + 1); // It should now be finalized. - assertEq(op.isOutputFinalized(nextOutputIndex), true); + assertEq(optimismPortal.isOutputFinalized(nextOutputIndex), true); // But not the block after it. vm.expectRevert(stdError.indexOOBError); - assertEq(op.isOutputFinalized(nextOutputIndex + 1), false); + assertEq(optimismPortal.isOutputFinalized(nextOutputIndex + 1), false); } } @@ -311,21 +341,24 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { messagePasserStorageRoot: _storageRoot, latestBlockhash: bytes32(uint256(0)) }); - _proposedBlockNumber = oracle.nextBlockNumber(); - _proposedOutputIndex = oracle.nextOutputIndex(); + _proposedBlockNumber = l2OutputOracle.nextBlockNumber(); + _proposedOutputIndex = l2OutputOracle.nextOutputIndex(); } /// @dev Setup the system for a ready-to-use state. function setUp() public override { // Configure the oracle to return the output root we've prepared. - vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1); - vm.prank(oracle.PROPOSER()); - oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); + vm.warp(l2OutputOracle.computeL2Timestamp(_proposedBlockNumber) + 1); + vm.prank(l2OutputOracle.PROPOSER()); + l2OutputOracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); // Warp beyond the finalization period for the block we've proposed. - vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp( + l2OutputOracle.getL2Output(_proposedOutputIndex).timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + + 1 + ); // Fund the portal so that we can withdraw ETH. - vm.deal(address(op), 0xFFFFFFFF); + vm.deal(address(optimismPortal), 0xFFFFFFFF); } /// @dev Asserts that the reentrant call will revert. @@ -333,18 +366,18 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { vm.expectRevert("OptimismPortal: can only trigger one withdrawal per transaction"); // Arguments here don't matter, as the require check is the first thing that happens. // We assume that this has already been proven. - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); // Assert that the withdrawal was not finalized. - assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx))); + assertFalse(optimismPortal.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx))); } /// @dev Tests that `proveWithdrawalTransaction` reverts when paused. function test_proveWithdrawalTransaction_paused_reverts() external { - vm.prank(op.GUARDIAN()); - op.pause(); + vm.prank(optimismPortal.GUARDIAN()); + optimismPortal.pause(); vm.expectRevert("OptimismPortal: paused"); - op.proveWithdrawalTransaction({ + optimismPortal.proveWithdrawalTransaction({ _tx: _defaultTx, _l2OutputIndex: _proposedOutputIndex, _outputRootProof: _outputRootProof, @@ -354,9 +387,9 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { /// @dev Tests that `proveWithdrawalTransaction` reverts when the target is the portal contract. function test_proveWithdrawalTransaction_onSelfCall_reverts() external { - _defaultTx.target = address(op); + _defaultTx.target = address(optimismPortal); vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract"); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); } /// @dev Tests that `proveWithdrawalTransaction` reverts when @@ -365,7 +398,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // Modify the version to invalidate the withdrawal proof. _outputRootProof.version = bytes32(uint256(1)); vm.expectRevert("OptimismPortal: invalid output root proof"); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); } /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal is missing. @@ -373,7 +406,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // modify the default test values to invalidate the proof. _defaultTx.data = hex"abcd"; vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key"); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); } /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal has already @@ -381,10 +414,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { function test_proveWithdrawalTransaction_replayProve_reverts() external { vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); vm.expectRevert("OptimismPortal: withdrawal hash has already been proven"); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); } /// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already @@ -392,7 +425,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external { vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash` // inside of the `provenWithdrawal`s mapping. @@ -405,7 +438,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // Store a different output root within the `provenWithdrawals` mapping without // touching the l2BlockNumber or timestamp. - vm.store(address(op), slot, bytes32(0)); + vm.store(address(optimismPortal), slot, bytes32(0)); // Warp ahead 1 second vm.warp(block.timestamp + 1); @@ -414,10 +447,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // our proof with a changed outputRoot vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Ensure that the withdrawal was updated within the mapping - (, uint128 timestamp,) = op.provenWithdrawals(_withdrawalHash); + (, uint128 timestamp,) = optimismPortal.provenWithdrawals(_withdrawalHash); assertEq(timestamp, block.timestamp); } @@ -426,7 +459,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() external { vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash` // inside of the `provenWithdrawal`s mapping. @@ -439,15 +472,15 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // Store a dummy output root within the `provenWithdrawals` mapping without touching the // l2BlockNumber or timestamp. - vm.store(address(op), slot, bytes32(0)); + vm.store(address(optimismPortal), slot, bytes32(0)); // Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle - Types.OutputProposal memory proposal = op.L2_ORACLE().getL2Output(_proposedOutputIndex); + Types.OutputProposal memory proposal = optimismPortal.L2_ORACLE().getL2Output(_proposedOutputIndex); // Propose the same output root again, creating the same output at a different index + l2BlockNumber. - vm.startPrank(op.L2_ORACLE().PROPOSER()); - op.L2_ORACLE().proposeL2Output( - proposal.outputRoot, op.L2_ORACLE().nextBlockNumber(), blockhash(block.number), block.number + vm.startPrank(optimismPortal.L2_ORACLE().PROPOSER()); + optimismPortal.L2_ORACLE().proposeL2Output( + proposal.outputRoot, optimismPortal.L2_ORACLE().nextBlockNumber(), blockhash(block.number), block.number ); vm.stopPrank(); @@ -458,10 +491,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // our proof with a changed outputRoot + a different output index vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex + 1, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction( + _defaultTx, _proposedOutputIndex + 1, _outputRootProof, _withdrawalProof + ); // Ensure that the withdrawal was updated within the mapping - (, uint128 timestamp,) = op.provenWithdrawals(_withdrawalHash); + (, uint128 timestamp,) = optimismPortal.provenWithdrawals(_withdrawalHash); assertEq(timestamp, block.timestamp); } @@ -469,7 +504,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external { vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); } /// @dev Tests that `finalizeWithdrawalTransaction` succeeds. @@ -478,23 +513,23 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.expectEmit(true, true, false, true); emit WithdrawalFinalized(_withdrawalHash, true); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); assert(address(bob).balance == bobBalanceBefore + 100); } /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the contract is paused. function test_finalizeWithdrawalTransaction_paused_reverts() external { - vm.prank(op.GUARDIAN()); - op.pause(); + vm.prank(optimismPortal.GUARDIAN()); + optimismPortal.pause(); vm.expectRevert("OptimismPortal: paused"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); } /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been @@ -502,7 +537,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { uint256 bobBalanceBefore = address(bob).balance; vm.expectRevert("OptimismPortal: withdrawal has not been proven yet"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); assert(address(bob).balance == bobBalanceBefore); } @@ -514,18 +549,18 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Mock a call where the resulting output root is anything but the original output root. In // this case we just use bytes32(uint256(1)). vm.mockCall( - address(op.L2_ORACLE()), + address(optimismPortal.L2_ORACLE()), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encode(bytes32(uint256(1)), _proposedBlockNumber) ); vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); assert(address(bob).balance == bobBalanceBefore); } @@ -538,19 +573,21 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // Prove our withdrawal vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Warp to after the finalization period - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); // Mock a startingTimestamp change on the L2 Oracle vm.mockCall( - address(op.L2_ORACLE()), abi.encodeWithSignature("startingTimestamp()"), abi.encode(block.timestamp + 1) + address(optimismPortal.L2_ORACLE()), + abi.encodeWithSignature("startingTimestamp()"), + abi.encode(block.timestamp + 1) ); // Attempt to finalize the withdrawal vm.expectRevert("OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); // Ensure that bob's balance has remained the same assertEq(bobBalanceBefore, address(bob).balance); @@ -564,15 +601,15 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // Prove our withdrawal vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Warp to after the finalization period - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); // Mock an outputRoot change on the output proposal before attempting // to finalize the withdrawal. vm.mockCall( - address(op.L2_ORACLE()), + address(optimismPortal.L2_ORACLE()), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encode( Types.OutputProposal(bytes32(uint256(0)), uint128(block.timestamp), uint128(_proposedBlockNumber)) @@ -581,7 +618,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // Attempt to finalize the withdrawal vm.expectRevert("OptimismPortal: output root proven is not the same as current output root"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); // Ensure that bob's balance has remained the same assertEq(bobBalanceBefore, address(bob).balance); @@ -595,22 +632,22 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // Prove our withdrawal vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Warp to after the finalization period - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); // Mock a timestamp change on the output proposal that has not passed the // finalization period. vm.mockCall( - address(op.L2_ORACLE()), + address(optimismPortal.L2_ORACLE()), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encode(Types.OutputProposal(_outputRoot, uint128(block.timestamp + 1), uint128(_proposedBlockNumber))) ); // Attempt to finalize the withdrawal vm.expectRevert("OptimismPortal: output proposal finalization period has not elapsed"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); // Ensure that bob's balance has remained the same assertEq(bobBalanceBefore, address(bob).balance); @@ -623,12 +660,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.expectEmit(true, true, true, true); emit WithdrawalFinalized(_withdrawalHash, false); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); assert(address(bob).balance == bobBalanceBefore); } @@ -637,17 +674,17 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { /// has not yet passed. function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external { // Setup the Oracle to return an output with a recent timestamp - uint256 recentTimestamp = block.timestamp - 1000; + uint256 recentTimestamp = block.timestamp - 1; vm.mockCall( - address(op.L2_ORACLE()), + address(optimismPortal.L2_ORACLE()), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encode(Types.OutputProposal(_outputRoot, uint128(recentTimestamp), uint128(_proposedBlockNumber))) ); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); } /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has already been @@ -655,15 +692,15 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { function test_finalizeWithdrawalTransaction_onReplay_reverts() external { vm.expectEmit(true, true, true, true); emit WithdrawalProven(_withdrawalHash, alice, bob); - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.expectEmit(true, true, true, true); emit WithdrawalFinalized(_withdrawalHash, true); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); vm.expectRevert("OptimismPortal: withdrawal has already been finalized"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); } /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal transaction @@ -691,7 +728,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { }); vm.mockCall( - address(op.L2_ORACLE()), + address(optimismPortal.L2_ORACLE()), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encode( Types.OutputProposal( @@ -702,11 +739,13 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ) ); - op.proveWithdrawalTransaction(insufficientGasTx, _proposedOutputIndex, outputRootProof, withdrawalProof); + optimismPortal.proveWithdrawalTransaction( + insufficientGasTx, _proposedOutputIndex, outputRootProof, withdrawalProof + ); - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.expectRevert("SafeCall: Not enough gas"); - op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx); + optimismPortal.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx); } /// @dev Tests that `finalizeWithdrawalTransaction` reverts if a sub-call attempts to finalize @@ -736,22 +775,22 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { }); // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp. - uint256 finalizedTimestamp = block.timestamp - oracle.FINALIZATION_PERIOD_SECONDS() - 1; + uint256 finalizedTimestamp = block.timestamp - l2OutputOracle.FINALIZATION_PERIOD_SECONDS() - 1; vm.mockCall( - address(op.L2_ORACLE()), + address(optimismPortal.L2_ORACLE()), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encode(Types.OutputProposal(outputRoot, uint128(finalizedTimestamp), uint128(_proposedBlockNumber))) ); vm.expectEmit(true, true, true, true); emit WithdrawalProven(withdrawalHash, alice, address(this)); - op.proveWithdrawalTransaction(_testTx, _proposedBlockNumber, outputRootProof, withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_testTx, _proposedBlockNumber, outputRootProof, withdrawalProof); - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.expectCall(address(this), _testTx.data); vm.expectEmit(true, true, true, true); emit WithdrawalFinalized(withdrawalHash, true); - op.finalizeWithdrawalTransaction(_testTx); + optimismPortal.finalizeWithdrawalTransaction(_testTx); // Ensure that bob's balance was not changed by the reentrant call. assert(address(bob).balance == bobBalanceBefore); @@ -768,7 +807,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { external { vm.assume( - _target != address(op) // Cannot call the optimism portal or a contract + _target != address(optimismPortal) // Cannot call the optimism portal or a contract && _target.code.length == 0 // No accounts with code && _target != CONSOLE // The console has no code but behaves like a contract && uint160(_target) > 9 // No precompiles (or zero address) @@ -776,10 +815,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // Total ETH supply is currently about 120M ETH. uint256 value = bound(_value, 0, 200_000_000 ether); - vm.deal(address(op), value); + vm.deal(address(optimismPortal), value); uint256 gasLimit = bound(_gasLimit, 0, 50_000_000); - uint256 nonce = messagePasser.messageNonce(); + uint256 nonce = l2ToL1MessagePasser.messageNonce(); // Get a withdrawal transaction and mock proof from the differential testing script. Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({ @@ -812,58 +851,46 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { // Setup the Oracle to return the outputRoot vm.mockCall( - address(oracle), - abi.encodeWithSelector(oracle.getL2Output.selector), + address(l2OutputOracle), + abi.encodeWithSelector(l2OutputOracle.getL2Output.selector), abi.encode(outputRoot, block.timestamp, 100) ); // Prove the withdrawal transaction - op.proveWithdrawalTransaction( + optimismPortal.proveWithdrawalTransaction( _tx, 100, // l2BlockNumber proof, withdrawalProof ); - (bytes32 _root,,) = op.provenWithdrawals(withdrawalHash); + (bytes32 _root,,) = optimismPortal.provenWithdrawals(withdrawalHash); assertTrue(_root != bytes32(0)); // Warp past the finalization period - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); // Finalize the withdrawal transaction vm.expectCallMinGas(_tx.target, _tx.value, uint64(_tx.gasLimit), _tx.data); - op.finalizeWithdrawalTransaction(_tx); - assertTrue(op.finalizedWithdrawals(withdrawalHash)); + optimismPortal.finalizeWithdrawalTransaction(_tx); + assertTrue(optimismPortal.finalizedWithdrawals(withdrawalHash)); } } contract OptimismPortalUpgradeable_Test is Portal_Initializer { - Proxy internal proxy; - uint64 initialBlockNum; - - /// @dev Sets up the test. - function setUp() public override { - super.setUp(); - initialBlockNum = uint64(block.number); - proxy = Proxy(payable(address(op))); - } - /// @dev Tests that the proxy is initialized correctly. function test_params_initValuesOnProxy_succeeds() external { - OptimismPortal p = OptimismPortal(payable(address(proxy))); - - (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = p.params(); - + (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params(); ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); + assertEq(prevBaseFee, rcfg.minimumBaseFee); assertEq(prevBoughtGas, 0); - assertEq(prevBlockNum, initialBlockNum); + assertEq(prevBlockNum, block.number - 1); } /// @dev Tests that the proxy cannot be initialized twice. function test_initialize_cannotInitProxy_reverts() external { vm.expectRevert("Initializable: contract is already initialized"); - OptimismPortal(payable(proxy)).initialize({ + optimismPortal.initialize({ _l2Oracle: L2OutputOracle(address(0)), _systemConfig: SystemConfig(address(0)), _guardian: address(0), @@ -873,8 +900,9 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer { /// @dev Tests that the implementation cannot be initialized twice. function test_initialize_cannotInitImpl_reverts() external { + address opImpl = mustGetAddress("OptimismPortal"); vm.expectRevert("Initializable: contract is already initialized"); - OptimismPortal(opImpl).initialize({ + OptimismPortal(payable(opImpl)).initialize({ _l2Oracle: L2OutputOracle(address(0)), _systemConfig: SystemConfig(address(0)), _guardian: address(0), @@ -885,21 +913,22 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer { /// @dev Tests that the proxy can be upgraded. function test_upgradeToAndCall_upgrading_succeeds() external { // Check an unused slot before upgrading. - bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21))); + bytes32 slot21Before = vm.load(address(optimismPortal), bytes32(uint256(21))); assertEq(bytes32(0), slot21Before); NextImpl nextImpl = new NextImpl(); - vm.startPrank(multisig); + + vm.startPrank(EIP1967Helper.getAdmin(address(optimismPortal))); // The value passed to the initialize must be larger than the last value // that initialize was called with. - proxy.upgradeToAndCall( + Proxy(payable(address(optimismPortal))).upgradeToAndCall( address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, Constants.INITIALIZER + 1) ); - assertEq(proxy.implementation(), address(nextImpl)); + assertEq(Proxy(payable(address(optimismPortal))).implementation(), address(nextImpl)); // Verify that the NextImpl contract initialized its values according as expected - bytes32 slot21After = vm.load(address(op), bytes32(uint256(21))); - bytes32 slot21Expected = NextImpl(address(op)).slot21Init(); + bytes32 slot21After = vm.load(address(optimismPortal), bytes32(uint256(21))); + bytes32 slot21Expected = NextImpl(address(optimismPortal)).slot21Init(); assertEq(slot21Expected, slot21After); } } @@ -945,6 +974,8 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer { // Pick a pseudorandom block number vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max) + uint256(_blockDiff)); + vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max)); + // Create a resource config to mock the call to the system config with ResourceMetering.ResourceConfig memory rcfg = ResourceMetering.ResourceConfig({ maxResourceLimit: _maxResourceLimit, @@ -961,18 +992,18 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer { // Set the resource params uint256 _prevBlockNum = block.number - _blockDiff; vm.store( - address(op), + address(optimismPortal), bytes32(uint256(1)), bytes32((_prevBlockNum << 192) | (uint256(_prevBoughtGas) << 128) | _prevBaseFee) ); // Ensure that the storage setting is correct - (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = op.params(); + (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params(); assertEq(prevBaseFee, _prevBaseFee); assertEq(prevBoughtGas, _prevBoughtGas); assertEq(prevBlockNum, _prevBlockNum); // Do a deposit, should not revert - op.depositTransaction{ gas: MAX_GAS_LIMIT }({ + optimismPortal.depositTransaction{ gas: MAX_GAS_LIMIT }({ _to: address(0x20), _value: 0x40, _gasLimit: _gasLimit, diff --git a/packages/contracts-bedrock/test/ProtocolVersions.t.sol b/packages/contracts-bedrock/test/ProtocolVersions.t.sol index 814c36ec9639..bed5c82d475e 100644 --- a/packages/contracts-bedrock/test/ProtocolVersions.t.sol +++ b/packages/contracts-bedrock/test/ProtocolVersions.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { CommonTest } from "test/CommonTest.t.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; @@ -14,44 +15,27 @@ import { Proxy } from "src/universal/Proxy.sol"; import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; contract ProtocolVersions_Init is CommonTest { - ProtocolVersions protocolVersions; - ProtocolVersions protocolVersionsImpl; - event ConfigUpdate(uint256 indexed version, ProtocolVersions.UpdateType indexed updateType, bytes data); - // Dummy values used to test getters - ProtocolVersion constant required = ProtocolVersion.wrap(0xabcd); - ProtocolVersion constant recommended = ProtocolVersion.wrap(0x1234); + ProtocolVersion required; + ProtocolVersion recommended; function setUp() public virtual override { super.setUp(); - - Proxy proxy = new Proxy(multisig); - protocolVersionsImpl = new ProtocolVersions(); - - vm.prank(multisig); - proxy.upgradeToAndCall( - address(protocolVersionsImpl), - abi.encodeCall( - ProtocolVersions.initialize, - ( - alice, // _owner, - required, - recommended - ) - ) - ); - - protocolVersions = ProtocolVersions(address(proxy)); + required = ProtocolVersion.wrap(cfg.requiredProtocolVersion()); + recommended = ProtocolVersion.wrap(cfg.recommendedProtocolVersion()); } } contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { /// @dev Tests that initialization sets the correct values. function test_initialize_values_succeeds() external { + ProtocolVersions protocolVersionsImpl = ProtocolVersions(mustGetAddress("ProtocolVersions")); + address owner = cfg.finalSystemOwner(); + assertEq(ProtocolVersion.unwrap(protocolVersions.required()), ProtocolVersion.unwrap(required)); assertEq(ProtocolVersion.unwrap(protocolVersions.recommended()), ProtocolVersion.unwrap(recommended)); - assertEq(protocolVersions.owner(), alice); + assertEq(protocolVersions.owner(), owner); assertEq(ProtocolVersion.unwrap(protocolVersionsImpl.required()), 0); assertEq(ProtocolVersion.unwrap(protocolVersionsImpl.recommended()), 0); @@ -60,6 +44,7 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { /// @dev Ensures that the events are emitted during initialization. function test_initialize_events_succeeds() external { + ProtocolVersions protocolVersionsImpl = ProtocolVersions(mustGetAddress("ProtocolVersions")); assertEq(protocolVersionsImpl.owner(), address(0xdEad)); // Wipe out the initialized slot so the proxy can be initialized again @@ -71,7 +56,7 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { vm.expectEmit(true, true, true, true, address(protocolVersions)); emit ConfigUpdate(0, ProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(recommended)); - vm.prank(multisig); + vm.prank(EIP1967Helper.getAdmin(address(protocolVersions))); Proxy(payable(address(protocolVersions))).upgradeToAndCall( address(protocolVersionsImpl), abi.encodeCall( diff --git a/packages/contracts-bedrock/test/SequencerFeeVault.t.sol b/packages/contracts-bedrock/test/SequencerFeeVault.t.sol index 37975c0d17cb..925a1b53b0f8 100644 --- a/packages/contracts-bedrock/test/SequencerFeeVault.t.sol +++ b/packages/contracts-bedrock/test/SequencerFeeVault.t.sol @@ -16,126 +16,142 @@ import { FeeVault } from "src/universal/FeeVault.sol"; import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; contract SequencerFeeVault_Test is FeeVault_Initializer { + address recipient; /// @dev Sets up the test suite. + function setUp() public override { super.setUp(); - vm.etch( - Predeploys.SEQUENCER_FEE_WALLET, - address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1)).code - ); - vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault"); + recipient = cfg.sequencerFeeVaultRecipient(); } /// @dev Tests that the minimum withdrawal amount is correct. function test_minWithdrawalAmount_succeeds() external { - assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), NON_ZERO_VALUE); + assertEq(sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.sequencerFeeVaultMinimumWithdrawalAmount()); } /// @dev Tests that the l1 fee wallet is correct. function test_constructor_succeeds() external { - assertEq(vault.l1FeeWallet(), recipient); + assertEq(sequencerFeeVault.l1FeeWallet(), recipient); } /// @dev Tests that the fee vault is able to receive ETH. function test_receive_succeeds() external { - uint256 balance = address(vault).balance; + uint256 balance = address(sequencerFeeVault).balance; vm.prank(alice); - (bool success,) = address(vault).call{ value: 100 }(hex""); + (bool success,) = address(sequencerFeeVault).call{ value: 100 }(hex""); assertEq(success, true); - assertEq(address(vault).balance, balance + 100); + assertEq(address(sequencerFeeVault).balance, balance + 100); } /// @dev Tests that `withdraw` reverts if the balance is less than the minimum /// withdrawal amount. function test_withdraw_notEnough_reverts() external { - assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT()); + assert(address(sequencerFeeVault).balance < sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT()); vm.expectRevert("FeeVault: withdrawal amount must be greater than minimum withdrawal amount"); - vault.withdraw(); + sequencerFeeVault.withdraw(); } /// @dev Tests that `withdraw` successfully initiates a withdrawal to L1. function test_withdraw_toL1_succeeds() external { - uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1; - vm.deal(address(vault), amount); + // Set the code with the withdrawal network set to L1 + vm.etch( + Predeploys.SEQUENCER_FEE_WALLET, + address( + new SequencerFeeVault(cfg.sequencerFeeVaultRecipient(), cfg.sequencerFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L1) + ).code + ); + + uint256 amount = sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT() + 1; + vm.deal(address(sequencerFeeVault), amount); // No ether has been withdrawn yet - assertEq(vault.totalProcessed(), 0); + assertEq(sequencerFeeVault.totalProcessed(), 0); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); - emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this)); + emit Withdrawal(address(sequencerFeeVault).balance, sequencerFeeVault.RECIPIENT(), address(this)); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); - emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this), FeeVault.WithdrawalNetwork.L1); + emit Withdrawal( + address(sequencerFeeVault).balance, + sequencerFeeVault.RECIPIENT(), + address(this), + FeeVault.WithdrawalNetwork.L1 + ); // The entire vault's balance is withdrawn vm.expectCall( Predeploys.L2_STANDARD_BRIDGE, - address(vault).balance, - abi.encodeWithSelector(StandardBridge.bridgeETHTo.selector, vault.l1FeeWallet(), 35_000, bytes("")) + address(sequencerFeeVault).balance, + abi.encodeWithSelector( + StandardBridge.bridgeETHTo.selector, sequencerFeeVault.l1FeeWallet(), 35_000, bytes("") + ) ); - vault.withdraw(); + sequencerFeeVault.withdraw(); // The withdrawal was successful - assertEq(vault.totalProcessed(), amount); - assertEq(address(vault).balance, ZERO_VALUE); + assertEq(sequencerFeeVault.totalProcessed(), amount); + assertEq(address(sequencerFeeVault).balance, 0); assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, amount); } } contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer { + address recipient; /// @dev Sets up the test suite. + function setUp() public override { super.setUp(); - vm.etch( - Predeploys.SEQUENCER_FEE_WALLET, - address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L2)).code - ); - vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault"); + recipient = cfg.sequencerFeeVaultRecipient(); } /// @dev Tests that `withdraw` successfully initiates a withdrawal to L2. function test_withdraw_toL2_succeeds() external { - uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1; - vm.deal(address(vault), amount); + uint256 amount = sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT() + 1; + vm.deal(address(sequencerFeeVault), amount); // No ether has been withdrawn yet - assertEq(vault.totalProcessed(), 0); + assertEq(sequencerFeeVault.totalProcessed(), 0); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); - emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this)); + emit Withdrawal(address(sequencerFeeVault).balance, sequencerFeeVault.RECIPIENT(), address(this)); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); - emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this), FeeVault.WithdrawalNetwork.L2); + emit Withdrawal( + address(sequencerFeeVault).balance, + sequencerFeeVault.RECIPIENT(), + address(this), + FeeVault.WithdrawalNetwork.L2 + ); // The entire vault's balance is withdrawn - vm.expectCall(recipient, address(vault).balance, bytes("")); + vm.expectCall(recipient, address(sequencerFeeVault).balance, bytes("")); - vault.withdraw(); + sequencerFeeVault.withdraw(); // The withdrawal was successful - assertEq(vault.totalProcessed(), amount); - assertEq(address(vault).balance, ZERO_VALUE); + assertEq(sequencerFeeVault.totalProcessed(), amount); + assertEq(address(sequencerFeeVault).balance, 0); assertEq(recipient.balance, amount); } /// @dev Tests that `withdraw` fails if the Recipient reverts. This also serves to simulate /// a situation where insufficient gas is provided to the RECIPIENT. function test_withdraw_toL2recipientReverts_fails() external { - uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT(); + uint256 amount = sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(); - vm.deal(address(vault), amount); + vm.deal(address(sequencerFeeVault), amount); // No ether has been withdrawn yet - assertEq(vault.totalProcessed(), 0); + assertEq(sequencerFeeVault.totalProcessed(), 0); // Ensure the RECIPIENT reverts - vm.etch(vault.RECIPIENT(), type(Reverter).runtimeCode); + vm.etch(sequencerFeeVault.RECIPIENT(), type(Reverter).runtimeCode); // The entire vault's balance is withdrawn - vm.expectCall(recipient, address(vault).balance, bytes("")); + vm.expectCall(recipient, address(sequencerFeeVault).balance, bytes("")); vm.expectRevert("FeeVault: failed to send ETH to L2 fee recipient"); - vault.withdraw(); - assertEq(vault.totalProcessed(), 0); + sequencerFeeVault.withdraw(); + assertEq(sequencerFeeVault.totalProcessed(), 0); } } diff --git a/packages/contracts-bedrock/test/SystemConfig.t.sol b/packages/contracts-bedrock/test/SystemConfig.t.sol index b6cb18cf7d7c..f9aa6cc1724d 100644 --- a/packages/contracts-bedrock/test/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/SystemConfig.t.sol @@ -15,89 +15,59 @@ import { Proxy } from "src/universal/Proxy.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; contract SystemConfig_Init is CommonTest { - SystemConfig sysConf; - SystemConfig systemConfigImpl; - event ConfigUpdate(uint256 indexed version, SystemConfig.UpdateType indexed updateType, bytes data); +} - // Dummy addresses used to test getters - address constant batchInbox = address(0x18); - address constant l1CrossDomainMessenger = address(0x20); - address constant l1ERC721Bridge = address(0x21); - address constant l1StandardBridge = address(0x22); - address constant l2OutputOracle = address(0x23); - address constant optimismPortal = address(0x24); - address constant optimismMintableERC20Factory = address(0x25); - uint256 constant overhead = 2100; - uint256 constant scalar = 1000000; - bytes32 constant batcherHash = bytes32(hex"abcd"); - uint64 constant gasLimit = 30_000_000; - address constant unsafeBlockSigner = address(1); +contract SystemConfig_Initialize_Test is SystemConfig_Init { + address batchInbox; + address owner; + uint256 overhead; + uint256 scalar; + bytes32 batcherHash; + uint64 gasLimit; + address unsafeBlockSigner; + address systemConfigImpl; + address optimismMintableERC20Factory; function setUp() public virtual override { super.setUp(); - - Proxy proxy = new Proxy(multisig); - systemConfigImpl = new SystemConfig(); - - vm.prank(multisig); - proxy.upgradeToAndCall( - address(systemConfigImpl), - abi.encodeCall( - SystemConfig.initialize, - ( - alice, // _owner, - overhead, // _overhead, - scalar, // _scalar, - batcherHash, // _batcherHash - gasLimit, // _gasLimit, - unsafeBlockSigner, // _unsafeBlockSigner, - Constants.DEFAULT_RESOURCE_CONFIG(), // _config, - 0, // _startBlock - batchInbox, // _batchInbox - SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: l1CrossDomainMessenger, - l1ERC721Bridge: l1ERC721Bridge, - l1StandardBridge: l1StandardBridge, - l2OutputOracle: l2OutputOracle, - optimismPortal: optimismPortal, - optimismMintableERC20Factory: optimismMintableERC20Factory - }) - ) - ) - ); - - sysConf = SystemConfig(address(proxy)); + batchInbox = cfg.batchInboxAddress(); + owner = cfg.finalSystemOwner(); + overhead = cfg.gasPriceOracleOverhead(); + scalar = cfg.gasPriceOracleScalar(); + batcherHash = bytes32(uint256(uint160(cfg.batchSenderAddress()))); + gasLimit = uint64(cfg.l2GenesisBlockGasLimit()); + unsafeBlockSigner = cfg.p2pSequencerAddress(); + systemConfigImpl = mustGetAddress("SystemConfig"); + optimismMintableERC20Factory = mustGetAddress("OptimismMintableERC20FactoryProxy"); } -} -contract SystemConfig_Initialize_Test is SystemConfig_Init { /// @dev Tests that initailization sets the correct values. function test_initialize_values_succeeds() external { - assertEq(sysConf.l1CrossDomainMessenger(), l1CrossDomainMessenger); - assertEq(sysConf.l1ERC721Bridge(), l1ERC721Bridge); - assertEq(sysConf.l1StandardBridge(), l1StandardBridge); - assertEq(sysConf.l2OutputOracle(), l2OutputOracle); - assertEq(sysConf.optimismPortal(), optimismPortal); - assertEq(sysConf.optimismMintableERC20Factory(), optimismMintableERC20Factory); - assertEq(sysConf.batchInbox(), batchInbox); - assertEq(sysConf.owner(), alice); - assertEq(sysConf.overhead(), overhead); - assertEq(sysConf.scalar(), scalar); - assertEq(sysConf.batcherHash(), batcherHash); - assertEq(sysConf.gasLimit(), gasLimit); - assertEq(sysConf.unsafeBlockSigner(), unsafeBlockSigner); + assertEq(systemConfig.l1CrossDomainMessenger(), address(l1CrossDomainMessenger)); + assertEq(systemConfig.l1ERC721Bridge(), address(l1ERC721Bridge)); + assertEq(systemConfig.l1StandardBridge(), address(l1StandardBridge)); + assertEq(systemConfig.l2OutputOracle(), address(l2OutputOracle)); + assertEq(systemConfig.optimismPortal(), address(optimismPortal)); + assertEq(systemConfig.optimismMintableERC20Factory(), optimismMintableERC20Factory); + assertEq(systemConfig.batchInbox(), batchInbox); + assertEq(systemConfig.owner(), owner); + assertEq(systemConfig.overhead(), overhead); + assertEq(systemConfig.scalar(), scalar); + assertEq(systemConfig.batcherHash(), batcherHash); + assertEq(systemConfig.gasLimit(), gasLimit); + assertEq(systemConfig.unsafeBlockSigner(), unsafeBlockSigner); // Depends on start block being set to 0 in `initialize` - assertEq(sysConf.startBlock(), block.number); + assertEq(systemConfig.startBlock(), block.number); // Depends on `initialize` being called with defaults - ResourceMetering.ResourceConfig memory cfg = Constants.DEFAULT_RESOURCE_CONFIG(); - ResourceMetering.ResourceConfig memory actual = sysConf.resourceConfig(); - assertEq(actual.maxResourceLimit, cfg.maxResourceLimit); - assertEq(actual.elasticityMultiplier, cfg.elasticityMultiplier); - assertEq(actual.baseFeeMaxChangeDenominator, cfg.baseFeeMaxChangeDenominator); - assertEq(actual.minimumBaseFee, cfg.minimumBaseFee); - assertEq(actual.systemTxMaxGas, cfg.systemTxMaxGas); - assertEq(actual.maximumBaseFee, cfg.maximumBaseFee); + ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG(); + ResourceMetering.ResourceConfig memory actual = systemConfig.resourceConfig(); + assertEq(actual.maxResourceLimit, rcfg.maxResourceLimit); + assertEq(actual.elasticityMultiplier, rcfg.elasticityMultiplier); + assertEq(actual.baseFeeMaxChangeDenominator, rcfg.baseFeeMaxChangeDenominator); + assertEq(actual.minimumBaseFee, rcfg.minimumBaseFee); + assertEq(actual.systemTxMaxGas, rcfg.systemTxMaxGas); + assertEq(actual.maximumBaseFee, rcfg.maximumBaseFee); } /// @dev Ensures that the start block override can be used to set the start block. @@ -105,15 +75,17 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { uint256 startBlock = 100; // Wipe out the initialized slot so the proxy can be initialized again - vm.store(address(sysConf), bytes32(0), bytes32(0)); + vm.store(address(systemConfig), bytes32(0), bytes32(0)); - assertEq(sysConf.startBlock(), block.number); + assertEq(systemConfig.startBlock(), block.number); // the startBlock slot is 106, wipe it out - vm.store(address(sysConf), bytes32(uint256(106)), bytes32(0)); - assertEq(sysConf.startBlock(), 0); + vm.store(address(systemConfig), bytes32(uint256(106)), bytes32(0)); + assertEq(systemConfig.startBlock(), 0); + + address admin = address(uint160(uint256(vm.load(address(systemConfig), Constants.PROXY_OWNER_ADDRESS)))); + vm.prank(admin); - vm.prank(multisig); - Proxy(payable(address(sysConf))).upgradeToAndCall( + Proxy(payable(address(systemConfig))).upgradeToAndCall( address(systemConfigImpl), abi.encodeCall( SystemConfig.initialize, @@ -128,31 +100,32 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { startBlock, // _startBlock batchInbox, // _batchInbox SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: l1CrossDomainMessenger, - l1ERC721Bridge: l1ERC721Bridge, - l1StandardBridge: l1StandardBridge, - l2OutputOracle: l2OutputOracle, - optimismPortal: optimismPortal, + l1CrossDomainMessenger: address(l1CrossDomainMessenger), + l1ERC721Bridge: address(l1ERC721Bridge), + l1StandardBridge: address(l1StandardBridge), + l2OutputOracle: address(l2OutputOracle), + optimismPortal: address(optimismPortal), optimismMintableERC20Factory: optimismMintableERC20Factory }) ) ) ); - assertEq(sysConf.startBlock(), startBlock); + assertEq(systemConfig.startBlock(), startBlock); } /// @dev Tests that initialization with start block already set is a noop. function test_initialize_startBlockNoop_reverts() external { // wipe out initialized slot so we can initialize again - vm.store(address(sysConf), bytes32(0), bytes32(0)); + vm.store(address(systemConfig), bytes32(0), bytes32(0)); // the startBlock slot is 106, set it to something non zero - vm.store(address(sysConf), bytes32(uint256(106)), bytes32(uint256(0xff))); + vm.store(address(systemConfig), bytes32(uint256(106)), bytes32(uint256(0xff))); // Initialize with a non zero start block, should see a revert - vm.prank(multisig); + address admin = address(uint160(uint256(vm.load(address(systemConfig), Constants.PROXY_OWNER_ADDRESS)))); + vm.prank(admin); // The call to initialize reverts due to: "SystemConfig: cannot override an already set start block" // but the proxy revert message bubbles up. - Proxy(payable(address(sysConf))).upgradeToAndCall( + Proxy(payable(address(systemConfig))).upgradeToAndCall( address(systemConfigImpl), abi.encodeCall( SystemConfig.initialize, @@ -167,11 +140,11 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { 1, // _startBlock batchInbox, // _batchInbox SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: l1CrossDomainMessenger, - l1ERC721Bridge: l1ERC721Bridge, - l1StandardBridge: l1StandardBridge, - l2OutputOracle: l2OutputOracle, - optimismPortal: optimismPortal, + l1CrossDomainMessenger: address(l1CrossDomainMessenger), + l1ERC721Bridge: address(l1ERC721Bridge), + l1StandardBridge: address(l1StandardBridge), + l2OutputOracle: address(l2OutputOracle), + optimismPortal: address(optimismPortal), optimismMintableERC20Factory: optimismMintableERC20Factory }) ) @@ -180,29 +153,31 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { // It was initialized with 1 but it was already set so the override // should be ignored. - uint256 startBlock = sysConf.startBlock(); + uint256 startBlock = systemConfig.startBlock(); assertEq(startBlock, 0xff); } /// @dev Ensures that the events are emitted during initialization. function test_initialize_events_succeeds() external { // Wipe out the initialized slot so the proxy can be initialized again - vm.store(address(sysConf), bytes32(0), bytes32(0)); - vm.store(address(sysConf), bytes32(uint256(106)), bytes32(0)); - assertEq(sysConf.startBlock(), 0); + vm.store(address(systemConfig), bytes32(0), bytes32(0)); + vm.store(address(systemConfig), bytes32(uint256(106)), bytes32(0)); + assertEq(systemConfig.startBlock(), 0); // The order depends here - vm.expectEmit(true, true, true, true, address(sysConf)); + vm.expectEmit(true, true, true, true, address(systemConfig)); emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(batcherHash)); - vm.expectEmit(true, true, true, true, address(sysConf)); + vm.expectEmit(true, true, true, true, address(systemConfig)); emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(overhead, scalar)); - vm.expectEmit(true, true, true, true, address(sysConf)); + vm.expectEmit(true, true, true, true, address(systemConfig)); emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(gasLimit)); - vm.expectEmit(true, true, true, true, address(sysConf)); + vm.expectEmit(true, true, true, true, address(systemConfig)); emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(unsafeBlockSigner)); - vm.prank(multisig); - Proxy(payable(address(sysConf))).upgradeToAndCall( + address admin = address(uint160(uint256(vm.load(address(systemConfig), Constants.PROXY_OWNER_ADDRESS)))); + vm.prank(admin); + + Proxy(payable(address(systemConfig))).upgradeToAndCall( address(systemConfigImpl), abi.encodeCall( SystemConfig.initialize, @@ -217,11 +192,11 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { 0, // _startBlock batchInbox, // _batchInbox SystemConfig.Addresses({ // _addresses - l1CrossDomainMessenger: l1CrossDomainMessenger, - l1ERC721Bridge: l1ERC721Bridge, - l1StandardBridge: l1StandardBridge, - l2OutputOracle: l2OutputOracle, - optimismPortal: optimismPortal, + l1CrossDomainMessenger: address(l1CrossDomainMessenger), + l1ERC721Bridge: address(l1ERC721Bridge), + l1StandardBridge: address(l1StandardBridge), + l2OutputOracle: address(l2OutputOracle), + optimismPortal: address(optimismPortal), optimismMintableERC20Factory: optimismMintableERC20Factory }) ) @@ -233,15 +208,19 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { contract SystemConfig_Initialize_TestFail is SystemConfig_Init { /// @dev Tests that initialization reverts if the gas limit is too low. function test_initialize_lowGasLimit_reverts() external { - uint64 minimumGasLimit = sysConf.minimumGasLimit(); + address systemConfigImpl = mustGetAddress("SystemConfig"); + uint64 minimumGasLimit = systemConfig.minimumGasLimit(); // Wipe out the initialized slot so the proxy can be initialized again - vm.store(address(sysConf), bytes32(0), bytes32(0)); - vm.prank(multisig); + vm.store(address(systemConfig), bytes32(0), bytes32(0)); + + address admin = address(uint160(uint256(vm.load(address(systemConfig), Constants.PROXY_OWNER_ADDRESS)))); + vm.prank(admin); + // The call to initialize reverts due to: "SystemConfig: gas limit too low" // but the proxy revert message bubbles up. vm.expectRevert("Proxy: delegatecall to new implementation contract failed"); - Proxy(payable(address(sysConf))).upgradeToAndCall( + Proxy(payable(address(systemConfig))).upgradeToAndCall( address(systemConfigImpl), abi.encodeCall( SystemConfig.initialize, @@ -273,32 +252,32 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { /// @dev Tests that `setBatcherHash` reverts if the caller is not the owner. function test_setBatcherHash_notOwner_reverts() external { vm.expectRevert("Ownable: caller is not the owner"); - sysConf.setBatcherHash(bytes32(hex"")); + systemConfig.setBatcherHash(bytes32(hex"")); } /// @dev Tests that `setGasConfig` reverts if the caller is not the owner. function test_setGasConfig_notOwner_reverts() external { vm.expectRevert("Ownable: caller is not the owner"); - sysConf.setGasConfig(0, 0); + systemConfig.setGasConfig(0, 0); } /// @dev Tests that `setGasLimit` reverts if the caller is not the owner. function test_setGasLimit_notOwner_reverts() external { vm.expectRevert("Ownable: caller is not the owner"); - sysConf.setGasLimit(0); + systemConfig.setGasLimit(0); } /// @dev Tests that `setUnsafeBlockSigner` reverts if the caller is not the owner. function test_setUnsafeBlockSigner_notOwner_reverts() external { vm.expectRevert("Ownable: caller is not the owner"); - sysConf.setUnsafeBlockSigner(address(0x20)); + systemConfig.setUnsafeBlockSigner(address(0x20)); } /// @dev Tests that `setResourceConfig` reverts if the caller is not the owner. function test_setResourceConfig_notOwner_reverts() external { ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG(); vm.expectRevert("Ownable: caller is not the owner"); - sysConf.setResourceConfig(config); + systemConfig.setResourceConfig(config); } /// @dev Tests that `setResourceConfig` reverts if the min base fee @@ -312,9 +291,9 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { minimumBaseFee: 2 gwei, maximumBaseFee: 1 gwei }); - vm.prank(sysConf.owner()); + vm.prank(systemConfig.owner()); vm.expectRevert("SystemConfig: min base fee must be less than max base"); - sysConf.setResourceConfig(config); + systemConfig.setResourceConfig(config); } /// @dev Tests that `setResourceConfig` reverts if the baseFeeMaxChangeDenominator @@ -328,14 +307,14 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { minimumBaseFee: 1 gwei, maximumBaseFee: 2 gwei }); - vm.prank(sysConf.owner()); + vm.prank(systemConfig.owner()); vm.expectRevert("SystemConfig: denominator must be larger than 1"); - sysConf.setResourceConfig(config); + systemConfig.setResourceConfig(config); } /// @dev Tests that `setResourceConfig` reverts if the gas limit is too low. function test_setResourceConfig_lowGasLimit_reverts() external { - uint64 gasLimit = sysConf.gasLimit(); + uint64 gasLimit = systemConfig.gasLimit(); ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ maxResourceLimit: uint32(gasLimit), @@ -345,9 +324,9 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { minimumBaseFee: 1 gwei, maximumBaseFee: 2 gwei }); - vm.prank(sysConf.owner()); + vm.prank(systemConfig.owner()); vm.expectRevert("SystemConfig: gas limit too low"); - sysConf.setResourceConfig(config); + systemConfig.setResourceConfig(config); } /// @dev Tests that `setResourceConfig` reverts if the elasticity multiplier @@ -361,9 +340,9 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { minimumBaseFee: 1 gwei, maximumBaseFee: 2 gwei }); - vm.prank(sysConf.owner()); + vm.prank(systemConfig.owner()); vm.expectRevert("SystemConfig: precision loss with target resource limit"); - sysConf.setResourceConfig(config); + systemConfig.setResourceConfig(config); } } @@ -373,9 +352,9 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { vm.expectEmit(true, true, true, true); emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash)); - vm.prank(sysConf.owner()); - sysConf.setBatcherHash(newBatcherHash); - assertEq(sysConf.batcherHash(), newBatcherHash); + vm.prank(systemConfig.owner()); + systemConfig.setBatcherHash(newBatcherHash); + assertEq(systemConfig.batcherHash(), newBatcherHash); } /// @dev Tests that `setGasConfig` updates the overhead and scalar successfully. @@ -383,23 +362,23 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { vm.expectEmit(true, true, true, true); emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(newOverhead, newScalar)); - vm.prank(sysConf.owner()); - sysConf.setGasConfig(newOverhead, newScalar); - assertEq(sysConf.overhead(), newOverhead); - assertEq(sysConf.scalar(), newScalar); + vm.prank(systemConfig.owner()); + systemConfig.setGasConfig(newOverhead, newScalar); + assertEq(systemConfig.overhead(), newOverhead); + assertEq(systemConfig.scalar(), newScalar); } /// @dev Tests that `setGasLimit` updates the gas limit successfully. function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external { - uint64 minimumGasLimit = sysConf.minimumGasLimit(); + uint64 minimumGasLimit = systemConfig.minimumGasLimit(); newGasLimit = uint64(bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))); vm.expectEmit(true, true, true, true); emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit)); - vm.prank(sysConf.owner()); - sysConf.setGasLimit(newGasLimit); - assertEq(sysConf.gasLimit(), newGasLimit); + vm.prank(systemConfig.owner()); + systemConfig.setGasLimit(newGasLimit); + assertEq(systemConfig.gasLimit(), newGasLimit); } /// @dev Tests that `setUnsafeBlockSigner` updates the block signer successfully. @@ -407,8 +386,8 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { vm.expectEmit(true, true, true, true); emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(newUnsafeSigner)); - vm.prank(sysConf.owner()); - sysConf.setUnsafeBlockSigner(newUnsafeSigner); - assertEq(sysConf.unsafeBlockSigner(), newUnsafeSigner); + vm.prank(systemConfig.owner()); + systemConfig.setUnsafeBlockSigner(newUnsafeSigner); + assertEq(systemConfig.unsafeBlockSigner(), newUnsafeSigner); } } diff --git a/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol index 6eef617f5095..b55b28642a91 100644 --- a/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol @@ -96,10 +96,10 @@ contract XDM_MinGasLimits is Messenger_Initializer { super.setUp(); // Deploy a relay actor - actor = new RelayActor(op, L1Messenger, vm, doFail); + actor = new RelayActor(optimismPortal, l1CrossDomainMessenger, vm, doFail); // Give the portal some ether to send to `relayMessage` - vm.deal(address(op), type(uint128).max); + vm.deal(address(optimismPortal), type(uint128).max); // Target the `RelayActor` contract targetContract(address(actor)); @@ -138,9 +138,9 @@ contract XDM_MinGasLimits_Succeeds is XDM_MinGasLimits { for (uint256 i = 0; i < length; ++i) { bytes32 hash = actor.hashes(i); // The message hash is set in the successfulMessages mapping - assertTrue(L1Messenger.successfulMessages(hash)); + assertTrue(l1CrossDomainMessenger.successfulMessages(hash)); // The message hash is not set in the failedMessages mapping - assertFalse(L1Messenger.failedMessages(hash)); + assertFalse(l1CrossDomainMessenger.failedMessages(hash)); } assertFalse(actor.reverted()); } @@ -171,9 +171,9 @@ contract XDM_MinGasLimits_Reverts is XDM_MinGasLimits { for (uint256 i = 0; i < length; ++i) { bytes32 hash = actor.hashes(i); // The message hash is not set in the successfulMessages mapping - assertFalse(L1Messenger.successfulMessages(hash)); + assertFalse(l1CrossDomainMessenger.successfulMessages(hash)); // The message hash is set in the failedMessages mapping - assertTrue(L1Messenger.failedMessages(hash)); + assertTrue(l1CrossDomainMessenger.failedMessages(hash)); } assertFalse(actor.reverted()); } diff --git a/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol index 79d637fca9d6..47544f89643b 100644 --- a/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol @@ -36,7 +36,7 @@ contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_In super.setUp(); // Create a proposer actor. - actor = new L2OutputOracle_Proposer(oracle, vm); + actor = new L2OutputOracle_Proposer(l2OutputOracle, vm); // Set the target contract to the proposer actor. targetContract(address(actor)); @@ -57,6 +57,6 @@ contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_In /// correspond to a block number that is less than the current output. function invariant_monotonicBlockNumIncrease() external { // Assert that the block number of proposals must monotonically increase. - assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber()); + assertTrue(l2OutputOracle.nextBlockNumber() >= l2OutputOracle.latestBlockNumber()); } } diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol index 49c73caea789..ad05c8b2ac29 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol @@ -109,18 +109,21 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer { messagePasserStorageRoot: _storageRoot, latestBlockhash: bytes32(uint256(0)) }); - _proposedBlockNumber = oracle.nextBlockNumber(); - _proposedOutputIndex = oracle.nextOutputIndex(); + _proposedBlockNumber = l2OutputOracle.nextBlockNumber(); + _proposedOutputIndex = l2OutputOracle.nextOutputIndex(); // Configure the oracle to return the output root we've prepared. - vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1); - vm.prank(oracle.PROPOSER()); - oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); + vm.warp(l2OutputOracle.computeL2Timestamp(_proposedBlockNumber) + 1); + vm.prank(l2OutputOracle.PROPOSER()); + l2OutputOracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); // Warp beyond the finalization period for the block we've proposed. - vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp( + l2OutputOracle.getL2Output(_proposedOutputIndex).timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + + 1 + ); // Fund the portal so that we can withdraw ETH. - vm.deal(address(op), 0xFFFFFFFF); + vm.deal(address(optimismPortal), 0xFFFFFFFF); } } @@ -130,7 +133,7 @@ contract OptimismPortal_Deposit_Invariant is Portal_Initializer { function setUp() public override { super.setUp(); // Create a deposit actor. - actor = new OptimismPortal_Depositor(vm, op); + actor = new OptimismPortal_Depositor(vm, optimismPortal); targetContract(address(actor)); @@ -155,12 +158,12 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness { super.setUp(); // Prove the withdrawal transaction - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Set the target contract to the portal proxy - targetContract(address(op)); + targetContract(address(optimismPortal)); // Exclude the proxy admin from the senders so that the proxy cannot be upgraded - excludeSender(EIP1967Helper.getAdmin(address(op))); + excludeSender(EIP1967Helper.getAdmin(address(optimismPortal))); } /// @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization @@ -170,7 +173,7 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness { /// until after the finalization period has elapsed. function invariant_cannotFinalizeBeforePeriodHasPassed() external { vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); } } @@ -179,18 +182,18 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness super.setUp(); // Prove the withdrawal transaction - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Warp past the finalization period. - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); // Finalize the withdrawal transaction. - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); // Set the target contract to the portal proxy - targetContract(address(op)); + targetContract(address(optimismPortal)); // Exclude the proxy admin from the senders so that the proxy cannot be upgraded - excludeSender(EIP1967Helper.getAdmin(address(op))); + excludeSender(EIP1967Helper.getAdmin(address(optimismPortal))); } /// @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal @@ -200,7 +203,7 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness /// allows a withdrawal to be finalized twice. function invariant_cannotFinalizeTwice() external { vm.expectRevert("OptimismPortal: withdrawal has already been finalized"); - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); } } @@ -209,15 +212,15 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant super.setUp(); // Prove the withdrawal transaction - op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); + optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); // Warp past the finalization period. - vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); + vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1); // Set the target contract to the portal proxy - targetContract(address(op)); + targetContract(address(optimismPortal)); // Exclude the proxy admin from the senders so that the proxy cannot be upgraded - excludeSender(EIP1967Helper.getAdmin(address(op))); + excludeSender(EIP1967Helper.getAdmin(address(optimismPortal))); } /// @custom:invariant A withdrawal should **always** be able to be finalized @@ -230,7 +233,7 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant function invariant_canAlwaysFinalize() external { uint256 bobBalanceBefore = address(bob).balance; - op.finalizeWithdrawalTransaction(_defaultTx); + optimismPortal.finalizeWithdrawalTransaction(_defaultTx); assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value); } From cecb3c163b693234333326c569b46e910a261f4a Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Wed, 1 Nov 2023 20:53:49 +0300 Subject: [PATCH 359/374] contracts-bedrock: modularize L2 setup --- packages/contracts-bedrock/foundry.toml | 1 - .../test/BenchmarkTest.t.sol | 12 +- .../contracts-bedrock/test/CommonTest.t.sol | 418 ------------------ .../test/CrossDomainMessenger.t.sol | 7 +- .../test/CrossDomainOwnable.t.sol | 4 +- .../test/CrossDomainOwnable2.t.sol | 8 +- .../test/CrossDomainOwnable3.t.sol | 4 +- .../test/DelayedVetoable.t.sol | 2 +- .../test/DisputeGameFactory.t.sol | 4 +- .../contracts-bedrock/test/Encoding.t.sol | 2 +- .../contracts-bedrock/test/FeeVault.t.sol | 2 +- .../test/GasPriceOracle.t.sol | 2 +- .../test/GovernanceToken.t.sol | 2 +- packages/contracts-bedrock/test/Hashing.t.sol | 2 +- .../test/Initializable.t.sol | 2 +- packages/contracts-bedrock/test/L1Block.t.sol | 2 +- .../test/L1CrossDomainMessenger.t.sol | 5 +- .../test/L1ERC721Bridge.t.sol | 2 +- .../test/L1StandardBridge.t.sol | 2 +- .../test/L2CrossDomainMessenger.t.sol | 4 +- .../test/L2ERC721Bridge.t.sol | 2 +- .../test/L2OutputOracle.t.sol | 12 +- .../test/L2StandardBridge.t.sol | 2 +- .../test/L2ToL1MessagePasser.t.sol | 14 +- .../test/LegacyERC20ETH.t.sol | 2 +- .../test/LegacyMessagePasser.t.sol | 2 +- .../contracts-bedrock/test/LibPosition.t.sol | 2 +- packages/contracts-bedrock/test/MIPS.t.sol | 2 +- .../contracts-bedrock/test/MintManager.t.sol | 2 +- .../test/OptimismMintableERC20.t.sol | 2 +- .../test/OptimismMintableERC20Factory.t.sol | 2 +- .../test/OptimismMintableERC721.t.sol | 2 +- .../test/OptimismMintableERC721Factory.t.sol | 2 +- .../test/OptimismPortal.t.sol | 28 +- .../test/ProtocolVersions.t.sol | 2 +- .../test/SequencerFeeVault.t.sol | 6 +- .../test/StandardBridge.t.sol | 2 +- .../contracts-bedrock/test/SystemConfig.t.sol | 2 +- .../invariants/CrossDomainMessenger.t.sol | 5 +- .../test/invariants/L2OutputOracle.t.sol | 4 +- .../test/invariants/OptimismPortal.t.sol | 6 +- .../test/setup/Bridge_Initializer.sol | 69 +++ .../test/setup/CommonTest.sol | 84 ++++ .../contracts-bedrock/test/setup/Events.sol | 97 ++++ .../contracts-bedrock/test/setup/Setup.sol | 201 +++++++++ 45 files changed, 536 insertions(+), 505 deletions(-) delete mode 100644 packages/contracts-bedrock/test/CommonTest.t.sol create mode 100644 packages/contracts-bedrock/test/setup/Bridge_Initializer.sol create mode 100644 packages/contracts-bedrock/test/setup/CommonTest.sol create mode 100644 packages/contracts-bedrock/test/setup/Events.sol create mode 100644 packages/contracts-bedrock/test/setup/Setup.sol diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml index dddcc64b128e..abd0cde2ba8b 100644 --- a/packages/contracts-bedrock/foundry.toml +++ b/packages/contracts-bedrock/foundry.toml @@ -59,4 +59,3 @@ runs = 512 [profile.lite] optimizer = false - diff --git a/packages/contracts-bedrock/test/BenchmarkTest.t.sol b/packages/contracts-bedrock/test/BenchmarkTest.t.sol index dfe0d9f180db..ef5662d17e6d 100644 --- a/packages/contracts-bedrock/test/BenchmarkTest.t.sol +++ b/packages/contracts-bedrock/test/BenchmarkTest.t.sol @@ -4,16 +4,18 @@ pragma solidity 0.8.15; // Testing utilities import { Test } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; -import "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; +import { Types } from "src/libraries/Types.sol"; // Free function for setting the prevBaseFee param in the OptimismPortal. function setPrevBaseFee(Vm _vm, address _op, uint128 _prevBaseFee) { _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee)); } -contract SetPrevBaseFee_Test is Portal_Initializer { +contract SetPrevBaseFee_Test is CommonTest { function test_setPrevBaseFee_succeeds() external { setPrevBaseFee(vm, address(optimismPortal), 100 gwei); (uint128 prevBaseFee,, uint64 prevBlockNum) = optimismPortal.params(); @@ -27,7 +29,7 @@ contract SetPrevBaseFee_Test is Portal_Initializer { // so that they are nothing more than the call we want measure the gas cost of. // In order to achieve this we make no assertions, and handle everything else in the setUp() // function. -contract GasBenchMark_OptimismPortal is Portal_Initializer { +contract GasBenchMark_OptimismPortal is CommonTest { // Reusable default values for a test withdrawal Types.WithdrawalTransaction _defaultTx; @@ -100,7 +102,7 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer { } } -contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer { +contract GasBenchMark_L1CrossDomainMessenger is Bridge_Initializer { function test_sendMessage_benchmark_0() external { vm.pauseGasMetering(); setPrevBaseFee(vm, address(optimismPortal), 1 gwei); @@ -192,7 +194,7 @@ contract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer { } } -contract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer { +contract GasBenchMark_L2OutputOracle is CommonTest { uint256 nextBlockNumber; function setUp() public override { diff --git a/packages/contracts-bedrock/test/CommonTest.t.sol b/packages/contracts-bedrock/test/CommonTest.t.sol deleted file mode 100644 index 5484c514ebb7..000000000000 --- a/packages/contracts-bedrock/test/CommonTest.t.sol +++ /dev/null @@ -1,418 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing utilities -import { Test, StdUtils } from "forge-std/Test.sol"; -import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; -import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; -import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; -import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; -import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; -import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; -import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; -import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; -import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; -import { L1FeeVault } from "src/L2/L1FeeVault.sol"; -import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; -import { FeeVault } from "src/universal/FeeVault.sol"; -import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; -import { L1Block } from "src/L2/L1Block.sol"; -import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; -import { FeeVault } from "src/universal/FeeVault.sol"; -import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -import { LegacyERC20ETH } from "src/legacy/LegacyERC20ETH.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { Types } from "src/libraries/Types.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { Proxy } from "src/universal/Proxy.sol"; -import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol"; -import { AddressManager } from "src/legacy/AddressManager.sol"; -import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol"; -import { IL1ChugSplashDeployer } from "src/legacy/L1ChugSplashProxy.sol"; -import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; -import { GovernanceToken } from "src/governance/GovernanceToken.sol"; -import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol"; -import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; -import { ResourceMetering } from "src/L1/ResourceMetering.sol"; -import { Deploy } from "scripts/Deploy.s.sol"; -import { FFIInterface } from "test/setup/FFIInterface.sol"; - -contract CommonTest is Deploy, Test { - address alice = address(128); - address bob = address(256); - - bytes32 constant nonZeroHash = keccak256(abi.encode("NON_ZERO")); - - event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); - - /// @dev OpenZeppelin Ownable.sol transferOwnership event - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - OptimismPortal optimismPortal; - L2OutputOracle l2OutputOracle; - SystemConfig systemConfig; - L1StandardBridge l1StandardBridge; - L1CrossDomainMessenger l1CrossDomainMessenger; - AddressManager addressManager; - L1ERC721Bridge l1ERC721Bridge; - OptimismMintableERC20Factory l1OptimismMintableERC20Factory; - ProtocolVersions protocolVersions; - - L2CrossDomainMessenger l2CrossDomainMessenger; - L2StandardBridge l2StandardBridge; - L2ToL1MessagePasser l2ToL1MessagePasser; - OptimismMintableERC20Factory l2OptimismMintableERC20Factory; - L2ERC721Bridge l2ERC721Bridge; - BaseFeeVault baseFeeVault; - SequencerFeeVault sequencerFeeVault; - L1FeeVault l1FeeVault; - GasPriceOracle gasPriceOracle; - L1Block l1Block; - LegacyMessagePasser legacyMessagePasser; - GovernanceToken governanceToken; - - FFIInterface ffi; - - function setUp() public virtual override { - // Give alice and bob some ETH - vm.deal(alice, 1 << 16); - vm.deal(bob, 1 << 16); - - vm.label(alice, "alice"); - vm.label(bob, "bob"); - - // Make sure we have a non-zero base fee - vm.fee(1000000000); - - // Set the deterministic deployer in state - vm.etch( - 0x4e59b44847b379578588920cA78FbF26c0B4956C, - hex"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" - ); - - ffi = new FFIInterface(); - - Deploy.setUp(); - Deploy.run(); - - // Set up L1 - optimismPortal = OptimismPortal(mustGetAddress("OptimismPortalProxy")); - l2OutputOracle = L2OutputOracle(mustGetAddress("L2OutputOracleProxy")); - systemConfig = SystemConfig(mustGetAddress("SystemConfigProxy")); - l1StandardBridge = L1StandardBridge(mustGetAddress("L1StandardBridgeProxy")); - l1CrossDomainMessenger = L1CrossDomainMessenger(mustGetAddress("L1CrossDomainMessengerProxy")); - addressManager = AddressManager(mustGetAddress("AddressManager")); - l1ERC721Bridge = L1ERC721Bridge(mustGetAddress("L1ERC721BridgeProxy")); - l1OptimismMintableERC20Factory = - OptimismMintableERC20Factory(mustGetAddress("OptimismMintableERC20FactoryProxy")); - protocolVersions = ProtocolVersions(mustGetAddress("ProtocolVersionsProxy")); - - vm.label(address(l2OutputOracle), "L2OutputOracle"); - vm.label(address(optimismPortal), "OptimismPortal"); - vm.label(address(systemConfig), "SystemConfig"); - vm.label(address(l1StandardBridge), "L1StandardBridge"); - vm.label(address(l1CrossDomainMessenger), "L1CrossDomainMessenger"); - vm.label(address(addressManager), "AddressManager"); - vm.label(address(l1ERC721Bridge), "L1ERC721Bridge"); - vm.label(address(l1OptimismMintableERC20Factory), "OptimismMintableERC20Factory"); - vm.label(address(protocolVersions), "ProtocolVersions"); - - // Set up L2. There are currently no proxies set in the L2 initialization. - vm.etch( - Predeploys.L2_CROSS_DOMAIN_MESSENGER, - address(new L2CrossDomainMessenger(address(l1CrossDomainMessenger))).code - ); - l2CrossDomainMessenger = L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); - l2CrossDomainMessenger.initialize(); - - vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code); - l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); - - vm.etch( - Predeploys.L2_STANDARD_BRIDGE, address(new L2StandardBridge(StandardBridge(payable(l1StandardBridge)))).code - ); - l2StandardBridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)); - l2StandardBridge.initialize(); - - vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(new OptimismMintableERC20Factory()).code); - l2OptimismMintableERC20Factory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); - l2OptimismMintableERC20Factory.initialize(Predeploys.L2_STANDARD_BRIDGE); - - vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code); - - vm.etch(Predeploys.L2_ERC721_BRIDGE, address(new L2ERC721Bridge(address(l1ERC721Bridge))).code); - l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); - l2ERC721Bridge.initialize(); - - vm.etch( - Predeploys.SEQUENCER_FEE_WALLET, - address( - new SequencerFeeVault(cfg.sequencerFeeVaultRecipient(), cfg.sequencerFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2) - ).code - ); - vm.etch( - Predeploys.BASE_FEE_VAULT, - address( - new BaseFeeVault(cfg.baseFeeVaultRecipient(), cfg.baseFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L1) - ).code - ); - vm.etch( - Predeploys.L1_FEE_VAULT, - address( - new L1FeeVault(cfg.l1FeeVaultRecipient(), cfg.l1FeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2) - ).code - ); - - sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); - baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); - l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); - - vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code); - l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); - - vm.etch(Predeploys.GAS_PRICE_ORACLE, address(new GasPriceOracle()).code); - gasPriceOracle = GasPriceOracle(Predeploys.GAS_PRICE_ORACLE); - - vm.etch(Predeploys.LEGACY_MESSAGE_PASSER, address(new LegacyMessagePasser()).code); - legacyMessagePasser = LegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); - - vm.etch(Predeploys.GOVERNANCE_TOKEN, address(new GovernanceToken()).code); - governanceToken = GovernanceToken(Predeploys.GOVERNANCE_TOKEN); - vm.store( - Predeploys.GOVERNANCE_TOKEN, - bytes32(uint256(3)), - bytes32(0x4f7074696d69736d000000000000000000000000000000000000000000000010) - ); - vm.store( - Predeploys.GOVERNANCE_TOKEN, - bytes32(uint256(4)), - bytes32(0x4f50000000000000000000000000000000000000000000000000000000000004) - ); - - // Set the governance token's owner to be the final system owner - address finalSystemOwner = cfg.finalSystemOwner(); - vm.prank(governanceToken.owner()); - governanceToken.transferOwnership(finalSystemOwner); - - vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, "OptimismMintableERC20Factory"); - vm.label(Predeploys.LEGACY_ERC20_ETH, "LegacyERC20ETH"); - vm.label(Predeploys.L2_STANDARD_BRIDGE, "L2StandardBridge"); - vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger"); - vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, "L2ToL1MessagePasser"); - vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault"); - vm.label(Predeploys.L2_ERC721_BRIDGE, "L2ERC721Bridge"); - vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault"); - vm.label(Predeploys.L1_FEE_VAULT, "L1FeeVault"); - vm.label(Predeploys.L1_BLOCK_ATTRIBUTES, "L1Block"); - vm.label(Predeploys.GAS_PRICE_ORACLE, "GasPriceOracle"); - vm.label(Predeploys.LEGACY_MESSAGE_PASSER, "LegacyMessagePasser"); - vm.label(Predeploys.GOVERNANCE_TOKEN, "GovernanceToken"); - vm.label(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), "L1CrossDomainMessenger_aliased"); - } - - function emitTransactionDeposited( - address _from, - address _to, - uint256 _mint, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes memory _data - ) - internal - { - emit TransactionDeposited(_from, _to, 0, abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)); - } -} - -contract L2OutputOracle_Initializer is CommonTest { - event OutputProposed( - bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp - ); - - event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); - - // @dev Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output - function warpToProposeTime(uint256 _nextBlockNumber) public { - vm.warp(l2OutputOracle.computeL2Timestamp(_nextBlockNumber) + 1); - } - - /// @dev Helper function to propose an output. - function proposeAnotherOutput() public { - bytes32 proposedOutput2 = keccak256(abi.encode()); - uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); - uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex(); - warpToProposeTime(nextBlockNumber); - uint256 proposedNumber = l2OutputOracle.latestBlockNumber(); - - uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval(); - // Ensure the submissionInterval is enforced - assertEq(nextBlockNumber, proposedNumber + submissionInterval); - - vm.roll(nextBlockNumber + 1); - - vm.expectEmit(true, true, true, true); - emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp); - - address proposer = cfg.l2OutputOracleProposer(); - vm.prank(proposer); - l2OutputOracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0); - } - - function setUp() public virtual override { - super.setUp(); - - // By default the first block has timestamp and number zero, which will cause underflows in the - // tests, so we'll move forward to these block values. - vm.warp(cfg.l2OutputOracleStartingTimestamp() + 1); - vm.roll(cfg.l2OutputOracleStartingBlockNumber() + 1); - } -} - -contract Portal_Initializer is L2OutputOracle_Initializer { - event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); - event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to); -} - -contract Messenger_Initializer is Portal_Initializer { - event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); - event SentMessageExtension1(address indexed sender, uint256 value); - event MessagePassed( - uint256 indexed nonce, - address indexed sender, - address indexed target, - uint256 value, - uint256 gasLimit, - bytes data, - bytes32 withdrawalHash - ); - event RelayedMessage(bytes32 indexed msgHash); - event FailedRelayedMessage(bytes32 indexed msgHash); - event TransactionDeposited( - address indexed from, - address indexed to, - uint256 mint, - uint256 value, - uint64 gasLimit, - bool isCreation, - bytes data - ); - event WhatHappened(bool success, bytes returndata); -} - -contract Bridge_Initializer is Messenger_Initializer { - ERC20 L1Token; - ERC20 BadL1Token; - OptimismMintableERC20 L2Token; - LegacyMintableERC20 LegacyL2Token; - ERC20 NativeL2Token; - ERC20 BadL2Token; - OptimismMintableERC20 RemoteL1Token; - - event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data); - - event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes data); - - event ERC20DepositInitiated( - address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data - ); - - event ERC20WithdrawalFinalized( - address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data - ); - - event WithdrawalInitiated( - address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data - ); - - event DepositFinalized( - address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data - ); - - event DepositFailed( - address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data - ); - - event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data); - - event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data); - - event ERC20BridgeInitiated( - address indexed localToken, - address indexed remoteToken, - address indexed from, - address to, - uint256 amount, - bytes data - ); - - event ERC20BridgeFinalized( - address indexed localToken, - address indexed remoteToken, - address indexed from, - address to, - uint256 amount, - bytes data - ); - - function setUp() public virtual override { - super.setUp(); - - L1Token = new ERC20("Native L1 Token", "L1T"); - - LegacyL2Token = new LegacyMintableERC20({ - _l2Bridge: address(l2StandardBridge), - _l1Token: address(L1Token), - _name: string.concat("LegacyL2-", L1Token.name()), - _symbol: string.concat("LegacyL2-", L1Token.symbol()) - }); - vm.label(address(LegacyL2Token), "LegacyMintableERC20"); - - // Deploy the L2 ERC20 now - L2Token = OptimismMintableERC20( - l2OptimismMintableERC20Factory.createStandardL2Token( - address(L1Token), - string(abi.encodePacked("L2-", L1Token.name())), - string(abi.encodePacked("L2-", L1Token.symbol())) - ) - ); - - BadL2Token = OptimismMintableERC20( - l2OptimismMintableERC20Factory.createStandardL2Token( - address(1), - string(abi.encodePacked("L2-", L1Token.name())), - string(abi.encodePacked("L2-", L1Token.symbol())) - ) - ); - - NativeL2Token = new ERC20("Native L2 Token", "L2T"); - - RemoteL1Token = OptimismMintableERC20( - l1OptimismMintableERC20Factory.createStandardL2Token( - address(NativeL2Token), - string(abi.encodePacked("L1-", NativeL2Token.name())), - string(abi.encodePacked("L1-", NativeL2Token.symbol())) - ) - ); - - BadL1Token = OptimismMintableERC20( - l1OptimismMintableERC20Factory.createStandardL2Token( - address(1), - string(abi.encodePacked("L1-", NativeL2Token.name())), - string(abi.encodePacked("L1-", NativeL2Token.symbol())) - ) - ); - } -} - -contract FeeVault_Initializer is Bridge_Initializer { - event Withdrawal(uint256 value, address to, address from); - event Withdrawal(uint256 value, address to, address from, FeeVault.WithdrawalNetwork withdrawalNetwork); -} diff --git a/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol index 8aa4c697ca14..a254b7312eee 100644 --- a/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainMessenger.t.sol @@ -1,10 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; - // Testing utilities import { Test } from "forge-std/Test.sol"; -import { Messenger_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { CallerCaller, Reverter } from "test/mocks/Callers.sol"; // Libraries @@ -16,7 +15,7 @@ import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; // CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2 // CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract. -contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { +contract CrossDomainMessenger_BaseGas_Test is Bridge_Initializer { /// @dev Ensure that baseGas passes for the max value of _minGasLimit, /// this is about 4 Billion. function test_baseGas_succeeds() external view { @@ -112,7 +111,7 @@ contract ExternalRelay is Test { /// @title CrossDomainMessenger_RelayMessage_Test /// @notice Fuzz tests re-entrancy into the CrossDomainMessenger relayMessage function. -contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { +contract CrossDomainMessenger_RelayMessage_Test is Bridge_Initializer { // Storage slot of the l2Sender uint256 constant senderSlotIndex = 50; diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol index bc7b06f8c9ac..1e7c10556a53 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; // Testing utilities import { VmSafe } from "forge-std/Vm.sol"; import { Test } from "forge-std/Test.sol"; -import { Portal_Initializer } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; @@ -46,7 +46,7 @@ contract CrossDomainOwnable_Test is Test { } } -contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer { +contract CrossDomainOwnableThroughPortal_Test is CommonTest { XDomainSetter setter; /// @dev Sets up the test suite. diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol index 6eb095cd216f..fa1244a0b0e1 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable2.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest, Messenger_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; // Libraries import { Hashing } from "src/libraries/Hashing.sol"; @@ -10,10 +10,10 @@ import { Encoding } from "src/libraries/Encoding.sol"; import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; // Target contract dependencies -import { AddressAliasHelper } from "../src/vendor/AddressAliasHelper.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; // Target contract -import { CrossDomainOwnable2 } from "../src/L2/CrossDomainOwnable2.sol"; +import { CrossDomainOwnable2 } from "src/L2/CrossDomainOwnable2.sol"; contract XDomainSetter2 is CrossDomainOwnable2 { uint256 public value; @@ -23,7 +23,7 @@ contract XDomainSetter2 is CrossDomainOwnable2 { } } -contract CrossDomainOwnable2_Test is Messenger_Initializer { +contract CrossDomainOwnable2_Test is Bridge_Initializer { XDomainSetter2 setter; /// @dev Sets up the test suite. diff --git a/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol b/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol index f770ae7d2bed..24eab5f55a48 100644 --- a/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol +++ b/packages/contracts-bedrock/test/CrossDomainOwnable3.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest, Messenger_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; // Libraries import { Hashing } from "src/libraries/Hashing.sol"; @@ -23,7 +23,7 @@ contract XDomainSetter3 is CrossDomainOwnable3 { } } -contract CrossDomainOwnable3_Test is Messenger_Initializer { +contract CrossDomainOwnable3_Test is Bridge_Initializer { XDomainSetter3 setter; /// @dev CrossDomainOwnable3.sol transferOwnership event diff --git a/packages/contracts-bedrock/test/DelayedVetoable.t.sol b/packages/contracts-bedrock/test/DelayedVetoable.t.sol index 90a259786585..93063359cb2e 100644 --- a/packages/contracts-bedrock/test/DelayedVetoable.t.sol +++ b/packages/contracts-bedrock/test/DelayedVetoable.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { DelayedVetoable } from "src/L1/DelayedVetoable.sol"; contract DelayedVetoable_Init is CommonTest { diff --git a/packages/contracts-bedrock/test/DisputeGameFactory.t.sol b/packages/contracts-bedrock/test/DisputeGameFactory.t.sol index a745b73fb04c..d9f058d2c558 100644 --- a/packages/contracts-bedrock/test/DisputeGameFactory.t.sol +++ b/packages/contracts-bedrock/test/DisputeGameFactory.t.sol @@ -8,9 +8,9 @@ import { Test } from "forge-std/Test.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { Proxy } from "src/universal/Proxy.sol"; -import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; -contract DisputeGameFactory_Init is L2OutputOracle_Initializer { +contract DisputeGameFactory_Init is CommonTest { DisputeGameFactory factory; FakeClone fakeClone; diff --git a/packages/contracts-bedrock/test/Encoding.t.sol b/packages/contracts-bedrock/test/Encoding.t.sol index 14ac3c81a0f7..35e9300f834e 100644 --- a/packages/contracts-bedrock/test/Encoding.t.sol +++ b/packages/contracts-bedrock/test/Encoding.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; diff --git a/packages/contracts-bedrock/test/FeeVault.t.sol b/packages/contracts-bedrock/test/FeeVault.t.sol index bbfa3792443a..98de40421442 100644 --- a/packages/contracts-bedrock/test/FeeVault.t.sol +++ b/packages/contracts-bedrock/test/FeeVault.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; // Target contract import { FeeVault } from "src/universal/FeeVault.sol"; diff --git a/packages/contracts-bedrock/test/GasPriceOracle.t.sol b/packages/contracts-bedrock/test/GasPriceOracle.t.sol index cee8c888f795..5e9d71e7baa5 100644 --- a/packages/contracts-bedrock/test/GasPriceOracle.t.sol +++ b/packages/contracts-bedrock/test/GasPriceOracle.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; contract GasPriceOracle_Test is CommonTest { event OverheadUpdated(uint256); diff --git a/packages/contracts-bedrock/test/GovernanceToken.t.sol b/packages/contracts-bedrock/test/GovernanceToken.t.sol index 1b9f5edca4e0..93f0585b3ee0 100644 --- a/packages/contracts-bedrock/test/GovernanceToken.t.sol +++ b/packages/contracts-bedrock/test/GovernanceToken.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; contract GovernanceToken_Test is CommonTest { address owner; diff --git a/packages/contracts-bedrock/test/Hashing.t.sol b/packages/contracts-bedrock/test/Hashing.t.sol index fc79c24422bd..98fa7ae485a0 100644 --- a/packages/contracts-bedrock/test/Hashing.t.sol +++ b/packages/contracts-bedrock/test/Hashing.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; diff --git a/packages/contracts-bedrock/test/Initializable.t.sol b/packages/contracts-bedrock/test/Initializable.t.sol index 47b4a2dd96c1..a9daa7785a03 100644 --- a/packages/contracts-bedrock/test/Initializable.t.sol +++ b/packages/contracts-bedrock/test/Initializable.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; diff --git a/packages/contracts-bedrock/test/L1Block.t.sol b/packages/contracts-bedrock/test/L1Block.t.sol index bdc3623faacd..c62a32e446f9 100644 --- a/packages/contracts-bedrock/test/L1Block.t.sol +++ b/packages/contracts-bedrock/test/L1Block.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Target contract import { L1Block } from "src/L2/L1Block.sol"; diff --git a/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol index 4d05977ff53b..bf49d25f5224 100644 --- a/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L1CrossDomainMessenger.t.sol @@ -2,8 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { Messenger_Initializer } from "test/CommonTest.t.sol"; -import { L2OutputOracle_Initializer } from "test/L2OutputOracle.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol"; // Libraries @@ -15,7 +14,7 @@ import { Encoding } from "src/libraries/Encoding.sol"; // Target contract dependencies import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -contract L1CrossDomainMessenger_Test is Messenger_Initializer { +contract L1CrossDomainMessenger_Test is Bridge_Initializer { /// @dev The receiver address address recipient = address(0xabbaacdc); diff --git a/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol index ac18fc7983f5..db7648dfbbb0 100644 --- a/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L1ERC721Bridge.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; // Target contract dependencies diff --git a/packages/contracts-bedrock/test/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1StandardBridge.t.sol index 4f8f5e15e7ba..8ffc4c0f6714 100644 --- a/packages/contracts-bedrock/test/L1StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L1StandardBridge.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.15; // Testing utilities import { stdStorage, StdStorage } from "forge-std/Test.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; diff --git a/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol index 0a9c5602813e..cbd13e5bfb41 100644 --- a/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L2CrossDomainMessenger.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { Messenger_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol"; // Libraries @@ -14,7 +14,7 @@ import { Types } from "src/libraries/Types.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; -contract L2CrossDomainMessenger_Test is Messenger_Initializer { +contract L2CrossDomainMessenger_Test is Bridge_Initializer { /// @dev Receiver address for testing address recipient = address(0xabbaacdc); diff --git a/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol b/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol index 43989983a39a..555724a7630f 100644 --- a/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol +++ b/packages/contracts-bedrock/test/L2ERC721Bridge.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; // Target contract dependencies import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; diff --git a/packages/contracts-bedrock/test/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/L2OutputOracle.t.sol index 6a7bb0c76469..ad523d5bbd3f 100644 --- a/packages/contracts-bedrock/test/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/L2OutputOracle.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { stdError } from "forge-std/Test.sol"; -import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { NextImpl } from "test/mocks/NextImpl.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; @@ -17,7 +17,7 @@ import { Proxy } from "src/universal/Proxy.sol"; // Target contract import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; -contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { +contract L2OutputOracle_constructor_Test is CommonTest { /// @dev Tests that constructor sets the initial values correctly. function test_constructor_succeeds() external { address proposer = cfg.l2OutputOracleProposer(); @@ -80,7 +80,7 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { } } -contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer { +contract L2OutputOracle_getter_Test is CommonTest { bytes32 proposedOutput1 = keccak256(abi.encode(1)); /// @dev Tests that `latestBlockNumber` returns the correct value. @@ -216,7 +216,7 @@ contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer { } } -contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer { +contract L2OutputOracle_proposeL2Output_Test is CommonTest { /// @dev Test that `proposeL2Output` succeeds for a valid input /// and when a block hash and number are not specified. function test_proposeL2Output_proposeAnotherOutput_succeeds() public { @@ -308,7 +308,7 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer { } } -contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { +contract L2OutputOracle_deleteOutputs_Test is CommonTest { /// @dev Tests that `deleteL2Outputs` succeeds for a single output. function test_deleteOutputs_singleOutput_succeeds() external { proposeAnotherOutput(); @@ -416,7 +416,7 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { } } -contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { +contract L2OutputOracleUpgradeable_Test is CommonTest { /// @dev Tests that the proxy is initialized with the correct values. function test_initValuesOnProxy_succeeds() external { address proposer = cfg.l2OutputOracleProposer(); diff --git a/packages/contracts-bedrock/test/L2StandardBridge.t.sol b/packages/contracts-bedrock/test/L2StandardBridge.t.sol index 1053c09d2c15..567f2ea9748a 100644 --- a/packages/contracts-bedrock/test/L2StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L2StandardBridge.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing utilities // Target contract is imported by the `Bridge_Initializer` -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { stdStorage, StdStorage } from "forge-std/Test.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; diff --git a/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol b/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol index 7ee5a43f9ad1..0c2c6c8b869a 100644 --- a/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol +++ b/packages/contracts-bedrock/test/L2ToL1MessagePasser.t.sol @@ -2,25 +2,13 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; contract L2ToL1MessagePasserTest is CommonTest { - event MessagePassed( - uint256 indexed nonce, - address indexed sender, - address indexed target, - uint256 value, - uint256 gasLimit, - bytes data, - bytes32 withdrawalHash - ); - - event WithdrawerBalanceBurnt(uint256 indexed amount); - /// @dev Tests that `initiateWithdrawal` succeeds and correctly sets the state /// of the message passer for the withdrawal hash. function testFuzz_initiateWithdrawal_succeeds( diff --git a/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol b/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol index 126fdfe661e2..62e2928f06b9 100644 --- a/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol +++ b/packages/contracts-bedrock/test/LegacyERC20ETH.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Target contract dependencies import { Predeploys } from "src/libraries/Predeploys.sol"; diff --git a/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol b/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol index d31e04720771..39eb479a3ac0 100644 --- a/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol +++ b/packages/contracts-bedrock/test/LegacyMessagePasser.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; contract LegacyMessagePasser_Test is CommonTest { /// @dev Tests that `passMessageToL1` succeeds. diff --git a/packages/contracts-bedrock/test/LibPosition.t.sol b/packages/contracts-bedrock/test/LibPosition.t.sol index a60f5e2bafca..20ff04e9fb44 100644 --- a/packages/contracts-bedrock/test/LibPosition.t.sol +++ b/packages/contracts-bedrock/test/LibPosition.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.15; import { Test } from "forge-std/Test.sol"; -import { LibPosition } from "../src/dispute/lib/LibPosition.sol"; +import { LibPosition } from "src/dispute/lib/LibPosition.sol"; import "src/libraries/DisputeTypes.sol"; /// @notice Tests for `LibPosition` diff --git a/packages/contracts-bedrock/test/MIPS.t.sol b/packages/contracts-bedrock/test/MIPS.t.sol index 7f1dfdead49a..f34b453e9c8c 100644 --- a/packages/contracts-bedrock/test/MIPS.t.sol +++ b/packages/contracts-bedrock/test/MIPS.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { CommonTest } from "./CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { MIPS } from "src/cannon/MIPS.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import "src/libraries/DisputeTypes.sol"; diff --git a/packages/contracts-bedrock/test/MintManager.t.sol b/packages/contracts-bedrock/test/MintManager.t.sol index 92fceec0ae1a..00cc791b98c2 100644 --- a/packages/contracts-bedrock/test/MintManager.t.sol +++ b/packages/contracts-bedrock/test/MintManager.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Target contract dependencies import { GovernanceToken } from "src/governance/GovernanceToken.sol"; diff --git a/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol index 5bda37ef875b..6bb332473ecd 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC20.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; diff --git a/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol index 82fb9c332e25..c856e721f825 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC20Factory.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; contract OptimismMintableTokenFactory_Test is Bridge_Initializer { event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); diff --git a/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol index a5ceade22cac..9a9eede4b4d6 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC721.t.sol @@ -5,7 +5,7 @@ import { ERC721, IERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { OptimismMintableERC721, IOptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; contract OptimismMintableERC721_Test is Bridge_Initializer { diff --git a/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol b/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol index 75f4d94167dd..d337b58a5b14 100644 --- a/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol +++ b/packages/contracts-bedrock/test/OptimismMintableERC721Factory.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import { Bridge_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol index bb68a0b4f5c9..58b25fb4b14c 100644 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/OptimismPortal.t.sol @@ -3,7 +3,8 @@ pragma solidity 0.8.15; // Testing utilities import { stdError } from "forge-std/Test.sol"; -import { Portal_Initializer } from "test/CommonTest.t.sol"; + +import { CommonTest } from "test/setup/CommonTest.sol"; import { NextImpl } from "test/mocks/NextImpl.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; @@ -20,7 +21,7 @@ import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; -contract OptimismPortal_Test is Portal_Initializer { +contract OptimismPortal_Test is CommonTest { event Paused(address); event Unpaused(address); @@ -193,7 +194,11 @@ contract OptimismPortal_Test is Portal_Initializer { external { _gasLimit = uint64( - bound(_gasLimit, optimismPortal.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) + bound( + _gasLimit, + optimismPortal.minimumGasLimit(uint64(_data.length)), + systemConfig.resourceConfig().maxResourceLimit + ) ); if (_isCreation) _to = address(0); @@ -232,7 +237,13 @@ contract OptimismPortal_Test is Portal_Initializer { ) external { - _gasLimit = uint64(bound(_gasLimit, optimismPortal.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit)); + _gasLimit = uint64( + bound( + _gasLimit, + optimismPortal.minimumGasLimit(uint64(_data.length)), + systemConfig.resourceConfig().maxResourceLimit + ) + ); if (_isCreation) _to = address(0); vm.expectEmit(address(optimismPortal)); @@ -246,7 +257,6 @@ contract OptimismPortal_Test is Portal_Initializer { _data: _data }); - vm.deal(address(this), _mint); vm.prank(address(this)); optimismPortal.depositTransaction{ value: _mint }({ @@ -306,7 +316,7 @@ contract OptimismPortal_Test is Portal_Initializer { } } -contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { +contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest { // Reusable default values for a test withdrawal Types.WithdrawalTransaction _defaultTx; @@ -876,7 +886,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { } } -contract OptimismPortalUpgradeable_Test is Portal_Initializer { +contract OptimismPortalUpgradeable_Test is CommonTest { /// @dev Tests that the proxy is initialized correctly. function test_params_initValuesOnProxy_succeeds() external { (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params(); @@ -884,7 +894,7 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer { assertEq(prevBaseFee, rcfg.minimumBaseFee); assertEq(prevBoughtGas, 0); - assertEq(prevBlockNum, block.number - 1); + assertEq(prevBlockNum, block.number); } /// @dev Tests that the proxy cannot be initialized twice. @@ -936,7 +946,7 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer { /// @title OptimismPortalResourceFuzz_Test /// @dev Test various values of the resource metering config to ensure that deposits cannot be /// broken by changing the config. -contract OptimismPortalResourceFuzz_Test is Portal_Initializer { +contract OptimismPortalResourceFuzz_Test is CommonTest { /// @dev The max gas limit observed throughout this test. Setting this too high can cause /// the test to take too long to run. uint256 constant MAX_GAS_LIMIT = 30_000_000; diff --git a/packages/contracts-bedrock/test/ProtocolVersions.t.sol b/packages/contracts-bedrock/test/ProtocolVersions.t.sol index bed5c82d475e..c8201495e7a9 100644 --- a/packages/contracts-bedrock/test/ProtocolVersions.t.sol +++ b/packages/contracts-bedrock/test/ProtocolVersions.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Libraries diff --git a/packages/contracts-bedrock/test/SequencerFeeVault.t.sol b/packages/contracts-bedrock/test/SequencerFeeVault.t.sol index 925a1b53b0f8..b7836de638df 100644 --- a/packages/contracts-bedrock/test/SequencerFeeVault.t.sol +++ b/packages/contracts-bedrock/test/SequencerFeeVault.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { FeeVault_Initializer } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { Reverter } from "test/mocks/Callers.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol"; @@ -15,7 +15,7 @@ import { FeeVault } from "src/universal/FeeVault.sol"; // Target contract import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; -contract SequencerFeeVault_Test is FeeVault_Initializer { +contract SequencerFeeVault_Test is CommonTest { address recipient; /// @dev Sets up the test suite. @@ -98,7 +98,7 @@ contract SequencerFeeVault_Test is FeeVault_Initializer { } } -contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer { +contract SequencerFeeVault_L2Withdrawal_Test is CommonTest { address recipient; /// @dev Sets up the test suite. diff --git a/packages/contracts-bedrock/test/StandardBridge.t.sol b/packages/contracts-bedrock/test/StandardBridge.t.sol index 000d2334ae34..0f437fead82f 100644 --- a/packages/contracts-bedrock/test/StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/StandardBridge.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { StandardBridge } from "src/universal/StandardBridge.sol"; -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { OptimismMintableERC20, ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; diff --git a/packages/contracts-bedrock/test/SystemConfig.t.sol b/packages/contracts-bedrock/test/SystemConfig.t.sol index f9aa6cc1724d..cbf924b636f7 100644 --- a/packages/contracts-bedrock/test/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/SystemConfig.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; // Testing utilities -import { CommonTest } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; diff --git a/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol index b55b28642a91..a2a1bf2e0d55 100644 --- a/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/invariants/CrossDomainMessenger.t.sol @@ -5,12 +5,13 @@ import { StdUtils } from "forge-std/StdUtils.sol"; import { Vm } from "forge-std/Vm.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; -import { Messenger_Initializer } from "test/CommonTest.t.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { Types } from "src/libraries/Types.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Encoding } from "src/libraries/Encoding.sol"; import { Hashing } from "src/libraries/Hashing.sol"; +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; contract RelayActor is StdUtils { // Storage slot of the l2Sender @@ -88,7 +89,7 @@ contract RelayActor is StdUtils { } } -contract XDM_MinGasLimits is Messenger_Initializer { +contract XDM_MinGasLimits is Bridge_Initializer { RelayActor actor; function init(bool doFail) public virtual { diff --git a/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol b/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol index 47544f89643b..c688ef419617 100644 --- a/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol +++ b/packages/contracts-bedrock/test/invariants/L2OutputOracle.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.15; -import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { Vm } from "forge-std/Vm.sol"; @@ -29,7 +29,7 @@ contract L2OutputOracle_Proposer { } } -contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_Initializer { +contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is CommonTest { L2OutputOracle_Proposer internal actor; function setUp() public override { diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol index ad05c8b2ac29..009a6a9daca1 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal.t.sol @@ -11,7 +11,7 @@ import { SystemConfig } from "src/L1/SystemConfig.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { Constants } from "src/libraries/Constants.sol"; -import { Portal_Initializer } from "test/CommonTest.t.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Types } from "src/libraries/Types.sol"; @@ -74,7 +74,7 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering { } } -contract OptimismPortal_Invariant_Harness is Portal_Initializer { +contract OptimismPortal_Invariant_Harness is CommonTest { // Reusable default values for a test withdrawal Types.WithdrawalTransaction _defaultTx; @@ -127,7 +127,7 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer { } } -contract OptimismPortal_Deposit_Invariant is Portal_Initializer { +contract OptimismPortal_Deposit_Invariant is CommonTest { OptimismPortal_Depositor internal actor; function setUp() public override { diff --git a/packages/contracts-bedrock/test/setup/Bridge_Initializer.sol b/packages/contracts-bedrock/test/setup/Bridge_Initializer.sol new file mode 100644 index 000000000000..6b931712935e --- /dev/null +++ b/packages/contracts-bedrock/test/setup/Bridge_Initializer.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { CommonTest } from "test/setup/CommonTest.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; +import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol"; + +/// @title Bridge_Initializer +/// @dev This contract extends the CommonTest contract with token deployments +/// meant to be used with the bridge contracts. +contract Bridge_Initializer is CommonTest { + ERC20 L1Token; + ERC20 BadL1Token; + OptimismMintableERC20 L2Token; + LegacyMintableERC20 LegacyL2Token; + ERC20 NativeL2Token; + ERC20 BadL2Token; + OptimismMintableERC20 RemoteL1Token; + + function setUp() public virtual override { + super.setUp(); + + L1Token = new ERC20("Native L1 Token", "L1T"); + + LegacyL2Token = new LegacyMintableERC20({ + _l2Bridge: address(l2StandardBridge), + _l1Token: address(L1Token), + _name: string.concat("LegacyL2-", L1Token.name()), + _symbol: string.concat("LegacyL2-", L1Token.symbol()) + }); + vm.label(address(LegacyL2Token), "LegacyMintableERC20"); + + // Deploy the L2 ERC20 now + L2Token = OptimismMintableERC20( + l2OptimismMintableERC20Factory.createStandardL2Token( + address(L1Token), + string(abi.encodePacked("L2-", L1Token.name())), + string(abi.encodePacked("L2-", L1Token.symbol())) + ) + ); + + BadL2Token = OptimismMintableERC20( + l2OptimismMintableERC20Factory.createStandardL2Token( + address(1), + string(abi.encodePacked("L2-", L1Token.name())), + string(abi.encodePacked("L2-", L1Token.symbol())) + ) + ); + + NativeL2Token = new ERC20("Native L2 Token", "L2T"); + + RemoteL1Token = OptimismMintableERC20( + l1OptimismMintableERC20Factory.createStandardL2Token( + address(NativeL2Token), + string(abi.encodePacked("L1-", NativeL2Token.name())), + string(abi.encodePacked("L1-", NativeL2Token.symbol())) + ) + ); + + BadL1Token = OptimismMintableERC20( + l1OptimismMintableERC20Factory.createStandardL2Token( + address(1), + string(abi.encodePacked("L1-", NativeL2Token.name())), + string(abi.encodePacked("L1-", NativeL2Token.symbol())) + ) + ); + } +} diff --git a/packages/contracts-bedrock/test/setup/CommonTest.sol b/packages/contracts-bedrock/test/setup/CommonTest.sol new file mode 100644 index 000000000000..74f040aa1da6 --- /dev/null +++ b/packages/contracts-bedrock/test/setup/CommonTest.sol @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test } from "forge-std/Test.sol"; +import { Setup } from "test/setup/Setup.sol"; +import { Events } from "test/setup/Events.sol"; +import { FFIInterface } from "test/setup/FFIInterface.sol"; + +/// @title CommonTest +/// @dev An extenstion to `Test` that sets up the optimism smart contracts. +contract CommonTest is Setup, Test, Events { + address alice = address(128); + address bob = address(256); + + bytes32 constant nonZeroHash = keccak256(abi.encode("NON_ZERO")); + + FFIInterface ffi; + + function setUp() public virtual override { + vm.deal(alice, type(uint64).max); + vm.deal(bob, type(uint64).max); + + vm.label(alice, "alice"); + vm.label(bob, "bob"); + + Setup.setUp(); + ffi = new FFIInterface(); + + // Make sure the base fee is non zero + vm.fee(1 gwei); + + // Set sane initialize block numbers + vm.warp(cfg.l2OutputOracleStartingTimestamp() + 1); + vm.roll(cfg.l2OutputOracleStartingBlockNumber() + 1); + + // Deploy L1 + Setup.L1(); + // Deploy L2 + Setup.L2({ cfg: cfg }); + } + + /// @dev Helper function that wraps `TransactionDeposited` event. + /// The magic `0` is the version. + function emitTransactionDeposited( + address _from, + address _to, + uint256 _mint, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + internal + { + emit TransactionDeposited(_from, _to, 0, abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data)); + } + + // @dev Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output + function warpToProposeTime(uint256 _nextBlockNumber) public { + vm.warp(l2OutputOracle.computeL2Timestamp(_nextBlockNumber) + 1); + } + + /// @dev Helper function to propose an output. + function proposeAnotherOutput() public { + bytes32 proposedOutput2 = keccak256(abi.encode()); + uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber(); + uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex(); + warpToProposeTime(nextBlockNumber); + uint256 proposedNumber = l2OutputOracle.latestBlockNumber(); + + uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval(); + // Ensure the submissionInterval is enforced + assertEq(nextBlockNumber, proposedNumber + submissionInterval); + + vm.roll(nextBlockNumber + 1); + + vm.expectEmit(true, true, true, true); + emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp); + + address proposer = cfg.l2OutputOracleProposer(); + vm.prank(proposer); + l2OutputOracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0); + } +} diff --git a/packages/contracts-bedrock/test/setup/Events.sol b/packages/contracts-bedrock/test/setup/Events.sol new file mode 100644 index 000000000000..a9d6d62979c9 --- /dev/null +++ b/packages/contracts-bedrock/test/setup/Events.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { FeeVault } from "src/universal/FeeVault.sol"; + +/// @title Events +/// @dev Contains various events that are tested against. This contract needs to +/// exist until we either modularize the implementations or use a newer version of +/// solc that allows for referencing events from other contracts. +contract Events { + /// @dev OpenZeppelin Ownable.sol transferOwnership event + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); + + event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success); + event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to); + + event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); + event SentMessageExtension1(address indexed sender, uint256 value); + event MessagePassed( + uint256 indexed nonce, + address indexed sender, + address indexed target, + uint256 value, + uint256 gasLimit, + bytes data, + bytes32 withdrawalHash + ); + event WithdrawerBalanceBurnt(uint256 indexed amount); + event RelayedMessage(bytes32 indexed msgHash); + event FailedRelayedMessage(bytes32 indexed msgHash); + event TransactionDeposited( + address indexed from, + address indexed to, + uint256 mint, + uint256 value, + uint64 gasLimit, + bool isCreation, + bytes data + ); + event WhatHappened(bool success, bytes returndata); + + event OutputProposed( + bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp + ); + + event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex); + + event Withdrawal(uint256 value, address to, address from); + event Withdrawal(uint256 value, address to, address from, FeeVault.WithdrawalNetwork withdrawalNetwork); + + event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data); + + event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes data); + + event ERC20DepositInitiated( + address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data + ); + + event ERC20WithdrawalFinalized( + address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data + ); + + event WithdrawalInitiated( + address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data + ); + + event DepositFinalized( + address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data + ); + + event DepositFailed( + address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data + ); + + event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data); + + event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data); + + event ERC20BridgeInitiated( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 amount, + bytes data + ); + + event ERC20BridgeFinalized( + address indexed localToken, + address indexed remoteToken, + address indexed from, + address to, + uint256 amount, + bytes data + ); +} diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol new file mode 100644 index 000000000000..0146ac82d0fc --- /dev/null +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol"; +import { L2StandardBridge } from "src/L2/L2StandardBridge.sol"; +import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; +import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol"; +import { BaseFeeVault } from "src/L2/BaseFeeVault.sol"; +import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; +import { L1FeeVault } from "src/L2/L1FeeVault.sol"; +import { GasPriceOracle } from "src/L2/GasPriceOracle.sol"; +import { L1Block } from "src/L2/L1Block.sol"; +import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol"; +import { GovernanceToken } from "src/governance/GovernanceToken.sol"; +import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol"; +import { LegacyERC20ETH } from "src/legacy/LegacyERC20ETH.sol"; +import { StandardBridge } from "src/universal/StandardBridge.sol"; +import { FeeVault } from "src/universal/FeeVault.sol"; +import { OptimismPortal } from "src/L1/OptimismPortal.sol"; +import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; +import { DeployConfig } from "scripts/DeployConfig.s.sol"; +import { Deploy } from "scripts/Deploy.s.sol"; +import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; +import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; +import { AddressManager } from "src/legacy/AddressManager.sol"; +import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; +import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; + +/// @title Setup +/// @dev This contact is responsible for setting up the contracts in state. It currently +/// sets the L2 contracts directly at the predeploy addresses instead of setting them +/// up behind proxies. In the future we will migrate to importing the genesis JSON +/// file that is created to set up the L2 contracts instead of setting them up manually. +contract Setup is Deploy { + OptimismPortal optimismPortal; + L2OutputOracle l2OutputOracle; + SystemConfig systemConfig; + L1StandardBridge l1StandardBridge; + L1CrossDomainMessenger l1CrossDomainMessenger; + AddressManager addressManager; + L1ERC721Bridge l1ERC721Bridge; + OptimismMintableERC20Factory l1OptimismMintableERC20Factory; + ProtocolVersions protocolVersions; + + L2CrossDomainMessenger l2CrossDomainMessenger; + L2StandardBridge l2StandardBridge; + L2ToL1MessagePasser l2ToL1MessagePasser; + OptimismMintableERC20Factory l2OptimismMintableERC20Factory; + L2ERC721Bridge l2ERC721Bridge; + BaseFeeVault baseFeeVault; + SequencerFeeVault sequencerFeeVault; + L1FeeVault l1FeeVault; + GasPriceOracle gasPriceOracle; + L1Block l1Block; + LegacyMessagePasser legacyMessagePasser; + GovernanceToken governanceToken; + LegacyERC20ETH legacyERC20ETH; + + function setUp() public virtual override { + Deploy.setUp(); + } + + /// @dev Sets up the L1 contracts. + function L1() public { + // Set the deterministic deployer in state to ensure that it is there + vm.etch( + 0x4e59b44847b379578588920cA78FbF26c0B4956C, + hex"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" + ); + + Deploy.run(); + + optimismPortal = OptimismPortal(mustGetAddress("OptimismPortalProxy")); + l2OutputOracle = L2OutputOracle(mustGetAddress("L2OutputOracleProxy")); + systemConfig = SystemConfig(mustGetAddress("SystemConfigProxy")); + l1StandardBridge = L1StandardBridge(mustGetAddress("L1StandardBridgeProxy")); + l1CrossDomainMessenger = L1CrossDomainMessenger(mustGetAddress("L1CrossDomainMessengerProxy")); + addressManager = AddressManager(mustGetAddress("AddressManager")); + l1ERC721Bridge = L1ERC721Bridge(mustGetAddress("L1ERC721BridgeProxy")); + l1OptimismMintableERC20Factory = + OptimismMintableERC20Factory(mustGetAddress("OptimismMintableERC20FactoryProxy")); + protocolVersions = ProtocolVersions(mustGetAddress("ProtocolVersionsProxy")); + + vm.label(address(l2OutputOracle), "L2OutputOracle"); + vm.label(mustGetAddress("L2OutputOracleProxy"), "L2OutputOracleProxy"); + vm.label(address(optimismPortal), "OptimismPortal"); + vm.label(mustGetAddress("OptimismPortalProxy"), "OptimismPortalProxy"); + vm.label(address(systemConfig), "SystemConfig"); + vm.label(mustGetAddress("SystemConfigProxy"), "SystemConfigProxy"); + vm.label(address(l1StandardBridge), "L1StandardBridge"); + vm.label(mustGetAddress("L1StandardBridgeProxy"), "L1StandardBridgeProxy"); + vm.label(address(l1CrossDomainMessenger), "L1CrossDomainMessenger"); + vm.label(mustGetAddress("L1CrossDomainMessengerProxy"), "L1CrossDomainMessengerProxy"); + vm.label(address(addressManager), "AddressManager"); + vm.label(address(l1ERC721Bridge), "L1ERC721Bridge"); + vm.label(mustGetAddress("L1ERC721BridgeProxy"), "L1ERC721BridgeProxy"); + vm.label(address(l1OptimismMintableERC20Factory), "OptimismMintableERC20Factory"); + vm.label(mustGetAddress("OptimismMintableERC20FactoryProxy"), "OptimismMintableERC20FactoryProxy"); + vm.label(address(protocolVersions), "ProtocolVersions"); + vm.label(mustGetAddress("ProtocolVersionsProxy"), "ProtocolVersionsProxy"); + vm.label(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), "L1CrossDomainMessenger_aliased"); + } + + /// @dev Sets up the L2 contracts. Depends on `L1()` being called first. + function L2(DeployConfig cfg) public { + // Set up L2. There are currently no proxies set in the L2 initialization. + vm.etch( + Predeploys.L2_CROSS_DOMAIN_MESSENGER, + address(new L2CrossDomainMessenger(address(l1CrossDomainMessenger))).code + ); + l2CrossDomainMessenger = L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); + l2CrossDomainMessenger.initialize(); + + vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code); + l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); + + vm.etch( + Predeploys.L2_STANDARD_BRIDGE, address(new L2StandardBridge(StandardBridge(payable(l1StandardBridge)))).code + ); + l2StandardBridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)); + l2StandardBridge.initialize(); + + vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(new OptimismMintableERC20Factory()).code); + l2OptimismMintableERC20Factory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); + l2OptimismMintableERC20Factory.initialize(Predeploys.L2_STANDARD_BRIDGE); + + vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code); + legacyERC20ETH = LegacyERC20ETH(Predeploys.LEGACY_ERC20_ETH); + + vm.etch(Predeploys.L2_ERC721_BRIDGE, address(new L2ERC721Bridge(address(l1ERC721Bridge))).code); + l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); + l2ERC721Bridge.initialize(); + + vm.etch( + Predeploys.SEQUENCER_FEE_WALLET, + address( + new SequencerFeeVault(cfg.sequencerFeeVaultRecipient(), cfg.sequencerFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2) + ).code + ); + vm.etch( + Predeploys.BASE_FEE_VAULT, + address( + new BaseFeeVault(cfg.baseFeeVaultRecipient(), cfg.baseFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L1) + ).code + ); + vm.etch( + Predeploys.L1_FEE_VAULT, + address( + new L1FeeVault(cfg.l1FeeVaultRecipient(), cfg.l1FeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2) + ).code + ); + + sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); + baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); + l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); + + vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code); + l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); + + vm.etch(Predeploys.GAS_PRICE_ORACLE, address(new GasPriceOracle()).code); + gasPriceOracle = GasPriceOracle(Predeploys.GAS_PRICE_ORACLE); + + vm.etch(Predeploys.LEGACY_MESSAGE_PASSER, address(new LegacyMessagePasser()).code); + legacyMessagePasser = LegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); + + vm.etch(Predeploys.GOVERNANCE_TOKEN, address(new GovernanceToken()).code); + governanceToken = GovernanceToken(Predeploys.GOVERNANCE_TOKEN); + vm.store( + Predeploys.GOVERNANCE_TOKEN, + bytes32(uint256(3)), + bytes32(0x4f7074696d69736d000000000000000000000000000000000000000000000010) + ); + vm.store( + Predeploys.GOVERNANCE_TOKEN, + bytes32(uint256(4)), + bytes32(0x4f50000000000000000000000000000000000000000000000000000000000004) + ); + + // Set the governance token's owner to be the final system owner + address finalSystemOwner = cfg.finalSystemOwner(); + vm.prank(governanceToken.owner()); + governanceToken.transferOwnership(finalSystemOwner); + + vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, "OptimismMintableERC20Factory"); + vm.label(Predeploys.LEGACY_ERC20_ETH, "LegacyERC20ETH"); + vm.label(Predeploys.L2_STANDARD_BRIDGE, "L2StandardBridge"); + vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger"); + vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, "L2ToL1MessagePasser"); + vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault"); + vm.label(Predeploys.L2_ERC721_BRIDGE, "L2ERC721Bridge"); + vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault"); + vm.label(Predeploys.L1_FEE_VAULT, "L1FeeVault"); + vm.label(Predeploys.L1_BLOCK_ATTRIBUTES, "L1Block"); + vm.label(Predeploys.GAS_PRICE_ORACLE, "GasPriceOracle"); + vm.label(Predeploys.LEGACY_MESSAGE_PASSER, "LegacyMessagePasser"); + vm.label(Predeploys.GOVERNANCE_TOKEN, "GovernanceToken"); + } +} From 123409e302478dbe90bc695a671076c2514dece9 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 3 Nov 2023 23:21:47 +0300 Subject: [PATCH 360/374] op-bindings: regenerate --- op-bindings/bindings/mips_more.go | 2 +- op-bindings/bindings/preimageoracle_more.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/op-bindings/bindings/mips_more.go b/op-bindings/bindings/mips_more.go index 42d41cd47ad9..52238e8bef32 100644 --- a/op-bindings/bindings/mips_more.go +++ b/op-bindings/bindings/mips_more.go @@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" -var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:305;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:305;2534:6:135;400:55:305;382:74;;370:2;355:18;2448:99:135;211:251:305;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:305;;;1743:2;1728:18;26025:6379:135;1609:177:305;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:305;19164:28:135;;;2164:21:305;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:305;14107:30:135;;;2511:21:305;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:305;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:305;37406:29:135;;;2860:21:305;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:305;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:305;20288:41:135;;;3208:21:305;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:305;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:305;;;8234:54:135;3601:23:305;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:305;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:305;21415:72:135;;;4259:21:305;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:305;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:305:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:305;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:305;-1:-1:-1;1349:2:305;1334:18;;1321:32;;-1:-1:-1;1365:16:305;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:305;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:305:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:305;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:305:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" +var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:308;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:308;2534:6:135;400:55:308;382:74;;370:2;355:18;2448:99:135;211:251:308;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:308;;;1743:2;1728:18;26025:6379:135;1609:177:308;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:308;19164:28:135;;;2164:21:308;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:308;14107:30:135;;;2511:21:308;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:308;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:308;37406:29:135;;;2860:21:308;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:308;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:308;20288:41:135;;;3208:21:308;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:308;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:308;;;8234:54:135;3601:23:308;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:308;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:308;21415:72:135;;;4259:21:308;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:308;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:308:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:308;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:308;-1:-1:-1;1349:2:308;1334:18;;1321:32;;-1:-1:-1;1365:16:308;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:308;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:308:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:308;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:308:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" func init() { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { diff --git a/op-bindings/bindings/preimageoracle_more.go b/op-bindings/bindings/preimageoracle_more.go index d03ea4e51ec2..e123a756178c 100644 --- a/op-bindings/bindings/preimageoracle_more.go +++ b/op-bindings/bindings/preimageoracle_more.go @@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" -var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:305;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:305;;607:22;589:41;;577:2;562:18;680:66:137;449:187:305;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:305;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:305;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:305;906:62:137;;;2890:21:305;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:305:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:305;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:305:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:305;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:305;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:305;1069:19;1056:33;;-1:-1:-1;641:454:305;-1:-1:-1;641:454:305:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:305;;2017:180;-1:-1:-1;2017:180:305:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:305;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:305;;3055:125::o" +var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:308;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:308;;607:22;589:41;;577:2;562:18;680:66:137;449:187:308;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:308;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:308;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:308;906:62:137;;;2890:21:308;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:308:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:308;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:308:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:308;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:308;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:308;1069:19;1056:33;;-1:-1:-1;641:454:308;-1:-1:-1;641:454:308:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:308;;2017:180;-1:-1:-1;2017:180:308:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:308;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:308;;3055:125::o" func init() { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { From eb5cf57457627e2af40f2f050d50cce42d2f1c83 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 6 Nov 2023 17:24:58 +0300 Subject: [PATCH 361/374] contracts-bedrock: cleanup --- packages/contracts-bedrock/test/FaultDisputeGame.t.sol | 5 +---- packages/contracts-bedrock/test/OptimismPortal.t.sol | 2 -- packages/contracts-bedrock/test/SystemConfig.t.sol | 4 ++-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol index 02b8cab16fee..134568776c3a 100644 --- a/packages/contracts-bedrock/test/FaultDisputeGame.t.sol +++ b/packages/contracts-bedrock/test/FaultDisputeGame.t.sol @@ -138,14 +138,11 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { /// to dispute the first output root by using genesis as the starting point. /// For now, it is critical that the first proposed output root of an OP stack /// chain is done so by an honest party. - - /* function test_initialize_firstOutput_reverts() public { - uint256 submissionInterval = oracle.SUBMISSION_INTERVAL(); + uint256 submissionInterval = l2OutputOracle.submissionInterval(); vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x11)); factory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(submissionInterval, block.number - 1)); } - */ /// @dev Tests that the `create` function reverts when the rootClaim does not disagree with the outcome. function testFuzz_initialize_badRootStatus_reverts(Claim rootClaim, bytes calldata extraData) public { diff --git a/packages/contracts-bedrock/test/OptimismPortal.t.sol b/packages/contracts-bedrock/test/OptimismPortal.t.sol index 58b25fb4b14c..414fc65a8be3 100644 --- a/packages/contracts-bedrock/test/OptimismPortal.t.sol +++ b/packages/contracts-bedrock/test/OptimismPortal.t.sol @@ -984,8 +984,6 @@ contract OptimismPortalResourceFuzz_Test is CommonTest { // Pick a pseudorandom block number vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max) + uint256(_blockDiff)); - vm.roll(uint256(keccak256(abi.encode(_blockDiff))) % uint256(type(uint16).max)); - // Create a resource config to mock the call to the system config with ResourceMetering.ResourceConfig memory rcfg = ResourceMetering.ResourceConfig({ maxResourceLimit: _maxResourceLimit, diff --git a/packages/contracts-bedrock/test/SystemConfig.t.sol b/packages/contracts-bedrock/test/SystemConfig.t.sol index cbf924b636f7..0b09b768c686 100644 --- a/packages/contracts-bedrock/test/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/SystemConfig.t.sol @@ -6,6 +6,7 @@ import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Target contract dependencies import { ResourceMetering } from "src/L1/ResourceMetering.sol"; @@ -121,8 +122,7 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { vm.store(address(systemConfig), bytes32(uint256(106)), bytes32(uint256(0xff))); // Initialize with a non zero start block, should see a revert - address admin = address(uint160(uint256(vm.load(address(systemConfig), Constants.PROXY_OWNER_ADDRESS)))); - vm.prank(admin); + vm.prank(EIP1967Helper.getAdmin(address(systemConfig))); // The call to initialize reverts due to: "SystemConfig: cannot override an already set start block" // but the proxy revert message bubbles up. Proxy(payable(address(systemConfig))).upgradeToAndCall( From 71df3b9aa75929d79903199f7c00359175defdf5 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 6 Nov 2023 18:03:10 +0300 Subject: [PATCH 362/374] contracts-bedrock: gas-snapshot --- packages/contracts-bedrock/.gas-snapshot | 533 ++++++++++++----------- 1 file changed, 267 insertions(+), 266 deletions(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 0f5e6129bcd2..2f376f8941ff 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -26,33 +26,33 @@ Bytes_toNibbles_Test:test_toNibbles_expectedResult128Bytes_works() (gas: 78882) Bytes_toNibbles_Test:test_toNibbles_expectedResult5Bytes_works() (gas: 3992) Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 823) Constants_Test:test_eip1967Constants_succeeds() (gas: 453) -CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20525) -CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8528) -CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57518) +CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20481) +CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8539) +CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57515) CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16655) -CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73597) +CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73600) CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10605) -CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28378) -CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 74058) -CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32111) -CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91600) +CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28363) +CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 74040) +CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32096) +CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91581) CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13260) CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35271) -CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52158) -CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48706) -CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12112) +CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52164) +CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48712) +CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12090) CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13460) -CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12177) -CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81600) +CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12155) +CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81556) CrossDomainOwnable_Test:test_onlyOwner_notOwner_reverts() (gas: 10597) CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34883) -DelayedVetoable_Getters_Test:test_getters() (gas: 24671) -DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 36263) -DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 15190) +DelayedVetoable_Getters_Test:test_getters() (gas: 24620) +DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 36289) +DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 15165) DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582) DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395) DisputeGameFactory_Owner_Test:test_owner_succeeds() (gas: 12611) -DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16067) +DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16143) DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44346) DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15974) DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18738) @@ -99,166 +99,167 @@ FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeed FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 655638) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 656576) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 656027) -FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 642366) -FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10439) -FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32385) +FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 642441) +FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10476) +FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32422) FaultDisputeGame_Test:test_gameData_succeeds() (gas: 32857) -FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8265) -FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57761) +FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8302) +FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57779) +FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 213868) FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228488) -FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594267) -FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23197) -FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13322) -FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 147390) -FaultDisputeGame_Test:test_move_duplicateClaimsDifferentSubgames_succeeds() (gas: 556832) -FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 585853) -FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 11010) -FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24668) -FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 152008) -FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 269473) -FaultDisputeGame_Test:test_resolve_claimAlreadyResolved_reverts() (gas: 272334) -FaultDisputeGame_Test:test_resolve_claimAtMaxDepthAlreadyResolved_reverts() (gas: 586606) -FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9776) -FaultDisputeGame_Test:test_resolve_outOfOrderResolution_reverts() (gas: 308993) -FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 139119) -FaultDisputeGame_Test:test_resolve_rootUncontestedButUnresolved_reverts() (gas: 15980) -FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 18428) -FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 51484) -FaultDisputeGame_Test:test_resolve_stepReached_succeeds() (gas: 498483) -FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 443381) -FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8232) +FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594294) +FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23200) +FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13325) +FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 147396) +FaultDisputeGame_Test:test_move_duplicateClaimsDifferentSubgames_succeeds() (gas: 556844) +FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 585884) +FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 11019) +FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24674) +FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 152017) +FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 269483) +FaultDisputeGame_Test:test_resolve_claimAlreadyResolved_reverts() (gas: 272368) +FaultDisputeGame_Test:test_resolve_claimAtMaxDepthAlreadyResolved_reverts() (gas: 586621) +FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9785) +FaultDisputeGame_Test:test_resolve_outOfOrderResolution_reverts() (gas: 309002) +FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 139125) +FaultDisputeGame_Test:test_resolve_rootUncontestedButUnresolved_reverts() (gas: 15923) +FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 18431) +FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 51487) +FaultDisputeGame_Test:test_resolve_stepReached_succeeds() (gas: 498467) +FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 443396) +FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8247) FeeVault_Test:test_constructor_baseFeeVault_succeeds() (gas: 17428) FeeVault_Test:test_constructor_l1FeeVault_succeeds() (gas: 17396) -GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354398) -GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952696) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 544879) +GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354511) +GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952674) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 544927) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4057119) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 446307) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 446161) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3491910) -GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 45340) +GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 45337) GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 88797) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68343) -GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68922) -GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143347) -GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8392) +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68320) +GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68973) +GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143295) +GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8348) GasPriceOracle_Test:test_decimals_succeeds() (gas: 6234) GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8340) -GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10657) -GasPriceOracle_Test:test_overhead_succeeds() (gas: 10637) -GasPriceOracle_Test:test_scalar_succeeds() (gas: 10722) -GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5956) -GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5976) -GovernanceToken_Test:test_approve_succeeds() (gas: 138023) -GovernanceToken_Test:test_burnFrom_succeeds() (gas: 127582) -GovernanceToken_Test:test_burn_succeeds() (gas: 119070) -GovernanceToken_Test:test_constructor_succeeds() (gas: 23693) +GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10724) +GasPriceOracle_Test:test_overhead_succeeds() (gas: 10681) +GasPriceOracle_Test:test_scalar_succeeds() (gas: 10678) +GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5934) +GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5954) +GovernanceToken_Test:test_approve_succeeds() (gas: 138001) +GovernanceToken_Test:test_burnFrom_succeeds() (gas: 127560) +GovernanceToken_Test:test_burn_succeeds() (gas: 119092) +GovernanceToken_Test:test_constructor_succeeds() (gas: 23757) GovernanceToken_Test:test_decreaseAllowance_succeeds() (gas: 141912) -GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 142022) -GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 21355) +GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 142066) +GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 21421) GovernanceToken_Test:test_mint_fromOwner_succeeds() (gas: 110895) -GovernanceToken_Test:test_transferFrom_succeeds() (gas: 151340) -GovernanceToken_Test:test_transfer_succeeds() (gas: 142867) +GovernanceToken_Test:test_transferFrom_succeeds() (gas: 151318) +GovernanceToken_Test:test_transfer_succeeds() (gas: 142845) Hashing_hashDepositSource_Test:test_hashDepositSource_succeeds() (gas: 700) -Initializer_Test:test_cannotReinitializeL1_succeeds() (gas: 101013) +Initializer_Test:test_cannotReinitializeL1_succeeds() (gas: 101030) L1BlockNumberTest:test_fallback_succeeds() (gas: 18655) L1BlockNumberTest:test_getL1BlockNumber_succeeds() (gas: 10625) L1BlockNumberTest:test_receive_succeeds() (gas: 25384) -L1BlockTest:test_basefee_succeeds() (gas: 7576) -L1BlockTest:test_hash_succeeds() (gas: 7671) -L1BlockTest:test_number_succeeds() (gas: 7651) +L1BlockTest:test_basefee_succeeds() (gas: 7599) +L1BlockTest:test_hash_succeeds() (gas: 7738) +L1BlockTest:test_number_succeeds() (gas: 7674) L1BlockTest:test_sequenceNumber_succeeds() (gas: 7676) -L1BlockTest:test_timestamp_succeeds() (gas: 7685) -L1BlockTest:test_updateValues_succeeds() (gas: 60549) +L1BlockTest:test_timestamp_succeeds() (gas: 7663) +L1BlockTest:test_updateValues_succeeds() (gas: 63327) L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24803) -L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49430) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 239747) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 233439) -L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 126367) -L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 79600) -L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 227457) -L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 76613) -L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 60802) -L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12410) -L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 33134) -L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 392982) -L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1669266) -L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 87934) +L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49407) +L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 239750) +L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 233442) +L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 126347) +L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 79644) +L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 227503) +L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 76636) +L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 60822) +L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12388) +L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 33178) +L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 392934) +L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1669270) +L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 87957) L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24282) -L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62734) -L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37330) -L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 455331) -L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 71019) -L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35761) -L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60608) -L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35185) -L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 455030) -L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70867) +L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62759) +L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37376) +L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 455270) +L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 71000) +L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35752) +L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60589) +L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35188) +L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 455010) +L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70870) L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 18927) L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 29495) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27242) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23283) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 25013) -L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 425310) -L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 517246) -L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 504475) -L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 723482) -L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 721016) -L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 24968) -L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 517343) -L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 504614) +L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27239) +L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23305) +L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 25035) +L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 425309) +L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 517214) +L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 504458) +L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 723450) +L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 720986) +L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 24955) +L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 517311) +L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 504597) L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 43427) -L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 57852) -L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 40313) -L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 40464) -L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 40350) -L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 503477) -L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 37194) -L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 37883) -L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 70086) +L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 57849) +L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 40320) +L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 40461) +L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 40347) +L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 503457) +L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 37182) +L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 37849) +L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 70062) L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 32693) L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 30416) -L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 617714) +L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 617691) L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8521) -L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 191123) +L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 191101) L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48936) L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 31159) -L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11712) +L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11756) L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 124025) -L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135857) +L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135887) L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 49311) L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10686) -L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 26476) +L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 26498) L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 21837) -L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 152170) +L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 152123) L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 29472) -L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 22228) +L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 22216) L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 24332) L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 19674) -L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 149761) +L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 149764) L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 29304) -L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 14638) +L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 14660) L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 33650) L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 241398) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 22196) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 18260) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 22091) -L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 174492) +L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 22193) +L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 18282) +L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 22113) +L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 174514) L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 32612) L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 56622) -L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 24804) -L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 26357) +L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 24782) +L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 26380) L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 191207) L2OutputOracle_constructor_Test:test_constructor_l2BlockTimeZero_reverts() (gas: 44322) -L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 44398) +L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 44354) L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 61377) L2OutputOracle_constructor_Test:test_initialize_badTimestamp_reverts() (gas: 12388) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 226802) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 118576) -L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 21030) +L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 226825) +L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 118642) +L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 21053) L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_nonExistent_reverts() (gas: 117047) -L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 318177) -L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 193280) -L2OutputOracle_getter_Test:test_computeL2Timestamp_succeeds() (gas: 44531) +L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 318242) +L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 193258) +L2OutputOracle_getter_Test:test_computeL2Timestamp_succeeds() (gas: 44553) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 277477) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17960) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 103519) @@ -266,7 +267,7 @@ L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: L2OutputOracle_getter_Test:test_getL2Output_succeeds() (gas: 109954) L2OutputOracle_getter_Test:test_latestBlockNumber_succeeds() (gas: 104504) L2OutputOracle_getter_Test:test_nextBlockNumber_succeeds() (gas: 17492) -L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 34143) +L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 34166) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_futureTimetamp_reverts() (gas: 34240) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_notProposer_reverts() (gas: 26076) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 109323) @@ -274,32 +275,32 @@ L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unexpectedBlockNumber_r L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 34946) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_wrongFork_reverts() (gas: 34466) L2OutputOracle_proposeL2Output_Test:test_proposeWithBlockhashAndHeight_succeeds() (gas: 100845) -L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 392348) -L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 392599) -L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 387993) -L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 396266) -L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 396611) -L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251910) -L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 388275) -L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 26215) -L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 26425) -L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 26230) -L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 96161) -L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 95024) -L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 45613) +L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 392327) +L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 392560) +L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 387960) +L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 396237) +L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 396580) +L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251901) +L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 388241) +L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 26200) +L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 26422) +L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 26227) +L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 96126) +L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 95023) +L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 45610) L2StandardBridge_Test:test_initialize_succeeds() (gas: 28938) -L2StandardBridge_Test:test_receive_succeeds() (gas: 177159) -L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 143423) -L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16587) -LegacyERC20ETH_Test:test_approve_doesNotExist_reverts() (gas: 10804) -LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10676) -LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6422) -LegacyERC20ETH_Test:test_decreaseAllowance_doesNotExist_reverts() (gas: 10739) -LegacyERC20ETH_Test:test_increaseAllowance_doesNotExist_reverts() (gas: 10749) -LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15773) -LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10709) -LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12970) -LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10793) +L2StandardBridge_Test:test_receive_succeeds() (gas: 177147) +L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 143411) +L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16586) +LegacyERC20ETH_Test:test_approve_doesNotExist_reverts() (gas: 10745) +LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10705) +LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6400) +LegacyERC20ETH_Test:test_decreaseAllowance_doesNotExist_reverts() (gas: 10747) +LegacyERC20ETH_Test:test_increaseAllowance_doesNotExist_reverts() (gas: 10757) +LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15795) +LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10672) +LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 13002) +LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10801) LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34629) LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689) LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8531) @@ -331,79 +332,79 @@ LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_rever LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954) MIPS_Test:test_add_succeeds() (gas: 123021) MIPS_Test:test_addiSign_succeeds() (gas: 122946) -MIPS_Test:test_addi_succeeds() (gas: 123144) -MIPS_Test:test_addu_succeeds() (gas: 122975) -MIPS_Test:test_addui_succeeds() (gas: 123206) -MIPS_Test:test_and_succeeds() (gas: 122994) -MIPS_Test:test_andi_succeeds() (gas: 122971) +MIPS_Test:test_addi_succeeds() (gas: 123166) +MIPS_Test:test_addu_succeeds() (gas: 123041) +MIPS_Test:test_addui_succeeds() (gas: 123162) +MIPS_Test:test_and_succeeds() (gas: 123017) +MIPS_Test:test_andi_succeeds() (gas: 122949) MIPS_Test:test_beq_succeeds() (gas: 203427) -MIPS_Test:test_bgez_succeeds() (gas: 122287) -MIPS_Test:test_bgtz_succeeds() (gas: 122164) -MIPS_Test:test_blez_succeeds() (gas: 122186) -MIPS_Test:test_bltz_succeeds() (gas: 122284) -MIPS_Test:test_bne_succeeds() (gas: 122329) -MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86558) -MIPS_Test:test_brk_succeeds() (gas: 122588) +MIPS_Test:test_bgez_succeeds() (gas: 122265) +MIPS_Test:test_bgtz_succeeds() (gas: 122205) +MIPS_Test:test_blez_succeeds() (gas: 122142) +MIPS_Test:test_bltz_succeeds() (gas: 122262) +MIPS_Test:test_bne_succeeds() (gas: 122351) +MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86536) +MIPS_Test:test_brk_succeeds() (gas: 122655) MIPS_Test:test_clo_succeeds() (gas: 122707) MIPS_Test:test_clone_succeeds() (gas: 122563) -MIPS_Test:test_clz_succeeds() (gas: 123199) +MIPS_Test:test_clz_succeeds() (gas: 123177) MIPS_Test:test_div_succeeds() (gas: 123134) -MIPS_Test:test_divu_succeeds() (gas: 123164) -MIPS_Test:test_exit_succeeds() (gas: 122634) -MIPS_Test:test_fcntl_succeeds() (gas: 204864) -MIPS_Test:test_illegal_instruction_fails() (gas: 91978) -MIPS_Test:test_invalid_root_fails() (gas: 436238) -MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121250) -MIPS_Test:test_jal_succeeds() (gas: 121239) +MIPS_Test:test_divu_succeeds() (gas: 123142) +MIPS_Test:test_exit_succeeds() (gas: 122657) +MIPS_Test:test_fcntl_succeeds() (gas: 204842) +MIPS_Test:test_illegal_instruction_fails() (gas: 92045) +MIPS_Test:test_invalid_root_fails() (gas: 436216) +MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121273) +MIPS_Test:test_jal_succeeds() (gas: 121217) MIPS_Test:test_jalr_succeeds() (gas: 122425) -MIPS_Test:test_jr_succeeds() (gas: 122140) -MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85861) -MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120994) -MIPS_Test:test_jump_succeeds() (gas: 120991) +MIPS_Test:test_jr_succeeds() (gas: 122096) +MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85928) +MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120972) +MIPS_Test:test_jump_succeeds() (gas: 120969) MIPS_Test:test_lb_succeeds() (gas: 128187) -MIPS_Test:test_lbu_succeeds() (gas: 128107) -MIPS_Test:test_lh_succeeds() (gas: 128251) -MIPS_Test:test_lhu_succeeds() (gas: 128125) -MIPS_Test:test_ll_succeeds() (gas: 128347) -MIPS_Test:test_lui_succeeds() (gas: 122228) +MIPS_Test:test_lbu_succeeds() (gas: 128085) +MIPS_Test:test_lh_succeeds() (gas: 128229) +MIPS_Test:test_lhu_succeeds() (gas: 128103) +MIPS_Test:test_ll_succeeds() (gas: 128303) +MIPS_Test:test_lui_succeeds() (gas: 122293) MIPS_Test:test_lw_succeeds() (gas: 127976) -MIPS_Test:test_lwl_succeeds() (gas: 243138) -MIPS_Test:test_lwr_succeeds() (gas: 243427) +MIPS_Test:test_lwl_succeeds() (gas: 243161) +MIPS_Test:test_lwr_succeeds() (gas: 243428) MIPS_Test:test_mfhi_succeeds() (gas: 122634) MIPS_Test:test_mflo_succeeds() (gas: 122718) -MIPS_Test:test_mmap_succeeds() (gas: 119636) +MIPS_Test:test_mmap_succeeds() (gas: 119637) MIPS_Test:test_movn_succeeds() (gas: 204054) -MIPS_Test:test_movz_succeeds() (gas: 203900) -MIPS_Test:test_mthi_succeeds() (gas: 122634) +MIPS_Test:test_movz_succeeds() (gas: 203923) +MIPS_Test:test_mthi_succeeds() (gas: 122678) MIPS_Test:test_mtlo_succeeds() (gas: 122741) -MIPS_Test:test_mul_succeeds() (gas: 122278) -MIPS_Test:test_mult_succeeds() (gas: 122915) -MIPS_Test:test_multu_succeeds() (gas: 122995) -MIPS_Test:test_nor_succeeds() (gas: 123087) -MIPS_Test:test_or_succeeds() (gas: 123046) +MIPS_Test:test_mul_succeeds() (gas: 122256) +MIPS_Test:test_mult_succeeds() (gas: 122959) +MIPS_Test:test_multu_succeeds() (gas: 123018) +MIPS_Test:test_nor_succeeds() (gas: 123109) +MIPS_Test:test_or_succeeds() (gas: 123024) MIPS_Test:test_ori_succeeds() (gas: 123026) MIPS_Test:test_preimage_read_succeeds() (gas: 235502) MIPS_Test:test_preimage_write_succeeds() (gas: 127574) -MIPS_Test:test_prestate_exited_succeeds() (gas: 113834) +MIPS_Test:test_prestate_exited_succeeds() (gas: 113835) MIPS_Test:test_sb_succeeds() (gas: 161547) MIPS_Test:test_sc_succeeds() (gas: 161752) -MIPS_Test:test_sh_succeeds() (gas: 161628) -MIPS_Test:test_sll_succeeds() (gas: 122260) -MIPS_Test:test_sllv_succeeds() (gas: 122424) -MIPS_Test:test_slt_succeeds() (gas: 205272) +MIPS_Test:test_sh_succeeds() (gas: 161606) +MIPS_Test:test_sll_succeeds() (gas: 122238) +MIPS_Test:test_sllv_succeeds() (gas: 122402) +MIPS_Test:test_slt_succeeds() (gas: 205250) MIPS_Test:test_sltu_succeeds() (gas: 123285) -MIPS_Test:test_sra_succeeds() (gas: 122490) +MIPS_Test:test_sra_succeeds() (gas: 122468) MIPS_Test:test_srav_succeeds() (gas: 122758) MIPS_Test:test_srl_succeeds() (gas: 122276) MIPS_Test:test_srlv_succeeds() (gas: 122506) MIPS_Test:test_step_abi_succeeds() (gas: 58532) -MIPS_Test:test_sub_succeeds() (gas: 123029) -MIPS_Test:test_subu_succeeds() (gas: 123092) -MIPS_Test:test_sw_succeeds() (gas: 161626) -MIPS_Test:test_swl_succeeds() (gas: 161643) -MIPS_Test:test_swr_succeeds() (gas: 161718) +MIPS_Test:test_sub_succeeds() (gas: 123007) +MIPS_Test:test_subu_succeeds() (gas: 123070) +MIPS_Test:test_sw_succeeds() (gas: 161604) +MIPS_Test:test_swl_succeeds() (gas: 161621) +MIPS_Test:test_swr_succeeds() (gas: 161696) MIPS_Test:test_xor_succeeds() (gas: 123029) -MIPS_Test:test_xori_succeeds() (gas: 123082) +MIPS_Test:test_xori_succeeds() (gas: 123147) MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5733) MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889) MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35845) @@ -425,77 +426,77 @@ MerkleTrie_get_Test:test_get_validProof9_succeeds() (gas: 48802) MerkleTrie_get_Test:test_get_wrongKeyProof_reverts() (gas: 50730) MerkleTrie_get_Test:test_get_zeroBranchValueLength_reverts() (gas: 41684) MerkleTrie_get_Test:test_get_zeroLengthKey_reverts() (gas: 3632) -MintManager_constructor_Test:test_constructor_succeeds() (gas: 10645) -MintManager_mint_Test:test_mint_afterPeriodElapsed_succeeds() (gas: 148140) -MintManager_mint_Test:test_mint_beforePeriodElapsed_reverts() (gas: 140523) -MintManager_mint_Test:test_mint_fromNotOwner_reverts() (gas: 11010) +MintManager_constructor_Test:test_constructor_succeeds() (gas: 10623) +MintManager_mint_Test:test_mint_afterPeriodElapsed_succeeds() (gas: 148184) +MintManager_mint_Test:test_mint_beforePeriodElapsed_reverts() (gas: 140479) +MintManager_mint_Test:test_mint_fromNotOwner_reverts() (gas: 11054) MintManager_mint_Test:test_mint_fromOwner_succeeds() (gas: 137330) MintManager_mint_Test:test_mint_moreThanCap_reverts() (gas: 142590) MintManager_upgrade_Test:test_upgrade_fromNotOwner_reverts() (gas: 11041) MintManager_upgrade_Test:test_upgrade_fromOwner_succeeds() (gas: 23509) MintManager_upgrade_Test:test_upgrade_toZeroAddress_reverts() (gas: 11070) Multichain:test_script_succeeds() (gas: 3078) -OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7717) -OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11180) -OptimismMintableERC20_Test:test_burn_succeeds() (gas: 51074) +OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7695) +OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11209) +OptimismMintableERC20_Test:test_burn_succeeds() (gas: 51050) OptimismMintableERC20_Test:test_erc165_supportsInterface_succeeds() (gas: 7832) OptimismMintableERC20_Test:test_l1Token_succeeds() (gas: 7717) OptimismMintableERC20_Test:test_l2Bridge_succeeds() (gas: 7672) OptimismMintableERC20_Test:test_legacy_succeeds() (gas: 14518) -OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11224) -OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63604) -OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7740) +OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11187) +OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63633) +OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7718) OptimismMintableERC721Factory_Test:test_constructor_succeeds() (gas: 8402) OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_sameTwice_reverts() (gas: 8937393460516800078) -OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316545) +OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316523) OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_zeroRemoteToken_reverts() (gas: 9542) -OptimismMintableERC721_Test:test_burn_notBridge_reverts() (gas: 136997) -OptimismMintableERC721_Test:test_burn_succeeds() (gas: 118933) +OptimismMintableERC721_Test:test_burn_notBridge_reverts() (gas: 136967) +OptimismMintableERC721_Test:test_burn_succeeds() (gas: 118874) OptimismMintableERC721_Test:test_constructor_succeeds() (gas: 24516) -OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11224) -OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140614) -OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9050) -OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163620) -OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 9812) -OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1142649) +OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11209) +OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140599) +OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9028) +OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163605) +OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 9856) +OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1142627) OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9621) OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516764416) OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1142596) OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 14593) -OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16211) -OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26775) -OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 186062) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178756) +OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16206) +OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26711) +OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 186086) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178734) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 182285) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41781) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 173977) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 174020) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 181245) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 154807) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 154785) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 219305) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 220984) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 220962) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 38751) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 209680) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 209658) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696162678) -OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 171324) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85828) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111318) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52951) +OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 171369) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85806) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111361) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52996) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 58892) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 297539) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227597) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227641) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166744) -OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154431) +OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154475) OptimismPortal_Test:test_constructor_succeeds() (gas: 33454) -OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14283) -OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512202) -OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14550) +OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14300) +OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512218) +OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14556) OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127617) -OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17643) +OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17639) OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 24487) OptimismPortal_Test:test_pause_succeeds() (gas: 27329) -OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 40906) -OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31558) -OptimismPortal_Test:test_unpause_succeeds() (gas: 27372) +OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 40883) +OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31580) +OptimismPortal_Test:test_unpause_succeeds() (gas: 27349) OptimistAllowlistTest:test_constructor_succeeds() (gas: 16407) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49650) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49254) @@ -549,10 +550,10 @@ PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 76076) PreimageOracle_Test:test_loadLocalData_multipleContexts_succeeds() (gas: 147718) PreimageOracle_Test:test_loadLocalData_onePart_succeeds() (gas: 75905) PreimageOracle_Test:test_loadLocalData_outOfBoundsOffset_reverts() (gas: 8882) -ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 41635) -ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 45046) -ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15553) -ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15565) +ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 41623) +ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 45024) +ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15531) +ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15587) ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 36440) ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15675) ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51084) @@ -669,25 +670,25 @@ SequencerFeeVault_Test:test_receive_succeeds() (gas: 17395) SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9399) SequencerFeeVault_Test:test_withdraw_toL1_succeeds() (gas: 618343) SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11595) -StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 50168) -StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33117) +StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 50181) +StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33142) Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31510, ~: 31821) Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31598, ~: 31598) Storage_Roundtrip_Test:test_setGetUint_succeeds(bytes32,uint256) (runs: 64, μ: 30731, ~: 31664) -SystemConfig_Initialize_Test:test_initialize_events_succeeds() (gas: 88186) -SystemConfig_Initialize_Test:test_initialize_startBlockNoop_reverts() (gas: 77159) +SystemConfig_Initialize_Test:test_initialize_events_succeeds() (gas: 88188) +SystemConfig_Initialize_Test:test_initialize_startBlockNoop_reverts() (gas: 77253) SystemConfig_Initialize_Test:test_initialize_startBlockOverride_succeeds() (gas: 81116) -SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 88523) +SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 88501) SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 59900) -SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 15652) +SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 15675) SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 15644) SystemConfig_Setters_TestFail:test_setGasLimit_notOwner_reverts() (gas: 15743) -SystemConfig_Setters_TestFail:test_setResourceConfig_badMinMax_reverts() (gas: 18614) -SystemConfig_Setters_TestFail:test_setResourceConfig_badPrecision_reverts() (gas: 21194) -SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas: 22242) -SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 16844) +SystemConfig_Setters_TestFail:test_setResourceConfig_badMinMax_reverts() (gas: 18592) +SystemConfig_Setters_TestFail:test_setResourceConfig_badPrecision_reverts() (gas: 21216) +SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas: 22264) +SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 16867) SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 18629) -SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 15657) +SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 15658) TransactorTest:test_call_succeeds() (gas: 26709) TransactorTest:test_call_unauthorized_reverts() (gas: 18117) TransactorTest:test_constructor_succeeds() (gas: 9739) From ae85ba8765cd819c2bdb9a3fcf46156460367869 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 6 Nov 2023 18:49:56 +0300 Subject: [PATCH 363/374] invariant-docs: regenerate --- .../contracts-bedrock/invariant-docs/CrossDomainMessenger.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md b/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md index 3fae2cddfa87..95ed2ffdfc19 100644 --- a/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md +++ b/packages/contracts-bedrock/invariant-docs/CrossDomainMessenger.md @@ -1,14 +1,14 @@ # `CrossDomainMessenger` Invariants ## A call to `relayMessage` should succeed if at least the minimum gas limit can be supplied to the target context, there is enough gas to complete execution of `relayMessage` after the target context's execution is finished, and the target context did not revert. -**Test:** [`CrossDomainMessenger.t.sol#L136`](../test/invariants/CrossDomainMessenger.t.sol#L136) +**Test:** [`CrossDomainMessenger.t.sol#L137`](../test/invariants/CrossDomainMessenger.t.sol#L137) There are two minimum gas limits here: - The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit. - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target contract. ## A call to `relayMessage` should assign the message hash to the `failedMessages` mapping if not enough gas is supplied to forward `minGasLimit` to the target context or if there is not enough gas to complete execution of `relayMessage` after the target context's execution is finished. -**Test:** [`CrossDomainMessenger.t.sol#L169`](../test/invariants/CrossDomainMessenger.t.sol#L169) +**Test:** [`CrossDomainMessenger.t.sol#L170`](../test/invariants/CrossDomainMessenger.t.sol#L170) There are two minimum gas limits here: - The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit. From 4f2aaa3a4ff1356c95bc55da30803068075608f7 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 6 Nov 2023 22:51:56 +0300 Subject: [PATCH 364/374] contracts-bedrock: fix review nits --- .../contracts-bedrock/test/setup/Setup.sol | 73 ++++++++----------- 1 file changed, 30 insertions(+), 43 deletions(-) diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 0146ac82d0fc..191176843d43 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -45,19 +45,19 @@ contract Setup is Deploy { OptimismMintableERC20Factory l1OptimismMintableERC20Factory; ProtocolVersions protocolVersions; - L2CrossDomainMessenger l2CrossDomainMessenger; - L2StandardBridge l2StandardBridge; - L2ToL1MessagePasser l2ToL1MessagePasser; - OptimismMintableERC20Factory l2OptimismMintableERC20Factory; - L2ERC721Bridge l2ERC721Bridge; - BaseFeeVault baseFeeVault; - SequencerFeeVault sequencerFeeVault; - L1FeeVault l1FeeVault; - GasPriceOracle gasPriceOracle; - L1Block l1Block; - LegacyMessagePasser legacyMessagePasser; - GovernanceToken governanceToken; - LegacyERC20ETH legacyERC20ETH; + L2CrossDomainMessenger l2CrossDomainMessenger = L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); + L2StandardBridge l2StandardBridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)); + L2ToL1MessagePasser l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); + OptimismMintableERC20Factory l2OptimismMintableERC20Factory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); + L2ERC721Bridge l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); + BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); + SequencerFeeVault sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); + L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); + GasPriceOracle gasPriceOracle = GasPriceOracle(Predeploys.GAS_PRICE_ORACLE); + L1Block l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); + LegacyMessagePasser legacyMessagePasser = LegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); + GovernanceToken governanceToken = GovernanceToken(Predeploys.GOVERNANCE_TOKEN); + LegacyERC20ETH legacyERC20ETH = LegacyERC20ETH(Predeploys.LEGACY_ERC20_ETH); function setUp() public virtual override { Deploy.setUp(); @@ -108,73 +108,60 @@ contract Setup is Deploy { function L2(DeployConfig cfg) public { // Set up L2. There are currently no proxies set in the L2 initialization. vm.etch( - Predeploys.L2_CROSS_DOMAIN_MESSENGER, + address(l2CrossDomainMessenger), address(new L2CrossDomainMessenger(address(l1CrossDomainMessenger))).code ); - l2CrossDomainMessenger = L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); l2CrossDomainMessenger.initialize(); - vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code); - l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); + vm.etch(address(l2ToL1MessagePasser), address(new L2ToL1MessagePasser()).code); vm.etch( - Predeploys.L2_STANDARD_BRIDGE, address(new L2StandardBridge(StandardBridge(payable(l1StandardBridge)))).code + address(l2StandardBridge), address(new L2StandardBridge(StandardBridge(payable(l1StandardBridge)))).code ); - l2StandardBridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)); l2StandardBridge.initialize(); - vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(new OptimismMintableERC20Factory()).code); - l2OptimismMintableERC20Factory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); - l2OptimismMintableERC20Factory.initialize(Predeploys.L2_STANDARD_BRIDGE); + vm.etch(address(l2OptimismMintableERC20Factory), address(new OptimismMintableERC20Factory()).code); + l2OptimismMintableERC20Factory.initialize(address(l2StandardBridge)); - vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code); - legacyERC20ETH = LegacyERC20ETH(Predeploys.LEGACY_ERC20_ETH); + vm.etch(address(legacyERC20ETH), address(new LegacyERC20ETH()).code); - vm.etch(Predeploys.L2_ERC721_BRIDGE, address(new L2ERC721Bridge(address(l1ERC721Bridge))).code); - l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); + vm.etch(address(l2ERC721Bridge), address(new L2ERC721Bridge(address(l1ERC721Bridge))).code); l2ERC721Bridge.initialize(); vm.etch( - Predeploys.SEQUENCER_FEE_WALLET, + address(sequencerFeeVault), address( new SequencerFeeVault(cfg.sequencerFeeVaultRecipient(), cfg.sequencerFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2) ).code ); vm.etch( - Predeploys.BASE_FEE_VAULT, + address(baseFeeVault), address( new BaseFeeVault(cfg.baseFeeVaultRecipient(), cfg.baseFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L1) ).code ); vm.etch( - Predeploys.L1_FEE_VAULT, + address(l1FeeVault), address( new L1FeeVault(cfg.l1FeeVaultRecipient(), cfg.l1FeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2) ).code ); - sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); - baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); - l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); + vm.etch(address(l1Block), address(new L1Block()).code); - vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code); - l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); + vm.etch(address(gasPriceOracle), address(new GasPriceOracle()).code); - vm.etch(Predeploys.GAS_PRICE_ORACLE, address(new GasPriceOracle()).code); - gasPriceOracle = GasPriceOracle(Predeploys.GAS_PRICE_ORACLE); + vm.etch(address(legacyMessagePasser), address(new LegacyMessagePasser()).code); - vm.etch(Predeploys.LEGACY_MESSAGE_PASSER, address(new LegacyMessagePasser()).code); - legacyMessagePasser = LegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); - - vm.etch(Predeploys.GOVERNANCE_TOKEN, address(new GovernanceToken()).code); - governanceToken = GovernanceToken(Predeploys.GOVERNANCE_TOKEN); + vm.etch(address(governanceToken), address(new GovernanceToken()).code); + // Set the ERC20 token name and symbol vm.store( - Predeploys.GOVERNANCE_TOKEN, + address(governanceToken), bytes32(uint256(3)), bytes32(0x4f7074696d69736d000000000000000000000000000000000000000000000010) ); vm.store( - Predeploys.GOVERNANCE_TOKEN, + address(governanceToken), bytes32(uint256(4)), bytes32(0x4f50000000000000000000000000000000000000000000000000000000000004) ); From cef1a2443f77906f40eb39f620b2f526f1f3e8b4 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 6 Nov 2023 23:30:06 +0300 Subject: [PATCH 365/374] contracts-bedrock: lint --- packages/contracts-bedrock/test/setup/Setup.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 191176843d43..2e4dae080c63 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -45,10 +45,12 @@ contract Setup is Deploy { OptimismMintableERC20Factory l1OptimismMintableERC20Factory; ProtocolVersions protocolVersions; - L2CrossDomainMessenger l2CrossDomainMessenger = L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); + L2CrossDomainMessenger l2CrossDomainMessenger = + L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); L2StandardBridge l2StandardBridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)); L2ToL1MessagePasser l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); - OptimismMintableERC20Factory l2OptimismMintableERC20Factory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); + OptimismMintableERC20Factory l2OptimismMintableERC20Factory = + OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); L2ERC721Bridge l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); SequencerFeeVault sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET)); @@ -108,8 +110,7 @@ contract Setup is Deploy { function L2(DeployConfig cfg) public { // Set up L2. There are currently no proxies set in the L2 initialization. vm.etch( - address(l2CrossDomainMessenger), - address(new L2CrossDomainMessenger(address(l1CrossDomainMessenger))).code + address(l2CrossDomainMessenger), address(new L2CrossDomainMessenger(address(l1CrossDomainMessenger))).code ); l2CrossDomainMessenger.initialize(); From 2eaa9c4468a5618056c824df6be6dfb7b62b6cc7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 21:27:44 +0000 Subject: [PATCH 366/374] build(deps): bump viem from 1.18.4 to 1.18.6 Bumps [viem](https://github.com/wagmi-dev/viem) from 1.18.4 to 1.18.6. - [Release notes](https://github.com/wagmi-dev/viem/releases) - [Commits](https://github.com/wagmi-dev/viem/compare/viem@1.18.4...viem@1.18.6) --- updated-dependencies: - dependency-name: viem dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/contracts-ts/package.json | 2 +- packages/fee-estimation/package.json | 2 +- packages/sdk/package.json | 2 +- packages/web3js-plugin/package.json | 2 +- pnpm-lock.yaml | 62 ++++++++++++++-------------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/contracts-ts/package.json b/packages/contracts-ts/package.json index 0873431b421d..a77d27227442 100644 --- a/packages/contracts-ts/package.json +++ b/packages/contracts-ts/package.json @@ -82,6 +82,6 @@ "change-case": "4.1.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "viem": "^1.18.4" + "viem": "^1.18.6" } } diff --git a/packages/fee-estimation/package.json b/packages/fee-estimation/package.json index 25d229db84a6..616f42e1ed14 100644 --- a/packages/fee-estimation/package.json +++ b/packages/fee-estimation/package.json @@ -44,7 +44,7 @@ "jsdom": "^22.1.0", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.18.4", + "viem": "^1.18.6", "vite": "^4.5.0", "vitest": "^0.34.2" }, diff --git a/packages/sdk/package.json b/packages/sdk/package.json index b1cd2122d1ce..afef1c23984f 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -56,7 +56,7 @@ "ts-node": "^10.9.1", "typedoc": "^0.25.3", "typescript": "^5.2.2", - "viem": "^1.18.4", + "viem": "^1.18.6", "vitest": "^0.34.2", "zod": "^3.22.4" }, diff --git a/packages/web3js-plugin/package.json b/packages/web3js-plugin/package.json index 5743c09969ab..aad802334e52 100644 --- a/packages/web3js-plugin/package.json +++ b/packages/web3js-plugin/package.json @@ -37,7 +37,7 @@ "@vitest/coverage-istanbul": "^0.34.6", "tsup": "^7.2.0", "typescript": "^5.2.2", - "viem": "^1.18.4", + "viem": "^1.18.6", "vite": "^4.5.0", "vitest": "^0.34.1", "zod": "^3.22.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d0895ffb6807..cc45b0d4c3d3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -298,11 +298,11 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) viem: - specifier: ^1.18.4 - version: 1.18.4(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.6 + version: 1.18.6(typescript@5.2.2)(zod@3.22.4) wagmi: specifier: '>1.0.0' - version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) + version: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.6) devDependencies: '@eth-optimism/contracts-bedrock': specifier: workspace:* @@ -324,7 +324,7 @@ importers: version: 1.5.2(@wagmi/core@1.4.5)(typescript@5.2.2)(wagmi@1.0.1) '@wagmi/core': specifier: ^1.4.5 - version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) + version: 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.6) abitype: specifier: ^0.10.2 version: 0.10.2(typescript@5.2.2) @@ -438,8 +438,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.4 - version: 1.18.4(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.6 + version: 1.18.6(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -529,8 +529,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.4 - version: 1.18.4(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.6 + version: 1.18.6(typescript@5.2.2)(zod@3.22.4) vitest: specifier: ^0.34.2 version: 0.34.2 @@ -569,8 +569,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 viem: - specifier: ^1.18.4 - version: 1.18.4(typescript@5.2.2)(zod@3.22.4) + specifier: ^1.18.6 + version: 1.18.6(typescript@5.2.2)(zod@3.22.4) vite: specifier: ^4.5.0 version: 4.5.0(@types/node@20.8.9) @@ -3197,7 +3197,7 @@ packages: resolution: {integrity: sha512-gYw0ki/EAuV1oSyMxpqandHjnthZjYYy+YWpTAzf8BqfXM3ItcZLpjxfg+3+mXW8HIO+3jw6T9iiqEXsqHaMMw==} dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.7.3 - viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.6(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - bufferutil - encoding @@ -4562,7 +4562,7 @@ packages: wagmi: optional: true dependencies: - '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) + '@wagmi/core': 1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.6) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) abort-controller: 3.0.0 bundle-require: 3.1.2(esbuild@0.16.17) @@ -4584,15 +4584,15 @@ packages: picocolors: 1.0.0 prettier: 2.8.8 typescript: 5.2.2 - viem: 1.18.4(typescript@5.2.2)(zod@3.22.3) - wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) + viem: 1.18.6(typescript@5.2.2)(zod@3.22.3) + wagmi: 1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.6) zod: 3.22.3 transitivePeerDependencies: - bufferutil - utf-8-validate dev: true - /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4): + /@wagmi/connectors@1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.6): resolution: {integrity: sha512-fl01vym19DE1uoE+MlASw5zo3Orr/YXlJRjOKLaKYtV+Q7jOLY4TwHgq7sEMs+JYOvFICFBEAlWNNxidr51AqQ==} peerDependencies: '@wagmi/chains': '>=0.2.0' @@ -4615,7 +4615,7 @@ packages: abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.6(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil @@ -4627,7 +4627,7 @@ packages: - utf-8-validate - zod - /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.4): + /@wagmi/connectors@3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.6): resolution: {integrity: sha512-UgwsQKQDFObJVJMf9pDfFoXTv710o4zrTHyhIWKBTMMkLpCMsMxN5+ZaDhBYt/BgoRinfRYQo8uwuwLhxE6Log==} peerDependencies: typescript: '>=5.0.4' @@ -4647,7 +4647,7 @@ packages: abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.6(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - '@types/react' @@ -4660,7 +4660,7 @@ packages: - zod dev: true - /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.4): + /@wagmi/core@1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.6): resolution: {integrity: sha512-Zzg4Ob92QMF9NsC+z5/8JZjMn3NCCnwVWGJlv79qRX9mp5Ku40OzJNvqDnjcSGjshe6H0L/KtFZAqTlmu8lT7w==} peerDependencies: typescript: '>=4.9.4' @@ -4670,11 +4670,11 @@ packages: optional: true dependencies: '@wagmi/chains': 0.2.22(typescript@5.2.2) - '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) + '@wagmi/connectors': 1.0.1(@wagmi/chains@0.2.22)(react@18.2.0)(typescript@5.2.2)(viem@1.18.6) abitype: 0.8.1(typescript@5.2.2) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.6(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -4688,7 +4688,7 @@ packages: - utf-8-validate - zod - /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.4): + /@wagmi/core@1.4.5(react@18.2.0)(typescript@5.2.2)(viem@1.18.6): resolution: {integrity: sha512-N9luRb1Uk4tBN9kaYcQSWKE9AsRt/rvZaFt5IZech4JPzNN2sQlfhKd9GEjOXYRDqEPHdDvos7qyBKiDNTz4GA==} peerDependencies: typescript: '>=5.0.4' @@ -4697,11 +4697,11 @@ packages: typescript: optional: true dependencies: - '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) + '@wagmi/connectors': 3.1.3(react@18.2.0)(typescript@5.2.2)(viem@1.18.6) abitype: 0.8.7(typescript@5.2.2)(zod@3.22.3) eventemitter3: 4.0.7 typescript: 5.2.2 - viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.6(typescript@5.2.2)(zod@3.22.4) zustand: 4.3.9(react@18.2.0) transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -14292,8 +14292,8 @@ packages: vfile-message: 2.0.4 dev: true - /viem@1.18.4(typescript@5.2.2)(zod@3.22.3): - resolution: {integrity: sha512-im+y30k+IGT6VtfD/q1V0RX5PaiHPsFTHkKqvTjTqV+ZT8RgJXzOGPXr5E0uPIm2cbJAJp6A9nR9BCHY7BKR2Q==} + /viem@1.18.6(typescript@5.2.2)(zod@3.22.3): + resolution: {integrity: sha512-oKkrxF2aqxjJ4pmm0ko7j+ZFRekP6VGIknSroV+6+dF+T31bscltPZwJ0fOJDxCOVhoVtxrKFRTkkasEVDblUA==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14315,8 +14315,8 @@ packages: - zod dev: true - /viem@1.18.4(typescript@5.2.2)(zod@3.22.4): - resolution: {integrity: sha512-im+y30k+IGT6VtfD/q1V0RX5PaiHPsFTHkKqvTjTqV+ZT8RgJXzOGPXr5E0uPIm2cbJAJp6A9nR9BCHY7BKR2Q==} + /viem@1.18.6(typescript@5.2.2)(zod@3.22.4): + resolution: {integrity: sha512-oKkrxF2aqxjJ4pmm0ko7j+ZFRekP6VGIknSroV+6+dF+T31bscltPZwJ0fOJDxCOVhoVtxrKFRTkkasEVDblUA==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -14809,7 +14809,7 @@ packages: xml-name-validator: 4.0.0 dev: true - /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.4): + /wagmi@1.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(viem@1.18.6): resolution: {integrity: sha512-+2UkZG9eA3tKqXj1wvlvI8mL0Bcff7Tf5CKfUOyQsdKcY+J5rfwYYya25G+jja57umpHFtfxRaL7xDkNjehrRg==} peerDependencies: react: '>=17.0.0' @@ -14822,12 +14822,12 @@ packages: '@tanstack/query-sync-storage-persister': 4.29.25 '@tanstack/react-query': 4.29.25(react-dom@18.2.0)(react@18.2.0) '@tanstack/react-query-persist-client': 4.29.25(@tanstack/react-query@4.29.25) - '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.4) + '@wagmi/core': 1.0.1(react@18.2.0)(typescript@5.2.2)(viem@1.18.6) abitype: 0.8.1(typescript@5.2.2) react: 18.2.0 typescript: 5.2.2 use-sync-external-store: 1.2.0(react@18.2.0) - viem: 1.18.4(typescript@5.2.2)(zod@3.22.4) + viem: 1.18.6(typescript@5.2.2)(zod@3.22.4) transitivePeerDependencies: - '@react-native-async-storage/async-storage' - bufferutil From 52d75ba138c56198f4fa06cb90f87d4b02ec769b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 21:33:37 +0000 Subject: [PATCH 367/374] build(deps-dev): bump eslint from 8.52.0 to 8.53.0 Bumps [eslint](https://github.com/eslint/eslint) from 8.52.0 to 8.53.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.52.0...v8.53.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- pnpm-lock.yaml | 268 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 219 insertions(+), 51 deletions(-) diff --git a/package.json b/package.json index 4ef0eea511f8..6270d565dedc 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "chai": "^4.3.10", "depcheck": "^1.4.7", "doctoc": "^2.2.0", - "eslint": "^8.52.0", + "eslint": "^8.53.0", "eslint-config-prettier": "^8.3.0", "eslint-config-standard": "^16.0.3", "eslint-plugin-import": "^2.29.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d0895ffb6807..65340f30e26f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,7 +17,7 @@ importers: devDependencies: '@babel/eslint-parser': specifier: ^7.18.2 - version: 7.22.15(@babel/core@7.22.10)(eslint@8.52.0) + version: 7.22.15(@babel/core@7.22.10)(eslint@8.53.0) '@changesets/changelog-github': specifier: ^0.4.8 version: 0.4.8 @@ -35,10 +35,10 @@ importers: version: 20.8.9 '@typescript-eslint/eslint-plugin': specifier: ^6.9.1 - version: 6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.52.0)(typescript@5.2.2) + version: 6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/parser': specifier: ^6.9.1 - version: 6.9.1(eslint@8.52.0)(typescript@5.2.2) + version: 6.9.1(eslint@8.53.0)(typescript@5.2.2) chai: specifier: ^4.3.10 version: 4.3.10 @@ -49,38 +49,38 @@ importers: specifier: ^2.2.0 version: 2.2.1 eslint: - specifier: ^8.52.0 - version: 8.52.0 + specifier: ^8.53.0 + version: 8.53.0 eslint-config-prettier: specifier: ^8.3.0 - version: 8.3.0(eslint@8.52.0) + version: 8.3.0(eslint@8.53.0) eslint-config-standard: specifier: ^16.0.3 - version: 16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.52.0) + version: 16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.53.0) eslint-plugin-import: specifier: ^2.29.0 - version: 2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.52.0) + version: 2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.53.0) eslint-plugin-jsdoc: specifier: ^35.1.2 - version: 35.5.1(eslint@8.52.0) + version: 35.5.1(eslint@8.53.0) eslint-plugin-node: specifier: ^11.1.0 - version: 11.1.0(eslint@8.52.0) + version: 11.1.0(eslint@8.53.0) eslint-plugin-prefer-arrow: specifier: ^1.2.3 - version: 1.2.3(eslint@8.52.0) + version: 1.2.3(eslint@8.53.0) eslint-plugin-prettier: specifier: ^4.0.0 - version: 4.2.1(eslint-config-prettier@8.3.0)(eslint@8.52.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@8.3.0)(eslint@8.53.0)(prettier@2.8.8) eslint-plugin-promise: specifier: ^5.1.0 - version: 5.2.0(eslint@8.52.0) + version: 5.2.0(eslint@8.53.0) eslint-plugin-react: specifier: ^7.24.0 - version: 7.33.2(eslint@8.52.0) + version: 7.33.2(eslint@8.53.0) eslint-plugin-unicorn: specifier: ^49.0.0 - version: 49.0.0(eslint@8.52.0) + version: 49.0.0(eslint@8.53.0) husky: specifier: ^8.0.3 version: 8.0.3 @@ -638,7 +638,7 @@ packages: - supports-color dev: true - /@babel/eslint-parser@7.22.15(@babel/core@7.22.10)(eslint@8.52.0): + /@babel/eslint-parser@7.22.15(@babel/core@7.22.10)(eslint@8.53.0): resolution: {integrity: sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: @@ -647,7 +647,7 @@ packages: dependencies: '@babel/core': 7.22.10 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 - eslint: 8.52.0 + eslint: 8.53.0 eslint-visitor-keys: 2.1.0 semver: 6.3.1 dev: true @@ -1811,6 +1811,16 @@ packages: eslint-visitor-keys: 3.4.3 dev: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.53.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.53.0 + eslint-visitor-keys: 3.4.3 + dev: true + /@eslint-community/regexpp@4.6.2: resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -1833,11 +1843,33 @@ packages: - supports-color dev: true + /@eslint/eslintrc@2.1.3: + resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4(supports-color@8.1.1) + espree: 9.6.1 + globals: 13.21.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + /@eslint/js@8.52.0: resolution: {integrity: sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@eslint/js@8.53.0: + resolution: {integrity: sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /@eth-optimism/contracts-periphery@1.0.8: resolution: {integrity: sha512-n8a9rmlMxl1lWSiC1zHUlr5Qk6qy85nhsmSgpU12El1WY75MOIPknSTQKj+yJhEmrTtI0PViWlKfgviY09pwUg==} dev: false @@ -4230,6 +4262,35 @@ packages: - supports-color dev: true + /@typescript-eslint/eslint-plugin@6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.53.0)(typescript@5.2.2): + resolution: {integrity: sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.6.2 + '@typescript-eslint/parser': 6.9.1(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.9.1 + '@typescript-eslint/type-utils': 6.9.1(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.9.1(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.9.1 + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.53.0 + graphemer: 1.4.0 + ignore: 5.2.4 + natural-compare: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.1(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/parser@6.9.1(eslint@8.52.0)(typescript@5.2.2): resolution: {integrity: sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4251,6 +4312,27 @@ packages: - supports-color dev: true + /@typescript-eslint/parser@6.9.1(eslint@8.53.0)(typescript@5.2.2): + resolution: {integrity: sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.9.1 + '@typescript-eslint/types': 6.9.1 + '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.9.1 + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.53.0 + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/scope-manager@6.9.1: resolution: {integrity: sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4279,6 +4361,26 @@ packages: - supports-color dev: true + /@typescript-eslint/type-utils@6.9.1(eslint@8.53.0)(typescript@5.2.2): + resolution: {integrity: sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.2.2) + '@typescript-eslint/utils': 6.9.1(eslint@8.53.0)(typescript@5.2.2) + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.53.0 + ts-api-utils: 1.0.1(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/types@6.9.1: resolution: {integrity: sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4324,6 +4426,25 @@ packages: - typescript dev: true + /@typescript-eslint/utils@6.9.1(eslint@8.53.0)(typescript@5.2.2): + resolution: {integrity: sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) + '@types/json-schema': 7.0.12 + '@types/semver': 7.5.0 + '@typescript-eslint/scope-manager': 6.9.1 + '@typescript-eslint/types': 6.9.1 + '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.2.2) + eslint: 8.53.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + /@typescript-eslint/visitor-keys@6.9.1: resolution: {integrity: sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -7457,16 +7578,16 @@ packages: engines: {node: '>=10'} dev: true - /eslint-config-prettier@8.3.0(eslint@8.52.0): + /eslint-config-prettier@8.3.0(eslint@8.53.0): resolution: {integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.52.0 + eslint: 8.53.0 dev: true - /eslint-config-standard@16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.52.0): + /eslint-config-standard@16.0.3(eslint-plugin-import@2.29.0)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.53.0): resolution: {integrity: sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==} peerDependencies: eslint: ^7.12.1 @@ -7474,10 +7595,10 @@ packages: eslint-plugin-node: ^11.1.0 eslint-plugin-promise: ^4.2.1 || ^5.0.0 dependencies: - eslint: 8.52.0 - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.52.0) - eslint-plugin-node: 11.1.0(eslint@8.52.0) - eslint-plugin-promise: 5.2.0(eslint@8.52.0) + eslint: 8.53.0 + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.53.0) + eslint-plugin-node: 11.1.0(eslint@8.53.0) + eslint-plugin-promise: 5.2.0(eslint@8.53.0) dev: true /eslint-import-resolver-node@0.3.9: @@ -7490,7 +7611,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.9)(eslint@8.52.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.9)(eslint@8.53.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -7511,26 +7632,26 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.9.1(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.9.1(eslint@8.53.0)(typescript@5.2.2) debug: 3.2.7 - eslint: 8.52.0 + eslint: 8.53.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-es@3.0.1(eslint@8.52.0): + /eslint-plugin-es@3.0.1(eslint@8.53.0): resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=4.19.1' dependencies: - eslint: 8.52.0 + eslint: 8.53.0 eslint-utils: 2.1.0 regexpp: 3.2.0 dev: true - /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.52.0): + /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.9.1)(eslint@8.53.0): resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==} engines: {node: '>=4'} peerDependencies: @@ -7540,16 +7661,16 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.9.1(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.9.1(eslint@8.53.0)(typescript@5.2.2) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.52.0 + eslint: 8.53.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.9)(eslint@8.52.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.9)(eslint@8.53.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -7565,7 +7686,7 @@ packages: - supports-color dev: true - /eslint-plugin-jsdoc@35.5.1(eslint@8.52.0): + /eslint-plugin-jsdoc@35.5.1(eslint@8.53.0): resolution: {integrity: sha512-pPYPWtsykwVEue1tYEyoppBj4dgF7XicF67tLLLraY6RQYBq7qMKjUHji19+hfiTtYKKBD0YfeK8hgjPAE5viw==} engines: {node: '>=12'} peerDependencies: @@ -7574,7 +7695,7 @@ packages: '@es-joy/jsdoccomment': 0.9.0-alpha.1 comment-parser: 1.1.6-beta.0 debug: 4.3.4(supports-color@8.1.1) - eslint: 8.52.0 + eslint: 8.53.0 esquery: 1.4.0 jsdoc-type-pratt-parser: 1.1.1 lodash: 4.17.21 @@ -7585,14 +7706,14 @@ packages: - supports-color dev: true - /eslint-plugin-node@11.1.0(eslint@8.52.0): + /eslint-plugin-node@11.1.0(eslint@8.53.0): resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=5.16.0' dependencies: - eslint: 8.52.0 - eslint-plugin-es: 3.0.1(eslint@8.52.0) + eslint: 8.53.0 + eslint-plugin-es: 3.0.1(eslint@8.53.0) eslint-utils: 2.1.0 ignore: 5.2.4 minimatch: 3.1.2 @@ -7600,15 +7721,15 @@ packages: semver: 6.3.1 dev: true - /eslint-plugin-prefer-arrow@1.2.3(eslint@8.52.0): + /eslint-plugin-prefer-arrow@1.2.3(eslint@8.53.0): resolution: {integrity: sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==} peerDependencies: eslint: '>=2.0.0' dependencies: - eslint: 8.52.0 + eslint: 8.53.0 dev: true - /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.3.0)(eslint@8.52.0)(prettier@2.8.8): + /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.3.0)(eslint@8.53.0)(prettier@2.8.8): resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -7619,22 +7740,22 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.52.0 - eslint-config-prettier: 8.3.0(eslint@8.52.0) + eslint: 8.53.0 + eslint-config-prettier: 8.3.0(eslint@8.53.0) prettier: 2.8.8 prettier-linter-helpers: 1.0.0 dev: true - /eslint-plugin-promise@5.2.0(eslint@8.52.0): + /eslint-plugin-promise@5.2.0(eslint@8.53.0): resolution: {integrity: sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: eslint: ^7.0.0 dependencies: - eslint: 8.52.0 + eslint: 8.53.0 dev: true - /eslint-plugin-react@7.33.2(eslint@8.52.0): + /eslint-plugin-react@7.33.2(eslint@8.53.0): resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} engines: {node: '>=4'} peerDependencies: @@ -7645,7 +7766,7 @@ packages: array.prototype.tosorted: 1.1.1 doctrine: 2.1.0 es-iterator-helpers: 1.0.13 - eslint: 8.52.0 + eslint: 8.53.0 estraverse: 5.3.0 jsx-ast-utils: 3.2.0 minimatch: 3.1.2 @@ -7659,17 +7780,17 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-unicorn@49.0.0(eslint@8.52.0): + /eslint-plugin-unicorn@49.0.0(eslint@8.53.0): resolution: {integrity: sha512-0fHEa/8Pih5cmzFW5L7xMEfUTvI9WKeQtjmKpTUmY+BiFCDxkxrTdnURJOHKykhtwIeyYsxnecbGvDCml++z4Q==} engines: {node: '>=16'} peerDependencies: eslint: '>=8.52.0' dependencies: '@babel/helper-validator-identifier': 7.22.20 - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) ci-info: 3.8.0 clean-regexp: 1.0.0 - eslint: 8.52.0 + eslint: 8.53.0 esquery: 1.5.0 indent-string: 4.0.0 is-builtin-module: 3.2.1 @@ -7767,6 +7888,53 @@ packages: - supports-color dev: true + /eslint@8.53.0: + resolution: {integrity: sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) + '@eslint-community/regexpp': 4.6.2 + '@eslint/eslintrc': 2.1.3 + '@eslint/js': 8.53.0 + '@humanwhocodes/config-array': 0.11.13 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4(supports-color@8.1.1) + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.21.0 + graphemer: 1.4.0 + ignore: 5.2.4 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + /espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} From 089c977d716f06d198cb495841a4ea2fd70a2793 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 21:42:55 +0000 Subject: [PATCH 368/374] build(deps-dev): bump nx from 17.0.2 to 17.0.3 Bumps [nx](https://github.com/nrwl/nx/tree/HEAD/packages/nx) from 17.0.2 to 17.0.3. - [Release notes](https://github.com/nrwl/nx/releases) - [Commits](https://github.com/nrwl/nx/commits/17.0.3/packages/nx) --- updated-dependencies: - dependency-name: nx dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- pnpm-lock.yaml | 76 +++++++++++++++++++++++++------------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index 4ef0eea511f8..e0421406c717 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "markdownlint": "^0.31.0", "markdownlint-cli2": "0.4.0", "mocha": "^10.2.0", - "nx": "17.0.2", + "nx": "17.0.3", "nyc": "^15.1.0", "patch-package": "^8.0.0", "prettier": "^2.8.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d0895ffb6807..b97267b59d94 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -97,8 +97,8 @@ importers: specifier: ^10.2.0 version: 10.2.0 nx: - specifier: 17.0.2 - version: 17.0.2 + specifier: 17.0.3 + version: 17.0.3 nx-cloud: specifier: latest version: 16.5.2 @@ -2997,11 +2997,11 @@ packages: - debug dev: true - /@nrwl/tao@17.0.2: - resolution: {integrity: sha512-H+htIRzQR6Ibael34rhQkpNkpFFFmaSTsIzdqkBqL4j5+FzSpZh67NJnWSY8vsYQGQL8Ncc+MHvpQC+7pyfgGw==} + /@nrwl/tao@17.0.3: + resolution: {integrity: sha512-X6zcwf6c3z7TuztRJWM/OCfzm7+LI4Uw4coc9+PWr44ohHkgId2wEJTzXrDT3+lvv8DgwPpgWPwqntw+YcgRYg==} hasBin: true dependencies: - nx: 17.0.2 + nx: 17.0.3 tslib: 2.6.2 transitivePeerDependencies: - '@swc-node/register' @@ -3009,8 +3009,8 @@ packages: - debug dev: true - /@nx/nx-darwin-arm64@17.0.2: - resolution: {integrity: sha512-OSZLRfV8VplYPEqMcIg3mbAsJXlXEHKrdlJ0KUTk8Hih2+wl7cxuSEwG7X7qfBUOz+ognxaqicL+hueNrgwjlQ==} + /@nx/nx-darwin-arm64@17.0.3: + resolution: {integrity: sha512-KA75JC/hgkt9qwK4dnN1tlaTXWdYItkNMjji6YjkyAYabbLKQKVcQoPocYP/RB/Gng+vNslXwuug2atgxDf43g==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -3018,8 +3018,8 @@ packages: dev: true optional: true - /@nx/nx-darwin-x64@17.0.2: - resolution: {integrity: sha512-olGt5R2dWYwdl1+I2RfJ8LdZO1elqhr9yDPnMIx//ZuN6T6wJA+Wdp2P3qpM1bY0F1lI/6AgjqzRyrTLUZ9cDA==} + /@nx/nx-darwin-x64@17.0.3: + resolution: {integrity: sha512-YVWk9jNibD7fzn8oNBl/UNu8NEfcVwFo5wiNyfOql495yP0tyGdZNHD4i/7aS2Y654G1JYDRf7TutJ7wWFU8bg==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -3027,8 +3027,8 @@ packages: dev: true optional: true - /@nx/nx-freebsd-x64@17.0.2: - resolution: {integrity: sha512-+mta0J2G2byd+rfZ275oZs0aYXC/s92nI9ySBFQFQZnKJ6bsAagdZHe+uETsnE4xdhFXD8kvNMJU1WTGlyFyjg==} + /@nx/nx-freebsd-x64@17.0.3: + resolution: {integrity: sha512-yiYkfY+3IrlBrlaXN6SO4Fnb0a+Ti+FPwAqRPpH6q3uTCh0NmNgE99ydtT31ZbgCF1ZwRK8NdCbuNO3w9uznwA==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] @@ -3036,8 +3036,8 @@ packages: dev: true optional: true - /@nx/nx-linux-arm-gnueabihf@17.0.2: - resolution: {integrity: sha512-m80CmxHHyNAJ8j/0rkjc0hg/eGQlf6V2sLsV+gEJkz2sTEEdgSOK4DvnWcZRWO/SWBnqigxoHX4Kf5TH1nmoHA==} + /@nx/nx-linux-arm-gnueabihf@17.0.3: + resolution: {integrity: sha512-x4h6QJlESJZ0bigUlxNEVyi7F/VWQQx+1IBptofXhK5eTOPjJ5qgINdM38AZg+kBJDz5XOVMDejg6RzHlhs0Tg==} engines: {node: '>= 10'} cpu: [arm] os: [linux] @@ -3045,8 +3045,8 @@ packages: dev: true optional: true - /@nx/nx-linux-arm64-gnu@17.0.2: - resolution: {integrity: sha512-AsD1H6wt68MK1u6vkmtNaFaxDMcyuk6dpo5kq1YT9cfUd614ys3qMUjVp3P2CXxzXh+0UDZeGrc6qotNKOkpJw==} + /@nx/nx-linux-arm64-gnu@17.0.3: + resolution: {integrity: sha512-1lysnsZv9FS+9fciK0qh5PhsQ8U+vyFoR/jiJl+3vqYNUwEmNLD0VEAZzpZL2SJXQqD5E0bjuQpYxiD7YRXImQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -3054,8 +3054,8 @@ packages: dev: true optional: true - /@nx/nx-linux-arm64-musl@17.0.2: - resolution: {integrity: sha512-f8pUFoZHBFQtHnopHgTEuwIiu0Rzem0dD7iK8SyyBy/lRAADtHCAHxaPAG+iatHAJ9h4DFIB50k9ybYxDtH2mg==} + /@nx/nx-linux-arm64-musl@17.0.3: + resolution: {integrity: sha512-0/bvSpbc4vOy9E24fu0ajDGe3SO8lmLtlxjXwGRcnzlt/MWM8sazoO0lX163/X2wF6tuL6+HXHOr6AeqsdeRXQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -3063,8 +3063,8 @@ packages: dev: true optional: true - /@nx/nx-linux-x64-gnu@17.0.2: - resolution: {integrity: sha512-PISrHjLTxv5w8bz50vPZH6puYos88xu28o4IbVyYWrUrhoFsAx9Zbn1D6gWDPMSaKJU32v1l+5bTciQjQJU8fQ==} + /@nx/nx-linux-x64-gnu@17.0.3: + resolution: {integrity: sha512-tKO6MYUxpUsHMuZrYy8hG20RIOdBY3kyEK8wxH8JZZaXKeYUK+5vv5DavWpY5wuu2jffNIJNsbUzcrqOlcbDOg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -3072,8 +3072,8 @@ packages: dev: true optional: true - /@nx/nx-linux-x64-musl@17.0.2: - resolution: {integrity: sha512-2wsqyBRjsxmAjxW+0lnGFtJLTk+AxgW7gjMv8NgLK8P1bc/sJYQB+g0o5op2z+szXRG3Noi0RZ9C0fG39EPFZw==} + /@nx/nx-linux-x64-musl@17.0.3: + resolution: {integrity: sha512-H88yBLrI51m6NGoCkpBYhacRyTBfDuf7x00SnxSfD1yLlxCazPUG7CGkMedpzXo10YHxCFvg7B/Fa23DRRleUg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -3081,8 +3081,8 @@ packages: dev: true optional: true - /@nx/nx-win32-arm64-msvc@17.0.2: - resolution: {integrity: sha512-Sc3sQUcS5xdk05PABe/knG6orG5rmHZdSUj6SMRpvYfN2tM3ziNn6/wCF/LJoW6n70OxrOEXXwLSRK/5WigXbA==} + /@nx/nx-win32-arm64-msvc@17.0.3: + resolution: {integrity: sha512-bKzmzjvgLB4IzLWTySqXgBgXawfw0ZSjUkscFQ3ZHrK9loMba1Ue8Ugy2DktlkUrCyPmGSot+YZViTzWP75C3w==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -3090,8 +3090,8 @@ packages: dev: true optional: true - /@nx/nx-win32-x64-msvc@17.0.2: - resolution: {integrity: sha512-XhET0BDk6fbvTBCs7m5gZii8+2WhLpiC1sZchJw4LAJN2VJBiy3I3xnvpQYGFOAWaCb/iUGpuN/qP/NlQ+LNgA==} + /@nx/nx-win32-x64-msvc@17.0.3: + resolution: {integrity: sha512-SJssAOyUM1IW9t84/Uzau9JHo14hnG5mxvcrborNGlLq+WnP0jzISVs7gvV2xWZ9j1JemxA5KLbkMuIkJyR6qQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -11274,8 +11274,8 @@ packages: - debug dev: true - /nx@17.0.2: - resolution: {integrity: sha512-utk9ufxLlRd210nEV6cKjMLVK0gup2ZMlNT41lLgUX/gp3Q59G1NkyLo3o29DxBh3AhNJ9q5MKgybmzDNdpudA==} + /nx@17.0.3: + resolution: {integrity: sha512-VShJISKCYt3iVJoMUPZiv67+0tiItxWMnfVmTmPZPio2Fu+wGc9U4ijjPxcmp2RJmLRaxkB9cn5rlrAvkIrNMA==} hasBin: true requiresBuild: true peerDependencies: @@ -11287,7 +11287,7 @@ packages: '@swc/core': optional: true dependencies: - '@nrwl/tao': 17.0.2 + '@nrwl/tao': 17.0.3 '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.6 @@ -11323,16 +11323,16 @@ packages: yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 17.0.2 - '@nx/nx-darwin-x64': 17.0.2 - '@nx/nx-freebsd-x64': 17.0.2 - '@nx/nx-linux-arm-gnueabihf': 17.0.2 - '@nx/nx-linux-arm64-gnu': 17.0.2 - '@nx/nx-linux-arm64-musl': 17.0.2 - '@nx/nx-linux-x64-gnu': 17.0.2 - '@nx/nx-linux-x64-musl': 17.0.2 - '@nx/nx-win32-arm64-msvc': 17.0.2 - '@nx/nx-win32-x64-msvc': 17.0.2 + '@nx/nx-darwin-arm64': 17.0.3 + '@nx/nx-darwin-x64': 17.0.3 + '@nx/nx-freebsd-x64': 17.0.3 + '@nx/nx-linux-arm-gnueabihf': 17.0.3 + '@nx/nx-linux-arm64-gnu': 17.0.3 + '@nx/nx-linux-arm64-musl': 17.0.3 + '@nx/nx-linux-x64-gnu': 17.0.3 + '@nx/nx-linux-x64-musl': 17.0.3 + '@nx/nx-win32-arm64-msvc': 17.0.3 + '@nx/nx-win32-x64-msvc': 17.0.3 transitivePeerDependencies: - debug dev: true From dce1e2f0ebbf40ac8c0baf8764b1455aa7a8154e Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Mon, 6 Nov 2023 15:44:28 -0800 Subject: [PATCH 369/374] op-node: Fixup PGN Sepolia Rollup Config --- op-node/rollup/superchain.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/op-node/rollup/superchain.go b/op-node/rollup/superchain.go index 88d802f5cf13..fe0e0ee460a3 100644 --- a/op-node/rollup/superchain.go +++ b/op-node/rollup/superchain.go @@ -110,5 +110,9 @@ func LoadOPStackRollupConfig(chainID uint64) (*Config, error) { cfg.ChannelTimeout = 120 cfg.MaxSequencerDrift = 1200 } + if chainID == pgnSepolia { + cfg.MaxSequencerDrift = 1000 + cfg.SeqWindowSize = 7200 + } return cfg, nil } From 62a804cf212a3f8ddf30120b246f6cef2e021226 Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Mon, 6 Nov 2023 17:11:04 -0700 Subject: [PATCH 370/374] op-node: Check withdrawals hash in P2P validation --- op-node/p2p/gossip.go | 6 ++++ op-node/p2p/gossip_test.go | 72 ++++++++++++++++++++++++++++++++++++++ specs/derivation.md | 7 ++-- specs/rollup-node-p2p.md | 1 + 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/op-node/p2p/gossip.go b/op-node/p2p/gossip.go index ffefa085dc6f..36951a76767d 100644 --- a/op-node/p2p/gossip.go +++ b/op-node/p2p/gossip.go @@ -326,6 +326,12 @@ func BuildBlocksValidator(log log.Logger, cfg *rollup.Config, runCfg GossipRunti return pubsub.ValidationReject } + // [REJECT] if a V2 Block has non-empty withdrawals + if blockVersion == eth.BlockV2 && len(*payload.Withdrawals) != 0 { + log.Warn("payload is on v2 topic, but has non-empty withdrawals", "bad_hash", payload.BlockHash.String(), "withdrawal_count", len(*payload.Withdrawals)) + return pubsub.ValidationReject + } + seen, ok := blockHeightLRU.Get(uint64(payload.BlockNumber)) if !ok { seen = new(seenBlocks) diff --git a/op-node/p2p/gossip_test.go b/op-node/p2p/gossip_test.go index 66533be2a6ea..0f47787d84ab 100644 --- a/op-node/p2p/gossip_test.go +++ b/op-node/p2p/gossip_test.go @@ -1,18 +1,28 @@ package p2p import ( + "bytes" "context" + "fmt" "math/big" "testing" + "time" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/golang/snappy" + + // "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testutils" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" pubsub "github.com/libp2p/go-libp2p-pubsub" + pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb" "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/require" @@ -89,3 +99,65 @@ func TestVerifyBlockSignature(t *testing.T) { require.Equal(t, pubsub.ValidationIgnore, result) }) } + +func createSignedP2Payload(payload *eth.ExecutionPayload, signer Signer, l2ChainID *big.Int) ([]byte, error) { + var buf bytes.Buffer + buf.Write(make([]byte, 65)) + if _, err := payload.MarshalSSZ(&buf); err != nil { + return nil, fmt.Errorf("failed to encoded execution payload to publish: %w", err) + } + data := buf.Bytes() + payloadData := data[65:] + sig, err := signer.Sign(context.TODO(), SigningDomainBlocksV1, l2ChainID, payloadData) + if err != nil { + return nil, fmt.Errorf("failed to sign execution payload with signer: %w", err) + } + copy(data[:65], sig[:]) + + // compress the full message + // This also copies the data, freeing up the original buffer to go back into the pool + return snappy.Encode(nil, data), nil +} + +// TestBlockValidator does some very basic tests of the p2p block validation logic +func TestBlockValidator(t *testing.T) { + // Params Set 1: Create the validation function + cfg := &rollup.Config{ + L2ChainID: big.NewInt(100), + } + secrets, err := e2eutils.DefaultMnemonicConfig.Secrets() + require.NoError(t, err) + runCfg := &testutils.MockRuntimeConfig{P2PSeqAddress: crypto.PubkeyToAddress(secrets.SequencerP2P.PublicKey)} + signer := &PreparedSigner{Signer: NewLocalSigner(secrets.SequencerP2P)} + + // valFnV1 := BuildBlocksValidator(testlog.Logger(t, log.LvlCrit), rollupCfg, runCfg, eth.BlockV1) + valFnV2 := BuildBlocksValidator(testlog.Logger(t, log.LvlCrit), cfg, runCfg, eth.BlockV2) + + // Params Set 2: Call the validation function + peerID := peer.ID("foo") + + // Valid Case + payload := eth.ExecutionPayload{ + Timestamp: hexutil.Uint64(time.Now().Unix()), + Withdrawals: &types.Withdrawals{}, + } + payload.BlockHash, _ = payload.CheckBlockHash() // hack to generate the block hash easily. + data, err := createSignedP2Payload(&payload, signer, cfg.L2ChainID) + require.NoError(t, err) + message := &pubsub.Message{Message: &pubsub_pb.Message{Data: data}} + res := valFnV2(context.TODO(), peerID, message) + require.Equal(t, res, pubsub.ValidationAccept) + + // Invalid because non-empty withdrawals when Canyon is active + payload = eth.ExecutionPayload{ + Timestamp: hexutil.Uint64(time.Now().Unix()), + Withdrawals: &types.Withdrawals{&types.Withdrawal{Index: 1, Validator: 1}}, + } + payload.BlockHash, _ = payload.CheckBlockHash() + data, err = createSignedP2Payload(&payload, signer, cfg.L2ChainID) + require.NoError(t, err) + message = &pubsub.Message{Message: &pubsub_pb.Message{Data: data}} + res = valFnV2(context.TODO(), peerID, message) + require.Equal(t, res, pubsub.ValidationReject) + +} diff --git a/specs/derivation.md b/specs/derivation.md index 09e4fb1ba267..7201d54a5d98 100644 --- a/specs/derivation.md +++ b/specs/derivation.md @@ -694,9 +694,12 @@ equivalents. The `v2` methods are backwards compatible with `v1` payloads but su [`engine_getPayloadV2`]: exec-engine.md#engine_getpayloadv2 [`engine_newPayloadV2`]: exec-engine.md#engine_newpayloadv2 -The execution payload is an object of type [`ExecutionPayloadV1`][eth-payload]. +The execution payload is an object of type [`ExecutionPayloadV2`][eth-payload]. -[eth-payload]: https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#executionpayloadv1 +[eth-payload]: https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#payloadattributesv2 + +With V2 of the execution payload, before Canyon the withdrawals field is required to be nil. After Canyon the +withdrawals field is required to be non-nil. The op-node should set the withdrawals field to be an empty list. #### Forkchoice synchronization diff --git a/specs/rollup-node-p2p.md b/specs/rollup-node-p2p.md index 828636d0a5d9..2733d4122046 100644 --- a/specs/rollup-node-p2p.md +++ b/specs/rollup-node-p2p.md @@ -291,6 +291,7 @@ An [extended-validator] checks the incoming messages as follows, in order of ope - `[REJECT]` if the `block_hash` in the `payload` is not valid - `[REJECT]` if the block is on the V1 topic and has withdrawals - `[REJECT]` if the block is on the V2 topic and does not have withdrawals +- `[REJECT]` if the block is on the V2 topic and has a non-zero amount of withdrawals - `[REJECT]` if more than 5 different blocks have been seen with the same block height - `[IGNORE]` if the block has already been seen - `[REJECT]` if the signature by the sequencer is not valid From 55f603e49da87ab557fef0e0ae290448d224b40f Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Mon, 6 Nov 2023 19:06:32 -0700 Subject: [PATCH 371/374] op-service/eth: Expose GasLimit from the header in BlockInfo --- op-service/eth/block_info.go | 5 +++++ op-service/sources/types.go | 4 ++++ op-service/testutils/l1info.go | 5 +++++ 3 files changed, 14 insertions(+) diff --git a/op-service/eth/block_info.go b/op-service/eth/block_info.go index 0b8d69189be8..15dff04a5529 100644 --- a/op-service/eth/block_info.go +++ b/op-service/eth/block_info.go @@ -20,6 +20,7 @@ type BlockInfo interface { BaseFee() *big.Int ReceiptHash() common.Hash GasUsed() uint64 + GasLimit() uint64 // HeaderRLP returns the RLP of the block header as per consensus rules // Returns an error if the header RLP could not be written @@ -100,6 +101,10 @@ func (h headerBlockInfo) GasUsed() uint64 { return h.Header.GasUsed } +func (h headerBlockInfo) GasLimit() uint64 { + return h.Header.GasLimit +} + func (h headerBlockInfo) HeaderRLP() ([]byte, error) { return rlp.EncodeToBytes(h.Header) } diff --git a/op-service/sources/types.go b/op-service/sources/types.go index 7ccf4c3b65c5..f3c5e8ac7c60 100644 --- a/op-service/sources/types.go +++ b/op-service/sources/types.go @@ -78,6 +78,10 @@ func (h headerInfo) GasUsed() uint64 { return h.Header.GasUsed } +func (h headerInfo) GasLimit() uint64 { + return h.Header.GasLimit +} + func (h headerInfo) HeaderRLP() ([]byte, error) { return rlp.EncodeToBytes(h.Header) } diff --git a/op-service/testutils/l1info.go b/op-service/testutils/l1info.go index 0109f5e1650b..249beb4df215 100644 --- a/op-service/testutils/l1info.go +++ b/op-service/testutils/l1info.go @@ -23,6 +23,7 @@ type MockBlockInfo struct { InfoBaseFee *big.Int InfoReceiptRoot common.Hash InfoGasUsed uint64 + InfoGasLimit uint64 InfoHeaderRLP []byte } @@ -66,6 +67,10 @@ func (l *MockBlockInfo) GasUsed() uint64 { return l.InfoGasUsed } +func (l *MockBlockInfo) GasLimit() uint64 { + return l.InfoGasLimit +} + func (l *MockBlockInfo) ID() eth.BlockID { return eth.BlockID{Hash: l.InfoHash, Number: l.InfoNum} } From b06320cd180600771f166d6fb688844c29abf08d Mon Sep 17 00:00:00 2001 From: Joshua Gutow Date: Mon, 6 Nov 2023 18:55:10 -0700 Subject: [PATCH 372/374] op-chain-ops: Canyon checker script --- op-chain-ops/cmd/check-canyon/main.go | 280 ++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 op-chain-ops/cmd/check-canyon/main.go diff --git a/op-chain-ops/cmd/check-canyon/main.go b/op-chain-ops/cmd/check-canyon/main.go new file mode 100644 index 000000000000..ae0d04cbb0b3 --- /dev/null +++ b/op-chain-ops/cmd/check-canyon/main.go @@ -0,0 +1,280 @@ +package main + +import ( + "bytes" + "context" + "errors" + "flag" + "fmt" + "math/big" + "os" + + "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-service/client" + "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/trie" +) + +func CalcBaseFee(parent eth.BlockInfo, elasticity uint64, canyonActive bool) *big.Int { + denomUint := uint64(50) + if canyonActive { + denomUint = uint64(250) + } + parentGasTarget := parent.GasLimit() / elasticity + // If the parent gasUsed is the same as the target, the baseFee remains unchanged. + if parent.GasUsed() == parentGasTarget { + return new(big.Int).Set(parent.BaseFee()) + } + + var ( + num = new(big.Int) + denom = new(big.Int) + ) + + if parent.GasUsed() > parentGasTarget { + // If the parent block used more gas than its target, the baseFee should increase. + // max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator) + num.SetUint64(parent.GasUsed() - parentGasTarget) + num.Mul(num, parent.BaseFee()) + num.Div(num, denom.SetUint64(parentGasTarget)) + num.Div(num, denom.SetUint64(denomUint)) + baseFeeDelta := math.BigMax(num, common.Big1) + + return num.Add(parent.BaseFee(), baseFeeDelta) + } else { + // Otherwise if the parent block used less gas than its target, the baseFee should decrease. + // max(0, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator) + num.SetUint64(parentGasTarget - parent.GasUsed()) + num.Mul(num, parent.BaseFee()) + num.Div(num, denom.SetUint64(parentGasTarget)) + num.Div(num, denom.SetUint64(denomUint)) + baseFee := num.Sub(parent.BaseFee(), num) + + return math.BigMax(baseFee, common.Big0) + } +} + +func ManuallyEncodeReceipts(receipts types.Receipts, canyonActive bool) [][]byte { + v := uint64(1) + for _, receipt := range receipts { + if receipt.Type == types.DepositTxType { + if canyonActive { + receipt.DepositReceiptVersion = &v + } else { + receipt.DepositReceiptVersion = nil + } + + } + } + var out [][]byte + for i := range receipts { + var buf bytes.Buffer + receipts.EncodeIndex(i, &buf) + out = append(out, buf.Bytes()) + } + return out +} + +type rawReceipts [][]byte + +func (s rawReceipts) Len() int { return len(s) } +func (s rawReceipts) EncodeIndex(i int, w *bytes.Buffer) { + w.Write(s[i]) +} +func HashList(list [][]byte) common.Hash { + hasher := trie.NewStackTrie(nil) + return types.DeriveSha(rawReceipts(list), hasher) +} + +type L2Client interface { + BlockByNumber(context.Context, *big.Int) (*types.Block, error) + CodeAt(context.Context, common.Address, *big.Int) ([]byte, error) + InfoByNumber(context.Context, uint64) (eth.BlockInfo, error) + FetchReceipts(context.Context, common.Hash) (eth.BlockInfo, types.Receipts, error) +} + +type Client struct { + *ethclient.Client + *sources.L1Client +} + +type Args struct { + Number uint64 + Elasticity uint64 + Client L2Client +} + +func ValidateReceipts(ctx Args, canyonActive bool) error { + block, err := ctx.Client.InfoByNumber(context.Background(), ctx.Number) + if err != nil { + return err + } + + _, receipts, err := ctx.Client.FetchReceipts(context.Background(), block.Hash()) + if err != nil { + return err + } + + have := block.ReceiptHash() + want := HashList(ManuallyEncodeReceipts(receipts, canyonActive)) + + if have != want { + return fmt.Errorf("Receipts do not look correct. canyonActive: %v. have: %v, want: %v", canyonActive, have, want) + } + + return nil +} + +func Validate1559Params(ctx Args, canyonActive bool) error { + block, err := ctx.Client.InfoByNumber(context.Background(), ctx.Number) + if err != nil { + return err + } + + if block.BaseFee().Cmp(big.NewInt(1000)) < 0 { + log.Info("Basefee to low to properly validate", "basefee", block.BaseFee()) + return nil + } + + parent, err := ctx.Client.InfoByNumber(context.Background(), ctx.Number-1) + if err != nil { + return err + } + + want := CalcBaseFee(parent, ctx.Elasticity, canyonActive) + have := block.BaseFee() + + if have.Cmp(want) != 0 { + return fmt.Errorf("BaseFee does not match. canyonActive: %v. have: %v, want: %v", canyonActive, have, want) + } + + return nil +} + +func ValidateWithdrawals(ctx Args, canyonActive bool) error { + block, err := ctx.Client.BlockByNumber(context.Background(), new(big.Int).SetUint64(ctx.Number)) + if err != nil { + return err + } + + if canyonActive && block.Withdrawals() == nil { + return errors.New("No nonwithdrawals in a canyon block") + } else if canyonActive && len(block.Withdrawals()) > 0 { + return errors.New("Withdrawals length is not zero in a canyon block") + } else if !canyonActive && block.Withdrawals() != nil { + return errors.New("Withdrawals in a pre-canyon block") + } + return nil +} + +func ValidateCreate2Deployer(ctx Args, canyonActive bool) error { + addr := common.HexToAddress("0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2") + code, err := ctx.Client.CodeAt(context.Background(), addr, new(big.Int).SetUint64(ctx.Number)) + if err != nil { + return err + } + codeHash := crypto.Keccak256Hash(code) + expectedCodeHash := common.HexToHash("0xb0550b5b431e30d38000efb7107aaa0ade03d48a7198a140edda9d27134468b2") + + if canyonActive && codeHash != expectedCodeHash { + return fmt.Errorf("Canyon active but code hash does not match. have: %v, want: %v", codeHash, expectedCodeHash) + } else if !canyonActive && codeHash == expectedCodeHash { + return fmt.Errorf("Canyon not active but code hashes do match. codeHash: %v", codeHash) + } + + return nil +} + +// CheckActivation takes a function f which determines in a specific block follows the rules of a fork. +// forkActivated tells `f` if the fork is active or not. `f` is called twice: First to validate that +// there is no error when checking the new value and second to validate the it returns an error when +// attempting to validate the block against the opposite of what is is. +// If any error is encountered, valid is set to false. +func CheckActivation(f func(Args, bool) error, ctx Args, forkActivated bool, valid *bool) { + if forkActivated { + if err := f(ctx, true); err != nil { + log.Error("Pre-state was invalid when it was expected to be valid", "err", err) + *valid = false + } + if err := f(ctx, false); err == nil { + log.Error("Post-state was valid when it was expected to be invalid") + *valid = false + } + } else { + if err := f(ctx, true); err == nil { + log.Error("Pre-state was valid when it was expected to be invalid") + *valid = false + } + if err := f(ctx, false); err != nil { + log.Error("Post-state was invalid when it was expected to be valid", "err", err) + *valid = false + } + } +} + +func main() { + logger := log.New() + + // Define the flag variables + var ( + canyonActive bool + number uint64 + elasticity uint64 + rpcURL string + ) + + valid := true + + // Define and parse the command-line flags + flag.BoolVar(&canyonActive, "canyon", false, "Set this flag to assert canyon behavior") + flag.Uint64Var(&number, "number", 31, "Block number to check") + flag.Uint64Var(&elasticity, "elasticity", 6, "Specify the EIP-1559 elasticity. 6 on mainnet/sepolia. 10 on goerli") + flag.StringVar(&rpcURL, "rpc-url", "http://localhost:8545", "Specify the L2 ETH RPC URL") + + // Parse the command-line arguments + flag.Parse() + + l2RPC, err := client.NewRPC(context.Background(), logger, rpcURL, client.WithDialBackoff(10)) + if err != nil { + log.Crit("Error creating RPC", "err", err) + } + c := &rollup.Config{SeqWindowSize: 10} + l2Cfg := sources.L1ClientDefaultConfig(c, true, sources.RPCKindBasic) + sourceClient, err := sources.NewL1Client(l2RPC, logger, nil, l2Cfg) + if err != nil { + log.Crit("Error creating RPC", "err", err) + } + ethClient, err := ethclient.Dial(rpcURL) + if err != nil { + log.Crit("Error creating RPC", "err", err) + } + + client := Client{ethClient, sourceClient} + + ctx := Args{ + Number: number, + Elasticity: elasticity, + Client: client, + } + + CheckActivation(ValidateReceipts, ctx, canyonActive, &valid) + CheckActivation(Validate1559Params, ctx, canyonActive, &valid) + CheckActivation(ValidateWithdrawals, ctx, canyonActive, &valid) + CheckActivation(ValidateCreate2Deployer, ctx, canyonActive, &valid) + + if !valid { + os.Exit(1) + } else if canyonActive { + log.Info(fmt.Sprintf("Successfully validated block %v as a Canyon block", number)) + } else { + log.Info(fmt.Sprintf("Successfully validated block %v as a Pre-Canyon block", number)) + } +} From 39e4a91ec7841ba709326e7c478d548402f34b48 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 7 Nov 2023 15:24:53 +0300 Subject: [PATCH 373/374] contracts-bedrock: visibility into flake A flake in CI was introduced when https://github.com/ethereum-optimism/optimism/pull/7928 was merged. It is probably due to a race condition when reading a file from disk. Is there a way to have foundry only do something once for the entire test suite? Tried moving things to the constructor instead of `setUp` but that did not work. Ideally we do not need to read the file from disk for each contract deployed, this adds a lot of overhead. A solution around this is to refactor the way that the deploy script works or to add in the env var that will skip the check that sometimes fails. --- packages/contracts-bedrock/scripts/Deployer.sol | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/scripts/Deployer.sol b/packages/contracts-bedrock/scripts/Deployer.sol index 0fe050b4151e..c1e230b0413b 100644 --- a/packages/contracts-bedrock/scripts/Deployer.sol +++ b/packages/contracts-bedrock/scripts/Deployer.sol @@ -88,7 +88,10 @@ abstract contract Deployer is Script { string memory chainIdPath = string.concat(deploymentsDir, "/.chainId"); try vm.readFile(chainIdPath) returns (string memory localChainId) { if (vm.envOr("STRICT_DEPLOYMENT", true)) { - require(vm.parseUint(localChainId) == chainId, "Misconfigured networks"); + require( + vm.parseUint(localChainId) == chainId, + string.concat("Misconfigured networks: ", localChainId, " != ", vm.toString(chainId)) + ); } } catch { vm.writeFile(chainIdPath, vm.toString(chainId)); From 98e7cff349e36989b22c4da8e1b5a726746bfcad Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Tue, 7 Nov 2023 16:19:40 +0300 Subject: [PATCH 374/374] contracts-bedrock: gas snapshot --- packages/contracts-bedrock/.gas-snapshot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/.gas-snapshot b/packages/contracts-bedrock/.gas-snapshot index 2f376f8941ff..d175e3c802c0 100644 --- a/packages/contracts-bedrock/.gas-snapshot +++ b/packages/contracts-bedrock/.gas-snapshot @@ -140,7 +140,7 @@ GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (g GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 88797) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68320) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68973) -GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143295) +GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143303) GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8348) GasPriceOracle_Test:test_decimals_succeeds() (gas: 6234) GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8340)