diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index f9afe08498..0fde89de6c 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -12,6 +12,8 @@ #### Orchestrator +- The "insufficient sender reserve" error now reports which check failed and the values involved (faceValue vs ticketEV vs sender max float, or faceValue vs redemption tx cost) so operators can tell whether the sender's reserve, `-ticketEV`, or `-maxFaceValue` needs adjusting + #### Transcoder ### Bug Fixes 🐞 diff --git a/pm/recipient.go b/pm/recipient.go index 2199842489..6eef5cbcc3 100644 --- a/pm/recipient.go +++ b/pm/recipient.go @@ -4,6 +4,7 @@ import ( "crypto/hmac" "crypto/rand" "crypto/sha256" + "fmt" "math/big" "sync" @@ -293,7 +294,7 @@ func (r *recipient) faceValue(sender ethcommon.Address) (*big.Int, error) { monitor.MaxFloat(sender.Hex(), maxFloat) } if faceValue.Cmp(r.cfg.EV) < 0 { - return nil, errInsufficientSenderReserve + return nil, fmt.Errorf("%w: faceValue %v is less than ticketEV %v (sender max float: %v); the sender's reserve is too low for this orchestrator's -ticketEV", errInsufficientSenderReserve, faceValue, r.cfg.EV, maxFloat) } // faceValue must be >= txCostWithGasPrice(current gasPrice) OR >= txCostWithGasPrice(avg gasPrice) @@ -309,7 +310,7 @@ func (r *recipient) faceValue(sender ethcommon.Address) (*big.Int, error) { // and needs to be redeemed. // For now, avgGasPrice is hardcoded. See the comment for avgGasPrice for TODO information. if faceValue.Cmp(txCost) < 0 && faceValue.Cmp(r.txCostWithGasPrice(avgGasPrice)) < 0 { - return nil, errInsufficientSenderReserve + return nil, fmt.Errorf("%w: faceValue %v cannot cover the ticket redemption tx cost (at current gas price: %v, at avg gas price: %v); increase -maxFaceValue or the sender's reserve", errInsufficientSenderReserve, faceValue, txCost, r.txCostWithGasPrice(avgGasPrice)) } return faceValue, nil diff --git a/pm/recipient_test.go b/pm/recipient_test.go index d84f5fab39..4cb0edc4f7 100644 --- a/pm/recipient_test.go +++ b/pm/recipient_test.go @@ -528,7 +528,8 @@ func TestTicketParams(t *testing.T) { // Test insufficient sender reserve error due to maxFloat < EV sm.maxFloat = new(big.Int).Sub(cfg.EV, big.NewInt(1)) _, err = r.TicketParams(sender, big.NewRat(1, 1)) - assert.EqualError(err, errInsufficientSenderReserve.Error()) + assert.ErrorIs(err, errInsufficientSenderReserve) + assert.ErrorContains(err, "less than ticketEV") // Test faceValue < txCostWithGasPrice(current gasPrice) and faceValue > txCostWithGasPrice(avg gasPrice) // Set current gasPrice higher than avg gasPrice @@ -553,7 +554,8 @@ func TestTicketParams(t *testing.T) { require.True(sm.maxFloat.Cmp(txCost) < 0) require.True(sm.maxFloat.Cmp(txCostAvgGasPrice) < 0) _, err = r.TicketParams(sender, big.NewRat(1, 1)) - assert.EqualError(err, errInsufficientSenderReserve.Error()) + assert.ErrorIs(err, errInsufficientSenderReserve) + assert.ErrorContains(err, "cannot cover the ticket redemption tx cost") // Test lazy evaluation when faceValue > txCostWithGasPrice(current gasPrice) // Set current gasPrice lower than avg gasPrice @@ -587,7 +589,7 @@ func TestTicketParams(t *testing.T) { sm.maxFloat = big.NewInt(0) // Set maxFloat to some value less than EV _, err = r.TicketParams(sender, big.NewRat(1, 1)) - assert.EqualError(err, errInsufficientSenderReserve.Error()) + assert.ErrorIs(err, errInsufficientSenderReserve) } func TestTxCostMultiplier_UsingFaceValue_ReturnsDefaultMultiplier(t *testing.T) { @@ -638,7 +640,7 @@ func TestTxCostMultiplier_InsufficientReserve_ReturnsError(t *testing.T) { mul, err := r.TxCostMultiplier(sender) assert.Nil(t, mul) - assert.EqualError(t, err, errInsufficientSenderReserve.Error()) + assert.ErrorIs(t, err, errInsufficientSenderReserve) } func TestTxCostMultiplier_ZeroTxCost_Returns_Zero(t *testing.T) {