Skip to content

Commit 8fe6175

Browse files
committed
WIP: TRON support
1 parent a4290be commit 8fe6175

File tree

6 files changed

+172
-1
lines changed

6 files changed

+172
-1
lines changed

framework/.changeset/v0.4.4.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add TRON network support

framework/components/blockchain/blockchain.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
// Input is a blockchain network configuration params
99
type Input struct {
1010
// Common EVM fields
11-
Type string `toml:"type" validate:"required,oneof=anvil geth besu solana aptos" envconfig:"net_type"`
11+
Type string `toml:"type" validate:"required,oneof=anvil geth besu solana aptos tron" envconfig:"net_type"`
1212
Image string `toml:"image"`
1313
PullImage bool `toml:"pull_image"`
1414
Port string `toml:"port"`
@@ -64,6 +64,8 @@ func NewBlockchainNetwork(in *Input) (*Output, error) {
6464
out, err = newSolana(in)
6565
case "aptos":
6666
out, err = newAptos(in)
67+
case "tron":
68+
out, err = newTron(in)
6769
default:
6870
return nil, fmt.Errorf("blockchain type is not supported or empty, must be 'anvil' or 'geth'")
6971
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package blockchain
2+
3+
import (
4+
"context"
5+
"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+
"os"
10+
"time"
11+
12+
"github.com/testcontainers/testcontainers-go"
13+
"github.com/testcontainers/testcontainers-go/wait"
14+
)
15+
16+
const (
17+
AccountsFile = `{
18+
"hdPath": "m/44'/195'/0'/0/",
19+
"mnemonic": "resemble birth wool happy sun burger fatal trumpet globe purity health ritual",
20+
"privateKeys": [
21+
"cf36898af3c63e13537063ae165ec8262fafac188f09200647b4b76b6f212b90",
22+
"7d5110f81cc6b2c65a532066e81fe813edf781e24f4e0fa42d22a3003dae7a54",
23+
"ae0de6fb5450622bfc96ec0c25a8a5cb85256d1f9d6cbbe5fd9de073d22f0060",
24+
"e972c3c213f8ba8cfe9a75e5d0b48310f4e35715f70986edd1eade904dd03437",
25+
"23d81a4d6c85661b58922e68db09cca0ebe77c787beb0e12c8d29da111568855"
26+
],
27+
"more": [
28+
{
29+
"hdPath": "m/44'/195'/0'/0/",
30+
"mnemonic": "resemble birth wool happy sun burger fatal trumpet globe purity health ritual",
31+
"privateKeys": [
32+
"cf36898af3c63e13537063ae165ec8262fafac188f09200647b4b76b6f212b90",
33+
"7d5110f81cc6b2c65a532066e81fe813edf781e24f4e0fa42d22a3003dae7a54",
34+
"ae0de6fb5450622bfc96ec0c25a8a5cb85256d1f9d6cbbe5fd9de073d22f0060",
35+
"e972c3c213f8ba8cfe9a75e5d0b48310f4e35715f70986edd1eade904dd03437",
36+
"23d81a4d6c85661b58922e68db09cca0ebe77c787beb0e12c8d29da111568855"
37+
]
38+
}
39+
]
40+
}
41+
`
42+
DefaultTronPort = "9090"
43+
DefaultTronSolidityPort = "8091"
44+
)
45+
46+
func defaultTron(in *Input) {
47+
if in.Image == "" {
48+
in.Image = "trontools/quickstart:2.1.1"
49+
}
50+
if in.Port == "" {
51+
in.Port = DefaultTronPort
52+
}
53+
}
54+
55+
func newTron(in *Input) (*Output, error) {
56+
defaultTron(in)
57+
ctx := context.Background()
58+
59+
containerName := framework.DefaultTCName("blockchain-node")
60+
bindPort := fmt.Sprintf("%s/tcp", in.Port)
61+
62+
accounts, err := os.CreateTemp("", "accounts.json")
63+
if err != nil {
64+
return nil, err
65+
}
66+
_, err = accounts.WriteString(AccountsFile)
67+
if err != nil {
68+
return nil, err
69+
}
70+
71+
req := testcontainers.ContainerRequest{
72+
AlwaysPullImage: in.PullImage,
73+
Image: in.Image,
74+
Name: containerName,
75+
ExposedPorts: []string{bindPort, "18190/tcp", "18191/tcp"},
76+
Networks: []string{framework.DefaultNetworkName},
77+
NetworkAliases: map[string][]string{
78+
framework.DefaultNetworkName: {containerName},
79+
},
80+
Env: map[string]string{
81+
"accounts": "10",
82+
},
83+
Labels: framework.DefaultTCLabels(),
84+
HostConfigModifier: func(h *container.HostConfig) {
85+
h.PortBindings = framework.MapTheSamePort(bindPort, "18190/tcp", "19191/tcp")
86+
},
87+
WaitingFor: wait.ForListeningPort(nat.Port(in.Port)).WithStartupTimeout(60 * time.Second).WithPollInterval(200 * time.Millisecond),
88+
Files: []testcontainers.ContainerFile{
89+
{
90+
HostFilePath: accounts.Name(),
91+
ContainerFilePath: "/config/accounts.json",
92+
FileMode: 0644,
93+
},
94+
},
95+
}
96+
97+
c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
98+
ContainerRequest: req,
99+
Started: true,
100+
})
101+
if err != nil {
102+
return nil, err
103+
}
104+
105+
host, err := c.Host(ctx)
106+
if err != nil {
107+
return nil, err
108+
}
109+
110+
return &Output{
111+
UseCache: true,
112+
ChainID: in.ChainID,
113+
Family: "tron",
114+
ContainerName: containerName,
115+
Nodes: []*Node{
116+
{
117+
HostHTTPUrl: fmt.Sprintf("http://%s:%s", host, in.Port),
118+
DockerInternalHTTPUrl: fmt.Sprintf("http://%s:%s", containerName, in.Port),
119+
},
120+
},
121+
}, nil
122+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
hdPath: 'm/44\'/60\'/0\'/0/',
3+
mnemonic: 'grid wire envelope task bright aerobic fragile mother asset wish harvest wild',
4+
privateKeys: [
5+
'27c2a416b135d52337725955359a08cd70a73844b1d58b909ecd42cd749a4acb',
6+
'e67a7dec7ce9fa6970a2a36d1f67a789ed1a684271e23c7df395354908d81853',
7+
'5eac42eb3484be190c24e050842ac9e8fa01debc84e3f48771d8b03e9bc21a29',
8+
'9b086cbf9bab77cfb7bab5155dc1c62b1eebd1c5c73822208832e9c4cfbe78b5',
9+
'4fe8f6582e7eeb6bd4e13aa56ec6fa02b4ec77f5fe99860352439fd856db4929',
10+
'f0c8c4812914ba6a3bc37c7e40f28bd4029f0f9e69da74b81ca6357a5a337e72',
11+
'9f7e1842bf257dfeabbb6f20f5c6e2f3a211b504e7cdb8a60fae20cfb9816176',
12+
'0ae57ff2059579af2639dca6b01ffdb47aab2c85e723f4c7ece3e272ee3e4eee',
13+
'43d5f335747e938659a95d3e82482015e69b50b10b8e59b8d12408b52d32aac0',
14+
'e08c645bc4907e9f83593c725f3fbb2e63fc69d603de46c3619c0bc8fb6c6bad'
15+
],
16+
more: []
17+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[blockchain_a]
2+
type = "tron"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package examples
2+
3+
import (
4+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
5+
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain"
6+
"github.com/stretchr/testify/require"
7+
"testing"
8+
)
9+
10+
type CfgTron struct {
11+
BlockchainA *blockchain.Input `toml:"blockchain_a" validate:"required"`
12+
}
13+
14+
func TestTRONSmoke(t *testing.T) {
15+
in, err := framework.Load[CfgTron](t)
16+
require.NoError(t, err)
17+
18+
bc, err := blockchain.NewBlockchainNetwork(in.BlockchainA)
19+
require.NoError(t, err)
20+
21+
t.Run("test something", func(t *testing.T) {
22+
// use internal URL to connect Chainlink nodes
23+
_ = bc.Nodes[0].DockerInternalHTTPUrl
24+
// use host URL to interact
25+
_ = bc.Nodes[0].HostHTTPUrl
26+
})
27+
}

0 commit comments

Comments
 (0)