github.com/klaytn/klaytn@v1.12.1/consensus/misc/kip71_test.go (about) 1 package misc 2 3 import ( 4 "math/big" 5 "math/rand" 6 "testing" 7 8 "github.com/klaytn/klaytn/blockchain/types" 9 "github.com/klaytn/klaytn/common" 10 "github.com/klaytn/klaytn/params" 11 ) 12 13 func getTestConfig(forkedBlockNum *big.Int) *params.ChainConfig { 14 testConfig := params.CypressChainConfig 15 testConfig.UnitPrice = uint64(25000000000) 16 testConfig.MagmaCompatibleBlock = forkedBlockNum 17 testConfig.Governance = ¶ms.GovernanceConfig{ 18 KIP71: params.GetDefaultKIP71Config(), 19 } 20 return testConfig 21 } 22 23 func TestEvenBaseFee(t *testing.T) { 24 tests := []struct { 25 upperBoundBaseFee uint64 26 lowerBoundBaseFee uint64 27 gasTarget uint64 28 baseFeeDenominator uint64 29 maxBlockGasUsedForBaseFee uint64 30 parentGasUsed uint64 31 parentBaseFee uint64 32 }{ 33 // Current default setting 34 {750000000000, 25000000000, 30000000, 20, 60000000, 43212345, 13009212843}, 35 {750000000000, 25000000000, 30000000, 20, 60000000, 34857284, 83009212843}, 36 {750000000000, 25000000000, 30000000, 20, 60000000, 0, 43009212843}, 37 {750000000000, 25000000000, 30000000, 20, 60000000, 0, 43009212843}, 38 {750000000000, 25000000000, 30000000, 20, 60000000, 0, 43009212843}, 39 {750000000000, 25000000000, 30000000, 20, 60000000, 69856837, 34958439443}, 40 {750000000000, 25000000000, 30000000, 20, 60000000, 18275847, 43459029443}, 41 {750000000000, 25000000000, 30000000, 20, 60000000, 34857359, 43009212843}, 42 {750000000000, 25000000000, 30000000, 20, 60000000, 28914728, 43009212843}, 43 {750000000000, 25000000000, 30000000, 20, 60000000, 83597392, 43238573843}, 44 {750000000000, 25000000000, 30000000, 20, 60000000, 28472874, 43009212843}, 45 {750000000000, 25000000000, 30000000, 20, 60000000, 34895734, 43009212843}, 46 {750000000000, 25000000000, 30000000, 20, 60000000, 17274858, 18432574843}, 47 {750000000000, 25000000000, 30000000, 20, 60000000, 39093494, 43009212843}, 48 {750000000000, 25000000000, 30000000, 20, 60000000, 18981884, 28574384343}, 49 {750000000000, 25000000000, 30000000, 20, 60000000, 12873, 43009212843}, 50 {750000000000, 25000000000, 30000000, 20, 60000000, 18273, 43009212843}, 51 {750000000000, 25000000000, 30000000, 20, 60000000, 1, 43009212843}, 52 {750000000000, 25000000000, 30000000, 20, 60000000, 18949, 43009212843}, 53 {750000000000, 25000000000, 30000000, 20, 60000000, 19828, 43009212843}, 54 // monkey test 1 55 {750000000001, 25123987327, 30000000, 20, 38573282, 83212345, 750000000000}, 56 {750000000003, 25000000000, 30000000, 20, 83478211, 43212345, 48572839123}, 57 {750000000005, 25000000000, 30000000, 20, 48471293, 43212345, 48572839123}, 58 {750000000006, 25000000000, 30000000, 20, 43852728, 43212345, 48572839123}, 59 {750000000007, 25000000000, 30000000, 20, 11282848, 43212345, 48572839123}, 60 {750000000009, 25000000000, 30000000, 20, 38574848, 43212345, 48572839123}, 61 {800000001233, 25000000000, 30000000, 20, 83839191, 43212345, 48572839123}, 62 {751231231233, 25000000000, 30000000, 20, 88391928, 43212345, 48572839123}, 63 {750321321321, 25000000000, 30000000, 20, 60000000, 43212345, 48572839123}, 64 {750000000777, 25000000000, 30000000, 20, 60000000, 43212345, 48572839123}, 65 // monkey test 2 66 {750000000000, 28347289478, 30000000, 20, 60000000, 43212345, 75489234128}, 67 {750000000000, 28729584848, 30000000, 20, 60000000, 43212345, 75489234128}, 68 {0, 0, 30000000, 20, 60000000, 0, 43009212843}, 69 {750000000000, 29999999999, 30000000, 20, 60000000, 43212345, 75489234128}, 70 {750000000000, 19999999999, 30000000, 20, 60000000, 43212345, 75489234128}, 71 {750000000000, 0, 30000000, 20, 60000000, 43212345, 75489234128}, 72 {750000000000, 1, 30000000, 1, 60000000, 0, 10}, 73 {750000000000, 0, 30000000, 20, 60000000, 43212345, 75489234128}, 74 {0, 0, 30000000, 20, 60000000, 43212345, 75489234128}, 75 {0, 0, 30000000, 20, 60000000, 43212345, 75489234128}, 76 } 77 78 testConfig := getTestConfig(big.NewInt(3)) 79 for _, test := range tests { 80 testConfig.Governance.KIP71.LowerBoundBaseFee = test.lowerBoundBaseFee 81 testConfig.Governance.KIP71.UpperBoundBaseFee = test.upperBoundBaseFee 82 testConfig.Governance.KIP71.GasTarget = test.gasTarget 83 testConfig.Governance.KIP71.MaxBlockGasUsedForBaseFee = test.maxBlockGasUsedForBaseFee 84 testConfig.Governance.KIP71.BaseFeeDenominator = test.baseFeeDenominator 85 86 parent := &types.Header{ 87 Number: common.Big3, 88 GasUsed: test.parentGasUsed, 89 BaseFee: new(big.Int).SetUint64(test.parentBaseFee), 90 } 91 even := NextMagmaBlockBaseFee(parent, testConfig.Governance.KIP71) 92 // even check 93 if even.Bit(0) != 0 { 94 t.Errorf("NextBlockBaseFee:%d is not a even number", even) 95 } 96 // lower bound check 97 if even.Cmp(new(big.Int).SetUint64(test.lowerBoundBaseFee)) < 0 { 98 t.Errorf("NextBlockBaseFee:%d is lower than lowerBoudnBaseFee:%d", even, test.lowerBoundBaseFee) 99 } 100 // upper bound check 101 if even.Cmp(new(big.Int).SetUint64(test.upperBoundBaseFee)) > 0 { 102 t.Errorf("NextBlockBaseFee:%d exceeded upperBoudnBaseFee:%d", even, test.upperBoundBaseFee) 103 } 104 } 105 } 106 107 func TestNextBlockBaseFee(t *testing.T) { 108 tests := []struct { 109 parentBaseFee int64 110 parentGasUsed uint64 111 nextBaseFee int64 112 }{ 113 {750000000000, 30000000, 750000000000}, // usage == target 114 {30000000000, 20000000, 29500000000}, // usage below target 115 {300000000000, 40000000, 305000000000}, // usage above target 116 } 117 for i, test := range tests { 118 parent := &types.Header{ 119 Number: common.Big3, 120 GasUsed: test.parentGasUsed, 121 BaseFee: big.NewInt(test.parentBaseFee), 122 } 123 if have, want := NextMagmaBlockBaseFee( 124 parent, 125 getTestConfig(big.NewInt(3)).Governance.KIP71), 126 big.NewInt(test.nextBaseFee); have.Cmp(want) != 0 { 127 t.Errorf("test %d: have %d want %d, ", i, have, want) 128 } 129 } 130 } 131 132 func TestNextBlockBaseFeeWhenGovernanceUpdated(t *testing.T) { 133 tests := []struct { 134 upperBoundBaseFee uint64 // updated upper bound 135 lowerBoundBaseFee uint64 // updated lower bound 136 parentGasUsed uint64 137 parentBaseFee int64 138 nextBaseFee int64 139 }{ 140 {750000000000, 25000000000, 30000000, 750000000000, 750000000000}, 141 {700000000000, 25000000000, 30000000, 750000000000, 700000000000}, 142 {800000000000, 25000000000, 30000000, 750000000000, 750000000000}, 143 {750000000000, 25000000000, 30000000, 25000000000, 25000000000}, 144 {750000000000, 30000000000, 30000000, 25000000000, 30000000000}, 145 {750000000000, 20000000000, 30000000, 25000000000, 25000000000}, 146 {750000000000, 25000000000, 40000000 /* > gasTarget(30000000) */, 750000000000, 750000000000}, 147 {750000000000, 25000000000, 20000000 /* < gasTarget(30000000) */, 25000000000, 25000000000}, 148 } 149 for i, test := range tests { 150 config := getTestConfig(common.Big2) 151 config.Governance.KIP71.UpperBoundBaseFee = test.upperBoundBaseFee 152 config.Governance.KIP71.LowerBoundBaseFee = test.lowerBoundBaseFee 153 parent := &types.Header{ 154 Number: common.Big3, 155 GasUsed: test.parentGasUsed, 156 BaseFee: big.NewInt(test.parentBaseFee), 157 } 158 if have, want := NextMagmaBlockBaseFee(parent, config.Governance.KIP71), big.NewInt(test.nextBaseFee); have.Cmp(want) != 0 { 159 t.Errorf("test %d: have %d want %d, ", i, have, want) 160 } 161 } 162 } 163 164 type BaseFeeTestCase struct { 165 genesisParentBaseFee *big.Int 166 hardforkedNum *big.Int 167 GasUsed uint64 168 compMethod func(*big.Int, *big.Int) bool 169 expectedBaseFee *big.Int 170 expectedNum int 171 } 172 173 func TestBlocksToReachExpectedBaseFee(t *testing.T) { 174 testCases := []BaseFeeTestCase{ 175 { 176 big.NewInt(25000000000), 177 common.Big3, 178 84000000, 179 func(a *big.Int, b *big.Int) bool { return a.Cmp(b) > 0 }, 180 big.NewInt(25000000000 * 2), 181 15, 182 }, 183 { 184 big.NewInt(60000000000), 185 common.Big3, 186 29000000, 187 func(a *big.Int, b *big.Int) bool { return a.Cmp(b) < 0 }, 188 big.NewInt(60000000000 / 2), 189 416, 190 }, 191 { 192 big.NewInt(25000000000), 193 common.Big3, 194 84000000, 195 func(a *big.Int, b *big.Int) bool { return a.Cmp(b) == 0 }, 196 big.NewInt(750000000000), 197 70, 198 }, 199 { 200 big.NewInt(750000000000), 201 common.Big3, 202 29000000, 203 func(a *big.Int, b *big.Int) bool { return a.Cmp(b) == 0 }, 204 big.NewInt(25000000000), 205 2040, 206 }, 207 } 208 209 for _, testCase := range testCases { 210 blocksToReachExpectedBaseFee(t, testCase) 211 } 212 } 213 214 func blocksToReachExpectedBaseFee(t *testing.T, testCase BaseFeeTestCase) { 215 testConfig := getTestConfig(big.NewInt(3)) 216 blockNum := 0 217 parentBaseFee := testCase.genesisParentBaseFee 218 for { 219 blockNum++ 220 parent := &types.Header{ 221 Number: testCase.hardforkedNum, 222 GasUsed: testCase.GasUsed, 223 BaseFee: parentBaseFee, 224 } 225 parentBaseFee = NextMagmaBlockBaseFee(parent, testConfig.Governance.KIP71) 226 227 if testCase.compMethod(parentBaseFee, testCase.expectedBaseFee) { 228 break 229 } 230 } 231 if blockNum != int(testCase.expectedNum) { 232 t.Errorf("block number %d expected block number %d, have %d didn't reach to %d", blockNum, testCase.expectedNum, parentBaseFee, testCase.expectedBaseFee) 233 } 234 } 235 236 func TestInactieDynamicPolicyBeforeForkedBlock(t *testing.T) { 237 parentBaseFee := big.NewInt(25000000000) 238 parent := &types.Header{ 239 Number: common.Big3, 240 GasUsed: 84000000, 241 } 242 nextBaseFee := NextMagmaBlockBaseFee(parent, getTestConfig(big.NewInt(5)).Governance.KIP71) 243 if parentBaseFee.Cmp(nextBaseFee) < 0 { 244 t.Errorf("before fork, dynamic base fee policy should be inactive, current base fee: %d next base fee: %d", parentBaseFee, nextBaseFee) 245 } 246 } 247 248 func TestActieDynamicPolicyAfterForkedBlock(t *testing.T) { 249 parentBaseFee := big.NewInt(25000000000) 250 parent := &types.Header{ 251 Number: common.Big3, 252 GasUsed: 84000000, 253 BaseFee: parentBaseFee, 254 } 255 nextBaseFee := NextMagmaBlockBaseFee(parent, getTestConfig(big.NewInt(2)).Governance.KIP71) 256 if parentBaseFee.Cmp(nextBaseFee) > 0 { 257 t.Errorf("after fork, dynamic base fee policy should be active, current base fee: %d next base fee: %d", parentBaseFee, nextBaseFee) 258 } 259 } 260 261 func BenchmarkNextBlockBaseFeeRandom(b *testing.B) { 262 parentBaseFee := big.NewInt(500000000000) 263 parent := &types.Header{ 264 Number: common.Big3, 265 GasUsed: 10000000, 266 BaseFee: parentBaseFee, 267 } 268 for i := 0; i < b.N; i++ { 269 if rand.Int()%2 == 0 { 270 parent.GasUsed = 10000000 271 } else { 272 parent.GasUsed = 40000000 273 } 274 _ = NextMagmaBlockBaseFee(parent, getTestConfig(big.NewInt(2)).Governance.KIP71) 275 } 276 } 277 278 func BenchmarkNextBlockBaseFeeUpperBound(b *testing.B) { 279 parentBaseFee := big.NewInt(750000000000) 280 parent := &types.Header{ 281 Number: common.Big3, 282 GasUsed: 40000000, 283 BaseFee: parentBaseFee, 284 } 285 for i := 0; i < b.N; i++ { 286 _ = NextMagmaBlockBaseFee(parent, getTestConfig(big.NewInt(2)).Governance.KIP71) 287 } 288 } 289 290 func BenchmarkNextBlockBaseFeeLowerBound(b *testing.B) { 291 parentBaseFee := big.NewInt(25000000000) 292 parent := &types.Header{ 293 Number: common.Big3, 294 GasUsed: 10000000, 295 BaseFee: parentBaseFee, 296 } 297 for i := 0; i < b.N; i++ { 298 _ = NextMagmaBlockBaseFee(parent, getTestConfig(big.NewInt(2)).Governance.KIP71) 299 } 300 }