@@ -4,14 +4,67 @@ import (
44 "context"
55 "fmt"
66 "github.com/docker/docker/api/types/container"
7+ "github.com/docker/docker/api/types/mount"
78 "github.com/smartcontractkit/chainlink-testing-framework/framework"
9+ "os"
810 "time"
911
1012 "github.com/docker/go-connections/nat"
1113 "github.com/testcontainers/testcontainers-go"
1214 "github.com/testcontainers/testcontainers-go/wait"
1315)
1416
17+ const (
18+ RootFundingAddr = `0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266`
19+ RootFundingWallet = `{"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"c36afd6e60b82d6844530bd6ab44dbc3b85a53e826c3a7f6fc6a75ce38c1e4c6","cipherparams":{"iv":"f69d2bb8cd0cb6274535656553b61806"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"80d5f5e38ba175b6b89acfc8ea62a6f163970504af301292377ff7baafedab53"},"mac":"f2ecec2c4d05aacc10eba5235354c2fcc3776824f81ec6de98022f704efbf065"},"id":"e5c124e9-e280-4b10-a27b-d7f3e516b408","version":3}`
20+ GenesisClique = `{
21+ "config": {
22+ "chainId": 1337,
23+ "homesteadBlock": 0,
24+ "daoForkBlock": 0,
25+ "daoForkSupport": true,
26+ "eip150Block": 0,
27+ "eip155Block": 0,
28+ "eip158Block": 0,
29+ "byzantiumBlock": 0,
30+ "constantinopleBlock": 0,
31+ "petersburgBlock": 0,
32+ "istanbulBlock": 0,
33+ "muirGlacierBlock": 0,
34+ "berlinBlock": 0,
35+ "londonBlock": 0,
36+ "arrowGlacierBlock": 0,
37+ "grayGlacierBlock": 0,
38+ "shanghaiTime": 0,
39+ "clique": {
40+ "period": 1,
41+ "epoch": 30000
42+ }
43+ },
44+ "difficulty": "1",
45+ "gasLimit": "800000000",
46+ "extradata": "0x0000000000000000000000000000000000000000000000000000000000000000f39Fd6e51aad88F6F4ce6aB8827279cffFb922660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
47+ "alloc": {
48+ "f39Fd6e51aad88F6F4ce6aB8827279cffFb92266": {
49+ "balance": "20000000000000000000000"
50+ }
51+ }
52+ }
53+ `
54+ )
55+
56+ var initScript = `
57+ #!/bin/bash
58+ if [ ! -d /root/.ethereum/keystore ]; then
59+ echo "/root/.ethereum/keystore not found, running 'geth init'..."
60+ geth init --datadir /root/.ethereum/devchain /root/genesis.json
61+ echo "...done!"
62+ fi
63+
64+ geth init --datadir /root/.ethereum/devchain /root/genesis.json
65+ geth "$@"
66+ `
67+
1568func defaultGeth (in * Input ) {
1669 if in .Image == "" {
1770 in .Image = "ethereum/client-go:v1.13.8"
@@ -36,30 +89,66 @@ func newGeth(in *Input) (*Output, error) {
3689 "--http.port" ,
3790 in .Port ,
3891 "--http.api" ,
39- "eth,net,web3" ,
92+ "eth,net,web3,personal,debug " ,
4093 "--ws" ,
4194 "--ws.addr" ,
4295 "0.0.0.0" ,
4396 "--ws.port" ,
4497 in .Port ,
4598 "--ws.api" ,
46- "eth,net,web3" ,
99+ "eth,net,web3,personal,debug " ,
47100 fmt .Sprintf ("--networkid=%s" , in .ChainID ),
48101 "--ipcdisable" ,
49102 "--graphql" ,
50103 "-graphql.corsdomain" , "*" ,
51104 "--allow-insecure-unlock" ,
52105 "--vmdebug" ,
53106 "--mine" ,
54- "--dev" ,
55- "--dev.period" ,
56- "1" ,
107+ "--miner.etherbase" , RootFundingAddr ,
108+ "--unlock" , RootFundingAddr ,
57109 }
58110 entryPoint := append (defaultCmd , in .DockerCmdParamsOverrides ... )
59111
60112 containerName := framework .DefaultTCName ("blockchain-node" )
61113 bindPort := fmt .Sprintf ("%s/tcp" , in .Port )
62114
115+ initScriptFile , err := os .CreateTemp ("" , "init_script" )
116+ if err != nil {
117+ return nil , err
118+ }
119+ _ , err = initScriptFile .WriteString (initScript )
120+ if err != nil {
121+ return nil , err
122+ }
123+ genesisFile , err := os .CreateTemp ("" , "genesis_json" )
124+ if err != nil {
125+ return nil , err
126+ }
127+ _ , err = genesisFile .WriteString (GenesisClique )
128+ if err != nil {
129+ return nil , err
130+ }
131+ keystoreDir , err := os .MkdirTemp ("" , "keystore" )
132+ if err != nil {
133+ return nil , err
134+ }
135+ key1File , err := os .CreateTemp (keystoreDir , "key1" )
136+ if err != nil {
137+ return nil , err
138+ }
139+ _ , err = key1File .WriteString (RootFundingWallet )
140+ if err != nil {
141+ return nil , err
142+ }
143+ configDir , err := os .MkdirTemp ("" , "config" )
144+ if err != nil {
145+ return nil , err
146+ }
147+ err = os .WriteFile (configDir + "/password.txt" , []byte ("" ), 0600 )
148+ if err != nil {
149+ return nil , err
150+ }
151+
63152 req := testcontainers.ContainerRequest {
64153 AlwaysPullImage : in .PullImage ,
65154 Image : in .Image ,
@@ -68,10 +157,38 @@ func newGeth(in *Input) (*Output, error) {
68157 NetworkAliases : map [string ][]string {
69158 framework .DefaultNetworkName : {containerName },
70159 },
160+ Entrypoint : []string {
161+ "sh" , "./root/init.sh" ,
162+ "--datadir" , "/root/.ethereum/devchain" ,
163+ "--password" , "/root/config/password.txt" ,
164+ },
71165 Name : containerName ,
72166 ExposedPorts : []string {bindPort },
73167 HostConfigModifier : func (h * container.HostConfig ) {
74168 h .PortBindings = framework .MapTheSamePort (bindPort )
169+ h .Mounts = append (h .Mounts , mount.Mount {
170+ Type : mount .TypeBind ,
171+ Source : keystoreDir ,
172+ Target : "/root/.ethereum/devchain/keystore/" ,
173+ ReadOnly : false ,
174+ }, mount.Mount {
175+ Type : mount .TypeBind ,
176+ Source : configDir ,
177+ Target : "/root/config/" ,
178+ ReadOnly : false ,
179+ })
180+ },
181+ Files : []testcontainers.ContainerFile {
182+ {
183+ HostFilePath : initScriptFile .Name (),
184+ ContainerFilePath : "/root/init.sh" ,
185+ FileMode : 0644 ,
186+ },
187+ {
188+ HostFilePath : genesisFile .Name (),
189+ ContainerFilePath : "/root/genesis.json" ,
190+ FileMode : 0644 ,
191+ },
75192 },
76193 WaitingFor : wait .ForListeningPort (nat .Port (in .Port )).WithStartupTimeout (15 * time .Second ),
77194 Cmd : entryPoint ,
0 commit comments