github.com/Finschia/finschia-sdk@v0.48.1/store/types/gas_test.go (about)

     1  package types
     2  
     3  import (
     4  	"math"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func TestInfiniteGasMeter(t *testing.T) {
    11  	t.Parallel()
    12  	meter := NewInfiniteGasMeter()
    13  	require.Equal(t, uint64(0), meter.Limit())
    14  	require.Equal(t, uint64(0), meter.GasConsumed())
    15  	require.Equal(t, uint64(0), meter.GasConsumedToLimit())
    16  	meter.ConsumeGas(10, "consume 10")
    17  	require.Equal(t, uint64(10), meter.GasConsumed())
    18  	require.Equal(t, uint64(10), meter.GasConsumedToLimit())
    19  	meter.RefundGas(1, "refund 1")
    20  	require.Equal(t, uint64(9), meter.GasConsumed())
    21  	require.False(t, meter.IsPastLimit())
    22  	require.False(t, meter.IsOutOfGas())
    23  	meter.ConsumeGas(Gas(math.MaxUint64/2), "consume half max uint64")
    24  	require.Panics(t, func() { meter.ConsumeGas(Gas(math.MaxUint64/2)+2, "panic") })
    25  	require.Panics(t, func() { meter.RefundGas(meter.GasConsumed()+1, "refund greater than consumed") })
    26  }
    27  
    28  func TestGasMeter(t *testing.T) {
    29  	t.Parallel()
    30  	cases := []struct {
    31  		limit Gas
    32  		usage []Gas
    33  	}{
    34  		{10, []Gas{1, 2, 3, 4}},
    35  		{1000, []Gas{40, 30, 20, 10, 900}},
    36  		{100000, []Gas{99999, 1}},
    37  		{100000000, []Gas{50000000, 40000000, 10000000}},
    38  		{65535, []Gas{32768, 32767}},
    39  		{65536, []Gas{32768, 32767, 1}},
    40  	}
    41  
    42  	for tcnum, tc := range cases {
    43  		meter := NewGasMeter(tc.limit)
    44  		used := uint64(0)
    45  
    46  		for unum, usage := range tc.usage {
    47  			usage := usage
    48  			used += usage
    49  			require.NotPanics(t, func() { meter.ConsumeGas(usage, "") }, "Not exceeded limit but panicked. tc #%d, usage #%d", tcnum, unum)
    50  			require.Equal(t, used, meter.GasConsumed(), "Gas consumption not match. tc #%d, usage #%d", tcnum, unum)
    51  			require.Equal(t, used, meter.GasConsumedToLimit(), "Gas consumption (to limit) not match. tc #%d, usage #%d", tcnum, unum)
    52  			require.False(t, meter.IsPastLimit(), "Not exceeded limit but got IsPastLimit() true")
    53  			if unum < len(tc.usage)-1 {
    54  				require.False(t, meter.IsOutOfGas(), "Not yet at limit but got IsOutOfGas() true")
    55  			} else {
    56  				require.True(t, meter.IsOutOfGas(), "At limit but got IsOutOfGas() false")
    57  			}
    58  		}
    59  
    60  		require.Panics(t, func() { meter.ConsumeGas(1, "") }, "Exceeded but not panicked. tc #%d", tcnum)
    61  		require.Equal(t, meter.GasConsumedToLimit(), meter.Limit(), "Gas consumption (to limit) not match limit")
    62  		require.Equal(t, meter.GasConsumed(), meter.Limit()+1, "Gas consumption not match limit+1")
    63  
    64  		require.NotPanics(t, func() { meter.RefundGas(1, "refund 1") })
    65  		require.Equal(t, meter.GasConsumed(), meter.Limit(), "Gas consumption not match limit+1")
    66  		require.Panics(t, func() { meter.RefundGas(meter.GasConsumed()+1, "refund greater than consumed") })
    67  
    68  		meter2 := NewGasMeter(math.MaxUint64)
    69  		meter2.ConsumeGas(Gas(math.MaxUint64/2), "consume half max uint64")
    70  		require.Panics(t, func() { meter2.ConsumeGas(Gas(math.MaxUint64/2)+2, "panic") })
    71  	}
    72  }
    73  
    74  func TestAddUint64Overflow(t *testing.T) {
    75  	t.Parallel()
    76  	testCases := []struct {
    77  		a, b     uint64
    78  		result   uint64
    79  		overflow bool
    80  	}{
    81  		{0, 0, 0, false},
    82  		{100, 100, 200, false},
    83  		{math.MaxUint64 / 2, math.MaxUint64/2 + 1, math.MaxUint64, false},
    84  		{math.MaxUint64 / 2, math.MaxUint64/2 + 2, 0, true},
    85  	}
    86  
    87  	for i, tc := range testCases {
    88  		res, overflow := addUint64Overflow(tc.a, tc.b)
    89  		require.Equal(
    90  			t, tc.overflow, overflow,
    91  			"invalid overflow result; tc: #%d, a: %d, b: %d", i, tc.a, tc.b,
    92  		)
    93  		require.Equal(
    94  			t, tc.result, res,
    95  			"invalid uint64 result; tc: #%d, a: %d, b: %d", i, tc.a, tc.b,
    96  		)
    97  	}
    98  }
    99  
   100  func TestTransientGasConfig(t *testing.T) {
   101  	t.Parallel()
   102  	config := TransientGasConfig()
   103  	require.Equal(t, config, GasConfig{
   104  		HasCost:          100,
   105  		DeleteCost:       100,
   106  		ReadCostFlat:     100,
   107  		ReadCostPerByte:  0,
   108  		WriteCostFlat:    200,
   109  		WriteCostPerByte: 3,
   110  		IterNextCostFlat: 3,
   111  	})
   112  }