Skip to content

Commit efe8d83

Browse files
committed
Add Canton Blockchain
1 parent 8444cb7 commit efe8d83

File tree

6 files changed

+1145
-1
lines changed

6 files changed

+1145
-1
lines changed

framework/components/blockchain/blockchain.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const (
2020
TypeSui = "sui"
2121
TypeTron = "tron"
2222
TypeTon = "ton"
23+
TypeCanton = "canton"
2324
)
2425

2526
// Blockchain node family
@@ -30,12 +31,13 @@ const (
3031
FamilySui = "sui"
3132
FamilyTron = "tron"
3233
FamilyTon = "ton"
34+
FamilyCanton = "canton"
3335
)
3436

3537
// Input is a blockchain network configuration params
3638
type Input struct {
3739
// Common EVM fields
38-
Type string `toml:"type" validate:"required,oneof=anvil geth besu solana aptos tron sui ton" envconfig:"net_type"`
40+
Type string `toml:"type" validate:"required,oneof=anvil geth besu solana aptos tron sui ton canton" envconfig:"net_type"`
3941
Image string `toml:"image"`
4042
PullImage bool `toml:"pull_image"`
4143
Port string `toml:"port"`
@@ -60,6 +62,9 @@ type Input struct {
6062
// Sui specific: faucet port for funding accounts
6163
FaucetPort string `toml:"faucet_port"`
6264

65+
// Canton specific
66+
NumberOfValidators int `toml:"number_of_validators"`
67+
6368
// GAPv2 specific params
6469
HostNetworkMode bool `toml:"host_network_mode"`
6570
CertificatesPath string `toml:"certificates_path"`
@@ -122,6 +127,8 @@ func NewWithContext(ctx context.Context, in *Input) (*Output, error) {
122127
out, err = newAnvilZksync(ctx, in)
123128
case TypeTon:
124129
out, err = newTon(ctx, in)
130+
case TypeCanton:
131+
out, err = newCanton(ctx, in)
125132
default:
126133
return nil, fmt.Errorf("blockchain type is not supported or empty, must be 'anvil' or 'geth'")
127134
}
@@ -148,6 +155,8 @@ func TypeToFamily(t string) (ChainFamily, error) {
148155
return ChainFamily(FamilyTron), nil
149156
case TypeTon:
150157
return ChainFamily(FamilyTon), nil
158+
case TypeCanton:
159+
return ChainFamily(FamilyCanton), nil
151160
default:
152161
return "", fmt.Errorf("blockchain type is not supported or empty: %s", t)
153162
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package blockchain
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/testcontainers/testcontainers-go"
8+
"github.com/testcontainers/testcontainers-go/network"
9+
10+
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain/canton"
11+
)
12+
13+
func newCanton(ctx context.Context, in *Input) (*Output, error) {
14+
if in.NumberOfValidators >= 100 {
15+
return nil, fmt.Errorf("number of validators too high: %d, max is 99", in.NumberOfValidators)
16+
}
17+
18+
// TODO - remove debug prints
19+
fmt.Println("Starting Canton blockchain node...")
20+
fmt.Println("Creating network...")
21+
dockerNetwork, err := network.New(ctx, network.WithAttachable())
22+
if err != nil {
23+
return nil, err
24+
}
25+
fmt.Println("Network created:", dockerNetwork.Name)
26+
27+
// Set up Postgres container
28+
postgresReq := canton.PostgresContainerRequest(in.NumberOfValidators, dockerNetwork.Name)
29+
fmt.Printf("Starting postgres container %s...\n", postgresReq.Name)
30+
c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
31+
ContainerRequest: postgresReq,
32+
Started: true,
33+
})
34+
if err != nil {
35+
return nil, err
36+
}
37+
_ = c
38+
fmt.Println("Postgres container started")
39+
40+
// Set up Canton container
41+
cantonReq := canton.CantonContainerRequest(dockerNetwork.Name, in.NumberOfValidators, in.Image)
42+
fmt.Printf("Starting canton container %s...\n", cantonReq.Name)
43+
cantonContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
44+
ContainerRequest: cantonReq,
45+
Started: true,
46+
})
47+
if err != nil {
48+
return nil, err
49+
}
50+
_ = cantonContainer
51+
fmt.Println("Canton container started")
52+
53+
// Set up Splice container
54+
spliceReq := canton.SpliceContainerRequest(dockerNetwork.Name, in.NumberOfValidators, in.Image)
55+
fmt.Printf("Starting splice container %s...\n", spliceReq.Name)
56+
spliceContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
57+
ContainerRequest: spliceReq,
58+
Started: true,
59+
})
60+
if err != nil {
61+
return nil, err
62+
}
63+
_ = spliceContainer
64+
fmt.Println("Splice container started")
65+
66+
// Set up Nginx container
67+
nginxReq := canton.NginxContainerRequest(dockerNetwork.Name, in.NumberOfValidators, in.Port)
68+
fmt.Printf("Starting nginx container %s...\n", nginxReq.Name)
69+
nginxContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
70+
ContainerRequest: nginxReq,
71+
Started: true,
72+
})
73+
if err != nil {
74+
return nil, err
75+
}
76+
fmt.Println("Nginx container started")
77+
78+
host, err := nginxContainer.Host(ctx)
79+
if err != nil {
80+
return nil, err
81+
}
82+
83+
return &Output{
84+
UseCache: false,
85+
Type: in.Type,
86+
Family: FamilyCanton,
87+
ContainerName: nginxReq.Name,
88+
Nodes: []*Node{
89+
{
90+
ExternalHTTPUrl: fmt.Sprintf("http://%s:%s", host, in.Port),
91+
InternalHTTPUrl: fmt.Sprintf("http://%s:%s", nginxReq.Name, in.Port), // TODO - should be docker-internal port instead?
92+
},
93+
},
94+
}, nil
95+
}

0 commit comments

Comments
 (0)