From fa43400a3ebf6bc2612f2524511847a329372565 Mon Sep 17 00:00:00 2001 From: tre Date: Thu, 27 Jun 2024 16:13:10 -0700 Subject: [PATCH] feat(genesis-state): embed genesis state files in go binary --- anvil/anvil.go | 33 ++++++++++++++++++++++++++++----- supersim.go | 13 ++++++++++--- supersim_test.go | 4 ++-- {testutils => utils}/rpc.go | 12 ++++++++++-- 4 files changed, 50 insertions(+), 12 deletions(-) rename {testutils => utils}/rpc.go (80%) diff --git a/anvil/anvil.go b/anvil/anvil.go index 2e9c9e46..84ffb5ad 100644 --- a/anvil/anvil.go +++ b/anvil/anvil.go @@ -5,16 +5,19 @@ import ( "context" "errors" "fmt" + "os" "os/exec" "sync/atomic" + "time" + "github.com/ethereum-optimism/supersim/utils" "github.com/ethereum/go-ethereum/log" ) type Config struct { - ChainId uint64 - Port uint64 - GenesisPath string + ChainId uint64 + Port uint64 + Genesis []byte } type Anvil struct { @@ -30,6 +33,10 @@ type Anvil struct { stoppedCh chan struct{} } +const ( + host = "127.0.0.1" +) + func New(log log.Logger, cfg *Config) *Anvil { resCtx, resCancel := context.WithCancel(context.Background()) return &Anvil{ @@ -49,12 +56,23 @@ func (a *Anvil) Start(ctx context.Context) error { anvilLog := a.log.New("chain.id", a.cfg.ChainId) anvilLog.Info("starting anvil") + tempFile, err := os.CreateTemp("", "genesis-*.json") + if err != nil { + return fmt.Errorf("Error creating temporary genesis file: %v", err) + } + defer os.Remove(tempFile.Name()) + + _, err = tempFile.Write(a.cfg.Genesis) + if err != nil { + return fmt.Errorf("Error writing to genesis file: %v", err) + } + // Prep args args := []string{ - "--host", "127.0.0.1", + "--host", host, "--chain-id", fmt.Sprintf("%d", a.cfg.ChainId), "--port", fmt.Sprintf("%d", a.cfg.Port), - "--init", fmt.Sprintf("%s", a.cfg.GenesisPath), + "--init", fmt.Sprintf("%s", tempFile.Name()), } a.cmd = exec.CommandContext(a.resourceCtx, "anvil", args...) @@ -90,6 +108,11 @@ func (a *Anvil) Start(ctx context.Context) error { if err := a.cmd.Start(); err != nil { return fmt.Errorf("failed to start anvil: %w", err) } + + if _, err := utils.WaitForAnvilClientToBeReady(fmt.Sprintf("http://%s:%d", host, a.cfg.Port), 5*time.Second); err != nil { + return fmt.Errorf("failed to start anvil: %w", err) + } + go func() { if err := a.cmd.Wait(); err != nil { anvilLog.Error("anvil terminated with an error", "error", err) diff --git a/supersim.go b/supersim.go index 8cbf3b09..b816fa3f 100644 --- a/supersim.go +++ b/supersim.go @@ -1,6 +1,7 @@ package supersim import ( + _ "embed" "fmt" "context" @@ -15,11 +16,17 @@ type Config struct { l2Chains []anvil.Config } +//go:embed genesis/genesis-l1.json +var genesisL1JSON []byte + +//go:embed genesis/genesis-l2.json +var genesisL2JSON []byte + var DefaultConfig = Config{ - l1Chain: anvil.Config{ChainId: 1, Port: 8545, GenesisPath: "genesis/genesis-l1.json"}, + l1Chain: anvil.Config{ChainId: 1, Port: 8545, Genesis: genesisL1JSON}, l2Chains: []anvil.Config{ - {ChainId: 10, Port: 9545, GenesisPath: "genesis/genesis-l2.json"}, - {ChainId: 30, Port: 9555, GenesisPath: "genesis/genesis-l2.json"}, + {ChainId: 10, Port: 9545, Genesis: genesisL2JSON}, + {ChainId: 30, Port: 9555, Genesis: genesisL2JSON}, }, } diff --git a/supersim_test.go b/supersim_test.go index 4f5e4281..cb23c123 100644 --- a/supersim_test.go +++ b/supersim_test.go @@ -9,7 +9,7 @@ import ( "time" oplog "github.com/ethereum-optimism/optimism/op-service/log" - "github.com/ethereum-optimism/supersim/testutils" + "github.com/ethereum-optimism/supersim/utils" ) const ( @@ -27,7 +27,7 @@ func TestGenesisState(t *testing.T) { defer supersim.Stop(context.Background()) for _, l2ChainConfig := range DefaultConfig.l2Chains { - client, err := testutils.WaitForAnvilClientToBeReady(fmt.Sprintf("http://127.0.0.1:%d", l2ChainConfig.Port), anvilClientTimeout) + client, err := utils.WaitForAnvilClientToBeReady(fmt.Sprintf("http://127.0.0.1:%d", l2ChainConfig.Port), anvilClientTimeout) if err != nil { t.Fatalf("Failed to connect to RPC server: %v", err) } diff --git a/testutils/rpc.go b/utils/rpc.go similarity index 80% rename from testutils/rpc.go rename to utils/rpc.go index f98d6ac1..de7e3cf9 100644 --- a/testutils/rpc.go +++ b/utils/rpc.go @@ -1,8 +1,9 @@ -package testutils +package utils import ( "context" "fmt" + "net/http" "time" "github.com/ethereum/go-ethereum/rpc" @@ -20,12 +21,19 @@ func WaitForAnvilClientToBeReady(rpcUrl string, timeout time.Duration) (*rpc.Cli case <-ctx.Done(): return nil, fmt.Errorf("timed out waiting for response from %s", rpcUrl) case <-ticker.C: - client, err := rpc.Dial(rpcUrl) + _, err := http.Get(rpcUrl) + if err != nil { fmt.Printf("Error making request: %v\n", err) continue } + client, err := rpc.Dial(rpcUrl) + if err != nil { + fmt.Printf("Error creating rpc client: %v\n", err) + continue + } + return client, nil } }