diff --git a/parser/balance_changes.go b/parser/balance_changes.go index 69d23c46..8cd149b5 100644 --- a/parser/balance_changes.go +++ b/parser/balance_changes.go @@ -42,7 +42,11 @@ func (p *Parser) skipOperation(op *types.Operation) (bool, error) { successful, err := p.Asserter.OperationSuccessful(op) if err != nil { // Should only occur if responses not validated - return false, err + return false, fmt.Errorf( + "failed to check the status of operation %s: %w", + types.PrintStruct(op), + err, + ) } if !successful { @@ -82,7 +86,11 @@ func (p *Parser) BalanceChanges( for _, op := range tx.Operations { skip, err := p.skipOperation(op) if err != nil { - return nil, err + return nil, fmt.Errorf( + "failed to skip operation %s: %w", + types.PrintStruct(op), + err, + ) } if skip { continue @@ -96,7 +104,7 @@ func (p *Parser) BalanceChanges( if blockRemoved { negatedValue, err := types.NegateValue(amountValue) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to flip the sign of %s: %w", amountValue, err) } amountValue = negatedValue } @@ -121,7 +129,12 @@ func (p *Parser) BalanceChanges( newDifference, err := types.AddValues(val.Difference, amountValue) if err != nil { - return nil, err + return nil, fmt.Errorf( + "failed to add %s and %s: %w", + val.Difference, + amountValue, + err, + ) } val.Difference = newDifference balanceChanges[key] = val diff --git a/parser/intent.go b/parser/intent.go index 93c6bb39..64ef81a3 100644 --- a/parser/intent.go +++ b/parser/intent.go @@ -28,28 +28,28 @@ import ( func ExpectedOperation(intent *types.Operation, observed *types.Operation) error { if types.Hash(intent.Account) != types.Hash(observed.Account) { return fmt.Errorf( - "%w: expected %s but got %s", - ErrExpectedOperationAccountMismatch, + "expected operation account identifier %s but got %s: %w", types.PrettyPrintStruct(intent.Account), types.PrettyPrintStruct(observed.Account), + ErrExpectedOperationAccountMismatch, ) } if types.Hash(intent.Amount) != types.Hash(observed.Amount) { return fmt.Errorf( - "%w: expected %s but got %s", - ErrExpectedOperationAmountMismatch, + "expected operation amount %s but got %s: %w", types.PrettyPrintStruct(intent.Amount), types.PrettyPrintStruct(observed.Amount), + ErrExpectedOperationAmountMismatch, ) } if intent.Type != observed.Type { return fmt.Errorf( - "%w: expected %s but got %s", - ErrExpectedOperationTypeMismatch, + "expected operation type %s but got %s: %w", intent.Type, observed.Type, + ErrExpectedOperationTypeMismatch, ) } @@ -89,7 +89,11 @@ func (p *Parser) ExpectedOperations( if confirmSuccess { obsSuccess, err := p.Asserter.OperationSuccessful(obs) if err != nil { - return fmt.Errorf("%w: unable to check operation success", err) + return fmt.Errorf( + "failed to check the status of operation %s: %w", + types.PrintStruct(obs), + err, + ) } if !obsSuccess { @@ -168,9 +172,9 @@ func ExpectedSigners(intent []*types.SigningPayload, observed []*types.AccountId hash := types.Hash(payload.AccountIdentifier) if _, exists := seenSigners[hash]; !exists { return fmt.Errorf( - "%w: %s", - ErrExpectedSignerMissing, + "payload account identifier %s is invalid: %w", types.PrintStruct(payload.AccountIdentifier), + ErrExpectedSignerMissing, ) } } @@ -179,9 +183,9 @@ func ExpectedSigners(intent []*types.SigningPayload, observed []*types.AccountId // were not expected. if len(unmatched) != 0 { return fmt.Errorf( - "%w: %s", + "unmatched signers are %s: %w", + types.PrintStruct(unmatched), ErrExpectedSignerUnexpectedSigner, - types.PrettyPrintStruct(unmatched), ) } diff --git a/parser/match_operations.go b/parser/match_operations.go index fc2a0d80..c98dc248 100644 --- a/parser/match_operations.go +++ b/parser/match_operations.go @@ -186,15 +186,15 @@ func metadataMatch(reqs []*MetadataDescription, metadata map[string]interface{}) for _, req := range reqs { val, ok := metadata[req.Key] if !ok { - return fmt.Errorf("%w: %s", ErrMetadataMatchKeyNotFound, req.Key) + return fmt.Errorf("key %s is invalid: %w", req.Key, ErrMetadataMatchKeyNotFound) } if reflect.TypeOf(val).Kind() != req.ValueKind { return fmt.Errorf( - "%w: value of %s is not of type %s", - ErrMetadataMatchKeyValueMismatch, + "value of %s is not of type %s: %w", req.Key, req.ValueKind, + ErrMetadataMatchKeyValueMismatch, ) } } @@ -221,7 +221,11 @@ func accountMatch(req *AccountDescription, account *types.AccountIdentifier) err // Optionally can require a certain subaccount address if subaccount is present if account.SubAccount != nil { if err := verifySubAccountAddress(req.SubAccountAddress, account.SubAccount); err != nil { - return err + return fmt.Errorf( + "failed to verify sub account address %s: %w", + req.SubAccountAddress, + err, + ) } } return nil @@ -241,11 +245,11 @@ func accountMatch(req *AccountDescription, account *types.AccountIdentifier) err // Optionally can require a certain subaccount address if err := verifySubAccountAddress(req.SubAccountAddress, account.SubAccount); err != nil { - return err + return fmt.Errorf("failed to verify sub account address %s: %w", req.SubAccountAddress, err) } if err := metadataMatch(req.SubAccountMetadataKeys, account.SubAccount.Metadata); err != nil { - return fmt.Errorf("%w: account metadata keys mismatch", err) + return fmt.Errorf("account metadata keys mismatch: %w", err) } return nil @@ -259,10 +263,10 @@ func verifySubAccountAddress( ) error { if len(subAccountAddress) > 0 && subAccount.Address != subAccountAddress { return fmt.Errorf( - "%w: expected %s but got %s", - ErrAccountMatchUnexpectedSubAccountAddr, + "expected sub account address %s but got %s: %w", subAccountAddress, subAccount.Address, + ErrAccountMatchUnexpectedSubAccountAddr, ) } return nil @@ -288,7 +292,12 @@ func amountMatch(req *AmountDescription, amount *types.Amount) error { } if !req.Sign.Match(amount) { - return fmt.Errorf("%w: expected %s", ErrAmountMatchUnexpectedSign, req.Sign.String()) + return fmt.Errorf( + "expected amount sign of amount %s is %s: %w", + types.PrintStruct(amount), + req.Sign.String(), + ErrAmountMatchUnexpectedSign, + ) } // If no currency is provided, anything is ok. @@ -298,10 +307,10 @@ func amountMatch(req *AmountDescription, amount *types.Amount) error { if amount.Currency == nil || types.Hash(amount.Currency) != types.Hash(req.Currency) { return fmt.Errorf( - "%w: expected %+v but got %+v", + "expected currency %s but got %s: %w", + types.PrintStruct(req.Currency), + types.PrintStruct(amount.Currency), ErrAmountMatchUnexpectedCurrency, - req.Currency, - amount.Currency, ) } @@ -314,15 +323,19 @@ func coinActionMatch(requiredAction types.CoinAction, coinChange *types.CoinChan } if coinChange == nil { - return fmt.Errorf("%w: expected %s", ErrCoinActionMatchCoinChangeIsNil, requiredAction) + return fmt.Errorf( + "coin change of coin action %s is invalid: %w", + requiredAction, + ErrCoinActionMatchCoinChangeIsNil, + ) } if coinChange.CoinAction != requiredAction { return fmt.Errorf( - "%w: expected %s but got %s", - ErrCoinActionMatchUnexpectedCoinAction, + "expected coin action %s but got %s: %w", requiredAction, coinChange.CoinAction, + ErrCoinActionMatchUnexpectedCoinAction, ) } @@ -396,21 +409,30 @@ func equalAmounts(ops []*types.Operation) error { val, err := types.AmountValue(ops[0].Amount) if err != nil { - return err + return fmt.Errorf( + "failed to return big int representation of %s: %w", + types.PrintStruct(ops[0].Amount), + err, + ) } for _, op := range ops { otherVal, err := types.AmountValue(op.Amount) if err != nil { - return err + return fmt.Errorf( + "failed to return big int representation of %s: %w", + types.PrintStruct(op.Amount), + err, + ) } if val.Cmp(otherVal) != 0 { return fmt.Errorf( - "%w: %s is not equal to %s", - ErrEqualAmountsNotEqual, + "operation amount %s is not equal to operation amount %s in %s: %w", + types.PrintStruct(ops), val.String(), otherVal.String(), + ErrEqualAmountsNotEqual, ) } } @@ -423,24 +445,37 @@ func equalAmounts(ops []*types.Operation) error { func oppositeAmounts(a *types.Operation, b *types.Operation) error { aVal, err := types.AmountValue(a.Amount) if err != nil { - return err + return fmt.Errorf( + "failed to return big int representation of %s: %w", + types.PrintStruct(a.Amount), + err, + ) } bVal, err := types.AmountValue(b.Amount) if err != nil { - return err + return fmt.Errorf( + "failed to return big int representation of %s: %w", + types.PrintStruct(b.Amount), + err, + ) } if aVal.Sign() == bVal.Sign() { - return fmt.Errorf("%w: %s and %s", ErrOppositeAmountsSameSign, aVal.String(), bVal.String()) + return fmt.Errorf( + "%s and %s have the same sign: %w", + aVal.String(), + bVal.String(), + ErrOppositeAmountsSameSign, + ) } if aVal.CmpAbs(bVal) != 0 { return fmt.Errorf( - "%w: %s and %s", - ErrOppositeAmountsAbsValMismatch, + "the absolute value of %s and %s is not same: %w", aVal.String(), bVal.String(), + ErrOppositeAmountsAbsValMismatch, ) } @@ -452,12 +487,20 @@ func oppositeAmounts(a *types.Operation, b *types.Operation) error { func oppositeOrZeroAmounts(a *types.Operation, b *types.Operation) error { aVal, err := types.AmountValue(a.Amount) if err != nil { - return err + return fmt.Errorf( + "failed to return big int representation of %s: %w", + types.PrintStruct(a.Amount), + err, + ) } bVal, err := types.AmountValue(b.Amount) if err != nil { - return err + return fmt.Errorf( + "failed to return big int representation of %s: %w", + types.PrintStruct(b.Amount), + err, + ) } zero := big.NewInt(0) @@ -466,15 +509,20 @@ func oppositeOrZeroAmounts(a *types.Operation, b *types.Operation) error { } if aVal.Sign() == bVal.Sign() { - return fmt.Errorf("%w: %s and %s", ErrOppositeAmountsSameSign, aVal.String(), bVal.String()) + return fmt.Errorf( + "%s and %s have the same sign: %w", + aVal.String(), + bVal.String(), + ErrOppositeAmountsSameSign, + ) } if aVal.CmpAbs(bVal) != 0 { return fmt.Errorf( - "%w: %s and %s", - ErrOppositeAmountsAbsValMismatch, + "the absolute value of %s and %s is not same: %w", aVal.String(), bVal.String(), + ErrOppositeAmountsAbsValMismatch, ) } @@ -485,7 +533,7 @@ func oppositeOrZeroAmounts(a *types.Operation, b *types.Operation) error { // equal addresses. func equalAddresses(ops []*types.Operation) error { if len(ops) <= 1 { - return fmt.Errorf("%w: got %d operations", ErrEqualAddressesTooFewOperations, len(ops)) + return fmt.Errorf("got %d operations: %w", len(ops), ErrEqualAddressesTooFewOperations) } base := "" @@ -502,10 +550,11 @@ func equalAddresses(ops []*types.Operation) error { if base != op.Account.Address { return fmt.Errorf( - "%w: %s is not equal to %s", - ErrEqualAddressesAddrMismatch, + "operation address %s is not equal to operation address %s in operation list %s: %w", + types.PrintStruct(ops), base, op.Account.Address, + ErrEqualAddressesAddrMismatch, ) } } @@ -515,18 +564,10 @@ func equalAddresses(ops []*types.Operation) error { func matchIndexValid(matches []*Match, index int) error { if index >= len(matches) { - return fmt.Errorf( - "%w: at index %d", - ErrMatchIndexValidIndexOutOfRange, - index, - ) + return ErrMatchIndexValidIndexOutOfRange } if matches[index] == nil { - return fmt.Errorf( - "%w: at index %d", - ErrMatchIndexValidIndexIsNil, - index, - ) + return ErrMatchIndexValidIndexIsNil } return nil @@ -537,14 +578,14 @@ func checkOps(requests [][]int, matches []*Match, valid func([]*types.Operation) ops := []*types.Operation{} for _, reqIndex := range batch { if err := matchIndexValid(matches, reqIndex); err != nil { - return fmt.Errorf("%w: index %d not valid", err, reqIndex) + return fmt.Errorf("index %d is invalid: %w", reqIndex, err) } ops = append(ops, matches[reqIndex].Operations...) } if err := valid(ops); err != nil { - return fmt.Errorf("%w operations not valid", err) + return fmt.Errorf("operations %s are invalid: %w", types.PrintStruct(ops), err) } } @@ -565,26 +606,26 @@ func compareOppositeMatches( // compare all possible pairs if err := matchIndexValid(matches, amountMatch[0]); err != nil { - return fmt.Errorf("%w: amounts comparison error", err) + return fmt.Errorf("match index %d is invalid: %w", amountMatch[0], err) } if err := matchIndexValid(matches, amountMatch[1]); err != nil { - return fmt.Errorf("%w: amounts comparison error", err) + return fmt.Errorf("match index %d is invalid: %w", amountMatch[1], err) } match0Ops := matches[amountMatch[0]].Operations match1Ops := matches[amountMatch[1]].Operations if err := equalAmounts(match0Ops); err != nil { return fmt.Errorf( - "%w: amounts comparison error for match index %d", - err, + "operation amounts are not equal for match index %d: %w", amountMatch[0], + err, ) } if err := equalAmounts(match1Ops); err != nil { return fmt.Errorf( - "%w: amounts comparison error for match index %d", - err, + "operation amounts are not equal for match index %d: %w", amountMatch[1], + err, ) } @@ -595,7 +636,7 @@ func compareOppositeMatches( match0Ops[0], match1Ops[0], ); err != nil { - return fmt.Errorf("%w: amounts do not match the amountChecker function", err) + return fmt.Errorf("amounts do not match the amountChecker function: %w", err) } } @@ -609,18 +650,18 @@ func comparisonMatch( matches []*Match, ) error { if err := checkOps(descriptions.EqualAmounts, matches, equalAmounts); err != nil { - return fmt.Errorf("%w: operation amounts not equal", err) + return fmt.Errorf("operation amounts are not equal: %w", err) } if err := checkOps(descriptions.EqualAddresses, matches, equalAddresses); err != nil { - return fmt.Errorf("%w: operation addresses not equal", err) + return fmt.Errorf("operation addresses are not equal: %w", err) } if err := compareOppositeMatches(descriptions.OppositeAmounts, matches, oppositeAmounts); err != nil { - return fmt.Errorf("%w: operation amounts not opposite", err) + return fmt.Errorf("operation amounts are not opposite: %w", err) } if err := compareOppositeMatches(descriptions.OppositeOrZeroAmounts, matches, oppositeOrZeroAmounts); err != nil { - return fmt.Errorf("%w: both operation amounts not opposite and not zero", err) + return fmt.Errorf("both operation amounts not opposite and not zero: %w", err) } return nil @@ -675,9 +716,9 @@ func MatchOperations( matchFound := operationMatch(op, operationDescriptions, matches) if !matchFound && descriptions.ErrUnmatched { return nil, fmt.Errorf( - "%w: at index %d", - ErrMatchOperationsMatchNotFound, + "at index %d: %w", i, + ErrMatchOperationsMatchNotFound, ) } } @@ -685,14 +726,18 @@ func MatchOperations( // Error if any *OperationDescription is not matched for i := 0; i < len(matches); i++ { if matches[i] == nil && !descriptions.OperationDescriptions[i].Optional { - return nil, fmt.Errorf("%w: %d", ErrMatchOperationsDescriptionNotMatched, i) + return nil, fmt.Errorf( + "%d operation description is invalid: %w", + i, + ErrMatchOperationsDescriptionNotMatched, + ) } } // Once matches are found, assert high-level descriptions between // *types.Operations if err := comparisonMatch(descriptions, matches); err != nil { - return nil, fmt.Errorf("%w: group descriptions not met", err) + return nil, fmt.Errorf("group descriptions not met: %w", err) } return matches, nil diff --git a/reconciler/errors.go b/reconciler/errors.go index 836b1e90..06f5997b 100644 --- a/reconciler/errors.go +++ b/reconciler/errors.go @@ -33,11 +33,6 @@ var ( // does not exist in the store. This likely means // that the block was orphaned. ErrBlockGone = errors.New("block gone") - - ErrGetCurrentBlockFailed = errors.New("unable to get current block for reconciliation") - ErrBlockExistsFailed = errors.New("unable to check if block exists") - ErrGetComputedBalanceFailed = errors.New("unable to get computed balance") - ErrLiveBalanceLookupFailed = errors.New("unable to lookup live balance") ) // Err takes an error as an argument and returns @@ -46,10 +41,6 @@ func Err(err error) bool { reconcilerErrors := []error{ ErrHeadBlockBehindLive, ErrBlockGone, - ErrGetCurrentBlockFailed, - ErrBlockExistsFailed, - ErrGetComputedBalanceFailed, - ErrLiveBalanceLookupFailed, } return utils.FindError(reconcilerErrors, err) diff --git a/reconciler/reconciler.go b/reconciler/reconciler.go index a90fcdc3..a0b4750d 100644 --- a/reconciler/reconciler.go +++ b/reconciler/reconciler.go @@ -219,7 +219,7 @@ func (r *Reconciler) queueChanges( err := r.inactiveAccountQueue(false, acctCurrency, block, true) r.inactiveQueueMutex.Unlock() if err != nil { - return err + return fmt.Errorf("failed to enqueue inactive account: %w", err) } // All changes will have the same block. Continue @@ -232,7 +232,7 @@ func (r *Reconciler) queueChanges( change.Currency, HeadBehind, ); err != nil { - return err + return fmt.Errorf("failed to call \"reconciliation skip\" action: %w", err) } continue @@ -288,8 +288,7 @@ func (r *Reconciler) CompareBalance( head, err := r.helper.CurrentBlock(ctx, dbTx) if err != nil { return zeroString, "", 0, fmt.Errorf( - "%w: %v", - ErrGetCurrentBlockFailed, + "failed to get current block: %w", err, ) } @@ -297,10 +296,10 @@ func (r *Reconciler) CompareBalance( // Check if live block is < head (or wait) if liveBlock.Index > head.Index { return zeroString, "", head.Index, fmt.Errorf( - "%w live block %d > head block %d", - ErrHeadBlockBehindLive, + "live block %d > head block %d: %w", liveBlock.Index, head.Index, + ErrHeadBlockBehindLive, ) } @@ -308,17 +307,16 @@ func (r *Reconciler) CompareBalance( canonical, err := r.helper.CanonicalBlock(ctx, dbTx, liveBlock) if err != nil { return zeroString, "", 0, fmt.Errorf( - "%w: %v: on live block %+v", - ErrBlockExistsFailed, + "unable to check if live block %s is in canonical chain: %w", + types.PrintStruct(liveBlock), err, - liveBlock, ) } if !canonical { return zeroString, "", head.Index, fmt.Errorf( - "%w %+v", + "live block %s is invalid: %w", + types.PrintStruct(liveBlock), ErrBlockGone, - liveBlock, ) } @@ -333,25 +331,29 @@ func (r *Reconciler) CompareBalance( if err != nil { if errors.Is(err, storageErrors.ErrAccountMissing) { return zeroString, "", head.Index, fmt.Errorf( - "%w for %+v:%+v", + "account %s is invalid for currency %s: %w", + types.PrintStruct(account), + types.PrintStruct(currency), storageErrors.ErrAccountMissing, - account, - currency, ) } return zeroString, "", head.Index, fmt.Errorf( - "%w for %+v:%+v: %v", - ErrGetComputedBalanceFailed, - account, - currency, + "failed to get computed balance for currency %s of account %s: %w", + types.PrintStruct(currency), + types.PrintStruct(account), err, ) } difference, err := types.SubtractValues(liveBalance, computedBalance.Value) if err != nil { - return "", "", -1, err + return "", "", -1, fmt.Errorf( + "failed to subtract values %s - %s: %w", + liveBalance, + computedBalance.Value, + err, + ) } return difference, computedBalance.Value, head.Index, nil @@ -383,11 +385,11 @@ func (r *Reconciler) bestLiveBalance( ) if err != nil { return nil, nil, fmt.Errorf( - "%w: unable to get live balance for %s %s at %d", - err, - types.PrintStruct(account), + "unable to get live balance for currency %s of account %s at %d: %w", types.PrintStruct(currency), + types.PrintStruct(account), lookupIndex, + err, ) } @@ -441,7 +443,7 @@ func (r *Reconciler) handleBalanceMismatch( block, ) if err != nil { // error only returned if we should exit on failure - return err + return fmt.Errorf("failed to call \"reconciliation fail\" action: %w", err) } return nil @@ -548,7 +550,7 @@ func (r *Reconciler) accountReconciliation( ) } - return err + return fmt.Errorf("failed to compare computed balance with live balance: %w", err) } if difference != zeroString { @@ -654,7 +656,7 @@ func (r *Reconciler) skipAndPrune( change.Currency, skipCause, ); err != nil { - return err + return fmt.Errorf("failed to call \"reconciliation skip\" action: %w", err) } return r.updateQueueMap( @@ -765,7 +767,13 @@ func (r *Reconciler) reconcileActiveAccounts(ctx context.Context) error { // nol fmt.Printf("%v: could not determine if at tip\n", tErr) } - return fmt.Errorf("%w: %v", ErrLiveBalanceLookupFailed, err) + return fmt.Errorf( + "failed to lookup balance for currency %s of account %s at height %d: %w", + types.PrintStruct(balanceChange.Currency), + types.PrintStruct(balanceChange.Account), + balanceChange.Block.Index, + err, + ) } err = r.accountReconciliation( @@ -817,14 +825,14 @@ func (r *Reconciler) shouldAttemptInactiveReconciliation( // When first start syncing, this loop may run before the genesis block is synced. // If this is the case, we should sleep and try again later instead of exiting. if err != nil { - r.debugLog("waiting to start intactive reconciliation until a block is synced...") + r.debugLog("waiting to start inactive reconciliation until a block is synced...") return false, nil } if head.Index < r.highWaterMark { r.debugLog( - "waiting to continue intactive reconciliation until reaching high water mark...", + "waiting to continue inactive reconciliation until reaching high water mark...", ) return false, nil @@ -912,7 +920,7 @@ func (r *Reconciler) reconcileInactiveAccounts( // nolint:gocognit nextAcct.Entry.Currency, TipFailure, ); err != nil { - return err + return fmt.Errorf("failed to call \"reconciliation skip\" action: %w", err) } if err := r.updateQueueMap( @@ -921,7 +929,7 @@ func (r *Reconciler) reconcileInactiveAccounts( // nolint:gocognit head.Index, pruneInactiveReconciliation, ); err != nil { - return err + return fmt.Errorf("failed to update queue map: %w", err) } continue @@ -929,7 +937,13 @@ func (r *Reconciler) reconcileInactiveAccounts( // nolint:gocognit fmt.Printf("%v: could not determine if at tip\n", tErr) } - return fmt.Errorf("%w: %v", ErrLiveBalanceLookupFailed, err) + return fmt.Errorf( + "failed to lookup balance for currency %s of account %s at height %d: %w", + types.PrintStruct(nextAcct.Entry.Currency), + types.PrintStruct(nextAcct.Entry.Account), + head.Index, + err, + ) } err = r.accountReconciliation( diff --git a/reconciler/reconciler_test.go b/reconciler/reconciler_test.go index 6c0f0487..8c909711 100644 --- a/reconciler/reconciler_test.go +++ b/reconciler/reconciler_test.go @@ -334,10 +334,10 @@ func TestCompareBalance(t *testing.T) { assert.Equal(t, "", cachedBalance) assert.Equal(t, int64(0), headIndex) assert.EqualError(t, err, fmt.Errorf( - "%w live block %d > head block %d", - ErrHeadBlockBehindLive, + "live block %d > head block %d: %w", 1, 0, + ErrHeadBlockBehindLive, ).Error()) mtxn.AssertExpectations(t) }) @@ -1348,7 +1348,7 @@ func TestReconcile_FailureOnlyActive(t *testing.T) { go func() { err := r.Reconcile(ctx) assert.Error(t, err) - assert.Contains(t, "reconciliation failed", err.Error()) + assert.Contains(t, err.Error(), "reconciliation failed") }() time.Sleep(1 * time.Second) @@ -1810,7 +1810,7 @@ func TestReconcile_NotExemptOnlyActive(t *testing.T) { go func() { err := r.Reconcile(ctx) assert.Error(t, err) - assert.Contains(t, "reconciliation failed", err.Error()) + assert.Contains(t, err.Error(), "reconciliation failed") }() err := r.QueueChanges(ctx, block, []*parser.BalanceChange{ @@ -1903,7 +1903,7 @@ func TestReconcile_NotExemptAddressOnlyActive(t *testing.T) { go func() { err := r.Reconcile(ctx) assert.Error(t, err) - assert.Contains(t, "reconciliation failed", err.Error()) + assert.Contains(t, err.Error(), "reconciliation failed") }() err := r.QueueChanges(ctx, block, []*parser.BalanceChange{ @@ -2000,7 +2000,7 @@ func TestReconcile_NotExemptWrongAddressOnlyActive(t *testing.T) { go func() { err := r.Reconcile(ctx) assert.Error(t, err) - assert.Contains(t, "reconciliation failed", err.Error()) + assert.Contains(t, err.Error(), "reconciliation failed") }() err := r.QueueChanges(ctx, block, []*parser.BalanceChange{ @@ -2220,7 +2220,7 @@ func TestReconcile_FailureOnlyInactive(t *testing.T) { err := r.Reconcile(ctx) assert.Error(t, err) - assert.Contains(t, "reconciliation failed", err.Error()) + assert.Contains(t, err.Error(), "reconciliation failed") mockHelper.AssertExpectations(t) mockHandler.AssertExpectations(t) @@ -2418,7 +2418,13 @@ func TestReconcile_ActiveNotIndexAtTipError(t *testing.T) { go func() { err := r.Reconcile(ctx) - assert.True(t, errors.Is(err, ErrLiveBalanceLookupFailed)) + expectErr := fmt.Errorf( + "failed to lookup balance for currency %s of account %s at height %d", + types.PrintStruct(accountCurrency.Currency), + types.PrintStruct(accountCurrency.Account), + int64(1), + ) + assert.Contains(t, err.Error(), expectErr.Error()) }() err := r.QueueChanges(ctx, block, []*parser.BalanceChange{ @@ -2482,7 +2488,13 @@ func TestReconcile_ActiveErrorIndexAtTipError(t *testing.T) { go func() { err := r.Reconcile(ctx) - assert.True(t, errors.Is(err, ErrLiveBalanceLookupFailed)) + expectErr := fmt.Errorf( + "failed to lookup balance for currency %s of account %s at height %d", + types.PrintStruct(accountCurrency.Currency), + types.PrintStruct(accountCurrency.Account), + int64(1), + ) + assert.Contains(t, err.Error(), expectErr.Error()) }() err := r.QueueChanges(ctx, block, []*parser.BalanceChange{ @@ -2633,7 +2645,13 @@ func TestReconcile_FailureNotIndexAtTipInactive(t *testing.T) { go func() { err := r.Reconcile(ctx) - assert.True(t, errors.Is(err, ErrLiveBalanceLookupFailed)) + expectErr := fmt.Errorf( + "failed to lookup balance for currency %s of account %s at height %d", + types.PrintStruct(accountCurrency.Currency), + types.PrintStruct(accountCurrency.Account), + int64(1), + ) + assert.Contains(t, err.Error(), expectErr.Error()) }() time.Sleep(1 * time.Second) @@ -2697,7 +2715,13 @@ func TestReconcile_FailureErrorIndexAtTipInactive(t *testing.T) { go func() { err := r.Reconcile(ctx) - assert.True(t, errors.Is(err, ErrLiveBalanceLookupFailed)) + expectErr := fmt.Errorf( + "failed to lookup balance for currency %s of account %s at height %d", + types.PrintStruct(accountCurrency.Currency), + types.PrintStruct(accountCurrency.Account), + int64(1), + ) + assert.Contains(t, err.Error(), expectErr.Error()) }() time.Sleep(1 * time.Second)