github.com/smartcontractkit/chainlink-testing-framework/libs@v0.0.0-20240227141906-ec710b4eb1a3/docker/test_env/non_dev_geth.go (about) 1 package test_env 2 3 import ( 4 "encoding/hex" 5 "fmt" 6 "io" 7 "os" 8 "strconv" 9 "strings" 10 "testing" 11 "time" 12 13 "github.com/ethereum/go-ethereum/accounts/keystore" 14 "github.com/ethereum/go-ethereum/common" 15 "github.com/ethereum/go-ethereum/ethclient" 16 "github.com/google/uuid" 17 "github.com/rs/zerolog" 18 "github.com/rs/zerolog/log" 19 tc "github.com/testcontainers/testcontainers-go" 20 tcwait "github.com/testcontainers/testcontainers-go/wait" 21 22 "github.com/smartcontractkit/chainlink-testing-framework/libs/blockchain" 23 "github.com/smartcontractkit/chainlink-testing-framework/libs/docker" 24 "github.com/smartcontractkit/chainlink-testing-framework/libs/logging" 25 "github.com/smartcontractkit/chainlink-testing-framework/libs/mirror" 26 "github.com/smartcontractkit/chainlink-testing-framework/libs/utils/templates" 27 "github.com/smartcontractkit/chainlink-testing-framework/libs/utils/testcontext" 28 ) 29 30 const ( 31 TX_NON_DEV_GETH_WS_PORT = "8546" 32 BOOTNODE_PORT = "30301" 33 ) 34 35 var ( 36 FundingAddresses = map[string]string{ 37 "f39fd6e51aad88f6f4ce6ab8827279cfffb92266": `{"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}`, 38 "70997970c51812dc3a010c7d01b50e0d17dc79c8": `{"address":"70997970c51812dc3a010c7d01b50e0d17dc79c8","crypto":{"cipher":"aes-128-ctr","ciphertext":"f8183fa00bc112645d3e23e29a233e214f7c708bf49d72750c08af88ad76c980","cipherparams":{"iv":"796d08e3e1f71bde89ed826abda96cda"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"03c864a22a1f7b06b1da12d8b93e024ac144f898285907c58b2abc135fc8a35c"},"mac":"5fe91b1a1821c0d9f85dfd582354ead9612e9a7e9adc38b06a2beff558c119ac"},"id":"d2cab765-5e30-42ae-bb91-f090d9574fae","version":3}`, 39 "3c44cdddb6a900fa2b585dd299e03d12fa4293bc": `{"address":"3c44cdddb6a900fa2b585dd299e03d12fa4293bc","crypto":{"cipher":"aes-128-ctr","ciphertext":"2cd6ab87086c47f343f2c4d957eace7986f3b3c87fc35a2aafbefb57a06d9f1c","cipherparams":{"iv":"4e16b6cd580866c1aa642fb4d7312c9b"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"0cabde93877f6e9a59070f9992f7a01848618263124835c90d4d07a0041fc57c"},"mac":"94b7776ea95b0ecd8406c7755acf17b389b7ebe489a8942e32082dfdc1f04f57"},"id":"ade1484b-a3bb-426f-9223-a1f5e3bde2e8","version":3}`, 40 "90f79bf6eb2c4f870365e785982e1f101e93b906": `{"address":"90f79bf6eb2c4f870365e785982e1f101e93b906","crypto":{"cipher":"aes-128-ctr","ciphertext":"15144214d323871e00f7b205368128061c91b77a27b7deec935f8f5b734f0d42","cipherparams":{"iv":"bb22ba8051ef9f60abded7a9f4f2c6ae"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"07331ef3035567c00830b4e50d5dd68bc877974b4ce38cd42fef755be01556c9"},"mac":"2294eacadaf2761851814451d8c7dcca20a606a0344335d98f09403aba4e82ca"},"id":"96af8cc7-97e1-4bba-8968-632b034986c2","version":3}`, 41 "15d34aaf54267db7d7c367839aaf71a00a2c6a65": `{"address":"15d34aaf54267db7d7c367839aaf71a00a2c6a65","crypto":{"cipher":"aes-128-ctr","ciphertext":"057878284a6c74d3ad99910adddd6b477b383837dbf2280efea585f0f0fdb012","cipherparams":{"iv":"e6eab29d60b526f305f8d47badf48687"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"dfdca8066d2486da5cb9a909d03744e2a8c6537930271e85e7cd8a5d952c0f22"},"mac":"f8352be41c9a06d69111ca4d8fcff0eef079b68b1173cad99803538991716c5d"},"id":"a35bb452-0d57-42d5-8d25-5a00a40a4db8","version":3}`, 42 "9965507d1a55bcc2695c58ba16fb37d819b0a4dc": `{"address":"9965507d1a55bcc2695c58ba16fb37d819b0a4dc","crypto":{"cipher":"aes-128-ctr","ciphertext":"5a73201500307c6aa98edd44d962b344a893768331454a61595ec848e738e9d2","cipherparams":{"iv":"5282de2b3e2b305019a2fed5c62f3383"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"6ad001831d097f175fff7d6cf61301e9620b32afd9a7a6437e6030af14576a96"},"mac":"0a55eddbd13c713aa8b8c4106b2fb62bc1d1e18e7177207a444f83a4d8426ed5"},"id":"27aed2b2-cb94-4d37-8819-b15219187bb5","version":3}`, 43 "976ea74026e726554db657fa54763abd0c3a0aa9": `{"address":"976ea74026e726554db657fa54763abd0c3a0aa9","crypto":{"cipher":"aes-128-ctr","ciphertext":"a6edf11e81b38e60a549696236cb9efc026e87adc45a9521ea7b2c45a2a9fbb9","cipherparams":{"iv":"82f4c79cd4b28a8585a9c78d758f832b"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"87400e16ecc320dadff85eccbf4dbaaea2dd91e50047e4aa391799bb319c1fd8"},"mac":"80c83dad05998db6c673a97096fcfad54636458f4a3c82483686b253f8cc9b69"},"id":"fc7d7694-6206-48fc-bb25-36b523f90df6","version":3}`, 44 "14dc79964da2c08b23698b3d3cc7ca32193d9955": `{"address":"14dc79964da2c08b23698b3d3cc7ca32193d9955","crypto":{"cipher":"aes-128-ctr","ciphertext":"410f258bc8b12a0250cba22cbc5e413534fcf90bf322ced6943189ad9e43b4b9","cipherparams":{"iv":"1dd6077a8bee9b3bf2ca90e6abc8a237"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"5d3358bf99bbcb82354f40e5501abf4336bc141ee05d8feed4fbe7eb8c08c917"},"mac":"9cd959fa1e8129a8deb86e0264ec81d6cde79b5a19ae259b7d00543c9037908a"},"id":"689d7ad2-fe46-4c09-9c2a-a50e607989b8","version":3}`, 45 "23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f": `{"address":"23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f","crypto":{"cipher":"aes-128-ctr","ciphertext":"13dccac740314edea20d44e6f3592575bbcb739ec5892d635326cff3c386eb86","cipherparams":{"iv":"bf42d811cd41fa97ddcae3425f8c3211"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"d2fa67cbb5e86d5bf9a90e27b8747bac493614b45778d43e9da1c14e06b2401d"},"mac":"7d2797cf344704d8f36265238d3938e06952c78ab7dfcbac53dc7f472c93d933"},"id":"4c8e899e-80f0-4417-9b1e-c5e29049f1e7","version":3}`, 46 "a0ee7a142d267c1f36714e4a8f75612f20a79720": `{"address":"a0ee7a142d267c1f36714e4a8f75612f20a79720","crypto":{"cipher":"aes-128-ctr","ciphertext":"56bc8766f47aeafae74eea333e1e890a3776d7fae6c48cbdbffb270655ce050d","cipherparams":{"iv":"a66129e6a110b3ddf93b4355aa147c58"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"15c4e8bcc80920139eb236d91194825f1fce27dd2af281e0f2752d8a5dbc48bd"},"mac":"db01e720866ce8bb7897dfc7773e064003ad53429a79732ee769cf6d02273570"},"id":"87b2d76f-1b70-4e4f-8b2a-5d1915c1177c","version":3}`, 47 "bcd4042de499d14e55001ccbb24a551f3b954096": `{"address":"bcd4042de499d14e55001ccbb24a551f3b954096","crypto":{"cipher":"aes-128-ctr","ciphertext":"e455eda6e38d246c03b930f845adfc8721ca75e9f47135cd4c18dbc3e5c5440a","cipherparams":{"iv":"0b1a0a24acc1ad25b0f170f751c2cb27"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"69f324ed0787794878bf5f84d4dbbc70dec1274cad666399edc48640605f64c8"},"mac":"f07da09c460a69f943f5639545d2b3f72c1e9789f0421ad41d3078ea3db12c96"},"id":"7ec7bb3c-c486-4785-a4fc-f8f4b2fc7764","version":3}`, 48 "71be63f3384f5fb98995898a86b02fb2426c5788": `{"address":"71be63f3384f5fb98995898a86b02fb2426c5788","crypto":{"cipher":"aes-128-ctr","ciphertext":"4194377a05fd3d13e0a3155dad974a003fe5f7a3b5acb35d7d97c50daa8990d4","cipherparams":{"iv":"607670778baf62b1e86394cf1980487a"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"d63b890ad7f4fcc857681faabe9319dffc53893966ef0810bf64c4f319b0ffc5"},"mac":"bfaf924959e65c8030ece259d52ed52d5d21bd74f1a67ae545d4bb289a479e16"},"id":"0c6af842-384f-49b6-b5b7-199a1e05486b","version":3}`, 49 } 50 ) 51 52 type PrivateGethChain struct { 53 PrimaryNode *NonDevGethNode 54 Nodes []*NonDevGethNode 55 NetworkConfig *blockchain.EVMNetwork 56 DockerNetworks []string 57 } 58 59 func NewPrivateGethChain(networkCfg *blockchain.EVMNetwork, dockerNetworks []string) PrivateChain { 60 evmChain := &PrivateGethChain{ 61 NetworkConfig: networkCfg, 62 DockerNetworks: dockerNetworks, 63 } 64 evmChain.PrimaryNode = NewNonDevGethNode(dockerNetworks, networkCfg) 65 evmChain.Nodes = []*NonDevGethNode{evmChain.PrimaryNode} 66 return evmChain 67 } 68 69 func (p *PrivateGethChain) WithTestInstance(t *testing.T) *PrivateGethChain { 70 p.PrimaryNode.l = logging.GetTestLogger(t) 71 return p 72 } 73 74 func (p *PrivateGethChain) GetPrimaryNode() NonDevNode { 75 return p.PrimaryNode 76 } 77 78 func (p *PrivateGethChain) GetNodes() []NonDevNode { 79 nodes := make([]NonDevNode, 0) 80 for _, node := range p.Nodes { 81 nodes = append(nodes, node) 82 } 83 return nodes 84 } 85 86 func (p *PrivateGethChain) GetNetworkConfig() *blockchain.EVMNetwork { 87 return p.NetworkConfig 88 } 89 90 func (p *PrivateGethChain) GetDockerNetworks() []string { 91 return p.DockerNetworks 92 } 93 94 type gethTxNodeConfig struct { 95 networkCfg *blockchain.EVMNetwork 96 chainId string 97 bootnodeInitPath string 98 genesisPath string 99 rootPath string 100 keystorePath string 101 initPath string 102 bootNodeURL string 103 accountAddr string 104 } 105 106 type NonDevGethNode struct { 107 EnvComponent 108 Config gethTxNodeConfig 109 ExternalHttpUrl string 110 InternalHttpUrl string 111 ExternalWsUrl string 112 InternalWsUrl string 113 EVMClient blockchain.EVMClient 114 EthClient *ethclient.Client 115 t *testing.T 116 l zerolog.Logger 117 } 118 119 func NewNonDevGethNode(networks []string, networkCfg *blockchain.EVMNetwork) *NonDevGethNode { 120 return &NonDevGethNode{ 121 Config: gethTxNodeConfig{ 122 chainId: strconv.FormatInt(networkCfg.ChainID, 10), 123 networkCfg: networkCfg, 124 }, 125 EnvComponent: EnvComponent{ 126 ContainerName: fmt.Sprintf("%s-%s", 127 strings.ReplaceAll(networkCfg.Name, " ", "_"), uuid.NewString()[0:3]), 128 Networks: networks, 129 }, 130 l: log.Logger, 131 } 132 } 133 134 func (g *NonDevGethNode) GetInternalHttpUrl() string { 135 return g.InternalHttpUrl 136 } 137 138 func (g *NonDevGethNode) GetInternalWsUrl() string { 139 return g.InternalWsUrl 140 } 141 142 func (g *NonDevGethNode) GetEVMClient() blockchain.EVMClient { 143 return g.EVMClient 144 } 145 146 func (g *NonDevGethNode) WithTestInstance(t *testing.T) NonDevNode { 147 g.t = t 148 g.l = logging.GetTestLogger(t) 149 return g 150 } 151 152 func (g *NonDevGethNode) createMountDirs() error { 153 initScriptFile, err := os.CreateTemp("", "init_script") 154 if err != nil { 155 return err 156 } 157 _, err = initScriptFile.WriteString(templates.InitNonDevGethScript) 158 if err != nil { 159 return err 160 } 161 g.Config.initPath = initScriptFile.Name() 162 163 bootinitScriptFile, err := os.CreateTemp("", "bootnode_init_script") 164 if err != nil { 165 return err 166 } 167 _, err = bootinitScriptFile.WriteString(templates.BootnodeScript) 168 if err != nil { 169 return err 170 } 171 g.Config.bootnodeInitPath = bootinitScriptFile.Name() 172 173 keystorePath, err := os.MkdirTemp("", "keystore") 174 if err != nil { 175 return err 176 } 177 g.Config.keystorePath = keystorePath 178 179 // Create keystore and ethereum account 180 ks := keystore.NewKeyStore(g.Config.keystorePath, keystore.StandardScryptN, keystore.StandardScryptP) 181 account, err := ks.NewAccount("") 182 if err != nil { 183 return err 184 } 185 g.Config.accountAddr = account.Address.Hex() 186 addr := strings.Replace(account.Address.Hex(), "0x", "", 1) 187 FundingAddresses[addr] = "" 188 signerBytes, err := hex.DecodeString(addr) 189 if err != nil { 190 fmt.Println("Error decoding signer address:", err) 191 return err 192 } 193 194 zeroBytes := make([]byte, 32) // Create 32 zero bytes 195 extradata := append(zeroBytes, signerBytes...) // Concatenate zero bytes and signer address 196 extradata = append(extradata, make([]byte, 65)...) // Concatenate 65 more zero bytes 197 198 fmt.Printf("Encoded extradata: 0x%s\n", hex.EncodeToString(extradata)) 199 200 i := 1 201 var accounts []string 202 for addr, v := range FundingAddresses { 203 if v == "" { 204 continue 205 } 206 f, err := os.Create(fmt.Sprintf("%s/%s", g.Config.keystorePath, fmt.Sprintf("key%d", i))) 207 if err != nil { 208 return err 209 } 210 _, err = f.WriteString(v) 211 if err != nil { 212 return err 213 } 214 i++ 215 accounts = append(accounts, addr) 216 } 217 err = os.WriteFile(g.Config.keystorePath+"/password.txt", []byte(""), 0600) 218 if err != nil { 219 return err 220 } 221 222 genesisJsonStr, err := templates.BuildGenesisJsonForNonDevChain(g.Config.chainId, accounts, fmt.Sprintf("0x%s", hex.EncodeToString(extradata))) 223 if err != nil { 224 return err 225 } 226 f, err := os.CreateTemp("", "genesis_json") 227 if err != nil { 228 return err 229 } 230 defer f.Close() 231 _, err = f.WriteString(genesisJsonStr) 232 if err != nil { 233 return err 234 } 235 236 g.Config.genesisPath = f.Name() 237 238 configDir, err := os.MkdirTemp("", "config") 239 if err != nil { 240 return err 241 } 242 g.Config.rootPath = configDir 243 244 return nil 245 } 246 247 func (g *NonDevGethNode) Start() error { 248 err := g.createMountDirs() 249 if err != nil { 250 return err 251 } 252 253 l := logging.GetTestContainersGoTestLogger(g.t) 254 bncr, err := g.getBootNodeContainerRequest() 255 if err != nil { 256 return err 257 } 258 bootNode, err := docker.StartContainerWithRetry(g.l, tc.GenericContainerRequest{ 259 ContainerRequest: bncr, 260 Reuse: true, 261 Started: true, 262 Logger: l, 263 }) 264 if err != nil { 265 return err 266 } 267 host, err := bootNode.Host(testcontext.Get(g.t)) 268 if err != nil { 269 return err 270 } 271 r, err := bootNode.CopyFileFromContainer(testcontext.Get(g.t), "/root/.ethereum/bootnodes") 272 if err != nil { 273 return err 274 } 275 defer r.Close() 276 b, err := io.ReadAll(r) 277 if err != nil { 278 return err 279 } 280 g.Config.bootNodeURL = fmt.Sprintf("enode://%s@%s:0?discport=%s", strings.TrimSpace(string(b)), host, BOOTNODE_PORT) 281 282 cr, err := g.getGethContainerRequest() 283 if err != nil { 284 return err 285 } 286 ct, err := docker.StartContainerWithRetry(g.l, tc.GenericContainerRequest{ 287 ContainerRequest: cr, 288 Reuse: true, 289 Started: true, 290 }) 291 if err != nil { 292 return err 293 } 294 g.Container = ct 295 return nil 296 } 297 298 func (g *NonDevGethNode) ConnectToClient() error { 299 ct := g.Container 300 if ct == nil { 301 return fmt.Errorf("container not started") 302 } 303 host, err := GetHost(testcontext.Get(g.t), ct) 304 if err != nil { 305 return err 306 } 307 port := NatPort(TX_GETH_HTTP_PORT) 308 httpPort, err := ct.MappedPort(testcontext.Get(g.t), port) 309 if err != nil { 310 return err 311 } 312 wsPort, err := ct.MappedPort(testcontext.Get(g.t), NatPort(TX_NON_DEV_GETH_WS_PORT)) 313 if err != nil { 314 return err 315 } 316 317 g.ExternalHttpUrl = fmt.Sprintf("http://%s:%s", host, httpPort.Port()) 318 g.InternalHttpUrl = fmt.Sprintf("http://%s:%s", g.ContainerName, TX_GETH_HTTP_PORT) 319 g.ExternalWsUrl = fmt.Sprintf("ws://%s:%s", host, wsPort.Port()) 320 g.InternalWsUrl = fmt.Sprintf("ws://%s:%s", g.ContainerName, TX_NON_DEV_GETH_WS_PORT) 321 322 networkConfig := g.Config.networkCfg 323 networkConfig.URLs = []string{g.ExternalWsUrl} 324 networkConfig.HTTPURLs = []string{g.ExternalHttpUrl} 325 326 ec, err := blockchain.NewEVMClientFromNetwork(*networkConfig, g.l) 327 if err != nil { 328 return err 329 } 330 at, err := ec.BalanceAt(testcontext.Get(g.t), common.HexToAddress("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266")) 331 if err != nil { 332 return err 333 } 334 fmt.Printf("balance: %s\n", at.String()) 335 g.EVMClient = ec 336 // to make sure all the pending txs are done 337 err = ec.WaitForEvents() 338 if err != nil { 339 return err 340 } 341 switch val := ec.(type) { 342 case *blockchain.EthereumMultinodeClient: 343 ethClient, ok := val.Clients[0].(*blockchain.EthereumClient) 344 if !ok { 345 return fmt.Errorf("could not get blockchain.EthereumClient from %+v", val) 346 } 347 g.EthClient = ethClient.Client 348 default: 349 return fmt.Errorf("%+v not supported for geth", val) 350 } 351 if err != nil { 352 return err 353 } 354 return nil 355 } 356 357 func (g *NonDevGethNode) getBootNodeContainerRequest() (tc.ContainerRequest, error) { 358 bootNodeImage, err := mirror.GetImage("ethereum/client-go:alltools") 359 if err != nil { 360 return tc.ContainerRequest{}, err 361 } 362 return tc.ContainerRequest{ 363 Name: g.ContainerName + "-bootnode", 364 Image: bootNodeImage, 365 Networks: g.Networks, 366 ExposedPorts: []string{"30301/udp"}, 367 WaitingFor: tcwait.ForLog("New local node record"). 368 WithStartupTimeout(999 * time.Second). 369 WithPollInterval(1 * time.Second), 370 Cmd: []string{"sh", "./root/boot_init.sh"}, 371 Files: []tc.ContainerFile{ 372 { 373 HostFilePath: g.Config.bootnodeInitPath, 374 ContainerFilePath: "/root/boot_init.sh", 375 FileMode: 0644, 376 }, 377 }, 378 Mounts: tc.ContainerMounts{ 379 tc.ContainerMount{ 380 Source: tc.GenericBindMountSource{ 381 HostPath: g.Config.rootPath, 382 }, 383 Target: "/root/.ethereum/", 384 }, 385 }, 386 }, nil 387 } 388 func (g *NonDevGethNode) getGethContainerRequest() (tc.ContainerRequest, error) { 389 gethImage, err := mirror.GetImage("ethereum/client-go:v") 390 if err != nil { 391 return tc.ContainerRequest{}, err 392 } 393 return tc.ContainerRequest{ 394 Name: g.ContainerName, 395 Image: gethImage, 396 ExposedPorts: []string{ 397 NatPortFormat(TX_GETH_HTTP_PORT), 398 NatPortFormat(TX_NON_DEV_GETH_WS_PORT), 399 "30303/tcp", "30303/udp"}, 400 Networks: g.Networks, 401 WaitingFor: tcwait.ForAll( 402 NewHTTPStrategy("/", NatPort(TX_GETH_HTTP_PORT)), 403 tcwait.ForLog("WebSocket enabled"), 404 NewWebSocketStrategy(NatPort(TX_NON_DEV_GETH_WS_PORT), g.l), 405 ), 406 Entrypoint: []string{"/bin/sh", "./root/init.sh", 407 "--http.vhosts=*", 408 "--nousb", "--metrics", "--nocompaction", "--syncmode", "full", 409 "--gcmode", "archive", 410 fmt.Sprintf("--bootnodes=%s", g.Config.bootNodeURL), 411 "--http", 412 "--http.corsdomain", "*", 413 "--http.api", "admin,debug,web3,eth,txpool,personal,clique,miner,net", 414 "--http.addr", "0.0.0.0", 415 fmt.Sprintf("--http.port=%s", TX_GETH_HTTP_PORT), 416 "--ws", 417 "--ws.origins", "*", 418 "--ws.api", "admin,debug,web3,eth,txpool,personal,clique,miner,net", 419 "--ws.addr", "0.0.0.0", 420 fmt.Sprintf("--ws.port=%s", TX_NON_DEV_GETH_WS_PORT), 421 "--unlock", g.Config.accountAddr, 422 "--mine", 423 "--miner.etherbase", g.Config.accountAddr, 424 "--miner.extradata", "tx", 425 "--miner.gasprice", "1", 426 "--miner.gaslimit", "400000000000000", 427 "--miner.extradata", "tx", 428 fmt.Sprintf("--networkid=%s", g.Config.chainId), 429 "--allow-insecure-unlock", 430 "--password", "/root/.ethereum/keystore/password.txt", 431 "--verbosity=5", 432 "--rpc.allow-unprotected-txs", 433 "--rpc.gascap", "0", 434 "--rpc.txfeecap", "0", 435 }, 436 Files: []tc.ContainerFile{ 437 { 438 HostFilePath: g.Config.initPath, 439 ContainerFilePath: "/root/init.sh", 440 FileMode: 0644, 441 }, 442 { 443 HostFilePath: g.Config.genesisPath, 444 ContainerFilePath: "/root/genesis.json", 445 FileMode: 0644, 446 }, 447 }, 448 Mounts: tc.ContainerMounts{ 449 tc.ContainerMount{ 450 Source: tc.GenericBindMountSource{ 451 HostPath: g.Config.keystorePath, 452 }, 453 Target: "/root/.ethereum/keystore/", 454 }, 455 tc.ContainerMount{ 456 Source: tc.GenericBindMountSource{ 457 HostPath: g.Config.rootPath, 458 }, 459 Target: "/root/.ethereum/", 460 }, 461 }, 462 }, nil 463 }