mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
118 lines
2.6 KiB
Go
118 lines
2.6 KiB
Go
package blockdag
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/kaspanet/kaspad/util/daghash"
|
|
)
|
|
|
|
// blockSet implements a basic unsorted set of blocks
|
|
type blockSet map[*blockNode]struct{}
|
|
|
|
// newBlockSet creates a new, empty BlockSet
|
|
func newBlockSet() blockSet {
|
|
return map[*blockNode]struct{}{}
|
|
}
|
|
|
|
// blockSetFromSlice converts a slice of blockNodes into an unordered set represented as map
|
|
func blockSetFromSlice(nodes ...*blockNode) blockSet {
|
|
set := newBlockSet()
|
|
for _, node := range nodes {
|
|
set.add(node)
|
|
}
|
|
return set
|
|
}
|
|
|
|
// add adds a blockNode to this BlockSet
|
|
func (bs blockSet) add(node *blockNode) {
|
|
bs[node] = struct{}{}
|
|
}
|
|
|
|
// remove removes a blockNode from this BlockSet, if exists
|
|
// Does nothing if this set does not contain the blockNode
|
|
func (bs blockSet) remove(node *blockNode) {
|
|
delete(bs, node)
|
|
}
|
|
|
|
// clone clones thie block set
|
|
func (bs blockSet) clone() blockSet {
|
|
clone := newBlockSet()
|
|
for node := range bs {
|
|
clone.add(node)
|
|
}
|
|
return clone
|
|
}
|
|
|
|
// subtract returns the difference between the BlockSet and another BlockSet
|
|
func (bs blockSet) subtract(other blockSet) blockSet {
|
|
diff := newBlockSet()
|
|
for node := range bs {
|
|
if !other.contains(node) {
|
|
diff.add(node)
|
|
}
|
|
}
|
|
return diff
|
|
}
|
|
|
|
// addSet adds all blockNodes in other set to this set
|
|
func (bs blockSet) addSet(other blockSet) {
|
|
for node := range other {
|
|
bs.add(node)
|
|
}
|
|
}
|
|
|
|
// addSlice adds provided slice to this set
|
|
func (bs blockSet) addSlice(slice []*blockNode) {
|
|
for _, node := range slice {
|
|
bs.add(node)
|
|
}
|
|
}
|
|
|
|
// union returns a BlockSet that contains all blockNodes included in this set,
|
|
// the other set, or both
|
|
func (bs blockSet) union(other blockSet) blockSet {
|
|
union := bs.clone()
|
|
|
|
union.addSet(other)
|
|
|
|
return union
|
|
}
|
|
|
|
// contains returns true iff this set contains node
|
|
func (bs blockSet) contains(node *blockNode) bool {
|
|
_, ok := bs[node]
|
|
return ok
|
|
}
|
|
|
|
// hashes returns the hashes of the blockNodes in this set.
|
|
func (bs blockSet) hashes() []*daghash.Hash {
|
|
hashes := make([]*daghash.Hash, 0, len(bs))
|
|
for node := range bs {
|
|
hashes = append(hashes, node.hash)
|
|
}
|
|
daghash.Sort(hashes)
|
|
return hashes
|
|
}
|
|
|
|
func (bs blockSet) String() string {
|
|
nodeStrs := make([]string, 0, len(bs))
|
|
for node := range bs {
|
|
nodeStrs = append(nodeStrs, node.String())
|
|
}
|
|
return strings.Join(nodeStrs, ",")
|
|
}
|
|
|
|
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(node.hash, bluestNode.hash)) {
|
|
bluestNode = node
|
|
maxScore = node.blueScore
|
|
}
|
|
}
|
|
return bluestNode
|
|
}
|