github.com/okex/exchain@v1.8.0/libs/tendermint/mempool/recommended_gasprice_test.go (about) 1 package mempool 2 3 import ( 4 "math/big" 5 "testing" 6 7 "github.com/ethereum/go-ethereum/params" 8 "github.com/stretchr/testify/require" 9 10 "github.com/okex/exchain/libs/tendermint/abci/example/kvstore" 11 cfg "github.com/okex/exchain/libs/tendermint/config" 12 "github.com/okex/exchain/libs/tendermint/proxy" 13 "github.com/okex/exchain/libs/tendermint/types" 14 ) 15 16 // tx for recommended gas price test 17 type RGPTX struct { 18 GU uint64 19 GP *big.Int 20 } 21 22 func NewRGPTX(gu uint64, gp *big.Int) RGPTX { 23 return RGPTX{ 24 GU: gu, 25 GP: gp, 26 } 27 } 28 29 func TestCListMempool_RecommendGP(t *testing.T) { 30 testCases := []struct { 31 title string 32 curBlockRGP *big.Int 33 isCurBlockCongested bool 34 35 gpMaxTxNum int64 36 gpMaxGasUsed int64 37 gpMode int 38 39 prepare func(int, int64, int64) 40 // build txs for one block 41 buildTxs func(int, int64, *int64, bool, bool) []RGPTX 42 43 expectedTotalGU []uint64 44 expectedRecommendGp []string 45 blocks int 46 47 needMultiple bool 48 gpDecrease bool 49 tpb []int 50 }{ 51 { 52 title: "5/5 empty block, higher gp mode", 53 curBlockRGP: big.NewInt(0), 54 gpMaxTxNum: 300, 55 gpMaxGasUsed: 40000000, 56 gpMode: types.CongestionHigherGpMode, 57 prepare: setMocConfig, 58 buildTxs: generateTxs, 59 expectedTotalGU: []uint64{0, 0, 0, 0, 0}, 60 expectedRecommendGp: []string{"100000000", "100000000", "100000000", "100000000", "100000000"}, 61 blocks: 5, 62 needMultiple: false, 63 gpDecrease: false, 64 tpb: []int{0, 0, 0, 0, 0}, 65 }, 66 { 67 title: "4/6 empty block, higher gp mode", 68 curBlockRGP: big.NewInt(0), 69 gpMaxTxNum: 300, 70 gpMaxGasUsed: 40000000, 71 gpMode: types.CongestionHigherGpMode, 72 prepare: setMocConfig, 73 buildTxs: generateTxs, 74 expectedTotalGU: []uint64{46329800, 0, 0, 0, 0, 46329800}, 75 expectedRecommendGp: []string{"100200099", "100000000", "100000000", "100000000", "100000000", "100200099"}, 76 blocks: 6, 77 needMultiple: false, 78 gpDecrease: false, 79 tpb: []int{200, 0, 0, 0, 0, 200}, 80 }, 81 82 { 83 title: "4/6 uncongested block, higher gp mode", 84 curBlockRGP: big.NewInt(0), 85 gpMaxTxNum: 300, 86 gpMaxGasUsed: 40000000, 87 gpMode: types.CongestionHigherGpMode, 88 prepare: setMocConfig, 89 buildTxs: generateTxs, 90 expectedTotalGU: []uint64{46329800, 23164900, 23164900, 23164900, 23164900, 46329800}, 91 expectedRecommendGp: []string{"100200099", "100000000", "100000000", "100000000", "100000000", "100200500"}, 92 blocks: 6, 93 needMultiple: false, 94 gpDecrease: false, 95 tpb: []int{200, 100, 100, 100, 100, 200}, 96 }, 97 { 98 title: "0/5 empty block, higher gp mode", 99 curBlockRGP: big.NewInt(0), 100 gpMaxTxNum: 300, 101 gpMaxGasUsed: 40000000, 102 gpMode: types.CongestionHigherGpMode, 103 prepare: setMocConfig, 104 buildTxs: generateTxs, 105 expectedTotalGU: []uint64{46329800, 46329800, 46329800, 46329800, 46329800}, 106 expectedRecommendGp: []string{"100200099", "100200099", "100200299", "100200499", "100200699"}, 107 blocks: 5, 108 needMultiple: false, 109 gpDecrease: false, 110 tpb: []int{200, 200, 200, 200, 200}, 111 }, 112 { 113 title: "2/5 empty block, higher gp mode", 114 curBlockRGP: big.NewInt(0), 115 gpMaxTxNum: 300, 116 gpMaxGasUsed: 40000000, 117 gpMode: types.CongestionHigherGpMode, 118 prepare: setMocConfig, 119 buildTxs: generateTxs, 120 expectedTotalGU: []uint64{46329800, 0, 46329800, 0, 46329800}, 121 expectedRecommendGp: []string{"100200099", "100000000", "100200099", "100000000", "100200299"}, 122 blocks: 5, 123 needMultiple: false, 124 gpDecrease: false, 125 tpb: []int{200, 0, 200, 0, 200}, 126 }, 127 { 128 title: "2/5 empty block, uncongestion, higher gp mode", 129 curBlockRGP: big.NewInt(0), 130 gpMaxTxNum: 300, 131 gpMaxGasUsed: 60000000, 132 gpMode: types.CongestionHigherGpMode, 133 prepare: setMocConfig, 134 buildTxs: generateTxs, 135 expectedTotalGU: []uint64{46329800, 0, 46329800, 0, 46329800}, 136 expectedRecommendGp: []string{"100000000", "100000000", "100000000", "100000000", "100000000"}, 137 blocks: 5, 138 needMultiple: false, 139 gpDecrease: false, 140 tpb: []int{200, 0, 200, 0, 200}, 141 }, 142 { 143 title: "0/5 empty block, minimal gp mode", 144 curBlockRGP: big.NewInt(0), 145 gpMaxTxNum: 300, 146 gpMaxGasUsed: 40000000, 147 gpMode: types.MinimalGpMode, 148 prepare: setMocConfig, 149 buildTxs: generateTxs, 150 expectedTotalGU: []uint64{46329800, 46329800, 46329800, 46329800, 46329800}, 151 expectedRecommendGp: []string{"0", "0", "0", "0", "0"}, 152 blocks: 5, 153 needMultiple: false, 154 gpDecrease: false, 155 tpb: []int{200, 200, 200, 200, 200}, 156 }, 157 { 158 title: "0/5 empty block, gp decrease, normal gp mode", 159 curBlockRGP: big.NewInt(0), 160 gpMaxTxNum: 300, 161 gpMaxGasUsed: 40000000, 162 gpMode: types.NormalGpMode, 163 prepare: setMocConfig, 164 buildTxs: generateTxs, 165 expectedTotalGU: []uint64{46329800, 46329800, 46329800, 46329800, 46329800}, 166 expectedRecommendGp: []string{"100199802", "100199802", "100199801", "100199603", "100199603"}, 167 blocks: 5, 168 needMultiple: false, 169 gpDecrease: true, 170 tpb: []int{200, 200, 200, 200, 200}, 171 }, 172 { 173 title: "0/5 empty block, gp decrease, higher gp mode", 174 curBlockRGP: big.NewInt(0), 175 gpMaxTxNum: 300, 176 gpMaxGasUsed: 40000000, 177 gpMode: types.CongestionHigherGpMode, 178 prepare: setMocConfig, 179 buildTxs: generateTxs, 180 expectedTotalGU: []uint64{46329800, 46329800, 46329800, 46329800, 46329800}, 181 expectedRecommendGp: []string{"100199900", "100199700", "100199700", "100199700", "100199700"}, 182 blocks: 5, 183 needMultiple: false, 184 gpDecrease: true, 185 tpb: []int{200, 200, 200, 200, 200}, 186 }, 187 { 188 title: "0/5 empty block, normal mode", 189 curBlockRGP: big.NewInt(0), 190 gpMaxTxNum: 300, 191 gpMaxGasUsed: 40000000, 192 gpMode: types.NormalGpMode, 193 prepare: setMocConfig, 194 buildTxs: generateTxs, 195 expectedTotalGU: []uint64{46329800, 46329800, 46329800, 46329800, 46329800}, 196 expectedRecommendGp: []string{"100200001", "100200201", "100200400", "100200402", "100200602"}, 197 blocks: 5, 198 needMultiple: false, 199 gpDecrease: false, 200 tpb: []int{200, 200, 200, 200, 200}, 201 }, 202 { 203 title: "0/5 empty block, uncongestion, higher gp mode", 204 curBlockRGP: big.NewInt(0), 205 gpMaxTxNum: 300, 206 gpMaxGasUsed: 60000000, 207 gpMode: types.CongestionHigherGpMode, 208 prepare: setMocConfig, 209 buildTxs: generateTxs, 210 expectedTotalGU: []uint64{46329800, 46329800, 46329800, 46329800, 46329800}, 211 expectedRecommendGp: []string{"100000000", "100000000", "100000000", "100000000", "100000000"}, 212 blocks: 5, 213 needMultiple: false, 214 gpDecrease: false, 215 tpb: []int{200, 200, 200, 200, 200}, 216 }, 217 { 218 title: "0/5 empty block, uncongestion, gp multiple, higher gp mode", 219 curBlockRGP: big.NewInt(0), 220 gpMaxTxNum: 300, 221 gpMaxGasUsed: 60000000, 222 gpMode: types.CongestionHigherGpMode, 223 prepare: setMocConfig, 224 buildTxs: generateTxs, 225 expectedTotalGU: []uint64{46329800, 46329800, 46329800, 46329800, 46329800}, 226 expectedRecommendGp: []string{"100000000", "100000000", "100000000", "100000000", "100000000"}, 227 blocks: 5, 228 needMultiple: true, 229 gpDecrease: false, 230 tpb: []int{200, 200, 200, 200, 200}, 231 }, 232 { 233 title: "0/5 empty block, congestion, gp multiple, higher gp mode", 234 curBlockRGP: big.NewInt(0), 235 gpMaxTxNum: 300, 236 gpMaxGasUsed: 40000000, 237 gpMode: types.CongestionHigherGpMode, 238 prepare: setMocConfig, 239 buildTxs: generateTxs, 240 expectedTotalGU: []uint64{46329800, 46329800, 46329800, 46329800, 46329800}, 241 expectedRecommendGp: []string{"5060109900", "5060109900", "5060120000", "5060130100", "5060140200"}, 242 blocks: 5, 243 needMultiple: true, 244 gpDecrease: false, 245 tpb: []int{200, 200, 200, 200, 200}, 246 }, 247 { 248 title: "0/5 empty block, congestion, gp decrease, gp multiple, higher gp mode", 249 curBlockRGP: big.NewInt(0), 250 gpMaxTxNum: 300, 251 gpMaxGasUsed: 40000000, 252 gpMode: types.CongestionHigherGpMode, 253 prepare: setMocConfig, 254 buildTxs: generateTxs, 255 expectedTotalGU: []uint64{46329800, 46329800, 46329800, 46329800, 46329800}, 256 expectedRecommendGp: []string{"5060094901", "5060084801", "5060084801", "5060084801", "5060084801"}, 257 blocks: 5, 258 needMultiple: true, 259 gpDecrease: true, 260 tpb: []int{200, 200, 200, 200, 200}, 261 }, 262 { 263 title: "0/5 empty block, congestion, gp multiple, normal mode", 264 curBlockRGP: big.NewInt(0), 265 gpMaxTxNum: 300, 266 gpMaxGasUsed: 40000000, 267 gpMode: types.NormalGpMode, 268 prepare: setMocConfig, 269 buildTxs: generateTxs, 270 expectedTotalGU: []uint64{46329800, 46329800, 46329800, 46329800, 46329800}, 271 expectedRecommendGp: []string{"100200001", "100200201", "100200400", "100200402", "100200602"}, 272 blocks: 5, 273 needMultiple: true, 274 gpDecrease: false, 275 tpb: []int{200, 200, 200, 200, 200}, 276 }, 277 } 278 279 for _, tc := range testCases { 280 t.Run(tc.title, func(tt *testing.T) { 281 // init mempool 282 app := kvstore.NewApplication() 283 cc := proxy.NewLocalClientCreator(app) 284 mempool, cleanup := newMempoolWithApp(cc) 285 defer cleanup() 286 287 tc.prepare(tc.gpMode, tc.gpMaxTxNum, tc.gpMaxGasUsed) 288 gpOffset := int64(200000) 289 baseGP := int64(params.GWei / 10) 290 291 for i := 0; i < tc.blocks; i++ { 292 totalGasUsed := uint64(0) 293 txs := tc.buildTxs(tc.tpb[i], baseGP, &gpOffset, tc.gpDecrease, tc.needMultiple) 294 for _, tx := range txs { 295 if cfg.DynamicConfig.GetDynamicGpMode() != types.MinimalGpMode { 296 mempool.gpo.CurrentBlockGPs.Update(tx.GP, tx.GU) 297 } 298 totalGasUsed += tx.GU 299 } 300 require.True(tt, totalGasUsed == tc.expectedTotalGU[i], "block gas expect %d, but get %d ", tc.expectedTotalGU[i], totalGasUsed) 301 if cfg.DynamicConfig.GetDynamicGpMode() != types.MinimalGpMode { 302 // calculate recommended GP 303 currentBlockGPsCopy := mempool.gpo.CurrentBlockGPs.Copy() 304 err := mempool.gpo.BlockGPQueue.Push(currentBlockGPsCopy) 305 require.Nil(tt, err) 306 tc.curBlockRGP, tc.isCurBlockCongested = mempool.gpo.RecommendGP() 307 tc.curBlockRGP = postProcessGP(tc.curBlockRGP, tc.isCurBlockCongested) 308 mempool.gpo.CurrentBlockGPs.Clear() 309 } 310 //fmt.Println("current recommended GP: ", tc.curBlockRGP) 311 require.True(tt, tc.expectedRecommendGp[i] == tc.curBlockRGP.String(), "recommend gas price expect %s, but get %s ", tc.expectedRecommendGp[i], tc.curBlockRGP.String()) 312 } 313 }) 314 } 315 } 316 317 func generateTxs(totalTxNum int, baseGP int64, gpOffset *int64, needDecreaseGP bool, needMultiple bool) []RGPTX { 318 // guPerTx is gas used of evm contract - Owner.sol 319 // bytecode := ethcommon.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032") 320 guPerTx := uint64(231649) 321 txs := make([]RGPTX, 0) 322 for txCount := 0; txCount < totalTxNum/2; txCount++ { 323 curTxGp := baseGP + *gpOffset 324 if !needDecreaseGP { 325 *gpOffset++ 326 } else { 327 *gpOffset-- 328 } 329 tx := NewRGPTX(guPerTx, big.NewInt(curTxGp)) 330 txs = append(txs, tx) 331 } 332 333 multiple := int64(1) 334 if needMultiple { 335 multiple = 100 336 } 337 for txCount := totalTxNum / 2; txCount < totalTxNum; txCount++ { 338 curTxGp := (baseGP + *gpOffset) * multiple 339 if !needDecreaseGP { 340 *gpOffset++ 341 } else { 342 *gpOffset-- 343 } 344 tx := NewRGPTX(guPerTx, big.NewInt(curTxGp)) 345 346 txs = append(txs, tx) 347 } 348 return txs 349 } 350 351 func setMocConfig(gpMode int, gpMaxTxNum int64, gpMaxGasUsed int64) { 352 moc := cfg.MockDynamicConfig{} 353 moc.SetDynamicGpMode(gpMode) 354 moc.SetDynamicGpMaxTxNum(gpMaxTxNum) 355 moc.SetDynamicGpMaxGasUsed(gpMaxGasUsed) 356 357 cfg.SetDynamicConfig(moc) 358 } 359 360 func postProcessGP(recommendedGP *big.Int, isCongested bool) *big.Int { 361 // minGP for test is 0.1GWei 362 minGP := big.NewInt(100000000) 363 maxGP := new(big.Int).Mul(minGP, big.NewInt(5000)) 364 365 rgp := new(big.Int).Set(minGP) 366 if cfg.DynamicConfig.GetDynamicGpMode() != types.MinimalGpMode { 367 // If current block is not congested, rgp == minimal gas price. 368 if isCongested { 369 rgp.Set(recommendedGP) 370 } 371 372 if rgp.Cmp(minGP) == -1 { 373 rgp.Set(minGP) 374 } 375 376 if rgp.Cmp(maxGP) == 1 { 377 rgp.Set(maxGP) 378 } 379 } 380 return rgp 381 }