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  }