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 }