github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/gasprice/constructive.go (about)

     1  package gasprice
     2  
     3  import (
     4  	"math/big"
     5  
     6  	"github.com/unicornultrafoundation/go-helios/utils/piecefunc"
     7  )
     8  
     9  func (gpo *Oracle) maxTotalGasPower() *big.Int {
    10  	rules := gpo.backend.GetRules()
    11  
    12  	allocBn := new(big.Int).SetUint64(rules.Economy.LongGasPower.AllocPerSec)
    13  	periodBn := new(big.Int).SetUint64(uint64(rules.Economy.LongGasPower.MaxAllocPeriod))
    14  	maxTotalGasPowerBn := new(big.Int).Mul(allocBn, periodBn)
    15  	maxTotalGasPowerBn.Div(maxTotalGasPowerBn, secondBn)
    16  	return maxTotalGasPowerBn
    17  }
    18  
    19  func (gpo *Oracle) effectiveMinGasPrice() *big.Int {
    20  	return gpo.constructiveGasPrice(0, 0, gpo.backend.GetRules().Economy.MinGasPrice)
    21  }
    22  
    23  func (gpo *Oracle) constructiveGasPrice(gasOffestAbs uint64, gasOffestRatio uint64, adjustedMinPrice *big.Int) *big.Int {
    24  	max := gpo.maxTotalGasPower()
    25  
    26  	current64 := gpo.backend.TotalGasPowerLeft()
    27  	if current64 > gasOffestAbs {
    28  		current64 -= gasOffestAbs
    29  	} else {
    30  		current64 = 0
    31  	}
    32  	current := new(big.Int).SetUint64(current64)
    33  
    34  	freeRatioBn := current.Mul(current, DecimalUnitBn)
    35  	freeRatioBn.Div(freeRatioBn, max)
    36  	freeRatio := freeRatioBn.Uint64()
    37  	if freeRatio > gasOffestRatio {
    38  		freeRatio -= gasOffestRatio
    39  	} else {
    40  		freeRatio = 0
    41  	}
    42  	if freeRatio > DecimalUnit {
    43  		freeRatio = DecimalUnit
    44  	}
    45  	v := gpo.constructiveGasPriceOf(freeRatio, adjustedMinPrice)
    46  	return v
    47  }
    48  
    49  var freeRatioToConstructiveGasRatio = piecefunc.NewFunc([]piecefunc.Dot{
    50  	{
    51  		X: 0,
    52  		Y: 25 * DecimalUnit,
    53  	},
    54  	{
    55  		X: 0.3 * DecimalUnit,
    56  		Y: 9 * DecimalUnit,
    57  	},
    58  	{
    59  		X: 0.5 * DecimalUnit,
    60  		Y: 3.75 * DecimalUnit,
    61  	},
    62  	{
    63  		X: 0.8 * DecimalUnit,
    64  		Y: 1.5 * DecimalUnit,
    65  	},
    66  	{
    67  		X: 0.95 * DecimalUnit,
    68  		Y: 1.05 * DecimalUnit,
    69  	},
    70  	{
    71  		X: DecimalUnit,
    72  		Y: DecimalUnit,
    73  	},
    74  })
    75  
    76  func (gpo *Oracle) constructiveGasPriceOf(freeRatio uint64, adjustedMinPrice *big.Int) *big.Int {
    77  	multiplier := new(big.Int).SetUint64(freeRatioToConstructiveGasRatio(freeRatio))
    78  
    79  	// gas price = multiplier * adjustedMinPrice
    80  	price := multiplier.Mul(multiplier, adjustedMinPrice)
    81  	return price.Div(price, DecimalUnitBn)
    82  }