github.com/Finschia/finschia-sdk@v0.49.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  			used += usage
    48  			require.NotPanics(t, func() { meter.ConsumeGas(usage, "") }, "Not exceeded limit but panicked. tc #%d, usage #%d", tcnum, unum)
    49  			require.Equal(t, used, meter.GasConsumed(), "Gas consumption not match. tc #%d, usage #%d", tcnum, unum)
    50  			require.Equal(t, used, meter.GasConsumedToLimit(), "Gas consumption (to limit) not match. tc #%d, usage #%d", tcnum, unum)
    51  			require.False(t, meter.IsPastLimit(), "Not exceeded limit but got IsPastLimit() true")
    52  			if unum < len(tc.usage)-1 {
    53  				require.False(t, meter.IsOutOfGas(), "Not yet at limit but got IsOutOfGas() true")
    54  			} else {
    55  				require.True(t, meter.IsOutOfGas(), "At limit but got IsOutOfGas() false")
    56  			}
    57  		}
    58  
    59  		require.Panics(t, func() { meter.ConsumeGas(1, "") }, "Exceeded but not panicked. tc #%d", tcnum)
    60  		require.Equal(t, meter.GasConsumedToLimit(), meter.Limit(), "Gas consumption (to limit) not match limit")
    61  		require.Equal(t, meter.GasConsumed(), meter.Limit()+1, "Gas consumption not match limit+1")
    62  
    63  		require.NotPanics(t, func() { meter.RefundGas(1, "refund 1") })
    64  		require.Equal(t, meter.GasConsumed(), meter.Limit(), "Gas consumption not match limit+1")
    65  		require.Panics(t, func() { meter.RefundGas(meter.GasConsumed()+1, "refund greater than consumed") })
    66  
    67  		meter2 := NewGasMeter(math.MaxUint64)
    68  		meter2.ConsumeGas(Gas(math.MaxUint64/2), "consume half max uint64")
    69  		require.Panics(t, func() { meter2.ConsumeGas(Gas(math.MaxUint64/2)+2, "panic") })
    70  	}
    71  }
    72  
    73  func TestAddUint64Overflow(t *testing.T) {
    74  	t.Parallel()
    75  	testCases := []struct {
    76  		a, b     uint64
    77  		result   uint64
    78  		overflow bool
    79  	}{
    80  		{0, 0, 0, false},
    81  		{100, 100, 200, false},
    82  		{math.MaxUint64 / 2, math.MaxUint64/2 + 1, math.MaxUint64, false},
    83  		{math.MaxUint64 / 2, math.MaxUint64/2 + 2, 0, true},
    84  	}
    85  
    86  	for i, tc := range testCases {
    87  		res, overflow := addUint64Overflow(tc.a, tc.b)
    88  		require.Equal(
    89  			t, tc.overflow, overflow,
    90  			"invalid overflow result; tc: #%d, a: %d, b: %d", i, tc.a, tc.b,
    91  		)
    92  		require.Equal(
    93  			t, tc.result, res,
    94  			"invalid uint64 result; tc: #%d, a: %d, b: %d", i, tc.a, tc.b,
    95  		)
    96  	}
    97  }
    98  
    99  func TestTransientGasConfig(t *testing.T) {
   100  	t.Parallel()
   101  	config := TransientGasConfig()
   102  	require.Equal(t, config, GasConfig{
   103  		HasCost:          100,
   104  		DeleteCost:       100,
   105  		ReadCostFlat:     100,
   106  		ReadCostPerByte:  0,
   107  		WriteCostFlat:    200,
   108  		WriteCostPerByte: 3,
   109  		IterNextCostFlat: 3,
   110  	})
   111  }