[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 return err
} }
selectedParent := parents.first() //TODO (Ori): This is wrong, done only for compilation bluestParent := parents.bluest()
blockHeight := parents.maxHeight() + 1 blockHeight := parents.maxHeight() + 1
block.SetHeight(blockHeight) block.SetHeight(blockHeight)
// The block must pass all of the validation rules which depend on the // The block must pass all of the validation rules which depend on the
// position of the block within the block DAG. // 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 { if err != nil {
return err return err
} }

View File

@ -125,15 +125,6 @@ func (bs blockSet) hashes() []daghash.Hash {
return hashes 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 { func (bs blockSet) String() string {
nodeStrs := make([]string, 0, len(bs)) nodeStrs := make([]string, 0, len(bs))
for _, node := range bs { for _, node := range bs {
@ -152,3 +143,17 @@ func (bs blockSet) anyChildInSet(block *blockNode) bool {
return false 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. // the checkpoints are not performed.
// //
// This function MUST be called with the chain state lock held (for writes). // 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 fastAdd := flags&BFFastAdd == BFFastAdd
if !fastAdd { if !fastAdd {
// Ensure the difficulty specified in the block header matches // Ensure the difficulty specified in the block header matches
// the calculated difficulty based on the previous block and // the calculated difficulty based on the previous block and
// difficulty retarget rules. // difficulty retarget rules.
expectedDifficulty, err := dag.calcNextRequiredDifficulty(selectedParent, expectedDifficulty, err := dag.calcNextRequiredDifficulty(bluestParent,
header.Timestamp) header.Timestamp)
if err != nil { if err != nil {
return err return err
@ -644,7 +644,7 @@ func (dag *BlockDAG) checkBlockHeaderContext(header *wire.BlockHeader, selectedP
// Ensure the timestamp for the block header is after the // Ensure the timestamp for the block header is after the
// median time of the last several blocks (medianTimeBlocks). // median time of the last several blocks (medianTimeBlocks).
medianTime := selectedParent.CalcPastMedianTime() medianTime := bluestParent.CalcPastMedianTime()
if !header.Timestamp.After(medianTime) { if !header.Timestamp.After(medianTime) {
str := "block timestamp of %v is not after expected %v" str := "block timestamp of %v is not after expected %v"
str = fmt.Sprintf(str, header.Timestamp, medianTime) 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. // for how the flags modify its behavior.
// //
// This function MUST be called with the chain state lock held (for writes). // 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) err := validateParents(&block.MsgBlock().Header, parents)
if err != nil { if err != nil {
return err return err
} }
// Perform all block header related validation checks. // Perform all block header related validation checks.
header := &block.MsgBlock().Header header := &block.MsgBlock().Header
err = dag.checkBlockHeaderContext(header, selectedParent, block.Height(), flags) err = dag.checkBlockHeaderContext(header, bluestParent, block.Height(), flags)
if err != nil { if err != nil {
return err return err
} }
fastAdd := flags&BFFastAdd == BFFastAdd fastAdd := flags&BFFastAdd == BFFastAdd
if !fastAdd { if !fastAdd {
blockTime := selectedParent.CalcPastMedianTime() blockTime := bluestParent.CalcPastMedianTime()
// Ensure all transactions in the block are finalized. // Ensure all transactions in the block are finalized.
for _, tx := range block.Transactions() { for _, tx := range block.Transactions() {