[DEV-164] add bluest parent (#74)

* [DEV-164] use bluestParent from time calculations

* [DEV-164] use bluestParent next difficulty calculations

* [DEV-164] get rid of blockset.first()
This commit is contained in:
Ori Newman 2018-10-04 10:35:22 +03:00 committed by Svarog
parent 29b9f6a9b2
commit df23d87503
3 changed files with 23 additions and 17 deletions

View File

@ -28,13 +28,13 @@ func (dag *BlockDAG) maybeAcceptBlock(block *util.Block, flags BehaviorFlags) er
return err
}
selectedParent := parents.first() //TODO (Ori): This is wrong, done only for compilation
bluestParent := parents.bluest()
blockHeight := parents.maxHeight() + 1
block.SetHeight(blockHeight)
// The block must pass all of the validation rules which depend on the
// position of the block within the block DAG.
err = dag.checkBlockContext(block, parents, selectedParent, flags)
err = dag.checkBlockContext(block, parents, bluestParent, flags)
if err != nil {
return err
}

View File

@ -125,15 +125,6 @@ func (bs blockSet) hashes() []daghash.Hash {
return hashes
}
// first returns the first block in this set or nil if this set is empty.
func (bs blockSet) first() *blockNode { //TODO: (Ori) This is wrong. Done only for compilation. We should probably get rid of this method
for _, block := range bs {
return block
}
return nil
}
func (bs blockSet) String() string {
nodeStrs := make([]string, 0, len(bs))
for _, node := range bs {
@ -152,3 +143,17 @@ func (bs blockSet) anyChildInSet(block *blockNode) bool {
return false
}
func (bs blockSet) bluest() *blockNode {
var bluestNode *blockNode
var maxScore uint64
for _, node := range bs {
if bluestNode == nil ||
node.blueScore > maxScore ||
(node.blueScore == maxScore && daghash.Less(&bluestNode.hash, &node.hash)) {
bluestNode = node
maxScore = node.blueScore
}
}
return bluestNode
}

View File

@ -624,13 +624,13 @@ func checkSerializedHeight(coinbaseTx *util.Tx, wantHeight int32) error {
// the checkpoints are not performed.
//
// This function MUST be called with the chain state lock held (for writes).
func (dag *BlockDAG) checkBlockHeaderContext(header *wire.BlockHeader, selectedParent *blockNode, blockHeight int32, flags BehaviorFlags) error {
func (dag *BlockDAG) checkBlockHeaderContext(header *wire.BlockHeader, bluestParent *blockNode, blockHeight int32, flags BehaviorFlags) error {
fastAdd := flags&BFFastAdd == BFFastAdd
if !fastAdd {
// Ensure the difficulty specified in the block header matches
// the calculated difficulty based on the previous block and
// difficulty retarget rules.
expectedDifficulty, err := dag.calcNextRequiredDifficulty(selectedParent,
expectedDifficulty, err := dag.calcNextRequiredDifficulty(bluestParent,
header.Timestamp)
if err != nil {
return err
@ -644,7 +644,7 @@ func (dag *BlockDAG) checkBlockHeaderContext(header *wire.BlockHeader, selectedP
// Ensure the timestamp for the block header is after the
// median time of the last several blocks (medianTimeBlocks).
medianTime := selectedParent.CalcPastMedianTime()
medianTime := bluestParent.CalcPastMedianTime()
if !header.Timestamp.After(medianTime) {
str := "block timestamp of %v is not after expected %v"
str = fmt.Sprintf(str, header.Timestamp, medianTime)
@ -725,21 +725,22 @@ func validateParents(blockHeader *wire.BlockHeader, parents blockSet) error {
// for how the flags modify its behavior.
//
// This function MUST be called with the chain state lock held (for writes).
func (dag *BlockDAG) checkBlockContext(block *util.Block, parents blockSet, selectedParent *blockNode, flags BehaviorFlags) error {
func (dag *BlockDAG) checkBlockContext(block *util.Block, parents blockSet, bluestParent *blockNode, flags BehaviorFlags) error {
err := validateParents(&block.MsgBlock().Header, parents)
if err != nil {
return err
}
// Perform all block header related validation checks.
header := &block.MsgBlock().Header
err = dag.checkBlockHeaderContext(header, selectedParent, block.Height(), flags)
err = dag.checkBlockHeaderContext(header, bluestParent, block.Height(), flags)
if err != nil {
return err
}
fastAdd := flags&BFFastAdd == BFFastAdd
if !fastAdd {
blockTime := selectedParent.CalcPastMedianTime()
blockTime := bluestParent.CalcPastMedianTime()
// Ensure all transactions in the block are finalized.
for _, tx := range block.Transactions() {