Skip to content

Commit

Permalink
starting anvil with port 0
Browse files Browse the repository at this point in the history
  • Loading branch information
hamdiallam committed Jul 9, 2024
1 parent f152658 commit d90bd4f
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 17 deletions.
57 changes: 42 additions & 15 deletions anvil/anvil.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"os"
"os/exec"
"strconv"
"strings"
"sync/atomic"
"time"
Expand Down Expand Up @@ -36,7 +37,8 @@ type Anvil struct {
}

const (
host = "127.0.0.1"
host = "127.0.0.1"
anvilListeningLogStr = "Listening on"
)

func New(log log.Logger, cfg *Config) *Anvil {
Expand All @@ -58,22 +60,24 @@ 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: %w", err)
}

_, err = tempFile.Write(a.cfg.Genesis)
if err != nil {
return fmt.Errorf("error writing to genesis file: %w", err)
}

// Prep args
args := []string{
"--host", host,
"--chain-id", fmt.Sprintf("%d", a.cfg.ChainId),
"--port", fmt.Sprintf("%d", a.cfg.Port),
"--init", tempFile.Name(),
}

if len(a.cfg.Genesis) > 0 {
tempFile, err := os.CreateTemp("", "genesis-*.json")
if err != nil {
return fmt.Errorf("error creating temporary genesis file: %w", err)
}
if _, err = tempFile.Write(a.cfg.Genesis); err != nil {
return fmt.Errorf("error writing to genesis file: %w", err)
}

defer os.Remove(tempFile.Name())
args = append(args, "--init", tempFile.Name())
}

a.cmd = exec.CommandContext(a.resourceCtx, "anvil", args...)
Expand All @@ -82,6 +86,10 @@ func (a *Anvil) Start(ctx context.Context) error {
a.resourceCancel()
}()

// In the event anvil is started with port 0, we'll need to block
// and see what port anvil eventually binds to when started
anvilPortCh := make(chan uint64)

// Handle stdout/stderr
// - TODO: Figure out best way to dump into logger. Some hex isn't showing appropriately
stdout, err := a.cmd.StdoutPipe()
Expand All @@ -95,7 +103,17 @@ func (a *Anvil) Start(ctx context.Context) error {
go func() {
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
anvilLog.Info(scanner.Text())
txt := scanner.Text()
anvilLog.Info(txt)

// scan for port if applicable
if a.cfg.Port == 0 && strings.HasPrefix(txt, anvilListeningLogStr) {
port, err := strconv.ParseInt(strings.Split(txt, ":")[1], 10, 64)
if err != nil {
panic(fmt.Errorf("unexpected anvil listening port log: %w", err))
}
anvilPortCh <- uint64(port)
}
}
}()
go func() {
Expand All @@ -111,8 +129,6 @@ func (a *Anvil) Start(ctx context.Context) error {
}

go func() {
defer os.Remove(tempFile.Name())

if err := a.cmd.Wait(); err != nil {
anvilLog.Error("anvil terminated with an error", "error", err)
} else {
Expand All @@ -121,6 +137,17 @@ func (a *Anvil) Start(ctx context.Context) error {
a.stoppedCh <- struct{}{}
}()

// wait & update the port if applicable. Since we're in the same routine to which `Start`
// is called, we're safe to overrwrite the `Port` field which the caller can observe
if a.cfg.Port == 0 {
done := ctx.Done()
select {
case a.cfg.Port = <-anvilPortCh:
case <-done:
return ctx.Err()
}
}

return nil
}

Expand Down
32 changes: 32 additions & 0 deletions anvil/anvil_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package anvil

import (
"context"
"testing"

"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/stretchr/testify/require"

"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
)

func TestAnvil(t *testing.T) {
cfg := Config{ChainId: 10, Port: 0}
testlog := testlog.Logger(t, log.LevelInfo)
anvil := New(testlog, &cfg)

require.NoError(t, anvil.Start(context.Background()))

// port overriden on startup
require.NotEqual(t, cfg.Port, 0)

client, err := rpc.Dial(anvil.Endpoint())
require.NoError(t, err)

// query chainId
var chainId math.HexOrDecimal64
require.NoError(t, client.CallContext(context.Background(), &chainId, "eth_chainId"))
require.Equal(t, uint64(chainId), cfg.ChainId)
}
4 changes: 2 additions & 2 deletions supersim.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ var genesisL2JSON []byte
var DefaultConfig = Config{
l1Chain: anvil.Config{ChainId: 1, Port: 8545, Genesis: genesisL1JSON},
l2Chains: []anvil.Config{
{ChainId: 10, Port: 9545, Genesis: genesisL2JSON},
{ChainId: 30, Port: 9555, Genesis: genesisL2JSON},
{ChainId: 10, Port: 0, Genesis: genesisL2JSON},
{ChainId: 30, Port: 0, Genesis: genesisL2JSON},
},
}

Expand Down

0 comments on commit d90bd4f

Please sign in to comment.