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 }