github.com/smartcontractkit/chainlink-testing-framework/libs@v0.0.0-20240227141906-ec710b4eb1a3/docker/test_env/eth2_init_helpers.go (about) 1 package test_env 2 3 import ( 4 "bytes" 5 "fmt" 6 "html/template" 7 "os" 8 "testing" 9 "time" 10 11 "github.com/google/uuid" 12 "github.com/rs/zerolog" 13 "github.com/rs/zerolog/log" 14 tc "github.com/testcontainers/testcontainers-go" 15 16 "github.com/smartcontractkit/chainlink-testing-framework/libs/docker" 17 "github.com/smartcontractkit/chainlink-testing-framework/libs/logging" 18 ) 19 20 type AfterGenesisHelper struct { 21 EnvComponent 22 chainConfig EthereumChainConfig 23 l zerolog.Logger 24 customConfigDataDir string 25 addressesToFund []string 26 t *testing.T 27 } 28 29 func NewInitHelper(chainConfig EthereumChainConfig, customConfigDataDir string, opts ...EnvComponentOption) *AfterGenesisHelper { 30 g := &AfterGenesisHelper{ 31 EnvComponent: EnvComponent{ 32 ContainerName: fmt.Sprintf("%s-%s", "after-genesis-helper", uuid.NewString()[0:8]), 33 }, 34 chainConfig: chainConfig, 35 customConfigDataDir: customConfigDataDir, 36 l: log.Logger, 37 addressesToFund: []string{}, 38 } 39 g.SetDefaultHooks() 40 for _, opt := range opts { 41 opt(&g.EnvComponent) 42 } 43 return g 44 } 45 46 func (g *AfterGenesisHelper) WithTestInstance(t *testing.T) *AfterGenesisHelper { 47 g.l = logging.GetTestLogger(t) 48 g.t = t 49 return g 50 } 51 52 func (g *AfterGenesisHelper) StartContainer() error { 53 r, err := g.getContainerRequest(g.Networks) 54 if err != nil { 55 return err 56 } 57 58 l := logging.GetTestContainersGoTestLogger(g.t) 59 _, err = docker.StartContainerWithRetry(g.l, tc.GenericContainerRequest{ 60 ContainerRequest: *r, 61 Reuse: true, 62 Started: true, 63 Logger: l, 64 }) 65 if err != nil { 66 return fmt.Errorf("cannot start after genesis helper container: %w", err) 67 } 68 69 g.l.Info().Str("containerName", g.ContainerName). 70 Msg("Started After Genesis Helper container") 71 72 return nil 73 } 74 75 func (g *AfterGenesisHelper) getContainerRequest(networks []string) (*tc.ContainerRequest, error) { 76 initScriptFile, err := os.CreateTemp("", "init.sh") 77 if err != nil { 78 return nil, err 79 } 80 81 initScript, err := g.buildInitScript() 82 if err != nil { 83 return nil, err 84 } 85 86 _, err = initScriptFile.WriteString(initScript) 87 if err != nil { 88 return nil, err 89 } 90 91 return &tc.ContainerRequest{ 92 Name: g.ContainerName, 93 Image: "protolambda/eth2-val-tools:latest", 94 ImagePlatform: "linux/x86_64", 95 Networks: networks, 96 WaitingFor: NewExitCodeStrategy().WithExitCode(0). 97 WithPollInterval(1 * time.Second).WithTimeout(10 * time.Second), 98 Entrypoint: []string{"sh", "/init.sh"}, 99 Files: []tc.ContainerFile{ 100 { 101 HostFilePath: initScriptFile.Name(), 102 ContainerFilePath: "/init.sh", 103 FileMode: 0744, 104 }, 105 }, 106 Mounts: tc.ContainerMounts{ 107 tc.ContainerMount{ 108 Source: tc.GenericBindMountSource{ 109 HostPath: g.customConfigDataDir, 110 }, 111 Target: tc.ContainerMountTarget(GENERATED_DATA_DIR_INSIDE_CONTAINER), 112 }, 113 }, 114 LifecycleHooks: []tc.ContainerLifecycleHooks{ 115 { 116 PostStarts: g.PostStartsHooks, 117 PostStops: g.PostStopsHooks, 118 }, 119 }, 120 }, nil 121 } 122 123 func (g *AfterGenesisHelper) buildInitScript() (string, error) { 124 initTemplate := `#!/bin/bash 125 echo "Saving wallet password to {{.WalletPasswordFileLocation}}" 126 echo "{{.WalletPassword}}" > {{.WalletPasswordFileLocation}} 127 echo "Saving execution client keystore file to {{.AccountKeystoreFileLocation}}" 128 mkdir -p {{.KeystoreDirLocation}} 129 echo '{"address":"123463a4b065722e99115d6c222f267d9cabb524","crypto":{"cipher":"aes-128-ctr","ciphertext":"93b90389b855889b9f91c89fd15b9bd2ae95b06fe8e2314009fc88859fc6fde9","cipherparams":{"iv":"9dc2eff7967505f0e6a40264d1511742"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"c07503bb1b66083c37527cd8f06f8c7c1443d4c724767f625743bd47ae6179a4"},"mac":"6d359be5d6c432d5bbb859484009a4bf1bd71b76e89420c380bd0593ce25a817"},"id":"622df904-0bb1-4236-b254-f1b8dfdff1ec","version":3}' > {{.AccountKeystoreFileLocation}} 130 echo "Saving execution client account password to {{.AccountPasswordFileLocation}}" 131 echo "" > {{.AccountPasswordFileLocation}} 132 echo "Saving jwt secret to {{.JwtFileLocation}}" 133 echo "0xfad2709d0bb03bf0e8ba3c99bea194575d3e98863133d1af638ed056d1d59345" > {{.JwtFileLocation}} 134 echo "All done!" 135 echo 136 echo "------------------------------------------------------------------" 137 formatted_genesis_date=$(date -d "@{{.GenesisTimestamp}}" '+%Y-%m-%d %H:%M:%S') 138 echo "Chain genesis timestamp: $formatted_genesis_date UTC" 139 140 current_timestamp=$(date +%s) 141 time_diff=$(({{.GenesisTimestamp}} - current_timestamp)) 142 echo "More or less $time_diff seconds from now" 143 echo "------------------------------------------------------------------" 144 ` 145 146 data := struct { 147 WalletPassword string 148 WalletPasswordFileLocation string 149 AccountPasswordFileLocation string 150 JwtFileLocation string 151 AccountKeystoreFileLocation string 152 KeystoreDirLocation string 153 GenesisTimestamp int 154 }{ 155 WalletPassword: WALLET_PASSWORD, 156 WalletPasswordFileLocation: VALIDATOR_WALLET_PASSWORD_FILE_INSIDE_CONTAINER, 157 AccountPasswordFileLocation: ACCOUNT_PASSWORD_FILE_INSIDE_CONTAINER, 158 JwtFileLocation: JWT_SECRET_FILE_LOCATION_INSIDE_CONTAINER, 159 AccountKeystoreFileLocation: ACCOUNT_KEYSTORE_FILE_INSIDE_CONTAINER, 160 KeystoreDirLocation: KEYSTORE_DIR_LOCATION_INSIDE_CONTAINER, 161 GenesisTimestamp: g.chainConfig.genesisTimestamp, 162 } 163 164 t, err := template.New("init").Parse(initTemplate) 165 if err != nil { 166 fmt.Println("Error parsing template:", err) 167 os.Exit(1) 168 } 169 170 var buf bytes.Buffer 171 err = t.Execute(&buf, data) 172 173 return buf.String(), err 174 }