@@ -30,7 +30,7 @@ const BundlerNodeMnemonicPlaceHolder = "$MNEMONIC"
3030
3131// ContainerManager manages containers
3232type ContainerManager struct {
33- supportedImages map [string ]ContainerDetails
33+ supportedImages map [string ]* ContainerDetails
3434 client * client.Client
3535 EthNodePort string
3636 CoinbaseKeystoreFile string
@@ -56,7 +56,7 @@ func NewContainerManager() (*ContainerManager, error) {
5656 }
5757
5858 return & ContainerManager {
59- supportedImages : map [string ]ContainerDetails {
59+ supportedImages : map [string ]* ContainerDetails {
6060 "transeptor" : {
6161 containerName : "betsy-transeptor" ,
6262 ContainerID : "" ,
@@ -78,6 +78,20 @@ func NewContainerManager() (*ContainerManager, error) {
7878 ExposedPorts : nil ,
7979 NodeType : "bundler" ,
8080 },
81+ "aabundler" : {
82+ containerName : "betsy-aabundler" ,
83+ ContainerID : "" ,
84+ imageName : "accountabstraction/bundler:0.7.0" ,
85+ IsRunning : false ,
86+ Cmd : []string {
87+ "--network" , "http://host.docker.internal:" + EthNodePortPlaceHolder ,
88+ "--entryPoint" , BundlerNodeEPAddressPlaceHolder ,
89+ "--beneficiary" , BundlerNodeBeneficiaryAddressPlaceHolder ,
90+ },
91+ Env : []string {},
92+ ExposedPorts : nil ,
93+ NodeType : "bundler" ,
94+ },
8195 "geth" : {
8296 containerName : "betsy-geth" ,
8397 ContainerID : "" ,
@@ -197,6 +211,35 @@ func (cm *ContainerManager) doPullImage(ctx context.Context, imageName string) (
197211 return true , nil
198212}
199213
214+ func (cm * ContainerManager ) doReplaceBundlerPlaceHolders (containerDetails * ContainerDetails , bwd wallet.BundlerWalletDetails ) {
215+ placeholders := map [string ]string {
216+ BundlerNodeEPAddressPlaceHolder : bwd .EntryPointAddress .Hex (),
217+ BundlerNodeBeneficiaryAddressPlaceHolder : bwd .Beneficiary .Hex (),
218+ BundlerNodeMnemonicPlaceHolder : bwd .Mnemonic ,
219+ EthNodePortPlaceHolder : cm .EthNodePort ,
220+ }
221+
222+ // Replace placeholders in Cmd slice
223+ for placeholder , value := range placeholders {
224+ replacePlaceHolderInSlice (& containerDetails .Cmd , placeholder , value )
225+ }
226+
227+ // Replace placeholders in Env slice
228+
229+ for placeholder , value := range placeholders {
230+ replacePlaceHolderInSlice (& containerDetails .Env , placeholder , value )
231+ }
232+ }
233+
234+ // replacePlaceHolderInSlice finds and replaces a placeholder in a slice of strings.
235+ func replacePlaceHolderInSlice (slice * []string , placeholder , replacement string ) {
236+ for i , item := range * slice {
237+ if strings .Contains (item , placeholder ) {
238+ (* slice )[i ] = strings .Replace (item , placeholder , replacement , 1 )
239+ }
240+ }
241+ }
242+
200243// RunContainerInTheBackground runs a Docker container in the background given its image and host port to bind
201244func (cm * ContainerManager ) RunContainerInTheBackground (ctx context.Context , image string , hostPort string ) (bool , error ) {
202245 imageFound , ok := cm .supportedImages [image ]
@@ -206,37 +249,11 @@ func (cm *ContainerManager) RunContainerInTheBackground(ctx context.Context, ima
206249
207250 // Update bundler node cmd with ethNode port
208251 if imageFound .NodeType == "bundler" {
209- foundIndexPort := 0
210- for index , item := range imageFound .Cmd {
211- if strings .HasSuffix (item , EthNodePortPlaceHolder ) {
212- foundIndexPort = index
213- break
214- }
215- }
216- imageFound .Cmd [foundIndexPort ] = strings .Replace (imageFound .Cmd [foundIndexPort ], EthNodePortPlaceHolder , cm .EthNodePort , 1 )
217-
218- bundlerDetails := ctx .Value (BundlerNodeWalletDetails ).(wallet.BundlerWalletDetails )
219- foundIndexBeneficiary := 0
220- foundIndexMnemonic := 0
221- foundIndexEntryPointAddress := 0
222- for index , item := range imageFound .Env {
223- if strings .HasSuffix (item , BundlerNodeBeneficiaryAddressPlaceHolder ) {
224- foundIndexBeneficiary = index
225- }
226-
227- if strings .Contains (item , BundlerNodeMnemonicPlaceHolder ) {
228- foundIndexMnemonic = index
229- }
230-
231- if strings .Contains (item , BundlerNodeEPAddressPlaceHolder ) {
232- foundIndexEntryPointAddress = index
233- }
234- }
235- imageFound .Env [foundIndexEntryPointAddress ] = strings .Replace (imageFound .Env [foundIndexEntryPointAddress ], BundlerNodeEPAddressPlaceHolder , bundlerDetails .EntryPointAddress .Hex (), 1 )
236- imageFound .Env [foundIndexBeneficiary ] = strings .Replace (imageFound .Env [foundIndexBeneficiary ], BundlerNodeBeneficiaryAddressPlaceHolder , bundlerDetails .Beneficiary .Hex (), 1 )
237- imageFound .Env [foundIndexMnemonic ] = strings .Replace (imageFound .Env [foundIndexMnemonic ], BundlerNodeMnemonicPlaceHolder , bundlerDetails .Mnemonic , 1 )
252+ bwd := ctx .Value (BundlerNodeWalletDetails ).(wallet.BundlerWalletDetails )
253+ cm .doReplaceBundlerPlaceHolders (imageFound , bwd )
238254 }
239255
256+ // Create and start the container
240257 containerPort := hostPort + "/tcp"
241258 config := & container.Config {
242259 Image : imageFound .imageName ,
@@ -245,13 +262,6 @@ func (cm *ContainerManager) RunContainerInTheBackground(ctx context.Context, ima
245262 ExposedPorts : nat.PortSet {
246263 nat .Port (containerPort ): struct {}{},
247264 },
248- // TODO: Use health check for bundlers and eth node
249- // HealthCheck: &container.HealthConfig{
250- // Test: []string{"CMD", "curl", "-f", "http://localhost:" + hostPort},
251- // Interval: 10 * time.Second,
252- // Timeout: 5 * time.Second,
253- // Retries: 5,
254- // },
255265 }
256266
257267 hostConfig := & container.HostConfig {
@@ -276,15 +286,11 @@ func (cm *ContainerManager) RunContainerInTheBackground(ctx context.Context, ima
276286
277287 // Update the container details
278288 log .Debug ().Msgf ("%s Container ID successfully started: %s\n " , image , resp .ID )
279- cm .supportedImages [image ] = ContainerDetails {
280- imageName : imageFound .imageName ,
281- Cmd : imageFound .Cmd ,
282- ExposedPorts : nat.PortSet {
283- nat .Port (containerPort ): struct {}{},
284- },
285- ContainerID : resp .ID ,
286- IsRunning : true ,
289+ imageFound .ExposedPorts = nat.PortSet {
290+ nat .Port (containerPort ): struct {}{},
287291 }
292+ imageFound .ContainerID = resp .ID
293+ imageFound .IsRunning = true
288294
289295 // Update EthNodeReady channel and signal that eth is ready by closing the channel
290296 if imageFound .NodeType == "eth" {
0 commit comments