diff --git a/consensus/eccpow/LDPCDifficulty.go b/consensus/eccpow/LDPCDifficulty.go index 36c6f4f6f4..8367a05d5e 100644 --- a/consensus/eccpow/LDPCDifficulty.go +++ b/consensus/eccpow/LDPCDifficulty.go @@ -35,6 +35,8 @@ var ( MinimumDifficulty = ProbToDifficulty(Table[0].miningProb) BlockGenerationTime = big.NewInt(36) // 36) // 10 ) // 36) Sensitivity = big.NewInt(8) + SensitivityAnnapurna = big.NewInt(1024) + threshold = big.NewInt(7) // BlockGenerationTime for Seoul BlockGenerationTimeSeoul = big.NewInt(10) // 36) // 10 ) // 36) @@ -165,6 +167,57 @@ func MakeLDPCDifficultyCalculator_Seoul() func(time uint64, parent *types.Header } } +func MakeLDPCDifficultyCalculatorAnnapurna() func(time uint64, parent *types.Header) *big.Int { + return func(time uint64, parent *types.Header) *big.Int { + bigTime := new(big.Int).SetUint64(time) + bigParentTime := new(big.Int).SetUint64(parent.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) // BlockGenerationTime + x.Sub(bigTime, bigParentTime) + //fmt.Printf("block_timestamp - parent_timestamp : %v\n", x) + + x.Div(x, threshold) + //fmt.Printf("(block_timestamp - parent_timestamp) / 7 : %v\n", x) + + if parent.UncleHash == types.EmptyUncleHash { + //fmt.Printf("No uncle\n") + x.Sub(big1, x) + } else { + //fmt.Printf("Uncle block exists") + x.Sub(big2, x) + } + //fmt.Printf("(2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) / 7 : %v\n", x) + + // max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99) + if x.Cmp(bigMinus99) < 0 { + x.Set(bigMinus99) + } + //fmt.Printf("max(1 - (block_timestamp - parent_timestamp) / 7, -99) : %v\n", x) + + // parent_diff + (parent_diff / Sensitivity * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 7), -99)) + y.Div(parent.Difficulty, SensitivityAnnapurna) + //fmt.Printf("parent.Difficulty / 1024 : %v\n", y) + + x.Mul(y, x) + //fmt.Printf("parent.Difficulty / 1024 * max(1 - (block_timestamp - parent_timestamp) / BlockGenerationTime, -99) : %v\n", x) + + x.Add(parent.Difficulty, x) + //fmt.Printf("parent.Difficulty - parent.Difficulty / 8 * max(1 - (block_timestamp - parent_timestamp) / BlockGenerationTime, -99) : %v\n", x) + + // minimum difficulty can ever be (before exponential factor) + if x.Cmp(SeoulDifficulty) < 0 { + x.Set(SeoulDifficulty) + } + + //fmt.Printf("x : %v, Minimum difficulty : %v\n", x, MinimumDifficulty) + return x + } +} + // SearchLevel return next level by using currentDifficulty of header // Type of Ethereum difficulty is *bit.Int so arg is *big.int func SearchLevel(difficulty *big.Int) int { @@ -206,4 +259,4 @@ func SearchLevel_Seoul(difficulty *big.Int) int { } return level -} +} \ No newline at end of file diff --git a/consensus/eccpow/consensus.go b/consensus/eccpow/consensus.go index 65cff8079e..d736717547 100644 --- a/consensus/eccpow/consensus.go +++ b/consensus/eccpow/consensus.go @@ -317,6 +317,8 @@ func (ecc *ECC) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, p switch { case chain.Config().IsSeoul(next): return calcDifficultySeoul(chain, time, parent) + case chain.Config().IsAnnapurna(next): + return calcDifficultyAnnapurna(chain, time, parent) //return calcDifficultyFrontier(time, parent) default: //fmt.Println("frontier") @@ -371,6 +373,12 @@ func calcDifficultySeoul(chain consensus.ChainHeaderReader, time uint64, parent return difficultyCalculator(time, parent) } +func calcDifficultyAnnapurna(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { + difficultyCalculator := MakeLDPCDifficultyCalculatorAnnapurna() + //return difficultyCalculator(chain, time, parent) + return difficultyCalculator(time, parent) +} + // Exported for fuzzing var FrontierDifficultyCalculator = calcDifficultyFrontier var DynamicDifficultyCalculator = makeDifficultyCalculator @@ -537,4 +545,4 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header reward.Add(reward, r) } state.AddBalance(header.Coinbase, reward) -} +} \ No newline at end of file diff --git a/params/config.go b/params/config.go index 615ee629a2..a0662363a3 100644 --- a/params/config.go +++ b/params/config.go @@ -338,6 +338,7 @@ var ( LondonBlock: big.NewInt(0), WorldlandBlock: big.NewInt(0), SeoulBlock: big.NewInt(0), + AnnapurnaBlock: big.NewInt(2_456_000), HalvingEndTime: big.NewInt(25228800), Eccpow: new(EccpowConfig), } @@ -379,6 +380,7 @@ var ( LondonBlock: big.NewInt(0), WorldlandBlock: big.NewInt(0), SeoulBlock: big.NewInt(0), + AnnapurnaBlock: big.NewInt(2_345_000), HalvingEndTime: big.NewInt(25228800), Eccpow: new(EccpowConfig), } @@ -455,16 +457,16 @@ var ( // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil, false, new(EthashConfig), nil, nil} + AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil, nil, false, new(EthashConfig), nil, nil} // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Clique consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} - TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil, false, new(EthashConfig), nil, nil} + TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil, nil, false, new(EthashConfig), nil, nil} //NonActivatedConfig = &ChainConfig{big.NewInt(1), nil, nil, false, nil, common.Hash{}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, new(EthashConfig), nil, nil} TestRules = TestChainConfig.Rules(new(big.Int), false) ) @@ -565,6 +567,7 @@ type ChainConfig struct { WorldlandBlock *big.Int `json:"worldlandBlock,omitempty"` // worldrand switch block (nil = no fork, 0 = already on worldland) HalvingEndTime *big.Int `json:"HalvingEndTime,omitempty"` SeoulBlock *big.Int `json:"seoulBlock,omitempty"` + AnnapurnaBlock *big.Int `json:"AnnapurnaBlock,omitempty"` // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. @@ -647,7 +650,6 @@ func (c *ChainConfig) String() string { banner += "Consensus: unknown\n" } //banner += "\n" - // Create a list of forks with a short description of them. Forks that only // makes sense for mainnet should be optional at printing to avoid bloating // the output for testnets and private networks. @@ -688,6 +690,9 @@ func (c *ChainConfig) String() string { if c.SeoulBlock != nil { banner += fmt.Sprintf(" - Seoul: %-8v\n", c.SeoulBlock) } + if c.AnnapurnaBlock != nil { + banner += fmt.Sprintf(" - Annapurna: %-8v\n", c.AnnapurnaBlock) + } banner += "\n" */ // Add a special section for the merge as it's non-obvious @@ -817,6 +822,12 @@ func (c *ChainConfig) IsSeoul(num *big.Int) bool { return isForked(c.SeoulBlock, num) } +// IsAnnapurna returns whether num is either equ`al to the Annapurna fork block or greater. +func (c *ChainConfig) IsAnnapurna(num *big.Int) bool { + return isForked(c.AnnapurnaBlock, num) +} + + // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { @@ -864,6 +875,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "cancunBlock", block: c.CancunBlock, optional: true}, {name: "worldlandBlock", block: c.WorldlandBlock, optional: true}, {name: "seoulBlock", block: c.SeoulBlock, optional: true}, + {name: "AnnapurnaBlock", block: c.AnnapurnaBlock, optional: true}, } { if lastFork.name != "" { // Next one must be higher number @@ -954,6 +966,10 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi if isForkIncompatible(c.SeoulBlock, newcfg.SeoulBlock, head) { return newCompatError("Seoul fork block", c.SeoulBlock, newcfg.SeoulBlock) } + if isForkIncompatible(c.AnnapurnaBlock, newcfg.AnnapurnaBlock, head) { + return newCompatError("Annapurna fork block", c.AnnapurnaBlock, newcfg.AnnapurnaBlock) + } + return nil } @@ -1047,6 +1063,7 @@ type Rules struct { IsMerge, IsShanghai, isCancun bool IsWorldland bool IsSeoul bool + IsAnnapurna bool } // Rules ensures c's ChainID is not nil. @@ -1072,5 +1089,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool) Rules { isCancun: c.IsCancun(num), IsWorldland: c.IsWorldland(num), IsSeoul: c.IsSeoul(num), + IsAnnapurna: c.IsAnnapurna(num), } -} +} \ No newline at end of file