diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index a84e5700a0..e91504c852 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1240,24 +1240,31 @@ 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 { @@ -1265,18 +1272,25 @@ func setDurationLimit(ctx *cli.Context, cfg *ethconfig.Config) { 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 } } @@ -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) diff --git a/consensus/blake3pow/blake3pow.go b/consensus/blake3pow/blake3pow.go index f5ea303a62..2cd4f16dc8 100644 --- a/consensus/blake3pow/blake3pow.go +++ b/consensus/blake3pow/blake3pow.go @@ -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 diff --git a/consensus/blake3pow/consensus.go b/consensus/blake3pow/consensus.go index 2551ed2db6..93221508f1 100644 --- a/consensus/blake3pow/consensus.go +++ b/consensus/blake3pow/consensus.go @@ -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. @@ -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 { @@ -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 } @@ -465,7 +461,7 @@ func (blake3pow *Blake3pow) ComputePowLight(header *types.Header) (common.Hash, // included uncles. The coinbase of each uncle block is also rewarded. func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { // Select the correct block reward based on chain progression - blockReward := misc.CalculateReward() + blockReward := misc.CalculateReward(header) coinbase, err := header.Coinbase().InternalAddress() if err != nil { diff --git a/consensus/blake3pow/poem.go b/consensus/blake3pow/poem.go index 494b77771f..c01e167bdc 100644 --- a/consensus/blake3pow/poem.go +++ b/consensus/blake3pow/poem.go @@ -29,15 +29,23 @@ func (blake3pow *Blake3pow) CalcOrder(header *types.Header) (*big.Int, int, erro // PRIME // PrimeEntropyThreshold number of zone blocks times the intrinsic logs of // the given header determines the prime block + totalDeltaSPrime := new(big.Int).Add(header.ParentDeltaS(common.REGION_CTX), header.ParentDeltaS(common.ZONE_CTX)) + totalDeltaSPrime = new(big.Int).Add(totalDeltaSPrime, intrinsicS) + primeDeltaSTarget := new(big.Int).Div(params.PrimeEntropyTarget, big2) + primeDeltaSTarget = new(big.Int).Mul(zoneThresholdS, primeDeltaSTarget) + primeBlockEntropyThreshold := new(big.Int).Add(zoneThresholdS, common.BitsToBigBits(params.PrimeEntropyTarget)) - if intrinsicS.Cmp(primeBlockEntropyThreshold) > 0 { + if intrinsicS.Cmp(primeBlockEntropyThreshold) > 0 && totalDeltaSPrime.Cmp(primeDeltaSTarget) > 0 { return intrinsicS, common.PRIME_CTX, nil } // REGION // Compute the total accumulated entropy since the last region block + totalDeltaSRegion := new(big.Int).Add(header.ParentDeltaS(common.ZONE_CTX), intrinsicS) + regionDeltaSTarget := new(big.Int).Div(params.RegionEntropyTarget, big2) + regionDeltaSTarget = new(big.Int).Mul(zoneThresholdS, regionDeltaSTarget) regionBlockEntropyThreshold := new(big.Int).Add(zoneThresholdS, common.BitsToBigBits(params.RegionEntropyTarget)) - if intrinsicS.Cmp(regionBlockEntropyThreshold) > 0 { + if intrinsicS.Cmp(regionBlockEntropyThreshold) > 0 && totalDeltaSRegion.Cmp(regionDeltaSTarget) > 0 { return intrinsicS, common.REGION_CTX, nil } diff --git a/consensus/misc/basefee.go b/consensus/misc/basefee.go index 9213126937..795cf30482 100644 --- a/consensus/misc/basefee.go +++ b/consensus/misc/basefee.go @@ -19,7 +19,6 @@ package misc import ( "math/big" - "github.com/dominant-strategies/go-quai/common" "github.com/dominant-strategies/go-quai/common/math" "github.com/dominant-strategies/go-quai/core/types" "github.com/dominant-strategies/go-quai/params" @@ -51,10 +50,7 @@ func calcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int { gasUsedDelta := new(big.Int).SetUint64(parent.GasUsed() - parentGasTarget) x := new(big.Int).Mul(parent.BaseFee(), gasUsedDelta) y := x.Div(x, parentGasTargetBig) - baseFeeDelta := math.BigMax( - x.Div(y, baseFeeChangeDenominator), - common.Big1, - ) + baseFeeDelta := math.BigMax(x.Div(y, baseFeeChangeDenominator), big.NewInt(params.GWei)) return x.Add(parent.BaseFee(), baseFeeDelta) } else { @@ -64,9 +60,6 @@ func calcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int { y := x.Div(x, parentGasTargetBig) baseFeeDelta := x.Div(y, baseFeeChangeDenominator) - return math.BigMax( - x.Sub(parent.BaseFee(), baseFeeDelta), - common.Big0, - ) + return math.BigMax(x.Sub(parent.BaseFee(), baseFeeDelta), big.NewInt(params.GWei)) } } diff --git a/consensus/misc/gaslimit.go b/consensus/misc/gaslimit.go deleted file mode 100644 index 24afc685e8..0000000000 --- a/consensus/misc/gaslimit.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package misc - -import ( - "errors" - "fmt" - - "github.com/dominant-strategies/go-quai/params" -) - -// VerifyGaslimit verifies the header gas limit according increase/decrease -// in relation to the parent gas limit. -func VerifyGaslimit(parentGasLimit, headerGasLimit uint64) error { - // Verify that the gas limit remains within allowed bounds - diff := int64(parentGasLimit) - int64(headerGasLimit) - if diff < 0 { - diff *= -1 - } - limit := parentGasLimit / params.GasLimitBoundDivisor - if uint64(diff) >= limit { - return fmt.Errorf("invalid gas limit: have %d, want %d +-= %d", headerGasLimit, parentGasLimit, limit-1) - } - if headerGasLimit < params.MinGasLimit { - return errors.New("invalid gas limit below 5000") - } - return nil -} diff --git a/consensus/misc/rewards.go b/consensus/misc/rewards.go index 917ce5fe53..79b6d6d8ef 100644 --- a/consensus/misc/rewards.go +++ b/consensus/misc/rewards.go @@ -1,45 +1,14 @@ package misc import ( - "log" "math/big" - "github.com/dominant-strategies/go-quai/common" + "github.com/dominant-strategies/go-quai/core/types" ) // CalculateReward calculates the coinbase rewards depending on the type of the block -// regions = # of regions -// zones = # of zones -// For each prime = Reward/3 -// For each region = Reward/(3*regions*time-factor) -// For each zone = Reward/(3*regions*zones*time-factor^2) -func CalculateReward() *big.Int { - reward := big.NewInt(5e18) - reward.Mul(reward, big.NewInt(1000)) - timeFactor := big.NewInt(10) - regions := big.NewInt(3) - zones := big.NewInt(3) - context := common.NodeLocation.Context() - if context == common.PRIME_CTX { - primeReward := big.NewInt(3) - primeReward.Div(reward, primeReward) - return primeReward - } else if context == common.REGION_CTX { - regionReward := big.NewInt(3) - regionReward.Mul(regionReward, regions) - regionReward.Mul(regionReward, timeFactor) - regionReward.Div(reward, regionReward) - return regionReward - } else if context == common.ZONE_CTX { - zoneReward := big.NewInt(3) - zoneReward.Mul(zoneReward, regions) - zoneReward.Mul(zoneReward, zones) - zoneReward.Mul(zoneReward, timeFactor) - zoneReward.Mul(zoneReward, timeFactor) - zoneReward.Div(reward, zoneReward) - return zoneReward - } else { - log.Fatal("unknown node context") - return nil - } +func CalculateReward(header *types.Header) *big.Int { + //// This Reward Schedule is only for Iron Age Testnet and has nothing to do + //// with the Mainnet Schedule + return new(big.Int).Mul(header.Difficulty(), big.NewInt(10e8)) } diff --git a/consensus/progpow/consensus.go b/consensus/progpow/consensus.go index edcc66de24..7f9a937849 100644 --- a/consensus/progpow/consensus.go +++ b/consensus/progpow/consensus.go @@ -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. @@ -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 { @@ -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 } @@ -498,7 +493,7 @@ func (progpow *Progpow) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h // included uncles. The coinbase of each uncle block is also rewarded. func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { // Select the correct block reward based on chain progression - blockReward := misc.CalculateReward() + blockReward := misc.CalculateReward(header) coinbase, err := header.Coinbase().InternalAddress() if err != nil { diff --git a/consensus/progpow/poem.go b/consensus/progpow/poem.go index 42d7dad25f..f19d677e06 100644 --- a/consensus/progpow/poem.go +++ b/consensus/progpow/poem.go @@ -26,20 +26,30 @@ func (progpow *Progpow) CalcOrder(header *types.Header) (*big.Int, int, error) { target := new(big.Int).Div(common.Big2e256, header.Difficulty()) zoneThresholdS := progpow.IntrinsicLogS(common.BytesToHash(target.Bytes())) - // Prime case - // PrimeEntropyThreshold number of zone blocks times the intrinsic logs of the given header determines the prime block + // PRIME + // PrimeEntropyThreshold number of zone blocks times the intrinsic logs of + // the given header determines the prime block + totalDeltaSPrime := new(big.Int).Add(header.ParentDeltaS(common.REGION_CTX), header.ParentDeltaS(common.ZONE_CTX)) + totalDeltaSPrime = new(big.Int).Add(totalDeltaSPrime, intrinsicS) + primeDeltaSTarget := new(big.Int).Div(params.PrimeEntropyTarget, big2) + primeDeltaSTarget = new(big.Int).Mul(zoneThresholdS, primeDeltaSTarget) + primeBlockEntropyThreshold := new(big.Int).Add(zoneThresholdS, common.BitsToBigBits(params.PrimeEntropyTarget)) - if intrinsicS.Cmp(primeBlockEntropyThreshold) > 0 { + if intrinsicS.Cmp(primeBlockEntropyThreshold) > 0 && totalDeltaSPrime.Cmp(primeDeltaSTarget) > 0 { return intrinsicS, common.PRIME_CTX, nil } // REGION // Compute the total accumulated entropy since the last region block + totalDeltaSRegion := new(big.Int).Add(header.ParentDeltaS(common.ZONE_CTX), intrinsicS) + regionDeltaSTarget := new(big.Int).Div(params.RegionEntropyTarget, big2) + regionDeltaSTarget = new(big.Int).Mul(zoneThresholdS, regionDeltaSTarget) regionBlockEntropyThreshold := new(big.Int).Add(zoneThresholdS, common.BitsToBigBits(params.RegionEntropyTarget)) - if intrinsicS.Cmp(regionBlockEntropyThreshold) > 0 { + if intrinsicS.Cmp(regionBlockEntropyThreshold) > 0 && totalDeltaSRegion.Cmp(regionDeltaSTarget) > 0 { return intrinsicS, common.REGION_CTX, nil } + // Zone case return intrinsicS, common.ZONE_CTX, nil } diff --git a/consensus/progpow/progpow.go b/consensus/progpow/progpow.go index 0a2b95008c..3b62db7043 100644 --- a/consensus/progpow/progpow.go +++ b/consensus/progpow/progpow.go @@ -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. diff --git a/core/block_validator.go b/core/block_validator.go index 3226bc2e48..0c905f0313 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -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 } diff --git a/core/core.go b/core/core.go index 597d8a4606..dbb9234a1b 100644 --- a/core/core.go +++ b/core/core.go @@ -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 ) @@ -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 { @@ -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) { diff --git a/core/slice.go b/core/slice.go index fdbc7eae59..fa33f05818 100644 --- a/core/slice.go +++ b/core/slice.go @@ -241,6 +241,9 @@ func (sl *Slice) Append(header *types.Header, domPendingHeader *types.Header, do time7 := common.PrettyDuration(time.Since(start)) + sl.phCacheMu.Lock() + defer sl.phCacheMu.Unlock() + var time8, time9 common.PrettyDuration var bestPh types.PendingHeader var exist bool @@ -255,7 +258,12 @@ func (sl *Slice) Append(header *types.Header, domPendingHeader *types.Header, do time8 = common.PrettyDuration(time.Since(start)) - subReorg = sl.miningStrategy(bestPh, block) + tempPendingHeader, err := sl.generateSlicePendingHeader(block, newTermini, domPendingHeader, domOrigin, false, false) + if err != nil { + return nil, false, err + } + + subReorg = sl.miningStrategy(bestPh, tempPendingHeader) if order < nodeCtx { // Store the inbound etxs for dom blocks that did not get picked and use @@ -279,8 +287,6 @@ func (sl *Slice) Append(header *types.Header, domPendingHeader *types.Header, do time9 = common.PrettyDuration(time.Since(start)) } - sl.phCacheMu.Lock() - defer sl.phCacheMu.Unlock() sl.updatePhCache(pendingHeaderWithTermini, true, nil, subReorg) var updateDom bool @@ -316,16 +322,18 @@ func (sl *Slice) Append(header *types.Header, domPendingHeader *types.Header, do log.Info("times during append:", "t0_1", time0_1, "t0_2", time0_2, "t1:", time1, "t2:", time2, "t3:", time3, "t4:", time4, "t5:", time5, "t6:", time6, "t7:", time7, "t8:", time8, "t9:", time9, "t10:", time10) log.Info("times during sub append:", "t6_1:", time6_1, "t6_2:", time6_2, "t6_3:", time6_3) log.Info("Appended new block", "number", block.Header().Number(), "hash", block.Hash(), - "uncles", len(block.Uncles()), "txs", len(block.Transactions()), "etxs", len(block.ExtTransactions()), "gas", block.GasUsed(), + "difficulty", block.Header().Difficulty(), + "uncles", len(block.Uncles()), "txs", len(block.Transactions()), "etxs", len(block.ExtTransactions()), "gas", block.GasUsed(), "gasLimit", block.GasLimit(), "root", block.Root(), "order", order, + "location", block.Header().Location(), "elapsed", common.PrettyDuration(time.Since(start))) if nodeCtx == common.ZONE_CTX { if updateDom { log.Info("Append updateDom", "oldTermini():", bestPh.Termini().DomTerminus(), "newTermini():", pendingHeaderWithTermini.Termini().DomTerminus(), "location:", common.NodeLocation) if sl.domClient != nil { - go sl.domClient.UpdateDom(context.Background(), bestPh.Termini().DomTerminus(), pendingHeaderWithTermini.Termini().DomTerminus(), pendingHeaderWithTermini.Header().ParentEntropy(), common.NodeLocation) + go sl.domClient.UpdateDom(context.Background(), bestPh.Termini().DomTerminus(), pendingHeaderWithTermini.Termini().DomTerminus(), pendingHeaderWithTermini.Header(), common.NodeLocation) } } return block.ExtTransactions(), subReorg, nil @@ -333,11 +341,11 @@ func (sl *Slice) Append(header *types.Header, domPendingHeader *types.Header, do return subPendingEtxs, subReorg, nil } } -func (sl *Slice) miningStrategy(bestPh types.PendingHeader, block *types.Block) bool { +func (sl *Slice) miningStrategy(bestPh types.PendingHeader, pendingHeader types.PendingHeader) bool { if bestPh.Header() == nil { // This is the case where we try to append the block before we have not initialized the bestPh return true } - subReorg := sl.poem(sl.engine.TotalLogS(block.Header()), bestPh.Header().ParentEntropy()) + subReorg := sl.poem(sl.engine.TotalLogPhS(pendingHeader.Header()), sl.engine.TotalLogPhS(bestPh.Header())) return subReorg } @@ -359,7 +367,7 @@ func (sl *Slice) relayPh(block *types.Block, pendingHeaderWithTermini types.Pend } else { log.Warn("Pending Header for Best ph key does not exist", "best ph key", sl.bestPhKey) } - } else if !domOrigin { + } else if !domOrigin && subReorg { for _, i := range sl.randomRelayArray() { if sl.subClients[i] != nil { sl.subClients[i].SubRelayPendingHeader(context.Background(), pendingHeaderWithTermini, pendingHeaderWithTermini.Header().ParentEntropy(), location, subReorg) @@ -370,7 +378,7 @@ func (sl *Slice) relayPh(block *types.Block, pendingHeaderWithTermini types.Pend // If a zone changes its best ph key on a dom block, it sends a signal to the // dom and we can relay that information to the coords, to build on the right dom header -func (sl *Slice) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, newEntropy *big.Int, location common.Location) { +func (sl *Slice) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, pendingHeader *types.Header, location common.Location) { nodeCtx := common.NodeLocation.Context() sl.phCacheMu.Lock() defer sl.phCacheMu.Unlock() @@ -384,18 +392,12 @@ func (sl *Slice) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, new log.Info("UpdateDom:", "oldTerminus:", oldTerminus, "newTerminus:", newTerminus, "oldDomTerminus:", oldDomTermini.DomTerminus(), "newDomTerminus:", newDomTermini.DomTerminus()) if nodeCtx == common.REGION_CTX && oldDomTermini.DomTerminus() == newDomTermini.DomTerminus() { // Can update - block := sl.hc.GetBlockByHash(newTerminus) + newPh := types.NewPendingHeader(pendingHeader, *newDomTermini) sl.bestPhKey = newTerminus - if block != nil { - pendingHeaderWithTermini, err := sl.generateSlicePendingHeader(block, *newDomTermini, types.EmptyHeader(), false, true, false) - if err != nil { - return - } - log.Info("pendingHeaderWithTermini:", "parent Hash:", pendingHeaderWithTermini.Header().ParentHash(), "Number", pendingHeaderWithTermini.Header().NumberArray()) - for _, i := range sl.randomRelayArray() { - if sl.subClients[i] != nil { - sl.subClients[i].SubRelayPendingHeader(context.Background(), pendingHeaderWithTermini, newEntropy, common.Location{}, true) - } + log.Info("newPh:", "parent Hash:", newPh.Header().ParentHash(), "Number", newPh.Header().NumberArray()) + for _, i := range sl.randomRelayArray() { + if sl.subClients[i] != nil { + sl.subClients[i].SubRelayPendingHeader(context.Background(), newPh, pendingHeader.ParentEntropy(common.ZONE_CTX), common.Location{}, true) } } return @@ -403,21 +405,15 @@ func (sl *Slice) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, new // need to update dom log.Info("Append need to updateDom", "oldDomTermini:", oldDomTermini, "newDomTermini:", newDomTermini, "location:", common.NodeLocation) if sl.domClient != nil { - go sl.domClient.UpdateDom(context.Background(), oldDomTermini.DomTerminus(), newDomTermini.DomTerminus(), newEntropy, location) + go sl.domClient.UpdateDom(context.Background(), oldDomTermini.DomTerminus(), newDomTermini.DomTerminus(), pendingHeader, location) } else { // Can update - block := sl.hc.GetBlockByHash(newTerminus) + newPh := types.NewPendingHeader(pendingHeader, *newDomTermini) sl.bestPhKey = newTerminus - if block != nil { - pendingHeaderWithTermini, err := sl.generateSlicePendingHeader(block, *newDomTermini, types.EmptyHeader(), false, true, false) - if err != nil { - return - } - log.Info("pendingHeaderWithTermini:", "parent Hash:", pendingHeaderWithTermini.Header().ParentHash(), "Number", pendingHeaderWithTermini.Header().NumberArray()) - for _, i := range sl.randomRelayArray() { - if sl.subClients[i] != nil { - go sl.subClients[i].SubRelayPendingHeader(context.Background(), pendingHeaderWithTermini, newEntropy, location, true) - } + log.Info("newPh:", "parent Hash:", newPh.Header().ParentHash(), "Number", newPh.Header().NumberArray()) + for _, i := range sl.randomRelayArray() { + if sl.subClients[i] != nil { + sl.subClients[i].SubRelayPendingHeader(context.Background(), newPh, pendingHeader.ParentEntropy(common.ZONE_CTX), common.Location{}, true) } } return @@ -498,6 +494,14 @@ func (sl *Slice) generateSlicePendingHeader(block *types.Block, newTermini types localPendingHeader = types.EmptyHeader() localPendingHeader.SetParentHash(block.Hash(), nodeCtx) localPendingHeader.SetNumber(big.NewInt(int64(block.NumberU64()) + 1)) + localPendingHeader.SetParentEntropy(sl.engine.TotalLogS(block.Header())) + if nodeCtx != common.PRIME_CTX { + if domOrigin { + localPendingHeader.SetParentDeltaS(big.NewInt(0), nodeCtx) + } else { + localPendingHeader.SetParentDeltaS(sl.engine.DeltaLogS(block.Header()), nodeCtx) + } + } manifestHash := sl.miner.worker.ComputeManifestHash(block.Header()) localPendingHeader.SetManifestHash(manifestHash) @@ -705,6 +709,10 @@ func (sl *Slice) computePendingHeader(localPendingHeaderWithTermini types.Pendin var newPh *types.Header if exists { + if domOrigin { + newPh = sl.combinePendingHeader(localPendingHeaderWithTermini.Header(), domPendingHeader, nodeCtx, true) + return types.NewPendingHeader(types.CopyHeader(newPh), localPendingHeaderWithTermini.Termini()) + } newPh = sl.combinePendingHeader(localPendingHeaderWithTermini.Header(), cachedPendingHeaderWithTermini.Header(), nodeCtx, true) return types.NewPendingHeader(types.CopyHeader(newPh), localPendingHeaderWithTermini.Termini()) } else { @@ -718,6 +726,8 @@ func (sl *Slice) computePendingHeader(localPendingHeaderWithTermini types.Pendin // updatePhCacheFromDom combines the recieved pending header with the pending header stored locally at a given terminus for specified context func (sl *Slice) updatePhCacheFromDom(pendingHeader types.PendingHeader, terminiIndex int, indices []int, newEntropy *big.Int, subReorg bool) error { + sl.phCacheMu.Lock() + defer sl.phCacheMu.Unlock() hash := pendingHeader.Termini().SubTerminiAtIndex(terminiIndex) localPendingHeader, exists := sl.readPhCache(hash) @@ -730,11 +740,9 @@ func (sl *Slice) updatePhCacheFromDom(pendingHeader types.PendingHeader, termini bestPh, exists := sl.readPhCache(sl.bestPhKey) nodeCtx := common.NodeLocation.Context() if nodeCtx == common.ZONE_CTX && exists && sl.bestPhKey != localPendingHeader.Termini().DomTerminus() && !sl.poem(newEntropy, bestPh.Header().ParentEntropy()) { - log.Info("subrelay rejected", "local dom terminus", localPendingHeader.Termini().DomTerminus(), "Number", localPendingHeader.Header().NumberArray(), "best ph key", sl.bestPhKey, "number", bestPh.Header().NumberArray(), "newentropy", newEntropy) - sl.phCacheMu.Lock() + log.Info("subrelay rejected", "local dom terminus", localPendingHeader.Termini().DomTerminus(), "Number", combinedPendingHeader.NumberArray(), "best ph key", sl.bestPhKey, "number", bestPh.Header().NumberArray(), "newentropy", newEntropy) sl.updatePhCache(types.NewPendingHeader(combinedPendingHeader, localPendingHeader.Termini()), false, nil, sl.poem(newEntropy, localPendingHeader.Header().ParentEntropy())) - sl.phCacheMu.Unlock() - go sl.domClient.UpdateDom(context.Background(), localPendingHeader.Termini().DomTerminus(), sl.bestPhKey, bestPh.Header().ParentEntropy(), common.NodeLocation) + go sl.domClient.UpdateDom(context.Background(), localPendingHeader.Termini().DomTerminus(), sl.bestPhKey, bestPh.Header(), common.NodeLocation) return nil } // Pick the head @@ -747,7 +755,7 @@ func (sl *Slice) updatePhCacheFromDom(pendingHeader types.PendingHeader, termini log.Error("Error setting current header", "err", err, "Hash", block.Hash()) return err } - log.Info("Choosing phHeader pickPhHead:", "NumberArray:", localPendingHeader.Header().NumberArray(), "Number:", localPendingHeader.Header().Number(), "ParentHash:", localPendingHeader.Header().ParentHash(), "Terminus:", localPendingHeader.Termini().DomTerminus()) + log.Info("Choosing phHeader pickPhHead:", "NumberArray:", combinedPendingHeader.NumberArray(), "Number:", combinedPendingHeader.Number(), "ParentHash:", combinedPendingHeader.ParentHash(), "Terminus:", localPendingHeader.Termini().DomTerminus()) sl.bestPhKey = localPendingHeader.Termini().DomTerminus() if block.Hash() != sl.hc.CurrentHeader().Hash() { sl.hc.chainHeadFeed.Send(ChainHeadEvent{block}) @@ -780,9 +788,7 @@ func (sl *Slice) updatePhCacheFromDom(pendingHeader types.PendingHeader, termini } } - sl.phCacheMu.Lock() sl.updatePhCache(types.NewPendingHeader(combinedPendingHeader, localPendingHeader.Termini()), false, nil, subReorg) - sl.phCacheMu.Unlock() return nil } @@ -806,7 +812,7 @@ func (sl *Slice) updatePhCache(pendingHeaderWithTermini types.PendingHeader, inS if !exists { return } - if !sl.poem(pendingHeaderWithTermini.Header().ParentEntropy(), bestPh.Header().ParentEntropy()) { + if !sl.miningStrategy(bestPh, pendingHeaderWithTermini) { return } } diff --git a/core/worker.go b/core/worker.go index d58a4fe0a1..b5f18e0c2b 100644 --- a/core/worker.go +++ b/core/worker.go @@ -881,12 +881,7 @@ func (w *worker) fillTransactions(interrupt *int32, env *environment, block *typ // into the given sealing block. The transaction selection and ordering strategy can // be customized with the plugin in the future. func (w *worker) adjustGasLimit(interrupt *int32, env *environment, parent *types.Block) { - percentGasUsed := parent.GasUsed() * 100 / parent.GasLimit() - if percentGasUsed > params.PercentGasUsedThreshold { - env.header.SetGasLimit(CalcGasLimit(parent.GasLimit(), w.config.GasCeil)) - } else { - env.header.SetGasLimit(CalcGasLimit(parent.GasLimit(), w.config.GasFloor)) - } + env.header.SetGasLimit(CalcGasLimit(parent.Header(), w.config.GasCeil)) } // ComputeManifestHash given a header computes the manifest hash for the header diff --git a/eth/api_backend.go b/eth/api_backend.go index 69a91fd6d1..0b51d952a1 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -472,8 +472,8 @@ func (b *QuaiAPIBackend) SubRelayPendingHeader(pendingHeader types.PendingHeader b.eth.core.SubRelayPendingHeader(pendingHeader, newEntropy, location, subReorg) } -func (b *QuaiAPIBackend) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, newEntropy *big.Int, location common.Location) { - b.eth.core.UpdateDom(oldTerminus, newTerminus, newEntropy, location) +func (b *QuaiAPIBackend) UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, pendingHeader *types.Header, location common.Location) { + b.eth.core.UpdateDom(oldTerminus, newTerminus, pendingHeader, location) } func (b *QuaiAPIBackend) RequestDomToAppendOrFetch(hash common.Hash, order int) { diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 13afbbf112..d0e8b9133b 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -181,6 +181,7 @@ func CreateProgpowConsensusEngine(stack *node.Node, chainConfig *params.ChainCon PowMode: config.PowMode, NotifyFull: config.NotifyFull, DurationLimit: config.DurationLimit, + GasCeil: config.GasCeil, }, notify, noverify) engine.SetThreads(-1) // Disable CPU mining return engine @@ -201,6 +202,7 @@ func CreateBlake3ConsensusEngine(stack *node.Node, chainConfig *params.ChainConf PowMode: config.PowMode, NotifyFull: config.NotifyFull, DurationLimit: config.DurationLimit, + GasCeil: config.GasCeil, }, notify, noverify) engine.SetThreads(-1) // Disable CPU mining return engine diff --git a/eth/fetcher/block_fetcher.go b/eth/fetcher/block_fetcher.go index f1cd195a81..f2d4e04f64 100644 --- a/eth/fetcher/block_fetcher.go +++ b/eth/fetcher/block_fetcher.go @@ -350,7 +350,12 @@ func (f *BlockFetcher) loop() { f.forgetBlock(hash) continue } - f.importBlocks(op.origin, op.block) + + // Only import blocks using the Fetcher if its within maxUncleDist + // This is done to prevent DDos on the append queue + if op != nil && op.block.NumberU64()+maxUncleDist > f.chainHeight() { + f.importBlocks(op.origin, op.block) + } } // Wait for an outside event to occur select { diff --git a/internal/quaiapi/backend.go b/internal/quaiapi/backend.go index 58f56177bb..563c17a487 100644 --- a/internal/quaiapi/backend.go +++ b/internal/quaiapi/backend.go @@ -77,7 +77,7 @@ type Backend interface { InsertBlock(ctx context.Context, block *types.Block) (int, error) PendingBlock() *types.Block SubRelayPendingHeader(pendingHeader types.PendingHeader, newEntropy *big.Int, location common.Location, subReorg bool) - UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, newEntropy *big.Int, location common.Location) + UpdateDom(oldTerminus common.Hash, newTerminus common.Hash, pendingHeader *types.Header, location common.Location) RequestDomToAppendOrFetch(hash common.Hash, order int) NewGenesisPendingHeader(pendingHeader *types.Header) GetPendingHeader() (*types.Header, error) diff --git a/internal/quaiapi/quai_api.go b/internal/quaiapi/quai_api.go index c1466ef801..26192e34d8 100644 --- a/internal/quaiapi/quai_api.go +++ b/internal/quaiapi/quai_api.go @@ -667,7 +667,7 @@ type DomUpdate struct { OldTerminus common.Hash NewTerminus common.Hash Location common.Location - NewEntropy *big.Int + Header *types.Header } func (s *PublicBlockChainQuaiAPI) UpdateDom(ctx context.Context, raw json.RawMessage) { @@ -677,7 +677,7 @@ func (s *PublicBlockChainQuaiAPI) UpdateDom(ctx context.Context, raw json.RawMes return } - s.b.UpdateDom(domUpdate.OldTerminus, domUpdate.NewTerminus, domUpdate.NewEntropy, domUpdate.Location) + s.b.UpdateDom(domUpdate.OldTerminus, domUpdate.NewTerminus, domUpdate.Header, domUpdate.Location) } type RequestDomToAppendOrFetchArgs struct { diff --git a/params/config.go b/params/config.go index 0f09a773d3..d1e9b1a645 100644 --- a/params/config.go +++ b/params/config.go @@ -26,18 +26,18 @@ import ( // Genesis hashes to enforce below configs on. var ( // Progpow GenesisHashes - ProgpowColosseumGenesisHash = common.HexToHash("0x6053d0826a42d11d44a2172d309809aa6abb97bf7cdc24a3dd8be81ee6528468") - ProgpowGardenGenesisHash = common.HexToHash("0x3725ae59140167e31e4d4457e9948d716c687ac3a4b278350137356ee73060d1") - ProgpowOrchardGenesisHash = common.HexToHash("0xeb625504882304b641551f8f33706cc4a7009b14325fa52af92274032504c46e") - ProgpowLocalGenesisHash = common.HexToHash("0x7f594e88d6c93a00680840a855b7c9349218751cc344562dacb43a63eec02d93") - ProgpowLighthouseGenesisHash = common.HexToHash("0x2cf2f1ab8901e7bad77fbe9a671c12218229bcc1a725ec1c7cb3342a076d4596") + ProgpowColosseumGenesisHash = common.HexToHash("0x4e21d4b21862f89a4f041a7c181b28c51258b5a5b948d8e84686f4bc6603ddd8") + ProgpowGardenGenesisHash = common.HexToHash("0x7823e58617576af80cc557595380b55c2d565b294e3b6438fc11c4410e48da5e") + ProgpowOrchardGenesisHash = common.HexToHash("0x4042b03aa7c4d6a58d4e6238b2da5c03dda97a0c7e7a7b1d237917a23ca4b0d6") + ProgpowLocalGenesisHash = common.HexToHash("0x53a10194f6b385aa037fe1911b52a56d4d0ac8f95f3e98ac4f546269429c288d") + ProgpowLighthouseGenesisHash = common.HexToHash("0x888542dc6e379e29db4c86934b05cfd4a376e1c19261db3f44d6e4e9f6ce0495") // Blake3GenesisHashes - Blake3PowColosseumGenesisHash = common.HexToHash("0xe6e0ff26dafbb1ff849b965fc300ebc9eee2708686943030d958dc4cc4b6c0ea") - Blake3PowGardenGenesisHash = common.HexToHash("0x3fb55aff423ca143fd714e256530be8a34e21bd85f8dc62587f9fb559b739f36") - Blake3PowOrchardGenesisHash = common.HexToHash("0x418ea8cd5f17277e4bb94cba7170a494fc53df23b915ed42a8fe9f6052a4327b") - Blake3PowLocalGenesisHash = common.HexToHash("0x6181f4781316452abf66aaafa44568a4e9f56bb10c276c9d7b3964efea4fbc56") - Blake3PowLighthouseGenesisHash = common.HexToHash("0x8431222ba8848050619fc1bca9447a351b7079684ea57c1cb0ab5d09d4bb4c51") + Blake3PowColosseumGenesisHash = common.HexToHash("0x40057f44be0809f939c7d70893d101abc74af1f1c535e406ec9909cfa2c20cbe") + Blake3PowGardenGenesisHash = common.HexToHash("0x0a942bb7fa04b80d658a64d0ca49c62199503a796abc169f05a1863421a22098") + Blake3PowOrchardGenesisHash = common.HexToHash("0x1f3743c323ec7a9a6a8150a33de81723abb70fa10ad49c35e365e48488430b56") + Blake3PowLocalGenesisHash = common.HexToHash("0x31ac78ff6abcd99ad1fd8cd1b8ef54cfb28bdc72f7a38311e67a9e34fc2adb45") + Blake3PowLighthouseGenesisHash = common.HexToHash("0xaadedd7ed5a68a8885b54079e8193ae5be8f9b9bf4799ea9f1612bca835f33da") ) var ( diff --git a/params/protocol_params.go b/params/protocol_params.go index 186d47c737..32a3c043d7 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -23,10 +23,13 @@ import ( ) const ( - GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. - PercentGasUsedThreshold uint64 = 95 // Percent Gas used threshold at which the gas limit adjusts - MinGasLimit uint64 = 5000000 // Minimum the gas limit may ever be. - GenesisGasLimit uint64 = 5000000 // Gas limit of the Genesis block. + GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. + PercentGasUsedThreshold uint64 = 50 // Percent Gas used threshold at which the gas limit adjusts + GasLimitStepOneBlockThreshold uint64 = 150000 + GasLimitStepTwoBlockThreshold uint64 = 300000 + GasLimitStepThreeBlockThreshold uint64 = 450000 + MinGasLimit uint64 = 5000000 // Minimum the gas limit may ever be. + GenesisGasLimit uint64 = 5000000 // Gas limit of the Genesis block. MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis. ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction. @@ -111,10 +114,10 @@ const ( // not exist. This logic is similar to call. CreateBySelfdestructGas uint64 = 25000 - BaseFeeChangeDenominator = 8 // Bounds the amount the base fee can change between blocks. - ElasticityMultiplier = 2 // Bounds the maximum gas limit a block may have. - InitialBaseFee = 1 // Initial base fee for blocks. - MaxBaseFee = 1 * GWei // Maximum base fee for blocks. + BaseFeeChangeDenominator = 8 // Bounds the amount the base fee can change between blocks. + ElasticityMultiplier = 2 // Bounds the maximum gas limit a block may have. + InitialBaseFee = 1 * GWei // Initial base fee for blocks. + MaxBaseFee = 100 * GWei // Maximum base fee for blocks. MaxCodeSize = 24576 // Maximum bytecode to permit for a contract @@ -138,21 +141,24 @@ const ( ) var ( - ColosseumGasCeil uint64 = 160000000 - GardenGasCeil uint64 = 160000000 - OrchardGasCeil uint64 = 50000000 - LighthouseGasCeil uint64 = 160000000 - LocalGasCeil uint64 = 20000000 - DifficultyBoundDivisor = big.NewInt(2048) // The bound divisor of the difficulty, used in the update calculations. - ZoneMinDifficulty = big.NewInt(1000) // The minimum difficulty in a zone. Prime & regions should be multiples of this value - MinimumDifficulty = ZoneMinDifficulty // The minimum that the difficulty may ever be. - GenesisDifficulty = ZoneMinDifficulty // Difficulty of the Genesis block. - DurationLimit = big.NewInt(12) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. - GardenDurationLimit = big.NewInt(7) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. - OrchardDurationLimit = big.NewInt(12) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. - LighthouseDurationLimit = big.NewInt(7) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. - LocalDurationLimit = big.NewInt(2) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. - TimeFactor = big.NewInt(7) - PrimeEntropyTarget = big.NewInt(441) // This is TimeFactor*TimeFactor*common.NumZonesInRegion*common.NumRegionsInPrime - RegionEntropyTarget = big.NewInt(21) // This is TimeFactor*common.NumZonesInRegion + GasCeil uint64 = 20000000 + ColosseumGasCeil uint64 = 110000000 + GardenGasCeil uint64 = 160000000 + OrchardGasCeil uint64 = 50000000 + LighthouseGasCeil uint64 = 160000000 + LocalGasCeil uint64 = 20000000 + DifficultyBoundDivisor = big.NewInt(2048) // The bound divisor of the difficulty, used in the update calculations. + ZoneMinDifficulty = big.NewInt(1000) // The minimum difficulty in a zone. Prime & regions should be multiples of this value + MinimumDifficulty = ZoneMinDifficulty // The minimum that the difficulty may ever be. + GenesisDifficulty = ZoneMinDifficulty // Difficulty of the Genesis block. + DurationLimit = big.NewInt(12) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. + GardenDurationLimit = big.NewInt(7) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. + OrchardDurationLimit = big.NewInt(12) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. + LighthouseDurationLimit = big.NewInt(7) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. + LocalDurationLimit = big.NewInt(2) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. + TimeFactor = big.NewInt(7) + PrimeEntropyTarget = big.NewInt(441) // This is TimeFactor*TimeFactor*common.NumZonesInRegion*common.NumRegionsInPrime + RegionEntropyTarget = big.NewInt(21) // This is TimeFactor*common.NumZonesInRegion + DifficultyAdjustmentPeriod = big.NewInt(360) // This is the number of blocks over which the average has to be taken + DifficultyAdjustmentFactor int64 = 40 // This is the factor that divides the log of the change in the difficulty ) diff --git a/quaiclient/quaiclient.go b/quaiclient/quaiclient.go index 40d9850c29..8f66a65891 100644 --- a/quaiclient/quaiclient.go +++ b/quaiclient/quaiclient.go @@ -122,11 +122,11 @@ func (ec *Client) SubRelayPendingHeader(ctx context.Context, pendingHeader types ec.c.CallContext(ctx, nil, "quai_subRelayPendingHeader", data) } -func (ec *Client) UpdateDom(ctx context.Context, oldTerminus common.Hash, newTerminus common.Hash, newEntropy *big.Int, location common.Location) { +func (ec *Client) UpdateDom(ctx context.Context, oldTerminus common.Hash, newTerminus common.Hash, pendingHeader *types.Header, location common.Location) { data := map[string]interface{}{"OldTerminus": oldTerminus} data["NewTerminus"] = newTerminus data["Location"] = location - data["NewEntropy"] = newEntropy + data["Header"] = pendingHeader.RPCMarshalHeader() ec.c.CallContext(ctx, nil, "quai_updateDom", data) }