github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/transactionPayerBalanceChecker_test.go (about) 1 package fvm_test 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/stretchr/testify/mock" 8 "github.com/stretchr/testify/require" 9 10 "github.com/onflow/cadence" 11 12 "github.com/onflow/flow-go/fvm" 13 fvmmock "github.com/onflow/flow-go/fvm/environment/mock" 14 "github.com/onflow/flow-go/fvm/errors" 15 "github.com/onflow/flow-go/fvm/storage/testutils" 16 "github.com/onflow/flow-go/model/flow" 17 ) 18 19 func TestTransactionPayerBalanceChecker(t *testing.T) { 20 payer := flow.HexToAddress("1") 21 t.Run("TransactionFeesEnabled == false disables the balance check", func(t *testing.T) { 22 env := &fvmmock.Environment{} 23 env.On("TransactionFeesEnabled").Return(false) 24 25 proc := &fvm.TransactionProcedure{} 26 proc.Transaction = &flow.TransactionBody{} 27 proc.Transaction.Payer = payer 28 29 txnState := testutils.NewSimpleTransaction(nil) 30 31 d := fvm.TransactionPayerBalanceChecker{} 32 maxFees, err := d.CheckPayerBalanceAndReturnMaxFees(proc, txnState, env) 33 require.NoError(t, err) 34 require.Equal(t, uint64(0), maxFees) 35 }) 36 37 t.Run("errors during CheckPayerBalanceAndGetMaxTxFees invocation are wrapped and returned", func(t *testing.T) { 38 someError := fmt.Errorf("some error") 39 40 env := &fvmmock.Environment{} 41 env.On("TransactionFeesEnabled").Return(true) 42 env.On("CheckPayerBalanceAndGetMaxTxFees", mock.Anything, mock.Anything, mock.Anything).Return( 43 nil, 44 someError) 45 46 proc := &fvm.TransactionProcedure{} 47 proc.Transaction = &flow.TransactionBody{} 48 proc.Transaction.Payer = payer 49 50 txnState := testutils.NewSimpleTransaction(nil) 51 52 d := fvm.TransactionPayerBalanceChecker{} 53 maxFees, err := d.CheckPayerBalanceAndReturnMaxFees(proc, txnState, env) 54 require.Error(t, err) 55 require.True(t, errors.HasFailureCode(err, errors.FailureCodePayerBalanceCheckFailure)) 56 require.ErrorIs(t, err, someError) 57 require.Equal(t, uint64(0), maxFees) 58 }) 59 60 t.Run("unexpected result type from CheckPayerBalanceAndGetMaxTxFees causes error", func(t *testing.T) { 61 env := &fvmmock.Environment{} 62 env.On("TransactionFeesEnabled").Return(true) 63 env.On("CheckPayerBalanceAndGetMaxTxFees", mock.Anything, mock.Anything, mock.Anything).Return( 64 cadence.Struct{}, 65 nil) 66 67 proc := &fvm.TransactionProcedure{} 68 proc.Transaction = &flow.TransactionBody{} 69 proc.Transaction.Payer = payer 70 71 txnState := testutils.NewSimpleTransaction(nil) 72 73 d := fvm.TransactionPayerBalanceChecker{} 74 maxFees, err := d.CheckPayerBalanceAndReturnMaxFees(proc, txnState, env) 75 require.Error(t, err) 76 require.True(t, errors.HasFailureCode(err, errors.FailureCodePayerBalanceCheckFailure)) 77 require.Equal(t, uint64(0), maxFees) 78 }) 79 80 t.Run("if payer can pay return max fees", func(t *testing.T) { 81 env := &fvmmock.Environment{} 82 env.On("TransactionFeesEnabled").Return(true) 83 env.On( 84 "CheckPayerBalanceAndGetMaxTxFees", 85 mock.Anything, 86 mock.Anything, 87 mock.Anything, 88 ).Return( 89 cadence.NewStruct([]cadence.Value{ 90 cadence.NewBool(true), 91 cadence.UFix64(100), 92 cadence.UFix64(100), 93 }).WithType(fvm.VerifyPayerBalanceResultType), 94 nil, 95 ) 96 97 proc := &fvm.TransactionProcedure{} 98 proc.Transaction = &flow.TransactionBody{} 99 proc.Transaction.Payer = payer 100 101 txnState := testutils.NewSimpleTransaction(nil) 102 103 d := fvm.TransactionPayerBalanceChecker{} 104 maxFees, err := d.CheckPayerBalanceAndReturnMaxFees(proc, txnState, env) 105 require.NoError(t, err) 106 require.Equal(t, uint64(100), maxFees) 107 }) 108 109 t.Run("if payer cannot pay return insufficient balance error", func(t *testing.T) { 110 env := &fvmmock.Environment{} 111 env.On("TransactionFeesEnabled").Return(true) 112 env.On( 113 "CheckPayerBalanceAndGetMaxTxFees", 114 mock.Anything, 115 mock.Anything, 116 mock.Anything, 117 ).Return( 118 cadence.NewStruct([]cadence.Value{ 119 cadence.NewBool(false), 120 cadence.UFix64(100), 121 cadence.UFix64(101), 122 }).WithType(fvm.VerifyPayerBalanceResultType), 123 nil, 124 ) 125 126 proc := &fvm.TransactionProcedure{} 127 proc.Transaction = &flow.TransactionBody{} 128 proc.Transaction.Payer = payer 129 130 txnState := testutils.NewSimpleTransaction(nil) 131 132 d := fvm.TransactionPayerBalanceChecker{} 133 maxFees, err := d.CheckPayerBalanceAndReturnMaxFees(proc, txnState, env) 134 require.Error(t, err) 135 require.Contains(t, err.Error(), errors.NewInsufficientPayerBalanceError(payer, 100).Error()) 136 require.Equal(t, uint64(0), maxFees) 137 }) 138 }