Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GasLimit controller change for the testnet #1101

18 changes: 16 additions & 2 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1240,43 +1240,57 @@ func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) {
}
}

func setDurationLimit(ctx *cli.Context, cfg *ethconfig.Config) {
func setConsensusEngineConfig(ctx *cli.Context, cfg *ethconfig.Config) {
if cfg.ConsensusEngine == "blake3" {
// Override any default configs for hard coded networks.
switch {
case ctx.GlobalBool(ColosseumFlag.Name):
cfg.Blake3Pow.DurationLimit = params.DurationLimit
cfg.Blake3Pow.GasCeil = params.ColosseumGasCeil
case ctx.GlobalBool(GardenFlag.Name):
cfg.Blake3Pow.DurationLimit = params.GardenDurationLimit
cfg.Blake3Pow.GasCeil = params.GardenGasCeil
case ctx.GlobalBool(OrchardFlag.Name):
cfg.Blake3Pow.DurationLimit = params.OrchardDurationLimit
cfg.Blake3Pow.GasCeil = params.OrchardGasCeil
case ctx.GlobalBool(LighthouseFlag.Name):
cfg.Blake3Pow.DurationLimit = params.LighthouseDurationLimit
cfg.Blake3Pow.GasCeil = params.LighthouseGasCeil
case ctx.GlobalBool(LocalFlag.Name):
cfg.Blake3Pow.DurationLimit = params.LocalDurationLimit
cfg.Blake3Pow.GasCeil = params.LocalGasCeil
case ctx.GlobalBool(DeveloperFlag.Name):
cfg.Blake3Pow.DurationLimit = params.DurationLimit
cfg.Blake3Pow.GasCeil = params.LocalGasCeil
default:
cfg.Blake3Pow.DurationLimit = params.DurationLimit
cfg.Blake3Pow.GasCeil = params.GasCeil

}
} else {
// Override any default configs for hard coded networks.
switch {
case ctx.GlobalBool(ColosseumFlag.Name):
cfg.Progpow.DurationLimit = params.DurationLimit
cfg.Progpow.GasCeil = params.ColosseumGasCeil
case ctx.GlobalBool(GardenFlag.Name):
cfg.Progpow.DurationLimit = params.GardenDurationLimit
cfg.Progpow.GasCeil = params.GardenGasCeil
case ctx.GlobalBool(OrchardFlag.Name):
cfg.Progpow.DurationLimit = params.OrchardDurationLimit
cfg.Progpow.GasCeil = params.OrchardGasCeil
case ctx.GlobalBool(LighthouseFlag.Name):
cfg.Progpow.DurationLimit = params.LighthouseDurationLimit
cfg.Progpow.GasCeil = params.LighthouseGasCeil
case ctx.GlobalBool(LocalFlag.Name):
cfg.Progpow.DurationLimit = params.LocalDurationLimit
cfg.Progpow.GasCeil = params.LocalGasCeil
case ctx.GlobalBool(DeveloperFlag.Name):
cfg.Progpow.DurationLimit = params.DurationLimit
cfg.Progpow.GasCeil = params.LocalGasCeil
default:
cfg.Progpow.DurationLimit = params.DurationLimit
cfg.Progpow.GasCeil = params.GasCeil

}
}
Expand Down Expand Up @@ -1425,7 +1439,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
} else {
cfg.ConsensusEngine = "progpow"
}
setDurationLimit(ctx, cfg)
setConsensusEngineConfig(ctx, cfg)

setWhitelist(ctx, cfg)

Expand Down
2 changes: 2 additions & 0 deletions consensus/blake3pow/blake3pow.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ type Config struct {

DurationLimit *big.Int

GasCeil uint64

// When set, notifications sent by the remote sealer will
// be block header JSON objects instead of work package arrays.
NotifyFull bool
Expand Down
44 changes: 20 additions & 24 deletions consensus/blake3pow/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/dominant-strategies/go-quai/log"
"github.com/dominant-strategies/go-quai/params"
"github.com/dominant-strategies/go-quai/trie"
"modernc.org/mathutil"
)

// Blake3pow proof-of-work protocol constants.
Expand Down Expand Up @@ -300,8 +301,10 @@ func (blake3pow *Blake3pow) verifyHeader(chain consensus.ChainHeaderReader, head
}
// Verify the block's gas usage and verify the base fee.
// Verify that the gas limit remains within allowed bounds
if err := misc.VerifyGaslimit(parent.GasLimit(), header.GasLimit()); err != nil {
return err
expectedGasLimit := core.CalcGasLimit(parent, blake3pow.config.GasCeil)
if expectedGasLimit != header.GasLimit() {
return fmt.Errorf("invalid gasLimit: have %d, want %d",
header.GasLimit(), expectedGasLimit)
}
// Verify the header is not malformed
if header.BaseFee() == nil {
Expand Down Expand Up @@ -331,48 +334,41 @@ func (blake3pow *Blake3pow) CalcDifficulty(chain consensus.ChainHeaderReader, pa
log.Error("Cannot CalcDifficulty for", "context", nodeCtx)
return nil
}
// algorithm:
// diff = (parent_diff +
// (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
// ) + 2^(periodCount - 2)

time := parent.Time()
///// Algorithm:
///// e = (DurationLimit - (parent.Time() - parentOfParent.Time())) * parent.Difficulty()
///// k = Floor(BinaryLog(parent.Difficulty()))/(DurationLimit*DifficultyAdjustmentFactor*AdjustmentPeriod)
///// Difficulty = Max(parent.Difficulty() + e * k, MinimumDifficulty)

if parent.Hash() == chain.Config().GenesisHash {
return parent.Difficulty()
}

parentOfParent := chain.GetHeaderByHash(parent.ParentHash())
if parentOfParent.Hash() == chain.Config().GenesisHash {
return parent.Difficulty()
}

time := parent.Time()
bigTime := new(big.Int).SetUint64(time)
bigParentTime := new(big.Int).SetUint64(parentOfParent.Time())

// holds intermediate values to make the algo easier to read & audit
x := new(big.Int)
y := new(big.Int)

// (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // duration_limit
x.Sub(bigTime, bigParentTime)
x.Sub(blake3pow.config.DurationLimit, x)
x.Mul(x, parent.Difficulty())
k, _ := mathutil.BinaryLog(new(big.Int).Set(parent.Difficulty()), 64)
x.Mul(x, big.NewInt(int64(k)))
x.Div(x, blake3pow.config.DurationLimit)
if parent.UncleHash() == types.EmptyUncleHash {
x.Sub(big1, x)
} else {
x.Sub(big2, x)
}
// max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99)
if x.Cmp(bigMinus99) < 0 {
x.Set(bigMinus99)
}
// parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
y.Div(parent.Difficulty(), params.DifficultyBoundDivisor)
x.Mul(y, x)
x.Add(parent.Difficulty(), x)
x.Div(x, big.NewInt(params.DifficultyAdjustmentFactor))
x.Div(x, params.DifficultyAdjustmentPeriod)
x.Add(x, parent.Difficulty())

// minimum difficulty can ever be (before exponential factor)
if x.Cmp(params.MinimumDifficulty) < 0 {
x.Set(params.MinimumDifficulty)
}

return x
}

Expand Down
42 changes: 0 additions & 42 deletions consensus/misc/gaslimit.go

This file was deleted.

45 changes: 20 additions & 25 deletions consensus/progpow/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/dominant-strategies/go-quai/log"
"github.com/dominant-strategies/go-quai/params"
"github.com/dominant-strategies/go-quai/trie"
"modernc.org/mathutil"
)

// Progpow proof-of-work protocol constants.
Expand Down Expand Up @@ -299,8 +300,10 @@ func (progpow *Progpow) verifyHeader(chain consensus.ChainHeaderReader, header,
}
// Verify the block's gas usage and verify the base fee.
// Verify that the gas limit remains within allowed bounds
if err := misc.VerifyGaslimit(parent.GasLimit(), header.GasLimit()); err != nil {
return err
expectedGasLimit := core.CalcGasLimit(parent, progpow.config.GasCeil)
if expectedGasLimit != header.GasLimit() {
return fmt.Errorf("invalid gasLimit: have %d, want %d",
header.GasLimit(), expectedGasLimit)
}
// Verify the header is not malformed
if header.BaseFee() == nil {
Expand Down Expand Up @@ -330,48 +333,40 @@ func (progpow *Progpow) CalcDifficulty(chain consensus.ChainHeaderReader, parent
log.Error("Cannot CalcDifficulty for", "context", nodeCtx)
return nil
}
// algorithm:
// diff = (parent_diff +
// (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
// ) + 2^(periodCount - 2)

time := parent.Time()
///// Algorithm:
///// e = (DurationLimit - (parent.Time() - parentOfParent.Time())) * parent.Difficulty()
///// k = Floor(BinaryLog(parent.Difficulty()))/(DurationLimit*2*DifficultyAdjustmentFactor*AdjustmentPeriod)
///// Difficulty = Max(parent.Difficulty() + e * k, MinimumDifficulty)

if parent.Hash() == chain.Config().GenesisHash {
return parent.Difficulty()
}

parentOfParent := chain.GetHeaderByHash(parent.ParentHash())
if parentOfParent.Hash() == chain.Config().GenesisHash {
return parent.Difficulty()
}

time := parent.Time()
bigTime := new(big.Int).SetUint64(time)
bigParentTime := new(big.Int).SetUint64(parentOfParent.Time())

// holds intermediate values to make the algo easier to read & audit
x := new(big.Int)
y := new(big.Int)

// (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // duration_limit
x.Sub(bigTime, bigParentTime)
x.Sub(progpow.config.DurationLimit, x)
x.Mul(x, parent.Difficulty())
k, _ := mathutil.BinaryLog(new(big.Int).Set(parent.Difficulty()), 64)
x.Mul(x, big.NewInt(int64(k)))
x.Div(x, progpow.config.DurationLimit)
if parent.UncleHash() == types.EmptyUncleHash {
x.Sub(big1, x)
} else {
x.Sub(big2, x)
}
// max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99)
if x.Cmp(bigMinus99) < 0 {
x.Set(bigMinus99)
}
// parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
y.Div(parent.Difficulty(), params.DifficultyBoundDivisor)
x.Mul(y, x)
x.Add(parent.Difficulty(), x)
x.Div(x, big.NewInt(params.DifficultyAdjustmentFactor))
x.Div(x, params.DifficultyAdjustmentPeriod)
x.Add(x, parent.Difficulty())

// minimum difficulty can ever be (before exponential factor)
if x.Cmp(params.MinimumDifficulty) < 0 {
x.Set(params.MinimumDifficulty)
}

return x
}

Expand Down
1 change: 1 addition & 0 deletions consensus/progpow/progpow.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ type Config struct {
CachesOnDisk int
CachesLockMmap bool
DurationLimit *big.Int
GasCeil uint64

// When set, notifications sent by the remote sealer will
// be block header JSON objects instead of work package arrays.
Expand Down
47 changes: 32 additions & 15 deletions core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,25 +144,42 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
// CalcGasLimit computes the gas limit of the next block after parent. It aims
// to keep the baseline gas close to the provided target, and increase it towards
// the target if the baseline gas is lower.
func CalcGasLimit(parentGasLimit, desiredLimit uint64) uint64 {
func CalcGasLimit(parent *types.Header, gasCeil uint64) uint64 {

parentGasLimit := parent.GasLimit()

delta := parentGasLimit/params.GasLimitBoundDivisor - 1
limit := parentGasLimit
if desiredLimit < params.MinGasLimit {

var desiredLimit uint64
percentGasUsed := parent.GasUsed() * 100 / parent.GasLimit()
if percentGasUsed > params.PercentGasUsedThreshold {
desiredLimit = CalcGasCeil(parent.NumberU64(), gasCeil)
if desiredLimit > gasCeil {
desiredLimit = gasCeil
}
if limit+delta > desiredLimit {
return desiredLimit
} else {
return limit + delta
}
} else {
desiredLimit = params.MinGasLimit
}
// If we're outside our allowed gas range, we try to hone towards them
if limit < desiredLimit {
limit = parentGasLimit + delta
if limit > desiredLimit {
limit = desiredLimit
if limit-delta/2 < desiredLimit {
return desiredLimit
} else {
return limit - delta/2
}
return limit
}
if limit > desiredLimit {
limit = parentGasLimit - delta
if limit < desiredLimit {
limit = desiredLimit
}
}

func CalcGasCeil(blockNumber uint64, gasCeil uint64) uint64 {
if blockNumber < params.GasLimitStepOneBlockThreshold {
return gasCeil / 4
} else if blockNumber < params.GasLimitStepTwoBlockThreshold {
return gasCeil / 2
} else if blockNumber < params.GasLimitStepThreeBlockThreshold {
return gasCeil * 3 / 4
}
return limit
return gasCeil
}
9 changes: 5 additions & 4 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const (
c_primeRetryThreshold = 1800 // Number of times a block is retry to be appended before eviction from append queue in Prime
c_regionRetryThreshold = 1200 // Number of times a block is retry to be appended before eviction from append queue in Region
c_zoneRetryThreshold = 600 // Number of times a block is retry to be appended before eviction from append queue in Zone
c_maxFutureBlocks = 15 // Number of blocks ahead of the current block to be put in the hashNumberList
c_maxFutureBlocks = 100 // Number of blocks ahead of the current block to be put in the hashNumberList
c_appendQueueRetryPriorityThreshold = 5 // If retry counter for a block is less than this number, then its put in the special list that is tried first to be appended
c_appendQueueRemoveThreshold = 10 // Number of blocks behind the block should be from the current header to be eligble for removal from the append queue
)
Expand Down Expand Up @@ -359,11 +359,12 @@ func (c *Core) WriteBlock(block *types.Block) {
}
nodeCtx := common.NodeLocation.Context()
if order == nodeCtx {
c.addToAppendQueue(block)
parentHeader := c.GetHeader(block.ParentHash(), block.NumberU64()-1)
if parentHeader != nil {
c.sl.WriteBlock(block)
c.InsertChain([]*types.Block{block})
}
c.addToAppendQueue(block)
// If a dom block comes in and we havent appended it yet
} else if order < nodeCtx && c.GetHeaderByHash(block.Hash()) == nil {
if c.sl.domClient != nil {
Expand Down Expand Up @@ -395,8 +396,8 @@ func (c *Core) SubRelayPendingHeader(slPendingHeader types.PendingHeader, newEnt
c.sl.SubRelayPendingHeader(slPendingHeader, newEntropy, location, subReorg)
}

func (c *Core) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, newEntropy *big.Int, location common.Location) {
c.sl.UpdateDom(oldTerminus, newTerminus, newEntropy, location)
func (c *Core) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, pendingHeader *types.Header, location common.Location) {
c.sl.UpdateDom(oldTerminus, newTerminus, pendingHeader, location)
}

func (c *Core) NewGenesisPendigHeader(pendingHeader *types.Header) {
Expand Down
Loading