Svarog c5707f64dc
[NOD-1420] Implement consensusStateManager (#985)
* [NOD-1420] Start working on ConsensusStateManager. Might be redundant due to recent changes

* [NOD-1420] Convert model to externalapi in utxo_algerbra helpers

* [NOD-1420] Add UTXO-diff algebra

* [NOD-1420] Prepare skeleton of calculateAcceptanceDataAndMultiset

* [NOD-1420] Added skeleton for AddBlockToVirtual

* [NOD-1420] Implement PopulateTransactionWithUTXOEntries

* [NOD-1420] Implement restorePastUTXO

* [NOD-1420] Implement finality check

* [NOD-1420] Move handling of tips to consensusStateManager

* [NOD-1420] Implement calculateAcceptanceDataAndMultiset

* [NOD-1420] Start implementing resolveBlockStatus

* [NOD-1420] Implement resolveBlockStatus

* [NOD-1420] Update related fields in end of resolveSingleBlockStatus

* [NOD-1420] Start working on selectVirtualParents

* [NOD-1420] Implemented BlockHeap

* [NOD-1420] Implement selectVirtualParents

* [NOD-1420] Implement updateVirtual

* [NOD-1420] Added comments where they were missing

* [NOD-1420] Place all consensusStateManager functions in correct files

* [NOD-1420] Return the missing outpoints from populateTransactionWithUTXOEntriesFromVirtualOrDiff

* [NOD-1420] Outpoint.ID -> TransactionID

* [NOD-1420] Fix Stringer tests

* [NOD-1420] Copy hash.FromString into utils

* [NOD-1420] SetParents should return an error

* [NOD-1420] Remove all reachabilityManager references from consensusStateManager

* [NOD-1420] Remove VirtualData. Get the info from the stores where needed

* [NOD-1420] Invert parameters to IsAncestorOf

* [NOD-1420] Use model.AcceptanceData

* [NOD-1420] Don't return accumulatedMassBefore in error cases

* [NOD-1420] Don't expect store functions to return nil when the requested data was found - instead add HasXXX functions

* [NOD-1420] addTransactionToMultiset sets isCoinbase properly

* [NOD-1420] expected hash string length is externalapi.DomainHashSize * 2

* [NOD-1420] Rename reachabilityTree -> reachabilityManager + updateReindexRoot if isNextVirtualSelectedParent

* [NOD-1420] ValidateCoinbaseTransaction in csm.verifyAndBuildUTXO

* [NOD-1420] Re-write HAsUTXODiffChild

* [NOD-1420] delete past_utxo.go.bak

* [NOD-1420] Implement validateCoinbaseTransaction in CSM

* [NOD-1420] Imlemented missing functionality in ValidateTransactionAndPopulateWithConsensusData

* [NOD-1420] Moved merge depth logic to MergeDepthManager

* [NOD-1420] Add logs
2020-11-02 16:18:53 +02:00

107 lines
2.9 KiB
Go

package dagtraversalmanager
import (
"container/heap"
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
type blockHeapNode struct {
hash *externalapi.DomainHash
ghostdagData *model.BlockGHOSTDAGData
}
// baseHeap is an implementation for heap.Interface that sorts blocks by their height
type baseHeap struct {
slice []*blockHeapNode
ghostdagManager model.GHOSTDAGManager
}
func (h baseHeap) Len() int { return len(h.slice) }
func (h baseHeap) Swap(i, j int) { h.slice[i], h.slice[j] = h.slice[j], h.slice[i] }
func (h *baseHeap) Push(x interface{}) {
h.slice = append(h.slice, x.(*blockHeapNode))
}
func (h *baseHeap) Pop() interface{} {
oldSlice := h.slice
oldLength := len(oldSlice)
popped := oldSlice[oldLength-1]
h.slice = oldSlice[0 : oldLength-1]
return popped
}
// upHeap extends baseHeap to include Less operation that traverses from bottom to top
type upHeap struct{ baseHeap }
func (h upHeap) Less(i, j int) bool {
heapNodeA := h.slice[i]
heapNodeB := h.slice[j]
return h.ghostdagManager.Less(heapNodeA.hash, heapNodeA.ghostdagData, heapNodeB.hash, heapNodeB.ghostdagData)
}
// downHeap extends baseHeap to include Less operation that traverses from top to bottom
type downHeap struct{ baseHeap }
func (h downHeap) Less(i, j int) bool {
heapNodeA := h.slice[i]
heapNodeB := h.slice[j]
return !h.ghostdagManager.Less(heapNodeA.hash, heapNodeA.ghostdagData, heapNodeB.hash, heapNodeB.ghostdagData)
}
// BlockHeap represents a mutable heap of Blocks, sorted by their height
type BlockHeap struct {
impl heap.Interface
ghostdagStore model.GHOSTDAGDataStore
dbContext model.DBReader
}
// NewDownHeap initializes and returns a new BlockHeap
func (dtm dagTraversalManager) NewDownHeap() model.BlockHeap {
h := BlockHeap{
impl: &downHeap{baseHeap{ghostdagManager: dtm.ghostdagManager}},
ghostdagStore: dtm.ghostdagDataStore,
dbContext: dtm.databaseContext,
}
heap.Init(h.impl)
return h
}
// NewUpHeap initializes and returns a new BlockHeap
func (dtm dagTraversalManager) NewUpHeap() model.BlockHeap {
h := BlockHeap{
impl: &upHeap{baseHeap{ghostdagManager: dtm.ghostdagManager}},
ghostdagStore: dtm.ghostdagDataStore,
dbContext: dtm.databaseContext,
}
heap.Init(h.impl)
return h
}
// Pop removes the block with lowest height from this heap and returns it
func (bh BlockHeap) Pop() *externalapi.DomainHash {
return heap.Pop(bh.impl).(*blockHeapNode).hash
}
// Push pushes the block onto the heap
func (bh BlockHeap) Push(blockHash *externalapi.DomainHash) error {
ghostdagData, err := bh.ghostdagStore.Get(bh.dbContext, blockHash)
if err != nil {
return err
}
heap.Push(bh.impl, &blockHeapNode{
hash: blockHash,
ghostdagData: ghostdagData,
})
return nil
}
// Len returns the length of this heap
func (bh BlockHeap) Len() int {
return bh.impl.Len()
}