[NOD-615] Make bluesAnticoneSizes a map with *blockNode as a key (#619)

This commit is contained in:
Ori Newman 2020-02-03 12:40:39 +02:00 committed by GitHub
parent eb953286ec
commit d8954f1339
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 14 deletions

View File

@ -80,7 +80,7 @@ type blockNode struct {
// bluesAnticoneSizes is a map holding the set of blues affected by this block and their // bluesAnticoneSizes is a map holding the set of blues affected by this block and their
// modified blue anticone size. // modified blue anticone size.
bluesAnticoneSizes map[daghash.Hash]dagconfig.KType bluesAnticoneSizes map[*blockNode]dagconfig.KType
// hash is the double sha 256 of the block. // hash is the double sha 256 of the block.
hash *daghash.Hash hash *daghash.Hash
@ -116,7 +116,7 @@ func (dag *BlockDAG) newBlockNode(blockHeader *wire.BlockHeader, parents blockSe
children: make(blockSet), children: make(blockSet),
blueScore: math.MaxUint64, // Initialized to the max value to avoid collisions with the genesis block blueScore: math.MaxUint64, // Initialized to the max value to avoid collisions with the genesis block
timestamp: dag.AdjustedTime().Unix(), timestamp: dag.AdjustedTime().Unix(),
bluesAnticoneSizes: make(map[daghash.Hash]dagconfig.KType), bluesAnticoneSizes: make(map[*blockNode]dagconfig.KType),
} }
// blockHeader is nil only for the virtual block // blockHeader is nil only for the virtual block

View File

@ -26,15 +26,16 @@ func TestBlueAnticoneSizesSize(t *testing.T) {
blockHeader := dagconfig.SimnetParams.GenesisBlock.Header blockHeader := dagconfig.SimnetParams.GenesisBlock.Header
node, _ := dag.newBlockNode(&blockHeader, newSet()) node, _ := dag.newBlockNode(&blockHeader, newSet())
hash := daghash.Hash{1} fakeBlue := &blockNode{hash: &daghash.Hash{1}}
dag.index.AddNode(fakeBlue)
// Setting maxKType to maximum value of KType. // Setting maxKType to maximum value of KType.
// As we verify above that KType is unsigned we can be sure that maxKType is indeed the maximum value of KType. // As we verify above that KType is unsigned we can be sure that maxKType is indeed the maximum value of KType.
maxKType := ^dagconfig.KType(0) maxKType := ^dagconfig.KType(0)
node.bluesAnticoneSizes[hash] = maxKType node.bluesAnticoneSizes[fakeBlue] = maxKType
serializedNode, _ := serializeBlockNode(node) serializedNode, _ := serializeBlockNode(node)
deserializedNode, _ := dag.deserializeBlockNode(serializedNode) deserializedNode, _ := dag.deserializeBlockNode(serializedNode)
if deserializedNode.bluesAnticoneSizes[hash] != maxKType { if deserializedNode.bluesAnticoneSizes[fakeBlue] != maxKType {
t.Fatalf("TestBlueAnticoneSizesSize: BlueAnticoneSize should not change when deserializing. Expected: %v but got %v", t.Fatalf("TestBlueAnticoneSizesSize: BlueAnticoneSize should not change when deserializing. Expected: %v but got %v",
maxKType, deserializedNode.bluesAnticoneSizes[hash]) maxKType, deserializedNode.bluesAnticoneSizes[fakeBlue])
} }
} }

View File

@ -706,17 +706,21 @@ func (dag *BlockDAG) deserializeBlockNode(blockRow []byte) (*blockNode, error) {
return nil, err return nil, err
} }
node.bluesAnticoneSizes = make(map[daghash.Hash]dagconfig.KType) node.bluesAnticoneSizes = make(map[*blockNode]dagconfig.KType)
for i := uint64(0); i < bluesAnticoneSizesLen; i++ { for i := uint64(0); i < bluesAnticoneSizesLen; i++ {
hash := &daghash.Hash{} hash := &daghash.Hash{}
if _, err := io.ReadFull(buffer, hash[:]); err != nil { if _, err := io.ReadFull(buffer, hash[:]); err != nil {
return nil, err return nil, err
} }
bluesAnticoneSize, err := binaryserializer.Uint8(buffer) bluesAnticoneSize, err := binaryserializer.Uint8(buffer)
node.bluesAnticoneSizes[*hash] = dagconfig.KType(bluesAnticoneSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
blue := dag.index.LookupNode(hash)
if blue == nil {
return nil, errors.Errorf("couldn't find block with hash %s", hash)
}
node.bluesAnticoneSizes[blue] = dagconfig.KType(bluesAnticoneSize)
} }
return node, nil return node, nil
@ -784,8 +788,8 @@ func serializeBlockNode(node *blockNode) ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
for blockHash, blueAnticoneSize := range node.bluesAnticoneSizes { for blue, blueAnticoneSize := range node.bluesAnticoneSizes {
_, err = w.Write(blockHash[:]) _, err = w.Write(blue.hash[:])
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -27,7 +27,7 @@ import (
// For further details see the article https://eprint.iacr.org/2018/104.pdf // For further details see the article https://eprint.iacr.org/2018/104.pdf
func (dag *BlockDAG) ghostdag(newNode *blockNode) (selectedParentAnticone []*blockNode, err error) { func (dag *BlockDAG) ghostdag(newNode *blockNode) (selectedParentAnticone []*blockNode, err error) {
newNode.selectedParent = newNode.parents.bluest() newNode.selectedParent = newNode.parents.bluest()
newNode.bluesAnticoneSizes[*newNode.selectedParent.hash] = 0 newNode.bluesAnticoneSizes[newNode.selectedParent] = 0
newNode.blues = []*blockNode{newNode.selectedParent} newNode.blues = []*blockNode{newNode.selectedParent}
selectedParentAnticone, err = dag.selectedParentAnticone(newNode) selectedParentAnticone, err = dag.selectedParentAnticone(newNode)
if err != nil { if err != nil {
@ -102,9 +102,9 @@ func (dag *BlockDAG) ghostdag(newNode *blockNode) (selectedParentAnticone []*blo
if possiblyBlue { if possiblyBlue {
// No k-cluster violation found, we can now set the candidate block as blue // No k-cluster violation found, we can now set the candidate block as blue
newNode.blues = append(newNode.blues, blueCandidate) newNode.blues = append(newNode.blues, blueCandidate)
newNode.bluesAnticoneSizes[*blueCandidate.hash] = candidateAnticoneSize newNode.bluesAnticoneSizes[blueCandidate] = candidateAnticoneSize
for blue, blueAnticoneSize := range candidateBluesAnticoneSizes { for blue, blueAnticoneSize := range candidateBluesAnticoneSizes {
newNode.bluesAnticoneSizes[*blue.hash] = blueAnticoneSize + 1 newNode.bluesAnticoneSizes[blue] = blueAnticoneSize + 1
} }
// The maximum length of node.blues can be K+1 because // The maximum length of node.blues can be K+1 because
@ -168,7 +168,7 @@ func (dag *BlockDAG) selectedParentAnticone(node *blockNode) ([]*blockNode, erro
// Expects 'block' to be in the blue set of 'context' // Expects 'block' to be in the blue set of 'context'
func (dag *BlockDAG) blueAnticoneSize(block, context *blockNode) (dagconfig.KType, error) { func (dag *BlockDAG) blueAnticoneSize(block, context *blockNode) (dagconfig.KType, error) {
for current := context; current != nil; current = current.selectedParent { for current := context; current != nil; current = current.selectedParent {
if blueAnticoneSize, ok := current.bluesAnticoneSizes[*block.hash]; ok { if blueAnticoneSize, ok := current.bluesAnticoneSizes[block]; ok {
return blueAnticoneSize, nil return blueAnticoneSize, nil
} }
} }