@@ -12,7 +12,6 @@ import (
1212 "github.com/ethereum/go-ethereum/accounts/abi/bind"
1313 "github.com/ethereum/go-ethereum/common"
1414 "github.com/ethereum/go-ethereum/core/types"
15- ethtypes "github.com/ethereum/go-ethereum/core/types"
1615 "github.com/ethereum/go-ethereum/crypto"
1716 "github.com/ethereum/go-ethereum/ethclient"
1817 "github.com/rs/zerolog/log"
@@ -161,20 +160,76 @@ func (ap *AccountPool) AddReusableNonce(address common.Address, nonce uint64) er
161160 return nil
162161}
163162
164- func (ap * AccountPool ) FundAccounts () error {
163+ func (ap * AccountPool ) FundAccounts (ctx context. Context ) error {
165164 ap .mu .Lock ()
166165 defer ap .mu .Unlock ()
167166
167+ wg := sync.WaitGroup {}
168+ wg .Add (len (ap .accounts ))
169+
170+ txCh := make (chan * types.Transaction , len (ap .accounts ))
171+ errCh := make (chan error , len (ap .accounts ))
172+
173+ tops , err := bind .NewKeyedTransactorWithChainID (ap .fundingPrivateKey , ap .chainID )
174+ if err != nil {
175+ log .Error ().Err (err ).Msg ("Unable create transaction signer" )
176+ return err
177+ }
178+
179+ nonce , err := ap .client .PendingNonceAt (ctx , tops .From )
180+ if err != nil {
181+ log .Error ().Err (err ).Msg ("Unable to get nonce" )
182+ }
183+
168184 for i := range ap .accounts {
169- account := ap .accounts [i ]
170- if ! account .funded {
171- err := ap .fundAccountIfNeeded (context .Background (), account )
185+ accountToFund := ap .accounts [i ]
186+ go func (forcedNonce uint64 , account Account ) {
187+ defer wg .Done ()
188+ if ! account .funded {
189+ tx , err := ap .fundAccountIfNeeded (ctx , account , & forcedNonce , false )
190+ if err != nil {
191+ errCh <- fmt .Errorf ("failed to fund account: %w" , err )
192+ }
193+ if tx != nil {
194+ txCh <- tx
195+ }
196+ }
197+ }(nonce , accountToFund )
198+ nonce ++
199+ }
200+
201+ wg .Wait ()
202+
203+ close (errCh )
204+ close (txCh )
205+
206+ for err := range errCh {
207+ if err != nil {
208+ return err
209+ }
210+ }
211+
212+ for tx := range txCh {
213+ if tx != nil {
214+ log .Debug ().
215+ Str ("address" , tx .To ().Hex ()).
216+ Str ("txHash" , tx .Hash ().Hex ()).
217+ Msg ("transaction to fund account sent" )
218+
219+ _ , err := ap .waitMined (ctx , tx )
172220 if err != nil {
173- return fmt .Errorf ("failed to fund account: %w" , err )
221+ log .Error ().
222+ Str ("address" , tx .To ().Hex ()).
223+ Str ("txHash" , tx .Hash ().Hex ()).
224+ Msgf ("transaction to fund account failed" )
225+ return err
174226 }
175227 }
176228 }
177229
230+ log .Debug ().
231+ Msg ("All accounts funded" )
232+
178233 return nil
179234}
180235
@@ -209,7 +264,7 @@ func (ap *AccountPool) next(ctx context.Context) (Account, error) {
209264 }
210265 account := ap .accounts [ap .currentAccountIndex ]
211266
212- err := ap .fundAccountIfNeeded (ctx , account )
267+ _ , err := ap .fundAccountIfNeeded (ctx , account , nil , true )
213268 if err != nil {
214269 return Account {}, err
215270 }
@@ -232,45 +287,46 @@ func (ap *AccountPool) next(ctx context.Context) (Account, error) {
232287 return account , nil
233288}
234289
235- func (ap * AccountPool ) fundAccountIfNeeded (ctx context.Context , account Account ) error {
290+ func (ap * AccountPool ) fundAccountIfNeeded (ctx context.Context , account Account , forcedNonce * uint64 , waitToFund bool ) ( * types. Transaction , error ) {
236291 // if account is funded, return it
237292 if account .funded {
238- return nil
293+ return nil , nil
239294 }
240295
241296 // Check if the account must be funded
242- balance , err := ap .client .BalanceAt (context . Background () , account .address , nil )
297+ balance , err := ap .client .BalanceAt (ctx , account .address , nil )
243298 if err != nil {
244- return fmt .Errorf ("failed to check account balance: %w" , err )
299+ return nil , fmt .Errorf ("failed to check account balance: %w" , err )
245300 }
246301 // if account has enough balance
247302 if balance .Cmp (ap .fundingAmount ) >= 0 {
248- return nil
303+ return nil , nil
249304 }
250305
251306 // Fund the account
252307 log .Debug ().
253308 Str ("address" , account .address .Hex ()).
254309 Str ("balance" , balance .String ()).
255310 Msg ("account needs to be funded" )
256- _ , err = ap .fund (ctx , account , true )
311+ tx , err : = ap .fund (ctx , account , forcedNonce , waitToFund )
257312 if err != nil {
258- return fmt .Errorf ("failed to fund account: %w" , err )
313+ return nil , fmt .Errorf ("failed to fund account: %w" , err )
259314 }
260315
261- balance , err = ap .client .BalanceAt (context .Background (), account .address , nil )
262- if err != nil {
263- return fmt .Errorf ("failed to check account balance: %w" , err )
316+ if waitToFund {
317+ balance , err = ap .client .BalanceAt (ctx , account .address , nil )
318+ if err != nil {
319+ return tx , fmt .Errorf ("failed to check account balance: %w" , err )
320+ }
321+ log .Debug ().
322+ Str ("address" , account .address .Hex ()).
323+ Str ("balance" , balance .String ()).
324+ Msg ("account funded" )
264325 }
265- log .Debug ().
266- Str ("address" , account .address .Hex ()).
267- Str ("balance" , balance .String ()).
268- Msg ("account funded" )
269-
270- return nil
326+ return tx , nil
271327}
272328
273- func (ap * AccountPool ) fund (ctx context.Context , acc Account , waitToFund bool ) (* types.Transaction , error ) {
329+ func (ap * AccountPool ) fund (ctx context.Context , acc Account , forcedNonce * uint64 , waitToFund bool ) (* types.Transaction , error ) {
274330 // Fund the account
275331 ltp := inputLoadTestParams
276332
@@ -282,14 +338,20 @@ func (ap *AccountPool) fund(ctx context.Context, acc Account, waitToFund bool) (
282338 tops .GasLimit = uint64 (21000 )
283339 tops = configureTransactOpts (ctx , ap .client , tops )
284340
285- nonce , err := ap .client .PendingNonceAt (ctx , tops .From )
286- if err != nil {
287- log .Error ().Err (err ).Msg ("Unable to get nonce" )
341+ var nonce uint64
342+
343+ if forcedNonce != nil {
344+ nonce = * forcedNonce
345+ } else {
346+ nonce , err = ap .client .PendingNonceAt (ctx , tops .From )
347+ if err != nil {
348+ log .Error ().Err (err ).Msg ("Unable to get nonce" )
349+ }
288350 }
289351
290- var tx * ethtypes .Transaction
352+ var tx * types .Transaction
291353 if * ltp .LegacyTransactionMode {
292- tx = ethtypes .NewTx (& ethtypes .LegacyTx {
354+ tx = types .NewTx (& types .LegacyTx {
293355 Nonce : nonce ,
294356 To : & acc .address ,
295357 Value : ap .fundingAmount ,
@@ -298,7 +360,7 @@ func (ap *AccountPool) fund(ctx context.Context, acc Account, waitToFund bool) (
298360 Data : nil ,
299361 })
300362 } else {
301- dynamicFeeTx := & ethtypes .DynamicFeeTx {
363+ dynamicFeeTx := & types .DynamicFeeTx {
302364 ChainID : ap .chainID ,
303365 Nonce : nonce ,
304366 To : & acc .address ,
@@ -308,7 +370,7 @@ func (ap *AccountPool) fund(ctx context.Context, acc Account, waitToFund bool) (
308370 Data : nil ,
309371 Value : ap .fundingAmount ,
310372 }
311- tx = ethtypes .NewTx (dynamicFeeTx )
373+ tx = types .NewTx (dynamicFeeTx )
312374 }
313375
314376 signedTx , err := tops .Signer (* ltp .FromETHAddress , tx )
@@ -333,10 +395,18 @@ func (ap *AccountPool) fund(ctx context.Context, acc Account, waitToFund bool) (
333395 if err != nil {
334396 log .Error ().
335397 Str ("address" , acc .address .Hex ()).
336- Str ("txHash" , receipt . TxHash .Hex ()).
337- Msgf ("transaction to fund account failed " )
398+ Str ("txHash" , signedTx . Hash () .Hex ()).
399+ Msgf ("failed to wait for transaction to be mined " )
338400 return nil , err
339401 }
402+
403+ if receipt .Status != types .ReceiptStatusSuccessful {
404+ log .Error ().
405+ Str ("address" , acc .address .Hex ()).
406+ Str ("txHash" , receipt .TxHash .Hex ()).
407+ Msgf ("failed to wait for transaction to be mined" )
408+ return nil , fmt .Errorf ("transaction failed" )
409+ }
340410 }
341411
342412 return signedTx , nil
@@ -353,9 +423,6 @@ func (ap *AccountPool) waitMined(ctx context.Context, tx *types.Transaction) (*t
353423 Msg ("Unable to wait for transaction to be mined" )
354424 return nil , err
355425 }
356- if receipt .Status != ethtypes .ReceiptStatusSuccessful {
357- return nil , fmt .Errorf ("transaction failed" )
358- }
359426 return receipt , nil
360427}
361428
0 commit comments