github.com/cryptoecc/eth-ecc@v0.0.3/consensus/eccpow/LDPCDifficulty.go (about) 1 package eccpow 2 3 import ( 4 "math" 5 "math/big" 6 7 "github.com/cryptoecc/ETH-ECC/core/types" 8 ) 9 10 /* 11 https://ethereum.stackexchange.com/questions/5913/how-does-the-ethereum-homestead-difficulty-adjustment-algorithm-work?noredirect=1&lq=1 12 https://github.com/ethereum/EIPs/issues/100 13 14 Ethereum difficulty adjustment 15 algorithm: 16 diff = (parent_diff + 17 (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) 18 ) + 2^(periodCount - 2) 19 20 LDPC difficulty adjustment 21 algorithm: 22 diff = (parent_diff + 23 (parent_diff / 256 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // BlockGenerationTime), -99))) 24 25 Why 8? 26 This number is sensitivity of blockgeneration time 27 If this number is high, difficulty is not changed much when block generation time is different from goal of block generation time 28 But if this number is low, difficulty is changed much when block generatin time is different from goal of block generation time 29 30 */ 31 32 // "github.com/ethereum/go-ethereum/consensus/ethash/consensus.go" 33 // Some weird constants to avoid constant memory allocs for them. 34 var ( 35 MinimumDifficulty = ProbToDifficulty(Table[0].miningProb) 36 BlockGenerationTime = big.NewInt(36) 37 Sensitivity = big.NewInt(8) 38 ) 39 40 // MakeLDPCDifficultyCalculator calculate difficulty using difficulty table 41 func MakeLDPCDifficultyCalculator() func(time uint64, parent *types.Header) *big.Int { 42 return func(time uint64, parent *types.Header) *big.Int { 43 bigTime := new(big.Int).SetUint64(time) 44 bigParentTime := new(big.Int).SetUint64(parent.Time) 45 46 // holds intermediate values to make the algo easier to read & audit 47 x := new(big.Int) 48 y := new(big.Int) 49 50 // (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // BlockGenerationTime 51 x.Sub(bigTime, bigParentTime) 52 //fmt.Printf("block_timestamp - parent_timestamp : %v\n", x) 53 54 x.Div(x, BlockGenerationTime) 55 //fmt.Printf("(block_timestamp - parent_timestamp) / BlockGenerationTime : %v\n", x) 56 57 if parent.UncleHash == types.EmptyUncleHash { 58 //fmt.Printf("No uncle\n") 59 x.Sub(big1, x) 60 } else { 61 //fmt.Printf("Uncle block exists") 62 x.Sub(big2, x) 63 } 64 //fmt.Printf("(2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) / BlockGenerationTime : %v\n", x) 65 66 // max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99) 67 if x.Cmp(bigMinus99) < 0 { 68 x.Set(bigMinus99) 69 } 70 //fmt.Printf("max(1 - (block_timestamp - parent_timestamp) / BlockGenerationTime, -99) : %v\n", x) 71 72 // parent_diff + (parent_diff / Sensitivity * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // BlockGenerationTime), -99)) 73 y.Div(parent.Difficulty, Sensitivity) 74 //fmt.Printf("parent.Difficulty / 8 : %v\n", y) 75 76 x.Mul(y, x) 77 //fmt.Printf("parent.Difficulty / 8 * max(1 - (block_timestamp - parent_timestamp) / BlockGenerationTime, -99) : %v\n", x) 78 79 x.Add(parent.Difficulty, x) 80 //fmt.Printf("parent.Difficulty - parent.Difficulty / 8 * max(1 - (block_timestamp - parent_timestamp) / BlockGenerationTime, -99) : %v\n", x) 81 82 // minimum difficulty can ever be (before exponential factor) 83 if x.Cmp(MinimumDifficulty) < 0 { 84 x.Set(MinimumDifficulty) 85 } 86 //fmt.Printf("x : %v, Minimum difficulty : %v\n", x, MinimumDifficulty) 87 88 return x 89 } 90 } 91 92 // SearchLevel return next level by using currentDifficulty of header 93 // Type of Ethereum difficulty is *bit.Int so arg is *big.int 94 func SearchLevel(difficulty *big.Int) int { 95 // foo := MakeLDPCDifficultyCalculator() 96 // Next level := SearchNextLevel(foo(currentBlock's time stamp, parentBlock)) 97 98 var currentProb = DifficultyToProb(difficulty) 99 var level int 100 101 distance := 1.0 102 for i := range Table { 103 if math.Abs(currentProb-Table[i].miningProb) <= distance { 104 level = Table[i].level 105 distance = math.Abs(currentProb - Table[i].miningProb) 106 } else { 107 break 108 } 109 } 110 111 return level 112 }