mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-10-14 00:59:33 +00:00
[NOD-700] Convert blockSet to map[*blockNode]struct{} (#604)
* [NOD-700] Convert blockSet to map[*blockNode]struct{}. * [NOD-700] Rename bluestNode to bluestBlock in bluest(). * [NOD-700] Make IsInSelectedParentChain not use the now-slower containsHash. * [NOD-700] Rename block to node in blockset.go. * [NOD-700] Remove containsHash and hashesEqual. * [NOD-700] Add a comment to IsInSelectedParentChain about how it'll fail if the given blockHash is not within the block index.
This commit is contained in:
parent
a10320ad7b
commit
11de12304e
@ -148,7 +148,7 @@ func (dag *BlockDAG) newBlockNode(blockHeader *wire.BlockHeader, parents blockSe
|
|||||||
|
|
||||||
// updateParentsChildren updates the node's parents to point to new node
|
// updateParentsChildren updates the node's parents to point to new node
|
||||||
func (node *blockNode) updateParentsChildren() {
|
func (node *blockNode) updateParentsChildren() {
|
||||||
for _, parent := range node.parents {
|
for parent := range node.parents {
|
||||||
parent.children.add(node)
|
parent.children.add(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,38 +7,38 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// blockSet implements a basic unsorted set of blocks
|
// blockSet implements a basic unsorted set of blocks
|
||||||
type blockSet map[daghash.Hash]*blockNode
|
type blockSet map[*blockNode]struct{}
|
||||||
|
|
||||||
// newSet creates a new, empty BlockSet
|
// newSet creates a new, empty BlockSet
|
||||||
func newSet() blockSet {
|
func newSet() blockSet {
|
||||||
return map[daghash.Hash]*blockNode{}
|
return map[*blockNode]struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setFromSlice converts a slice of blocks into an unordered set represented as map
|
// setFromSlice converts a slice of blockNodes into an unordered set represented as map
|
||||||
func setFromSlice(blocks ...*blockNode) blockSet {
|
func setFromSlice(nodes ...*blockNode) blockSet {
|
||||||
set := newSet()
|
set := newSet()
|
||||||
for _, block := range blocks {
|
for _, node := range nodes {
|
||||||
set.add(block)
|
set.add(node)
|
||||||
}
|
}
|
||||||
return set
|
return set
|
||||||
}
|
}
|
||||||
|
|
||||||
// add adds a block to this BlockSet
|
// add adds a blockNode to this BlockSet
|
||||||
func (bs blockSet) add(block *blockNode) {
|
func (bs blockSet) add(node *blockNode) {
|
||||||
bs[*block.hash] = block
|
bs[node] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove removes a block from this BlockSet, if exists
|
// remove removes a blockNode from this BlockSet, if exists
|
||||||
// Does nothing if this set does not contain the block
|
// Does nothing if this set does not contain the blockNode
|
||||||
func (bs blockSet) remove(block *blockNode) {
|
func (bs blockSet) remove(node *blockNode) {
|
||||||
delete(bs, *block.hash)
|
delete(bs, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
// clone clones thie block set
|
// clone clones thie block set
|
||||||
func (bs blockSet) clone() blockSet {
|
func (bs blockSet) clone() blockSet {
|
||||||
clone := newSet()
|
clone := newSet()
|
||||||
for _, block := range bs {
|
for node := range bs {
|
||||||
clone.add(block)
|
clone.add(node)
|
||||||
}
|
}
|
||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
@ -46,29 +46,29 @@ func (bs blockSet) clone() blockSet {
|
|||||||
// subtract returns the difference between the BlockSet and another BlockSet
|
// subtract returns the difference between the BlockSet and another BlockSet
|
||||||
func (bs blockSet) subtract(other blockSet) blockSet {
|
func (bs blockSet) subtract(other blockSet) blockSet {
|
||||||
diff := newSet()
|
diff := newSet()
|
||||||
for _, block := range bs {
|
for node := range bs {
|
||||||
if !other.contains(block) {
|
if !other.contains(node) {
|
||||||
diff.add(block)
|
diff.add(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
// addSet adds all blocks in other set to this set
|
// addSet adds all blockNodes in other set to this set
|
||||||
func (bs blockSet) addSet(other blockSet) {
|
func (bs blockSet) addSet(other blockSet) {
|
||||||
for _, block := range other {
|
for node := range other {
|
||||||
bs.add(block)
|
bs.add(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// addSlice adds provided slice to this set
|
// addSlice adds provided slice to this set
|
||||||
func (bs blockSet) addSlice(slice []*blockNode) {
|
func (bs blockSet) addSlice(slice []*blockNode) {
|
||||||
for _, block := range slice {
|
for _, node := range slice {
|
||||||
bs.add(block)
|
bs.add(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// union returns a BlockSet that contains all blocks included in this set,
|
// union returns a BlockSet that contains all blockNodes included in this set,
|
||||||
// the other set, or both
|
// the other set, or both
|
||||||
func (bs blockSet) union(other blockSet) blockSet {
|
func (bs blockSet) union(other blockSet) blockSet {
|
||||||
union := bs.clone()
|
union := bs.clone()
|
||||||
@ -78,39 +78,16 @@ func (bs blockSet) union(other blockSet) blockSet {
|
|||||||
return union
|
return union
|
||||||
}
|
}
|
||||||
|
|
||||||
// contains returns true iff this set contains block
|
// contains returns true iff this set contains node
|
||||||
func (bs blockSet) contains(block *blockNode) bool {
|
func (bs blockSet) contains(node *blockNode) bool {
|
||||||
_, ok := bs[*block.hash]
|
_, ok := bs[node]
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// containsHash returns true iff this set contains a block hash
|
// hashes returns the hashes of the blockNodes in this set.
|
||||||
func (bs blockSet) containsHash(hash *daghash.Hash) bool {
|
|
||||||
_, ok := bs[*hash]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// hashesEqual returns true if the given hashes are equal to the hashes
|
|
||||||
// of the blocks in this set.
|
|
||||||
// NOTE: The given hash slice must not contain duplicates.
|
|
||||||
func (bs blockSet) hashesEqual(hashes []*daghash.Hash) bool {
|
|
||||||
if len(hashes) != len(bs) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, hash := range hashes {
|
|
||||||
if _, wasFound := bs[*hash]; !wasFound {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// hashes returns the hashes of the blocks in this set.
|
|
||||||
func (bs blockSet) hashes() []*daghash.Hash {
|
func (bs blockSet) hashes() []*daghash.Hash {
|
||||||
hashes := make([]*daghash.Hash, 0, len(bs))
|
hashes := make([]*daghash.Hash, 0, len(bs))
|
||||||
for _, node := range bs {
|
for node := range bs {
|
||||||
hashes = append(hashes, node.hash)
|
hashes = append(hashes, node.hash)
|
||||||
}
|
}
|
||||||
daghash.Sort(hashes)
|
daghash.Sort(hashes)
|
||||||
@ -119,15 +96,15 @@ func (bs blockSet) hashes() []*daghash.Hash {
|
|||||||
|
|
||||||
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 {
|
||||||
nodeStrs = append(nodeStrs, node.String())
|
nodeStrs = append(nodeStrs, node.String())
|
||||||
}
|
}
|
||||||
return strings.Join(nodeStrs, ",")
|
return strings.Join(nodeStrs, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
// anyChildInSet returns true iff any child of block is contained within this set
|
// anyChildInSet returns true iff any child of node is contained within this set
|
||||||
func (bs blockSet) anyChildInSet(block *blockNode) bool {
|
func (bs blockSet) anyChildInSet(node *blockNode) bool {
|
||||||
for _, child := range block.children {
|
for child := range node.children {
|
||||||
if bs.contains(child) {
|
if bs.contains(child) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -139,7 +116,7 @@ func (bs blockSet) anyChildInSet(block *blockNode) bool {
|
|||||||
func (bs blockSet) bluest() *blockNode {
|
func (bs blockSet) bluest() *blockNode {
|
||||||
var bluestNode *blockNode
|
var bluestNode *blockNode
|
||||||
var maxScore uint64
|
var maxScore uint64
|
||||||
for _, node := range bs {
|
for node := range bs {
|
||||||
if bluestNode == nil ||
|
if bluestNode == nil ||
|
||||||
node.blueScore > maxScore ||
|
node.blueScore > maxScore ||
|
||||||
(node.blueScore == maxScore && daghash.Less(node.hash, bluestNode.hash)) {
|
(node.blueScore == maxScore && daghash.Less(node.hash, bluestNode.hash)) {
|
||||||
|
@ -243,54 +243,3 @@ func TestBlockSetUnion(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBlockSetHashesEqual(t *testing.T) {
|
|
||||||
node1 := &blockNode{hash: &daghash.Hash{10}}
|
|
||||||
node2 := &blockNode{hash: &daghash.Hash{20}}
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
set blockSet
|
|
||||||
hashes []*daghash.Hash
|
|
||||||
expectedResult bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "empty set, no hashes",
|
|
||||||
set: setFromSlice(),
|
|
||||||
hashes: []*daghash.Hash{},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "empty set, one hash",
|
|
||||||
set: setFromSlice(),
|
|
||||||
hashes: []*daghash.Hash{node1.hash},
|
|
||||||
expectedResult: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "set and hashes of different length",
|
|
||||||
set: setFromSlice(node1, node2),
|
|
||||||
hashes: []*daghash.Hash{node1.hash},
|
|
||||||
expectedResult: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "set equal to hashes",
|
|
||||||
set: setFromSlice(node1, node2),
|
|
||||||
hashes: []*daghash.Hash{node1.hash, node2.hash},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "set equal to hashes, different order",
|
|
||||||
set: setFromSlice(node1, node2),
|
|
||||||
hashes: []*daghash.Hash{node2.hash, node1.hash},
|
|
||||||
expectedResult: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
result := test.set.hashesEqual(test.hashes)
|
|
||||||
if result != test.expectedResult {
|
|
||||||
t.Errorf("blockSet.hashesEqual: unexpected result in test '%s'. "+
|
|
||||||
"Expected: %t, got: %t", test.name, test.expectedResult, result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -154,7 +154,7 @@ func newTestNode(dag *BlockDAG, parents blockSet, blockVersion int32, bits uint3
|
|||||||
}
|
}
|
||||||
|
|
||||||
func addNodeAsChildToParents(node *blockNode) {
|
func addNodeAsChildToParents(node *blockNode) {
|
||||||
for _, parent := range node.parents {
|
for parent := range node.parents {
|
||||||
parent.children.add(node)
|
parent.children.add(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -773,7 +773,7 @@ func (dag *BlockDAG) updateFinalityPoint() {
|
|||||||
|
|
||||||
func (dag *BlockDAG) finalizeNodesBelowFinalityPoint(deleteDiffData bool) {
|
func (dag *BlockDAG) finalizeNodesBelowFinalityPoint(deleteDiffData bool) {
|
||||||
queue := make([]*blockNode, 0, len(dag.lastFinalityPoint.parents))
|
queue := make([]*blockNode, 0, len(dag.lastFinalityPoint.parents))
|
||||||
for _, parent := range dag.lastFinalityPoint.parents {
|
for parent := range dag.lastFinalityPoint.parents {
|
||||||
queue = append(queue, parent)
|
queue = append(queue, parent)
|
||||||
}
|
}
|
||||||
var blockHashesToDelete []*daghash.Hash
|
var blockHashesToDelete []*daghash.Hash
|
||||||
@ -788,7 +788,7 @@ func (dag *BlockDAG) finalizeNodesBelowFinalityPoint(deleteDiffData bool) {
|
|||||||
if deleteDiffData {
|
if deleteDiffData {
|
||||||
blockHashesToDelete = append(blockHashesToDelete, current.hash)
|
blockHashesToDelete = append(blockHashesToDelete, current.hash)
|
||||||
}
|
}
|
||||||
for _, parent := range current.parents {
|
for parent := range current.parents {
|
||||||
queue = append(queue, parent)
|
queue = append(queue, parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1125,7 +1125,7 @@ func (node *blockNode) updateParentsDiffs(dag *BlockDAG, newBlockUTXO UTXOSet) e
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, parent := range node.parents {
|
for parent := range node.parents {
|
||||||
diffChild, err := dag.utxoDiffStore.diffChildByNode(parent)
|
diffChild, err := dag.utxoDiffStore.diffChildByNode(parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -1236,7 +1236,7 @@ func (dag *BlockDAG) restoreUTXO(node *blockNode) (UTXOSet, error) {
|
|||||||
|
|
||||||
// updateTipsUTXO builds and applies new diff UTXOs for all the DAG's tips
|
// updateTipsUTXO builds and applies new diff UTXOs for all the DAG's tips
|
||||||
func updateTipsUTXO(dag *BlockDAG, virtualUTXO UTXOSet) error {
|
func updateTipsUTXO(dag *BlockDAG, virtualUTXO UTXOSet) error {
|
||||||
for _, tip := range dag.virtual.parents {
|
for tip := range dag.virtual.parents {
|
||||||
tipUTXO, err := dag.restoreUTXO(tip)
|
tipUTXO, err := dag.restoreUTXO(tip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -1419,13 +1419,21 @@ func (dag *BlockDAG) acceptingBlock(node *blockNode) (*blockNode, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the node is a chain-block itself, the accepting block is its chain-child
|
// If the node is a chain-block itself, the accepting block is its chain-child
|
||||||
if dag.IsInSelectedParentChain(node.hash) {
|
isNodeInSelectedParentChain, err := dag.IsInSelectedParentChain(node.hash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if isNodeInSelectedParentChain {
|
||||||
if len(node.children) == 0 {
|
if len(node.children) == 0 {
|
||||||
// If the node is the selected tip, it doesn't have an accepting block
|
// If the node is the selected tip, it doesn't have an accepting block
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
for _, child := range node.children {
|
for child := range node.children {
|
||||||
if dag.IsInSelectedParentChain(child.hash) {
|
isChildInSelectedParentChain, err := dag.IsInSelectedParentChain(child.hash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if isChildInSelectedParentChain {
|
||||||
return child, nil
|
return child, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1469,11 +1477,17 @@ func (dag *BlockDAG) oldestChainBlockWithBlueScoreGreaterThan(blueScore uint64)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsInSelectedParentChain returns whether or not a block hash is found in the selected
|
// IsInSelectedParentChain returns whether or not a block hash is found in the selected
|
||||||
// parent chain.
|
// parent chain. Note that this method returns an error if the given blockHash does not
|
||||||
|
// exist within the block index.
|
||||||
//
|
//
|
||||||
// This method MUST be called with the DAG lock held
|
// This method MUST be called with the DAG lock held
|
||||||
func (dag *BlockDAG) IsInSelectedParentChain(blockHash *daghash.Hash) bool {
|
func (dag *BlockDAG) IsInSelectedParentChain(blockHash *daghash.Hash) (bool, error) {
|
||||||
return dag.virtual.selectedParentChainSet.containsHash(blockHash)
|
blockNode := dag.index.LookupNode(blockHash)
|
||||||
|
if blockNode == nil {
|
||||||
|
str := fmt.Sprintf("block %s is not in the DAG", blockHash)
|
||||||
|
return false, errNotInDAG(str)
|
||||||
|
}
|
||||||
|
return dag.virtual.selectedParentChainSet.contains(blockNode), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectedParentChain returns the selected parent chain starting from blockHash (exclusive)
|
// SelectedParentChain returns the selected parent chain starting from blockHash (exclusive)
|
||||||
@ -1494,7 +1508,11 @@ func (dag *BlockDAG) SelectedParentChain(blockHash *daghash.Hash) ([]*daghash.Ha
|
|||||||
// If blockHash is not in the selected parent chain, go down its selected parent chain
|
// If blockHash is not in the selected parent chain, go down its selected parent chain
|
||||||
// until we find a block that is in the main selected parent chain.
|
// until we find a block that is in the main selected parent chain.
|
||||||
var removedChainHashes []*daghash.Hash
|
var removedChainHashes []*daghash.Hash
|
||||||
for !dag.IsInSelectedParentChain(blockHash) {
|
isBlockInSelectedParentChain, err := dag.IsInSelectedParentChain(blockHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
for !isBlockInSelectedParentChain {
|
||||||
removedChainHashes = append(removedChainHashes, blockHash)
|
removedChainHashes = append(removedChainHashes, blockHash)
|
||||||
|
|
||||||
node := dag.index.LookupNode(blockHash)
|
node := dag.index.LookupNode(blockHash)
|
||||||
@ -1544,7 +1562,7 @@ func (dag *BlockDAG) TipHashes() []*daghash.Hash {
|
|||||||
func (dag *BlockDAG) CurrentBits() uint32 {
|
func (dag *BlockDAG) CurrentBits() uint32 {
|
||||||
tips := dag.virtual.tips()
|
tips := dag.virtual.tips()
|
||||||
minBits := uint32(math.MaxUint32)
|
minBits := uint32(math.MaxUint32)
|
||||||
for _, tip := range tips {
|
for tip := range tips {
|
||||||
if minBits > tip.Header().Bits {
|
if minBits > tip.Header().Bits {
|
||||||
minBits = tip.Header().Bits
|
minBits = tip.Header().Bits
|
||||||
}
|
}
|
||||||
@ -1665,7 +1683,7 @@ func (dag *BlockDAG) antiPastBetween(lowHash, highHash *daghash.Hash, maxEntries
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
candidateNodes.Push(current)
|
candidateNodes.Push(current)
|
||||||
for _, parent := range current.parents {
|
for parent := range current.parents {
|
||||||
queue.Push(parent)
|
queue.Push(parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -723,7 +723,7 @@ func TestConfirmations(t *testing.T) {
|
|||||||
|
|
||||||
// Check that each of the tips has a 0 confirmations
|
// Check that each of the tips has a 0 confirmations
|
||||||
tips := dag.virtual.tips()
|
tips := dag.virtual.tips()
|
||||||
for _, tip := range tips {
|
for tip := range tips {
|
||||||
tipConfirmations, err := dag.blockConfirmations(tip)
|
tipConfirmations, err := dag.blockConfirmations(tip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("TestConfirmations: confirmations for tip unexpectedly failed: %s", err)
|
t.Fatalf("TestConfirmations: confirmations for tip unexpectedly failed: %s", err)
|
||||||
@ -828,7 +828,11 @@ func TestAcceptingBlock(t *testing.T) {
|
|||||||
branchingChainTip := prepareAndProcessBlock(t, dag, chainBlocks[len(chainBlocks)-3])
|
branchingChainTip := prepareAndProcessBlock(t, dag, chainBlocks[len(chainBlocks)-3])
|
||||||
|
|
||||||
// Make sure that branchingChainTip is not in the selected parent chain
|
// Make sure that branchingChainTip is not in the selected parent chain
|
||||||
if dag.IsInSelectedParentChain(branchingChainTip.BlockHash()) {
|
isBranchingChainTipInSelectedParentChain, err := dag.IsInSelectedParentChain(branchingChainTip.BlockHash())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("TestAcceptingBlock: IsInSelectedParentChain unexpectedly failed: %s", err)
|
||||||
|
}
|
||||||
|
if isBranchingChainTipInSelectedParentChain {
|
||||||
t.Fatalf("TestAcceptingBlock: branchingChainTip wasn't expected to be in the selected parent chain")
|
t.Fatalf("TestAcceptingBlock: branchingChainTip wasn't expected to be in the selected parent chain")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ func (dag *BlockDAG) selectedParentAnticone(node *blockNode) ([]*blockNode, erro
|
|||||||
selectedParentPast := newSet()
|
selectedParentPast := newSet()
|
||||||
var queue []*blockNode
|
var queue []*blockNode
|
||||||
// Queueing all parents (other than the selected parent itself) for processing.
|
// Queueing all parents (other than the selected parent itself) for processing.
|
||||||
for _, parent := range node.parents {
|
for parent := range node.parents {
|
||||||
if parent == node.selectedParent {
|
if parent == node.selectedParent {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -144,7 +144,7 @@ func (dag *BlockDAG) selectedParentAnticone(node *blockNode) ([]*blockNode, erro
|
|||||||
current, queue = queue[0], queue[1:]
|
current, queue = queue[0], queue[1:]
|
||||||
// For each parent of a the current node we check whether it is in the past of the selected parent. If not,
|
// For each parent of a the current node we check whether it is in the past of the selected parent. If not,
|
||||||
// we add the it to the resulting anticone-set and queue it for further processing.
|
// we add the it to the resulting anticone-set and queue it for further processing.
|
||||||
for _, parent := range current.parents {
|
for parent := range current.parents {
|
||||||
if anticoneSet.contains(parent) || selectedParentPast.contains(parent) {
|
if anticoneSet.contains(parent) || selectedParentPast.contains(parent) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -389,7 +389,11 @@ func dbFetchTxAcceptingBlock(dbTx database.Tx, txID *daghash.TxID, dag *blockdag
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if dag.IsInSelectedParentChain(blockHash) {
|
isBlockInSelectedParentChain, err := dag.IsInSelectedParentChain(blockHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if isBlockInSelectedParentChain {
|
||||||
return blockHash, nil
|
return blockHash, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -602,7 +602,7 @@ func validateParents(blockHeader *wire.BlockHeader, parents blockSet) error {
|
|||||||
minBlueScore := uint64(math.MaxUint64)
|
minBlueScore := uint64(math.MaxUint64)
|
||||||
queue := newDownHeap()
|
queue := newDownHeap()
|
||||||
visited := newSet()
|
visited := newSet()
|
||||||
for _, parent := range parents {
|
for parent := range parents {
|
||||||
// isFinalized might be false-negative because node finality status is
|
// isFinalized might be false-negative because node finality status is
|
||||||
// updated in a separate goroutine. This is why later the block is
|
// updated in a separate goroutine. This is why later the block is
|
||||||
// checked more thoroughly on the finality rules in dag.checkFinalityRules.
|
// checked more thoroughly on the finality rules in dag.checkFinalityRules.
|
||||||
@ -612,7 +612,7 @@ func validateParents(blockHeader *wire.BlockHeader, parents blockSet) error {
|
|||||||
if parent.blueScore < minBlueScore {
|
if parent.blueScore < minBlueScore {
|
||||||
minBlueScore = parent.blueScore
|
minBlueScore = parent.blueScore
|
||||||
}
|
}
|
||||||
for _, grandParent := range parent.parents {
|
for grandParent := range parent.parents {
|
||||||
if !visited.contains(grandParent) {
|
if !visited.contains(grandParent) {
|
||||||
queue.Push(grandParent)
|
queue.Push(grandParent)
|
||||||
visited.add(grandParent)
|
visited.add(grandParent)
|
||||||
@ -628,7 +628,7 @@ func validateParents(blockHeader *wire.BlockHeader, parents blockSet) error {
|
|||||||
blockHeader.BlockHash()))
|
blockHeader.BlockHash()))
|
||||||
}
|
}
|
||||||
if current.blueScore > minBlueScore {
|
if current.blueScore > minBlueScore {
|
||||||
for _, parent := range current.parents {
|
for parent := range current.parents {
|
||||||
if !visited.contains(parent) {
|
if !visited.contains(parent) {
|
||||||
queue.Push(parent)
|
queue.Push(parent)
|
||||||
visited.add(parent)
|
visited.add(parent)
|
||||||
|
@ -124,7 +124,8 @@ func TestCheckConnectBlockTemplate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
blockNode3 := dag.index.LookupNode(blocks[3].Hash())
|
blockNode3 := dag.index.LookupNode(blocks[3].Hash())
|
||||||
if blockNode3.children.containsHash(blocks[4].Hash()) {
|
blockNode4 := dag.index.LookupNode(blocks[4].Hash())
|
||||||
|
if blockNode3.children.contains(blockNode4) {
|
||||||
t.Errorf("Block 4 wasn't successfully detached as a child from block3")
|
t.Errorf("Block 4 wasn't successfully detached as a child from block3")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ func (v *virtualBlock) SetTips(tips blockSet) {
|
|||||||
// This function MUST be called with the view mutex locked (for writes).
|
// This function MUST be called with the view mutex locked (for writes).
|
||||||
func (v *virtualBlock) addTip(newTip *blockNode) *chainUpdates {
|
func (v *virtualBlock) addTip(newTip *blockNode) *chainUpdates {
|
||||||
updatedTips := v.tips().clone()
|
updatedTips := v.tips().clone()
|
||||||
for _, parent := range newTip.parents {
|
for parent := range newTip.parents {
|
||||||
updatedTips.remove(parent)
|
updatedTips.remove(parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,11 @@ func buildGetBlockVerboseResult(s *Server, block *util.Block, isVerboseTx bool)
|
|||||||
selectedParentHashStr = selectedParentHash.String()
|
selectedParentHashStr = selectedParentHash.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
isChainBlock := s.cfg.DAG.IsInSelectedParentChain(hash)
|
isChainBlock, err := s.cfg.DAG.IsInSelectedParentChain(hash)
|
||||||
|
if err != nil {
|
||||||
|
context := "Could not get whether block is in the selected parent chain"
|
||||||
|
return nil, internalRPCError(err.Error(), context)
|
||||||
|
}
|
||||||
|
|
||||||
result := &rpcmodel.GetBlockVerboseResult{
|
result := &rpcmodel.GetBlockVerboseResult{
|
||||||
Hash: hash.String(),
|
Hash: hash.String(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user