From 30818f62800e6deeda97b40ccbcfdc9b55fd898b Mon Sep 17 00:00:00 2001 From: Raghava Pamula Date: Wed, 13 Apr 2022 11:14:47 -0400 Subject: [PATCH] Add validation for negative fee amount (#397) --- asserter/block.go | 15 ++++++- asserter/block_test.go | 90 ++++++++++++++++++++++++++++++++++++++++++ asserter/errors.go | 2 + 3 files changed, 106 insertions(+), 1 deletion(-) diff --git a/asserter/block.go b/asserter/block.go index 1d623f3f..ad173af9 100644 --- a/asserter/block.go +++ b/asserter/block.go @@ -320,7 +320,20 @@ func (a *Asserter) Operations( // nolint:gocognit ) } - val, _ := new(big.Int).SetString(op.Amount.Value, 10) + val, err := types.BigInt(op.Amount.Value) + if err != nil { + return err + } + + // Validate that fee operation amount is negative + if val.Sign() != -1 { + return fmt.Errorf( + "%w: operation index %d", + ErrFeeAmountNotNegative, + op.OperationIdentifier.Index, + ) + } + feeTotal.Add(feeTotal, val) feeCount++ } diff --git a/asserter/block_test.go b/asserter/block_test.go index a9524a41..27cad096 100644 --- a/asserter/block_test.go +++ b/asserter/block_test.go @@ -293,6 +293,14 @@ func TestOperationsValidations(t *testing.T) { }, } + invalidFeeAmount = &types.Amount{ + Value: "100", + Currency: &types.Currency{ + Symbol: "BTC", + Decimals: 8, + }, + } + validAccount = &types.AccountIdentifier{ Address: "test", } @@ -513,6 +521,88 @@ func TestOperationsValidations(t *testing.T) { construction: false, err: ErrRelatedOperationInFeeNotAllowed, }, + + "fee amount is non-negative": { + operations: []*types.Operation{ + { + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(0), + }, + Type: "PAYMENT", + Status: types.String("SUCCESS"), + Account: validAccount, + Amount: validDepositAmount, + }, + { + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(1), + }, + Type: "PAYMENT", + Status: types.String("SUCCESS"), + Account: validAccount, + Amount: &types.Amount{ + Value: "-2000", + Currency: &types.Currency{ + Symbol: "BTC", + Decimals: 8, + }, + }, + }, + { + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(2), + }, + Type: "FEE", + Status: types.String("SUCCESS"), + Account: validAccount, + Amount: invalidFeeAmount, + }, + }, + validationFilePath: "data/validation_fee_and_payment_unbalanced.json", + construction: false, + err: ErrFeeAmountNotNegative, + }, + + "fee amount is negative as expected": { + operations: []*types.Operation{ + { + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(0), + }, + Type: "PAYMENT", + Status: types.String("SUCCESS"), + Account: validAccount, + Amount: validDepositAmount, + }, + { + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(1), + }, + Type: "PAYMENT", + Status: types.String("SUCCESS"), + Account: validAccount, + Amount: &types.Amount{ + Value: "-2000", + Currency: &types.Currency{ + Symbol: "BTC", + Decimals: 8, + }, + }, + }, + { + OperationIdentifier: &types.OperationIdentifier{ + Index: int64(2), + }, + Type: "FEE", + Status: types.String("SUCCESS"), + Account: validAccount, + Amount: validFeeAmount, + }, + }, + validationFilePath: "data/validation_fee_and_payment_unbalanced.json", + construction: false, + err: nil, + }, } for name, test := range tests { diff --git a/asserter/errors.go b/asserter/errors.go index 0048414d..a4603f89 100644 --- a/asserter/errors.go +++ b/asserter/errors.go @@ -103,6 +103,7 @@ var ( ErrFeeAmountNotBalancing = errors.New("fee amount doesn't balance") ErrPaymentCountMismatch = errors.New("payment count doesn't match") ErrFeeCountMismatch = errors.New("fee count doesn't match") + ErrFeeAmountNotNegative = errors.New("fee amount is not negative") BlockErrs = []error{ ErrAmountValueMissing, @@ -142,6 +143,7 @@ var ( ErrDuplicateRelatedTransaction, ErrPaymentAmountNotBalancing, ErrFeeAmountNotBalancing, + ErrFeeAmountNotNegative, } )