Skip to content

Commit

Permalink
refactor waitforanvil
Browse files Browse the repository at this point in the history
  • Loading branch information
jakim929 committed Jul 9, 2024
1 parent dad31ee commit a167a84
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 73 deletions.
53 changes: 53 additions & 0 deletions anvil/anvil.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import (
"fmt"
"os"
"os/exec"
"strings"
"sync/atomic"
"time"

"github.com/ethereum/go-ethereum/rpc"

"github.com/ethereum/go-ethereum/log"
)
Expand Down Expand Up @@ -141,6 +145,55 @@ func (a *Anvil) Endpoint() string {
return fmt.Sprintf("http://%s:%d", host, a.cfg.Port)
}

func (a *Anvil) WaitUntilReady(ctx context.Context) error {
return waitForAnvilEndpointToBeReady(ctx, a.Endpoint(), 10*time.Second)
}

func (a *Anvil) ChainId() uint64 {
return a.cfg.ChainId
}

func waitForAnvilEndpointToBeReady(ctx context.Context, endpoint string, timeout time.Duration) error {
client, err := rpc.Dial(endpoint)
if err != nil {
return fmt.Errorf("failed to create client: %w", err)
}

defer client.Close()

if err := waitForAnvilClientToBeReady(ctx, client, timeout); err != nil {
return fmt.Errorf("failed to connect to RPC server: %w", err)
}

return nil
}

func waitForAnvilClientToBeReady(ctx context.Context, client *rpc.Client, timeout time.Duration) error {
timeoutCtx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

ticker := time.NewTicker(100 * time.Millisecond)
defer ticker.Stop()

for {
select {
case <-ctx.Done():
return fmt.Errorf("context cancelled")
case <-timeoutCtx.Done():
return fmt.Errorf("timed out waiting for response from client")
case <-ticker.C:
var result string
callErr := client.Call(&result, "web3_clientVersion")

if callErr != nil {
continue
}

if strings.HasPrefix(result, "anvil") {
return nil
}

return fmt.Errorf("unexpected client version: %s", result)
}
}
}
52 changes: 38 additions & 14 deletions supersim.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import (
"fmt"
"strings"
"sync"
"time"

"context"

"github.com/ethereum-optimism/supersim/anvil"
"github.com/ethereum-optimism/supersim/utils"

"github.com/ethereum/go-ethereum/log"
)
Expand Down Expand Up @@ -59,25 +57,17 @@ func (s *Supersim) Start(ctx context.Context) error {
return fmt.Errorf("l1 chain failed to start: %w", err)
}

var wg sync.WaitGroup
waitForAnvil := func(anvil *anvil.Anvil) {
defer wg.Done()
wg.Add(1)
utils.WaitForAnvilEndpointToBeReady(anvil.Endpoint(), 10*time.Second)
}

go waitForAnvil(s.l1Chain)

for _, l2Chain := range s.l2Chains {
if err := l2Chain.Start(ctx); err != nil {
return fmt.Errorf("l2 chain failed to start: %w", err)
}
go waitForAnvil(l2Chain)
}

wg.Wait()
if err := s.WaitUntilReady(); err != nil {
return fmt.Errorf("supersim failed to get ready: %w", err)
}

s.log.Info("Supersim is ready")
s.log.Info("supersim is ready")
s.log.Info(s.ConfigAsString())

return nil
Expand All @@ -103,6 +93,40 @@ func (s *Supersim) Stopped() bool {
return s.l1Chain.Stopped()
}

func (s *Supersim) WaitUntilReady() error {
var once sync.Once
var err error
ctx, cancel := context.WithCancel(context.Background())

handleErr := func(e error) {
if e != nil {
once.Do(func() {
err = e
cancel()
})
}
}

var wg sync.WaitGroup

waitForAnvil := func(anvil *anvil.Anvil) {
defer wg.Done()
handleErr(anvil.WaitUntilReady(ctx))
}

wg.Add(1)
go waitForAnvil(s.l1Chain)

for _, l2Chain := range s.l2Chains {
wg.Add(1)
go waitForAnvil(l2Chain)
}

wg.Wait()

return err
}

func (s *Supersim) ConfigAsString() string {
var b strings.Builder

Expand Down
13 changes: 6 additions & 7 deletions supersim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"time"

oplog "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum-optimism/supersim/utils"

"github.com/ethereum/go-ethereum/rpc"
)
Expand All @@ -25,7 +24,7 @@ const (
func TestGenesisState(t *testing.T) {
logger := oplog.NewLogger(os.Stderr, oplog.DefaultCLIConfig())
supersim := NewSupersim(logger, &DefaultConfig)
_ = supersim.Start(context.Background())
err := supersim.Start(context.Background())

defer func() {
err := supersim.Stop(context.Background())
Expand All @@ -34,6 +33,10 @@ func TestGenesisState(t *testing.T) {
}
}()

if err != nil {
t.Fatalf("Failed to start supersim: %v", err)
}

for _, l2ChainConfig := range DefaultConfig.l2Chains {
rpcUrl := fmt.Sprintf("http://127.0.0.1:%d", l2ChainConfig.Port)
client, clientCreateErr := rpc.Dial(rpcUrl)
Expand All @@ -42,14 +45,10 @@ func TestGenesisState(t *testing.T) {
t.Fatalf("Failed to create client: %v", clientCreateErr)
}

err := utils.WaitForAnvilClientToBeReady(client, anvilClientTimeout)
if err != nil {
t.Fatalf("Failed to connect to RPC server: %v", err)
}
defer client.Close()

var code string
err = client.CallContext(context.Background(), &code, "eth_getCode", crossL2InboxAddress, "latest")
err := client.CallContext(context.Background(), &code, "eth_getCode", crossL2InboxAddress, "latest")
if err != nil {
log.Fatalf("Failed to get code: %v", err)
}
Expand Down
52 changes: 0 additions & 52 deletions utils/rpc.go

This file was deleted.

0 comments on commit a167a84

Please sign in to comment.