Skip to content

Commit b5d31e3

Browse files
author
Ilan
committed
Add anvil zksync with default parameters
1 parent f1b6a5a commit b5d31e3

File tree

6 files changed

+188
-58
lines changed

6 files changed

+188
-58
lines changed
Lines changed: 10 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
package blockchain
22

33
import (
4-
"context"
54
"fmt"
6-
"github.com/docker/docker/api/types/container"
7-
"github.com/docker/go-connections/nat"
8-
"github.com/smartcontractkit/chainlink-testing-framework/framework"
9-
"github.com/testcontainers/testcontainers-go"
10-
"github.com/testcontainers/testcontainers-go/wait"
115
"strings"
12-
"time"
6+
7+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
138
)
149

1510
const (
@@ -31,60 +26,18 @@ func defaultAnvil(in *Input) {
3126
// newAnvil deploy foundry anvil node
3227
func newAnvil(in *Input) (*Output, error) {
3328
defaultAnvil(in)
34-
ctx := context.Background()
29+
req := baseRequest(in)
30+
31+
req.Image = fmt.Sprintf("%s", in.Image)
32+
req.AlwaysPullImage = in.PullImage
33+
3534
entryPoint := []string{"anvil"}
3635
defaultCmd := []string{"--host", "0.0.0.0", "--port", in.Port, "--chain-id", in.ChainID}
3736
entryPoint = append(entryPoint, defaultCmd...)
3837
entryPoint = append(entryPoint, in.DockerCmdParamsOverrides...)
38+
req.Entrypoint = entryPoint
39+
3940
framework.L.Info().Any("Cmd", strings.Join(entryPoint, " ")).Msg("Creating anvil with command")
40-
bindPort := fmt.Sprintf("%s/tcp", in.Port)
41-
containerName := framework.DefaultTCName("blockchain-node")
4241

43-
req := testcontainers.ContainerRequest{
44-
AlwaysPullImage: in.PullImage,
45-
Image: fmt.Sprintf("%s", in.Image),
46-
Labels: framework.DefaultTCLabels(),
47-
Name: containerName,
48-
ExposedPorts: []string{bindPort},
49-
HostConfigModifier: func(h *container.HostConfig) {
50-
h.PortBindings = framework.MapTheSamePort(bindPort)
51-
framework.ResourceLimitsFunc(h, in.ContainerResources)
52-
},
53-
Networks: []string{framework.DefaultNetworkName},
54-
NetworkAliases: map[string][]string{
55-
framework.DefaultNetworkName: {containerName},
56-
},
57-
WaitingFor: wait.ForListeningPort(nat.Port(in.Port)).WithStartupTimeout(10 * time.Second).WithPollInterval(200 * time.Millisecond),
58-
Entrypoint: entryPoint,
59-
}
60-
c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
61-
ContainerRequest: req,
62-
Started: true,
63-
})
64-
if err != nil {
65-
return nil, err
66-
}
67-
host, err := framework.GetHost(c)
68-
if err != nil {
69-
return nil, err
70-
}
71-
mp, err := c.MappedPort(ctx, nat.Port(bindPort))
72-
if err != nil {
73-
return nil, err
74-
}
75-
return &Output{
76-
UseCache: true,
77-
Family: "evm",
78-
ChainID: in.ChainID,
79-
ContainerName: containerName,
80-
Container: c,
81-
Nodes: []*Node{
82-
{
83-
HostWSUrl: fmt.Sprintf("ws://%s:%s", host, mp.Port()),
84-
HostHTTPUrl: fmt.Sprintf("http://%s:%s", host, mp.Port()),
85-
DockerInternalWSUrl: fmt.Sprintf("ws://%s:%s", containerName, in.Port),
86-
DockerInternalHTTPUrl: fmt.Sprintf("http://%s:%s", containerName, in.Port),
87-
},
88-
},
89-
}, nil
42+
return createGenericEvmContainer(in, req)
9043
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Use latest Ubuntu as the base image
2+
FROM ubuntu:latest
3+
4+
RUN apt update
5+
RUN apt install -y curl git
6+
7+
RUN curl -L https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/install-foundry-zksync | bash
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package blockchain
2+
3+
import (
4+
"strings"
5+
6+
"github.com/testcontainers/testcontainers-go"
7+
8+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
9+
)
10+
11+
func defaultAnvilZksync(in *Input) {
12+
if in.ChainID == "" {
13+
in.ChainID = "260"
14+
}
15+
if in.Port == "" {
16+
in.Port = "8011"
17+
}
18+
}
19+
20+
func newAnvilZksync(in *Input) (*Output, error) {
21+
defaultAnvilZksync(in)
22+
req := baseRequest(in)
23+
24+
// anvil-zskync has no public image builds.
25+
// see: https://foundry-book.zksync.io/getting-started/installation#using-foundry-with-docker
26+
req.FromDockerfile = testcontainers.FromDockerfile{
27+
Context: ".",
28+
Dockerfile: "anvilZksync.Dockerfile",
29+
KeepImage: true,
30+
}
31+
32+
req.Entrypoint = []string{"/bin/sh", "-c", "/root/.foundry/bin/anvil-zksync --offline run"}
33+
34+
framework.L.Info().Any("Cmd", strings.Join(req.Entrypoint, " ")).Msg("Creating anvil with command")
35+
36+
return createGenericEvmContainer(in, req)
37+
}

framework/components/blockchain/blockchain.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package blockchain
22

33
import (
44
"fmt"
5-
"github.com/smartcontractkit/chainlink-testing-framework/framework"
5+
66
"github.com/testcontainers/testcontainers-go"
7+
8+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
79
)
810

911
// Input is a blockchain network configuration params
@@ -75,6 +77,8 @@ func NewBlockchainNetwork(in *Input) (*Output, error) {
7577
out, err = newSui(in)
7678
case "tron":
7779
out, err = newTron(in)
80+
case "anvil-zksync":
81+
out, err = newAnvilZksync(in)
7882
default:
7983
return nil, fmt.Errorf("blockchain type is not supported or empty, must be 'anvil' or 'geth'")
8084
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package blockchain
2+
3+
import (
4+
"encoding/json"
5+
"io"
6+
"net/http"
7+
"strconv"
8+
"strings"
9+
"testing"
10+
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
func TestAnvil(t *testing.T) {
15+
anvilOut, err := NewBlockchainNetwork(&Input{
16+
Type: "anvil",
17+
})
18+
require.NoError(t, err)
19+
20+
testChain(t, 1337, anvilOut)
21+
}
22+
23+
func TestAnvilZksync(t *testing.T) {
24+
anvilOut, err := NewBlockchainNetwork(&Input{
25+
Type: "anvil-zksync",
26+
})
27+
require.NoError(t, err)
28+
29+
testChain(t, 260, anvilOut)
30+
}
31+
32+
func testChain(t *testing.T, chainId int64, output *Output) {
33+
rpcUrl := output.Nodes[0].HostHTTPUrl
34+
35+
reqBody := `{"jsonrpc": "2.0", "method": "eth_chainId", "params": [], "id": 1}`
36+
resp, err := http.Post(rpcUrl, "application/json", strings.NewReader(reqBody))
37+
require.NoError(t, err)
38+
defer resp.Body.Close()
39+
require.Equal(t, http.StatusOK, resp.StatusCode)
40+
41+
responseData, err := io.ReadAll(resp.Body)
42+
require.NoError(t, err)
43+
t.Logf("JSON RPC Response: %s", responseData)
44+
var respJSON struct {
45+
Result string `json:"result"`
46+
}
47+
err = json.Unmarshal(responseData, &respJSON)
48+
require.NoError(t, err)
49+
50+
actualChainId, err := strconv.ParseInt(strings.TrimPrefix(respJSON.Result, "0x"), 16, 64)
51+
require.NoError(t, err)
52+
53+
require.Equal(t, chainId, actualChainId)
54+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package blockchain
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/docker/docker/api/types/container"
9+
"github.com/docker/go-connections/nat"
10+
"github.com/testcontainers/testcontainers-go"
11+
"github.com/testcontainers/testcontainers-go/wait"
12+
13+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
14+
)
15+
16+
func baseRequest(in *Input) testcontainers.ContainerRequest {
17+
containerName := framework.DefaultTCName("blockchain-node")
18+
bindPort := fmt.Sprintf("%s/tcp", in.Port)
19+
20+
return testcontainers.ContainerRequest{
21+
Labels: framework.DefaultTCLabels(),
22+
Name: containerName,
23+
ExposedPorts: []string{bindPort},
24+
HostConfigModifier: func(h *container.HostConfig) {
25+
h.PortBindings = framework.MapTheSamePort(bindPort)
26+
framework.ResourceLimitsFunc(h, in.ContainerResources)
27+
},
28+
Networks: []string{framework.DefaultNetworkName},
29+
NetworkAliases: map[string][]string{
30+
framework.DefaultNetworkName: {containerName},
31+
},
32+
WaitingFor: wait.ForListeningPort(nat.Port(in.Port)).WithStartupTimeout(10 * time.Second).WithPollInterval(200 * time.Millisecond),
33+
}
34+
}
35+
36+
func createGenericEvmContainer(in *Input, req testcontainers.ContainerRequest) (*Output, error) {
37+
ctx := context.Background()
38+
39+
c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
40+
ContainerRequest: req,
41+
Started: true,
42+
})
43+
if err != nil {
44+
return nil, err
45+
}
46+
47+
host, err := framework.GetHost(c)
48+
if err != nil {
49+
return nil, err
50+
}
51+
52+
bindPort := req.ExposedPorts[0]
53+
mp, err := c.MappedPort(ctx, nat.Port(bindPort))
54+
if err != nil {
55+
return nil, err
56+
}
57+
58+
containerName := req.Name
59+
60+
return &Output{
61+
UseCache: true,
62+
Family: "evm",
63+
ChainID: in.ChainID,
64+
ContainerName: containerName,
65+
Container: c,
66+
Nodes: []*Node{
67+
{
68+
HostWSUrl: fmt.Sprintf("ws://%s:%s", host, mp.Port()),
69+
HostHTTPUrl: fmt.Sprintf("http://%s:%s", host, mp.Port()),
70+
DockerInternalWSUrl: fmt.Sprintf("ws://%s:%s", containerName, in.Port),
71+
DockerInternalHTTPUrl: fmt.Sprintf("http://%s:%s", containerName, in.Port),
72+
},
73+
},
74+
}, nil
75+
}

0 commit comments

Comments
 (0)