Skip to content

Commit

Permalink
feat: prefund default accounts with 4337 eth
Browse files Browse the repository at this point in the history
  • Loading branch information
V00D00-child committed Jul 1, 2024
1 parent 79eb7b4 commit 81fc8e6
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 78 deletions.
18 changes: 15 additions & 3 deletions cmd/betsy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func main() {
log.Err(err).Msg("Failed to run ETH node conatiner")
return nil
case <-readyChan:
log.Info().Msg("ETH node is ready, starting bundler and creating wallet...")
log.Info().Msg("ETH node is ready, starting bundler and creating and funding dev wallet...")

// create dev wallet
bestyWallet, err := wallet.NewWallet(
Expand All @@ -179,10 +179,22 @@ func main() {
log.Err(err).Msg("Failed to create wallet")
return nil
}
bestyWallet.PrintDevAccounts()

err = bestyWallet.PrintDevAccounts(ctx)
if err != nil {
log.Err(err).Msg("Failed to print dev accounts")
return nil
}

// Start the bundler container
ctxWithBundlerDetails := context.WithValue(ctx, docker.BundlerNodeWalletDetails, wallet.BundlerWalletDetails{
Beneficiary: bestyWallet.BundlerBeneficiaryAddress,
Mnemonic: wallet.DefaultSeedPhrase,
EntryPointAddress: bestyWallet.EntryPointAddress,
})

_, err = containerManager.RunContainerInTheBackground(
ctxWithReadyChan,
ctxWithBundlerDetails,
cCtx.String("bundler"),
strconv.Itoa(cCtx.Int("bundler.port")),
)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ require (
github.com/ethereum/go-ethereum v1.14.5
github.com/gin-gonic/gin v1.10.0
github.com/rs/zerolog v1.33.0
github.com/tyler-smith/go-bip32 v1.0.0
github.com/tyler-smith/go-bip39 v1.1.0
github.com/urfave/cli/v2 v2.27.2
)

Expand Down Expand Up @@ -68,8 +70,6 @@ require (
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8=
github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw=
Expand Down Expand Up @@ -356,6 +357,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
Expand Down
127 changes: 60 additions & 67 deletions internal/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import (
const EthNodeReady = "ethNodeReady"
const EthNodePortPlaceHolder = "$ETH_PORT"

const BundlerNodeWalletDetails = "bundlerNodeWalletDetails"
const BundlerNodeEPAddressPlaceHolder = "$ENTRYPOINT_ADDRESS"
const BundlerNodeBeneficiaryAddressPlaceHolder = "$BENEFICIARY"
const BundlerNodeMnemonicPlaceHolder = "$MNEMONIC"

// ContainerManager manages containers
type ContainerManager struct {
supportedImages map[string]ContainerDetails
Expand Down Expand Up @@ -66,8 +71,9 @@ func NewContainerManager() (*ContainerManager, error) {
"--network", "http://host.docker.internal:" + EthNodePortPlaceHolder,
},
Env: []string{
"TRANSEPTOR_MNEMONIC=" + wallet.DefaultSeedPhrase,
"TRANSEPTOR_BENEFICIARY=0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
"TRANSEPTOR_MNEMONIC=" + BundlerNodeMnemonicPlaceHolder,
"TRANSEPTOR_BENEFICIARY=" + BundlerNodeBeneficiaryAddressPlaceHolder,
"TRANSEPTOR_ENTRYPOINT_ADDRESS=" + BundlerNodeEPAddressPlaceHolder,
},
ExposedPorts: nil,
NodeType: "bundler",
Expand Down Expand Up @@ -200,14 +206,35 @@ func (cm *ContainerManager) RunContainerInTheBackground(ctx context.Context, ima

// Update bundler node cmd with ethnode port
if imageFound.NodeType == "bundler" {
foundIndex := 0
foundIndexPort := 0
for index, item := range imageFound.Cmd {
if strings.HasSuffix(item, "ETH_PORT") {
foundIndex = index
if strings.HasSuffix(item, EthNodePortPlaceHolder) {
foundIndexPort = index
break
}
}
imageFound.Cmd[foundIndex] = strings.Replace(imageFound.Cmd[foundIndex], EthNodePortPlaceHolder, cm.EthNodePort, 1)
imageFound.Cmd[foundIndexPort] = strings.Replace(imageFound.Cmd[foundIndexPort], EthNodePortPlaceHolder, cm.EthNodePort, 1)

bundlerDetails := ctx.Value(BundlerNodeWalletDetails).(wallet.BundlerWalletDetails)
foundIndexBeneficiary := 0
foundIndexMnemonic := 0
foundIndexEntryPointAddress := 0
for index, item := range imageFound.Env {
if strings.HasSuffix(item, BundlerNodeBeneficiaryAddressPlaceHolder) {
foundIndexBeneficiary = index
}

if strings.Contains(item, BundlerNodeMnemonicPlaceHolder) {
foundIndexMnemonic = index
}

if strings.Contains(item, BundlerNodeEPAddressPlaceHolder) {
foundIndexEntryPointAddress = index
}
}
imageFound.Env[foundIndexEntryPointAddress] = strings.Replace(imageFound.Env[foundIndexEntryPointAddress], BundlerNodeEPAddressPlaceHolder, bundlerDetails.EntryPointAddress.Hex(), 1)
imageFound.Env[foundIndexBeneficiary] = strings.Replace(imageFound.Env[foundIndexBeneficiary], BundlerNodeBeneficiaryAddressPlaceHolder, bundlerDetails.Beneficiary.Hex(), 1)
imageFound.Env[foundIndexMnemonic] = strings.Replace(imageFound.Env[foundIndexMnemonic], BundlerNodeMnemonicPlaceHolder, bundlerDetails.Mnemonic, 1)
}

constinerPort := hostPort + "/tcp"
Expand Down Expand Up @@ -276,7 +303,7 @@ func (cm *ContainerManager) RunContainerInTheBackground(ctx context.Context, ima
}

log.Info().Msgf("Attempting to find eth.coinbase keystore file at /tmp on container: %s", resp.ID)
coinbaseKeystoreFile, err := findCoinbaseKeystoreFileNative(resp.ID, "tmp")
coinbaseKeystoreFile, err := findCoinbaseKeystoreFile(resp.ID, "tmp")
if err != nil {
return false, err
}
Expand All @@ -292,49 +319,38 @@ func (cm *ContainerManager) RunContainerInTheBackground(ctx context.Context, ima
return true, nil
}

// TODO: Fix the EOF error when runing the ls command on the container
// findCoinbaseKeystoreFile executes the ls command to find keystore file for the temporary pre-allocated developer account available and unlocked as eth.coinbase(using docker api client)
func findCoinbaseKeystoreFile(ctx context.Context, client *client.Client, containerID string, dir string) (string, error) {
execConfig := container.ExecOptions{
Cmd: []string{"ls", dir},
AttachStdout: true,
AttachStderr: true,
}
execIDResp, err := client.ContainerExecCreate(ctx, containerID, execConfig)
if err != nil {
return "", err
}
// StopAndRemoveRunningContainers stops all running containers that are supported
func (cm *ContainerManager) StopAndRemoveRunningContainers(ctx context.Context) (bool, error) {
for _, containerDetails := range cm.supportedImages {
if containerDetails.IsRunning {
log.Info().Msgf("Attempting to stop container %s", containerDetails.ContainerID)
noWaitTimeout := 0

respAttach, err := client.ContainerExecAttach(ctx, execIDResp.ID, container.ExecStartOptions{})
if err != nil {
return "", err
}
defer respAttach.Close()
if err := cm.client.ContainerStop(ctx, containerDetails.ContainerID, container.StopOptions{Timeout: &noWaitTimeout}); err != nil {
return false, err
}
log.Info().Msgf("Successfully stopped container %s", containerDetails.ContainerID)

output := make([]byte, 1024)
n, err := respAttach.Reader.Read(output)
if err != nil {
fmt.Println("Got a error when listing:", err)
return "", err
if err := cm.client.ContainerRemove(ctx, containerDetails.ContainerID, container.RemoveOptions{}); err != nil {
return false, err
}
log.Info().Msgf("Successfully removed container %s", containerDetails.ContainerID)
}
}

fmt.Printf("Files in /tmp:\n%s\n", string(output[:n]))
return string(output[:n]), nil
return true, nil
}

// findCoinbaseKeystoreFileNative executes the ls command to find keystore file for the temporary pre-allocated developer account available and unlocked as eth.coinbase(using docker exec)
func findCoinbaseKeystoreFileNative(containerID string, dir string) (string, error) {
// findCoinbaseKeystoreFile executes the ls command to find keystore file for the temporary pre-allocated developer account available and unlocked as eth.coinbase(using docker exec)
func findCoinbaseKeystoreFile(containerID string, dir string) (string, error) {
cmd := exec.Command("docker", "exec", containerID, "ls", dir)
output, err := cmd.Output()
if err != nil {
return "", err
}

// Print the output for debugging purposes
fmt.Println("Files in directory:", dir)
fmt.Println(string(output))

// Recursive find
log.Debug().Msgf("Files in directory: %s\n%s", dir, string(output))
fileList := strings.Split(strings.TrimSpace(string(output)), "\n")
for _, file := range fileList {
if strings.Contains(file, "UTC") {
Expand All @@ -356,7 +372,7 @@ func findCoinbaseKeystoreFileNative(containerID string, dir string) (string, err
if !strings.Contains(file, ".") { // Assuming files without dots are directories
newDir := strings.TrimSuffix(dir, "/") + "/" + file
log.Info().Msgf("Not found, searching deeper in directory: %s", newDir)
foundPath, err := findCoinbaseKeystoreFileNative(containerID, newDir)
foundPath, err := findCoinbaseKeystoreFile(containerID, newDir)
if err == nil {
return foundPath, nil
}
Expand All @@ -368,11 +384,10 @@ func findCoinbaseKeystoreFileNative(containerID string, dir string) (string, err
return "", fmt.Errorf("keystore file not found in directory: %s", dir)
}

// copyFileFromContainer copies a file from a Docker container to the local filesystem
func copyFileFromContainer(containerID, filePath string, destDir string) error {
// Determine the destination path on the host machine
destPath := filepath.Join(destDir, filepath.Base(filePath))
destLocalFilePath := filepath.Join(destDir, filepath.Base(filePath))

// Ensure the destination directory exists
if err := os.MkdirAll(destDir, 0755); err != nil {
log.Error().Err(err).Msgf("Error creating directory %s", destDir)
return err
Expand All @@ -387,42 +402,20 @@ func copyFileFromContainer(containerID, filePath string, destDir string) error {
}

// Create a new file in local directory
destFile, err := os.Create(destPath)
destFile, err := os.Create(destLocalFilePath)
if err != nil {
log.Error().Err(err).Msgf("Error creating file %s", destPath)
log.Error().Err(err).Msgf("Error creating file %s", destLocalFilePath)
return err
}
defer destFile.Close()

// Write the file contents to the local file
_, err = destFile.Write(output)
if err != nil {
log.Error().Err(err).Msgf("Error writing to file %s", destPath)
log.Error().Err(err).Msgf("Error writing to file %s", destLocalFilePath)
return err
}

log.Info().Msgf("Copied file %s from container %s to %s", filePath, containerID, destPath)
log.Info().Msgf("Copied file %s from container %s to %s", filePath, containerID, destLocalFilePath)
return nil
}

// StopAndRemoveRunningContainers stops all running containers that are supported
func (cm *ContainerManager) StopAndRemoveRunningContainers(ctx context.Context) (bool, error) {
for _, containerDetails := range cm.supportedImages {
if containerDetails.IsRunning {
log.Info().Msgf("Attempting to stop container %s", containerDetails.ContainerID)
noWaitTimeout := 0

if err := cm.client.ContainerStop(ctx, containerDetails.ContainerID, container.StopOptions{Timeout: &noWaitTimeout}); err != nil {
return false, err
}
log.Info().Msgf("Successfully stopped container %s", containerDetails.ContainerID)

if err := cm.client.ContainerRemove(ctx, containerDetails.ContainerID, container.RemoveOptions{}); err != nil {
return false, err
}
log.Info().Msgf("Successfully removed container %s", containerDetails.ContainerID)
}
}

return true, nil
}
Loading

0 comments on commit 81fc8e6

Please sign in to comment.