mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
set block difficulty belong to creator turn
This commit is contained in:
parent
8bcb58b070
commit
6af064ec32
4 changed files with 62 additions and 60 deletions
|
|
@ -352,12 +352,12 @@ func (c *Posv) verifyHeader(chain consensus.ChainReader, header *types.Header, p
|
|||
if header.UncleHash != uncleHash {
|
||||
return errInvalidUncleHash
|
||||
}
|
||||
// Ensure that the block's difficulty is meaningful (may not be correct at this point)
|
||||
if number > 0 {
|
||||
if header.Difficulty == nil || (header.Difficulty.Cmp(diffInTurn) != 0 && header.Difficulty.Cmp(diffNoTurn) != 0) {
|
||||
return errInvalidDifficulty
|
||||
}
|
||||
}
|
||||
//// Ensure that the block's difficulty is meaningful (may not be correct at this point)
|
||||
//if number > 0 {
|
||||
// if header.Difficulty.Int64() != 1 {
|
||||
// return errInvalidDifficulty
|
||||
// }
|
||||
//}
|
||||
// If all checks passed, validate any special fields for hard forks
|
||||
if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil {
|
||||
return err
|
||||
|
|
@ -483,30 +483,35 @@ func WhoIsCreator(snap *Snapshot, header *types.Header) (common.Address, error)
|
|||
return m, nil
|
||||
}
|
||||
|
||||
func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header, cur common.Address) (int, int, bool, error) {
|
||||
func (c *Posv) YourTurn(chain consensus.ChainReader, parent *types.Header) (int, int, int, bool, error) {
|
||||
masternodes := c.GetMasternodes(chain, parent)
|
||||
snap, err := c.GetSnapshot(chain, parent)
|
||||
if err != nil {
|
||||
log.Error("Failed when trying to commit new work", "err", err)
|
||||
return 0, -1, -1, false, err
|
||||
}
|
||||
if len(masternodes) == 0 {
|
||||
return -1, -1, true, nil
|
||||
return 0, -1, -1, false, errors.New("Not found master nodes")
|
||||
}
|
||||
pre := common.Address{}
|
||||
// masternode[0] has chance to create block 1
|
||||
var err error
|
||||
preIndex := -1
|
||||
if header.Number.Uint64() != 0 {
|
||||
pre, err = WhoIsCreator(snap, header)
|
||||
if parent.Number.Uint64() != 0 {
|
||||
pre, err = WhoIsCreator(snap, parent)
|
||||
if err != nil {
|
||||
return 0, 0, false, err
|
||||
return 0, 0, 0, false, err
|
||||
}
|
||||
preIndex = position(masternodes, pre)
|
||||
}
|
||||
curIndex := position(masternodes, cur)
|
||||
log.Info("Masternodes cycle info", "number of masternodes", len(masternodes), "previous", pre, "position", preIndex, "current", cur, "position", curIndex)
|
||||
curIndex := position(masternodes, c.signer)
|
||||
log.Info("Masternodes cycle info", "number of masternodes", len(masternodes), "previous", pre, "position", preIndex, "current", c.signer, "position", curIndex)
|
||||
for i, s := range masternodes {
|
||||
fmt.Printf("%d - %s\n", i, s.String())
|
||||
}
|
||||
if (preIndex+1)%len(masternodes) == curIndex {
|
||||
return preIndex, curIndex, true, nil
|
||||
return len(masternodes), preIndex, curIndex, true, nil
|
||||
}
|
||||
return preIndex, curIndex, false, nil
|
||||
return len(masternodes), preIndex, curIndex, false, nil
|
||||
}
|
||||
|
||||
// snapshot retrieves the authorization snapshot at a given point in time.
|
||||
|
|
@ -625,6 +630,7 @@ func (c *Posv) verifySeal(chain consensus.ChainReader, header *types.Header, par
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debug("verify seal block", "number", header.Number, "hash", header.Hash(), "difficulty", header.Difficulty)
|
||||
masternodes := c.GetMasternodes(chain, header)
|
||||
mstring := []string{}
|
||||
for _, m := range masternodes {
|
||||
|
|
@ -742,9 +748,13 @@ func (c *Posv) Prepare(chain consensus.ChainReader, header *types.Header) error
|
|||
}
|
||||
c.lock.RUnlock()
|
||||
}
|
||||
parent := chain.GetHeader(header.ParentHash, number-1)
|
||||
if parent == nil {
|
||||
return consensus.ErrUnknownAncestor
|
||||
}
|
||||
// Set the correct difficulty
|
||||
header.Difficulty = big.NewInt(1)
|
||||
|
||||
header.Difficulty = c.CalcDifficulty(chain, 0, parent)
|
||||
log.Debug("CalcDifficulty ", "number", header.Number, "difficulty", header.Difficulty)
|
||||
// Ensure the extra data has all it's components
|
||||
if len(header.Extra) < extraVanity {
|
||||
header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...)
|
||||
|
|
@ -782,10 +792,7 @@ func (c *Posv) Prepare(chain consensus.ChainReader, header *types.Header) error
|
|||
header.MixDigest = common.Hash{}
|
||||
|
||||
// Ensure the timestamp has the correct delay
|
||||
parent := chain.GetHeader(header.ParentHash, number-1)
|
||||
if parent == nil {
|
||||
return consensus.ErrUnknownAncestor
|
||||
}
|
||||
|
||||
header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(c.config.Period))
|
||||
if header.Time.Int64() < time.Now().Unix() {
|
||||
header.Time = big.NewInt(time.Now().Unix())
|
||||
|
|
@ -928,22 +935,23 @@ func (c *Posv) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan
|
|||
// that a new block should have based on the previous blocks in the chain and the
|
||||
// current signer.
|
||||
func (c *Posv) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
|
||||
snap, err := c.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil)
|
||||
len, preIndex, curIndex, _, err := c.YourTurn(chain, parent)
|
||||
if err != nil {
|
||||
return nil
|
||||
return big.NewInt(int64(len + curIndex - preIndex))
|
||||
}
|
||||
return CalcDifficulty(snap, c.signer)
|
||||
return big.NewInt(int64(len - Hop(len, preIndex, curIndex)))
|
||||
}
|
||||
|
||||
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
|
||||
// that a new block should have based on the previous blocks in the chain and the
|
||||
// current signer.
|
||||
func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
|
||||
if snap.inturn(snap.Number+1, signer) {
|
||||
return new(big.Int).Set(diffInTurn)
|
||||
}
|
||||
return new(big.Int).Set(diffNoTurn)
|
||||
}
|
||||
//func CalcDifficulty(snap *Snapshot, parent *types.Header, signer common.Address) *big.Int {
|
||||
//
|
||||
// if snap.inturn(snap.Number+1, signer) {
|
||||
// return new(big.Int).Set(diffInTurn)
|
||||
// }
|
||||
// return new(big.Int).Set(diffNoTurn)
|
||||
//}
|
||||
|
||||
// APIs implements consensus.Engine, returning the user facing RPC API to allow
|
||||
// controlling the signer voting.
|
||||
|
|
@ -1057,3 +1065,14 @@ func ExtractValidatorsFromBytes(byteValidators []byte) []int64 {
|
|||
|
||||
return validators
|
||||
}
|
||||
|
||||
func Hop(len, pre, cur int) int {
|
||||
switch {
|
||||
case pre < cur:
|
||||
return cur - (pre + 1)
|
||||
case pre > cur:
|
||||
return (len - pre) + (cur - 1)
|
||||
default:
|
||||
return len - 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -906,7 +906,7 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
|
|||
defer bc.mu.Unlock()
|
||||
|
||||
currentBlock := bc.CurrentBlock()
|
||||
//localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
|
||||
localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
|
||||
externTd := new(big.Int).Add(block.Difficulty(), ptd)
|
||||
|
||||
// Irrelevant of the canonical status, write the block itself to the database
|
||||
|
|
@ -980,8 +980,12 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
|
|||
// If the total difficulty is higher than our known, add it to the canonical chain
|
||||
// Second clause in the if statement reduces the vulnerability to selfish mining.
|
||||
// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
|
||||
|
||||
reorg := block.NumberU64() > currentBlock.NumberU64()
|
||||
reorg := externTd.Cmp(localTd) > 0
|
||||
currentBlock = bc.CurrentBlock()
|
||||
if !reorg && externTd.Cmp(localTd) == 0 {
|
||||
// Split same-difficulty blocks by number
|
||||
reorg = block.NumberU64() > currentBlock.NumberU64()
|
||||
}
|
||||
if reorg {
|
||||
// Reorganise the chain if the parent is not the head block
|
||||
if block.ParentHash() != currentBlock.Hash() {
|
||||
|
|
|
|||
|
|
@ -657,17 +657,14 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
|||
trueTD = new(big.Int).Sub(request.TD, request.Block.Difficulty())
|
||||
)
|
||||
// Update the peers total difficulty if better than the previous
|
||||
_, td := p.Head()
|
||||
currentBlock := pm.blockchain.CurrentBlock()
|
||||
currentTd := pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
|
||||
log.Debug("NewBlockMsg", "p", p, "number", request.Block.NumberU64(), "trueTD", trueTD, "td", td, "currentTd", currentTd)
|
||||
if trueTD.Cmp(td) > 0 {
|
||||
if _, td := p.Head(); trueTD.Cmp(td) > 0 {
|
||||
p.SetHead(trueHead, trueTD)
|
||||
|
||||
// Schedule a sync if above ours. Note, this will not fire a sync for a gap of
|
||||
// a singe block (as the true TD is below the propagated block), however this
|
||||
// scenario should easily be covered by the fetcher.
|
||||
if trueTD.Cmp(currentTd) > 0 {
|
||||
currentBlock := pm.blockchain.CurrentBlock()
|
||||
if trueTD.Cmp(pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64())) > 0 {
|
||||
go pm.synchronise(p)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -472,17 +472,6 @@ func abs(x int64) int64 {
|
|||
return x
|
||||
}
|
||||
|
||||
func hop(len, pre, cur int) int {
|
||||
switch {
|
||||
case pre < cur:
|
||||
return cur - (pre + 1)
|
||||
case pre > cur:
|
||||
return (len - pre) + (cur - 1)
|
||||
default:
|
||||
return len - 1
|
||||
}
|
||||
}
|
||||
|
||||
func (self *worker) commitNewWork() {
|
||||
self.mu.Lock()
|
||||
defer self.mu.Unlock()
|
||||
|
|
@ -508,14 +497,7 @@ func (self *worker) commitNewWork() {
|
|||
if self.config.Posv != nil {
|
||||
// get masternodes set from latest checkpoint
|
||||
c := self.engine.(*posv.Posv)
|
||||
masternodes := c.GetMasternodes(self.chain, parent.Header())
|
||||
snap, err := c.GetSnapshot(self.chain, parent.Header())
|
||||
if err != nil {
|
||||
log.Error("Failed when trying to commit new work", "err", err)
|
||||
return
|
||||
}
|
||||
signers = snap.Signers
|
||||
preIndex, curIndex, ok, err := posv.YourTurn(masternodes, snap, parent.Header(), self.coinbase)
|
||||
len, preIndex, curIndex, ok, err := c.YourTurn(self.chain, parent.Header())
|
||||
if err != nil {
|
||||
log.Error("Failed when trying to commit new work", "err", err)
|
||||
return
|
||||
|
|
@ -531,7 +513,7 @@ func (self *worker) commitNewWork() {
|
|||
// you're not allowed to create this block
|
||||
return
|
||||
}
|
||||
h := hop(len(masternodes), preIndex, curIndex)
|
||||
h := posv.Hop(len, preIndex, curIndex)
|
||||
gap := waitPeriod * int64(h)
|
||||
// Check nearest checkpoint block in hop range.
|
||||
nearest := self.config.Posv.Epoch - (parent.Header().Number.Uint64() % self.config.Posv.Epoch)
|
||||
|
|
|
|||
Loading…
Reference in a new issue