github.com/okex/exchain@v1.8.0/libs/tendermint/mempool/recommended_gasprice.go (about) 1 package mempool 2 3 import ( 4 "fmt" 5 "math/big" 6 "sort" 7 8 "github.com/okex/exchain/libs/system/trace" 9 cfg "github.com/okex/exchain/libs/tendermint/config" 10 "github.com/okex/exchain/libs/tendermint/types" 11 ) 12 13 type GPOConfig struct { 14 Weight int 15 Default *big.Int 16 Blocks int 17 } 18 19 func NewGPOConfig(weight int, checkBlocks int) GPOConfig { 20 return GPOConfig{ 21 Weight: weight, 22 // default gas price is 0.1GWei 23 Default: big.NewInt(100000000), 24 Blocks: checkBlocks, 25 } 26 } 27 28 // Oracle recommends gas prices based on the content of recent blocks. 29 type Oracle struct { 30 CurrentBlockGPs *types.SingleBlockGPs 31 // hold the gas prices of the latest few blocks 32 BlockGPQueue *types.BlockGPResults 33 lastPrice *big.Int 34 weight int 35 } 36 37 // NewOracle returns a new gasprice oracle which can recommend suitable 38 // gasprice for newly created transaction. 39 func NewOracle(params GPOConfig) *Oracle { 40 cbgp := types.NewSingleBlockGPs() 41 bgpq := types.NewBlockGPResults(params.Blocks) 42 weight := params.Weight 43 if weight < 0 { 44 weight = 0 45 } 46 if weight > 100 { 47 weight = 100 48 } 49 return &Oracle{ 50 CurrentBlockGPs: cbgp, 51 BlockGPQueue: bgpq, 52 // Note: deep copy is necessary here 53 lastPrice: new(big.Int).Set(params.Default), 54 weight: weight, 55 } 56 } 57 58 func (gpo *Oracle) RecommendGP() (*big.Int, bool) { 59 60 gasUsedThreshold := cfg.DynamicConfig.GetDynamicGpMaxGasUsed() 61 txNumThreshold := cfg.DynamicConfig.GetDynamicGpMaxTxNum() 62 63 allTxsLen := int64(len(gpo.CurrentBlockGPs.GetAll())) 64 // If the current block's total gas consumption is more than gasUsedThreshold, 65 // or the number of tx in the current block is more than txNumThreshold, 66 // then we consider the chain to be congested. 67 isCongested := (int64(gpo.CurrentBlockGPs.GetGasUsed()) >= gasUsedThreshold) || (allTxsLen >= txNumThreshold) 68 trace.GetElapsedInfo().AddInfo(trace.IsCongested, fmt.Sprintf("%t", isCongested)) 69 70 // If GP mode is CongestionHigherGpMode, increase the recommended gas price when the network is congested. 71 adoptHigherGp := (cfg.DynamicConfig.GetDynamicGpMode() == types.CongestionHigherGpMode) && isCongested 72 73 txPrices := gpo.BlockGPQueue.ExecuteSamplingBy(gpo.lastPrice, adoptHigherGp) 74 75 price := new(big.Int).Set(gpo.lastPrice) 76 77 if len(txPrices) > 0 { 78 sort.Sort(types.BigIntArray(txPrices)) 79 price.Set(txPrices[(len(txPrices)-1)*gpo.weight/100]) 80 } 81 gpo.lastPrice.Set(price) 82 83 trace.GetElapsedInfo().AddInfo(trace.RecommendedGP, fmt.Sprintf("%sWei", price.String())) 84 return price, isCongested 85 }