github.com/onflow/flow-go@v0.33.17/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("CheckPayerBalanceAndGetMaxTxFees", mock.Anything, mock.Anything, mock.Anything).Return(
    84  			cadence.Struct{
    85  				Fields: []cadence.Value{
    86  					cadence.NewBool(true),
    87  					cadence.UFix64(100),
    88  					cadence.UFix64(100),
    89  				},
    90  			},
    91  			nil)
    92  
    93  		proc := &fvm.TransactionProcedure{}
    94  		proc.Transaction = &flow.TransactionBody{}
    95  		proc.Transaction.Payer = payer
    96  
    97  		txnState := testutils.NewSimpleTransaction(nil)
    98  
    99  		d := fvm.TransactionPayerBalanceChecker{}
   100  		maxFees, err := d.CheckPayerBalanceAndReturnMaxFees(proc, txnState, env)
   101  		require.NoError(t, err)
   102  		require.Equal(t, uint64(100), maxFees)
   103  	})
   104  
   105  	t.Run("if payer cannot pay return insufficient balance error", func(t *testing.T) {
   106  		env := &fvmmock.Environment{}
   107  		env.On("TransactionFeesEnabled").Return(true)
   108  		env.On("CheckPayerBalanceAndGetMaxTxFees", mock.Anything, mock.Anything, mock.Anything).Return(
   109  			cadence.Struct{
   110  				Fields: []cadence.Value{
   111  					cadence.NewBool(false),
   112  					cadence.UFix64(100),
   113  					cadence.UFix64(101),
   114  				},
   115  			},
   116  			nil)
   117  
   118  		proc := &fvm.TransactionProcedure{}
   119  		proc.Transaction = &flow.TransactionBody{}
   120  		proc.Transaction.Payer = payer
   121  
   122  		txnState := testutils.NewSimpleTransaction(nil)
   123  
   124  		d := fvm.TransactionPayerBalanceChecker{}
   125  		maxFees, err := d.CheckPayerBalanceAndReturnMaxFees(proc, txnState, env)
   126  		require.Error(t, err)
   127  		require.Contains(t, err.Error(), errors.NewInsufficientPayerBalanceError(payer, 100).Error())
   128  		require.Equal(t, uint64(0), maxFees)
   129  	})
   130  }