Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions utils/tx/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,40 +77,51 @@
close(errChan)
}()

// Process results
// Fix race condition: previously we checked error count prematurely and could
// exit before API polling discovered the tx. Now we wait for both goroutines
// to complete before deciding success/failure.
var errors []error
resultChanClosed := false
errChanClosed := false

for {
select {
case result, ok := <-resultChan:
if ok && result.Success {
if !ok {
resultChanClosed = true
} else if result.Success {
spinner.Success(fmt.Sprintf("Transaction succeeded via %s!", result.Source))
pterm.Info.Printf("Gas wanted: %d, Gas used: %d\n", result.GasWanted, result.GasUsed)
cancel()
return nil
} else if ok && !result.Success {
} else {
spinner.Fail(fmt.Sprintf("Transaction failed via %s", result.Source))
cancel()
return fmt.Errorf("transaction failed with code %d: %s", result.Code, result.Log)
}
case err := <-errChan:
if err != nil {
case err, ok := <-errChan:
if !ok {
errChanClosed = true
} else if err != nil {
errors = append(errors, err)
}
case <-ctx.Done():
spinner.Fail("Timeout waiting for transaction")
return fmt.Errorf("timeout waiting for transaction")
}

if len(errors) == 2 || (strings.HasPrefix(endpoint, "ws") && len(errors) == 1) {
spinner.Fail("All monitoring methods failed")
return fmt.Errorf("all monitoring methods failed: %v", errors)
}

if resultChan == nil && errChan == nil {
// Only exit after both goroutines have completed
if resultChanClosed && errChanClosed {
break
}
}

// Only report failure after both methods have finished
if len(errors) > 0 {
spinner.Fail("All monitoring methods failed")
return fmt.Errorf("all monitoring methods failed: %v", errors)
}

spinner.Fail("Transaction monitoring completed without result")
return fmt.Errorf("transaction monitoring completed without finding transaction")
}
Expand Down Expand Up @@ -291,9 +302,9 @@
if err != nil {
continue
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
resp.Body.Close()

Check failure on line 307 in utils/tx/tx.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `resp.Body.Close` is not checked (errcheck)
continue
}

Expand All @@ -309,6 +320,7 @@
}

body, err := io.ReadAll(resp.Body)
resp.Body.Close()

Check failure on line 323 in utils/tx/tx.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `resp.Body.Close` is not checked (errcheck)
if err != nil {
continue
}
Expand Down
Loading