diff --git a/accountwallet/faucet.go b/accountwallet/faucet.go index 2ab321a..5b43d60 100644 --- a/accountwallet/faucet.go +++ b/accountwallet/faucet.go @@ -46,7 +46,7 @@ func (a *AccountWallet) RequestFaucetFunds(clt models.Client, receiveAddr iotago return nil, ierrors.Wrap(err, "failed to request funds from faucet") } - outputID, outputStruct, err := utils.AwaitAddressUnspentOutputToBeAccepted(clt, receiveAddr, 10*time.Second) + outputID, outputStruct, err := utils.AwaitAddressUnspentOutputToBeAccepted(clt, receiveAddr) if err != nil { return nil, ierrors.Wrap(err, "failed to await faucet funds") } diff --git a/evilwallet/evilwallet.go b/evilwallet/evilwallet.go index 4621fb6..5ef6a9f 100644 --- a/evilwallet/evilwallet.go +++ b/evilwallet/evilwallet.go @@ -25,9 +25,6 @@ const ( // FaucetRequestSplitNumber defines the number of outputs to split from a faucet request. FaucetRequestSplitNumber = 120 faucetTokensPerRequest iotago.BaseToken = 432_000_000 - - waitForAcceptance = 20 * time.Second - awaitAcceptationSleep = 1 * time.Second ) var ( @@ -286,7 +283,7 @@ func (e *EvilWallet) requestFaucetFunds(wallet *Wallet) (output *models.Output, return nil, ierrors.Wrap(err, "failed to request funds from faucet") } - outputID, iotaOutput, err := utils.AwaitAddressUnspentOutputToBeAccepted(clt, receiveAddr, 10*time.Second) + outputID, iotaOutput, err := utils.AwaitAddressUnspentOutputToBeAccepted(clt, receiveAddr) if err != nil { return nil, ierrors.Wrap(err, "failed to await faucet output acceptance") } diff --git a/evilwallet/output_manager.go b/evilwallet/output_manager.go index d27c68f..90b3251 100644 --- a/evilwallet/output_manager.go +++ b/evilwallet/output_manager.go @@ -2,7 +2,6 @@ package evilwallet import ( "sync" - "time" "go.uber.org/atomic" @@ -14,10 +13,6 @@ import ( iotago "github.com/iotaledger/iota.go/v4" ) -const ( - awaitOutputToBeConfirmed = 10 * time.Second -) - // OutputManager keeps track of the output statuses. type OutputManager struct { connector models.Connector @@ -117,7 +112,7 @@ func (o *OutputManager) Track(outputIDs ...iotago.OutputID) (allConfirmed bool) go func(id iotago.OutputID, clt models.Client) { defer wg.Done() - if !utils.AwaitOutputToBeAccepted(clt, id, awaitOutputToBeConfirmed) { + if !utils.AwaitOutputToBeAccepted(clt, id) { unconfirmedOutputFound.Store(true) } }(ID, o.connector.GetClient()) @@ -239,7 +234,7 @@ func (o *OutputManager) AwaitTransactionsAcceptance(txIDs ...iotago.TransactionI defer func() { <-semaphore }() - err := utils.AwaitTransactionToBeAccepted(clt, txID, waitForAcceptance, txLeft) + err := utils.AwaitTransactionToBeAccepted(clt, txID, txLeft) txLeft.Dec() if err != nil { o.log.Errorf("Error awaiting transaction %s to be accepted: %s", txID.String(), err) diff --git a/spammer/spamming_functions.go b/spammer/spamming_functions.go index 17dd7ba..09caff2 100644 --- a/spammer/spamming_functions.go +++ b/spammer/spamming_functions.go @@ -138,7 +138,7 @@ func createBlowBallCenter(s *Spammer) (iotago.BlockID, error) { }, }, s.IssuerAlias, clt) - err := utils.AwaitBlockToBeConfirmed(clt, centerID, 30*time.Second) + err := utils.AwaitBlockToBeConfirmed(clt, centerID) return centerID, err } diff --git a/utils/utils.go b/utils/utils.go index 194a376..0506f5e 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -4,20 +4,24 @@ import ( "context" "time" + "go.uber.org/atomic" + evillogger "github.com/iotaledger/evil-tools/logger" "github.com/iotaledger/evil-tools/models" "github.com/iotaledger/hive.go/ierrors" "github.com/iotaledger/hive.go/lo" iotago "github.com/iotaledger/iota.go/v4" "github.com/iotaledger/iota.go/v4/nodeclient/apimodels" - "go.uber.org/atomic" ) var UtilsLogger = evillogger.New("Utils") const ( - waitForAcceptance = 20 * time.Second - awaitAcceptationSleep = 1 * time.Second + MaxRetries = 20 + AwaitInterval = 1 * time.Second + + confirmed = "confirmed" + finalized = "finalized" ) // SplitBalanceEqually splits the balance equally between `splitNumber` outputs. @@ -41,27 +45,25 @@ func SplitBalanceEqually(splitNumber int, balance iotago.BaseToken) []iotago.Bas // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // AwaitTransactionToBeAccepted awaits for acceptance of a single transaction. -func AwaitBlockToBeConfirmed(clt models.Client, blkID iotago.BlockID, waitFor time.Duration) error { - s := time.Now() - - for ; time.Since(s) < waitFor; time.Sleep(awaitAcceptationSleep) { +func AwaitBlockToBeConfirmed(clt models.Client, blkID iotago.BlockID) error { + for i := 0; i < MaxRetries; i++ { state := clt.GetBlockConfirmationState(blkID) - if state == "confirmed" || state == "finalized" { + if state == confirmed || state == finalized { return nil } + + time.Sleep(AwaitInterval) } UtilsLogger.Debugf("Block not confirmed: %s", blkID.ToHex()) return ierrors.Errorf("Block not confirmed: %s", blkID.ToHex()) - } // AwaitTransactionToBeAccepted awaits for acceptance of a single transaction. -func AwaitTransactionToBeAccepted(clt models.Client, txID iotago.TransactionID, waitFor time.Duration, txLeft *atomic.Int64) error { - s := time.Now() +func AwaitTransactionToBeAccepted(clt models.Client, txID iotago.TransactionID, txLeft *atomic.Int64) error { var accepted bool - for ; time.Since(s) < waitFor; time.Sleep(awaitAcceptationSleep) { + for i := 0; i < MaxRetries; i++ { resp, err := clt.GetBlockState(txID) if resp == nil { UtilsLogger.Debugf("Block state API error: %v", err) @@ -87,6 +89,8 @@ func AwaitTransactionToBeAccepted(clt models.Client, txID iotago.TransactionID, accepted = true break } + + time.Sleep(AwaitInterval) } if !accepted { return ierrors.Errorf("transaction %s not accepted in time", txID) @@ -97,16 +101,15 @@ func AwaitTransactionToBeAccepted(clt models.Client, txID iotago.TransactionID, return nil } -func AwaitAddressUnspentOutputToBeAccepted(clt models.Client, addr iotago.Address, waitFor time.Duration) (outputID iotago.OutputID, output iotago.Output, err error) { +func AwaitAddressUnspentOutputToBeAccepted(clt models.Client, addr iotago.Address) (outputID iotago.OutputID, output iotago.Output, err error) { indexer, err := clt.Indexer() if err != nil { return iotago.EmptyOutputID, nil, ierrors.Wrap(err, "failed to get indexer client") } - s := time.Now() addrBech := addr.Bech32(clt.CommittedAPI().ProtocolParameters().Bech32HRP()) - for ; time.Since(s) < waitFor; time.Sleep(awaitAcceptationSleep) { + for i := 0; i < MaxRetries; i++ { res, err := indexer.Outputs(context.Background(), &apimodels.BasicOutputsQuery{ AddressBech32: addrBech, }) @@ -127,6 +130,8 @@ func AwaitAddressUnspentOutputToBeAccepted(clt models.Client, addr iotago.Addres return lo.Return1(res.Response.Items.OutputIDs())[0], unspents[0], nil } + + time.Sleep(AwaitInterval) } return iotago.EmptyOutputID, nil, ierrors.Errorf("no unspent outputs found for address %s due to timeout", addrBech) @@ -134,15 +139,16 @@ func AwaitAddressUnspentOutputToBeAccepted(clt models.Client, addr iotago.Addres // AwaitOutputToBeAccepted awaits for output from a provided outputID is accepted. Timeout is waitFor. // Useful when we have only an address and no transactionID, e.g. faucet funds request. -func AwaitOutputToBeAccepted(clt models.Client, outputID iotago.OutputID, waitFor time.Duration) (accepted bool) { - s := time.Now() +func AwaitOutputToBeAccepted(clt models.Client, outputID iotago.OutputID) (accepted bool) { accepted = false - for ; time.Since(s) < waitFor; time.Sleep(awaitAcceptationSleep) { + for i := 0; i < MaxRetries; i++ { confirmationState := clt.GetOutputConfirmationState(outputID) if confirmationState == "confirmed" { accepted = true break } + + time.Sleep(AwaitInterval) } return accepted