diff --git a/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go b/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go index b74cec547..f4e060c81 100644 --- a/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go +++ b/domain/consensus/datastructures/acceptancedatastore/acceptancedatastore.go @@ -25,14 +25,8 @@ func New() model.AcceptanceDataStore { } // Stage stages the given acceptanceData for the given blockHash -func (ads *acceptanceDataStore) Stage(blockHash *externalapi.DomainHash, acceptanceData model.AcceptanceData) error { - clone, err := ads.cloneAcceptanceData(acceptanceData) - if err != nil { - return err - } - - ads.staging[*blockHash] = clone - return nil +func (ads *acceptanceDataStore) Stage(blockHash *externalapi.DomainHash, acceptanceData model.AcceptanceData) { + ads.staging[*blockHash] = acceptanceData.Clone() } func (ads *acceptanceDataStore) IsStaged() bool { @@ -107,12 +101,3 @@ func (ads *acceptanceDataStore) deserializeAcceptanceData(acceptanceDataBytes [] func (ads *acceptanceDataStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey { return bucket.Key(hash[:]) } - -func (ads *acceptanceDataStore) cloneAcceptanceData(acceptanceData model.AcceptanceData) (model.AcceptanceData, error) { - serialized, err := ads.serializeAcceptanceData(acceptanceData) - if err != nil { - return nil, err - } - - return ads.deserializeAcceptanceData(serialized) -} diff --git a/domain/consensus/datastructures/blockheaderstore/blockheaderstore.go b/domain/consensus/datastructures/blockheaderstore/blockheaderstore.go index 27e08451c..b68734433 100644 --- a/domain/consensus/datastructures/blockheaderstore/blockheaderstore.go +++ b/domain/consensus/datastructures/blockheaderstore/blockheaderstore.go @@ -54,14 +54,8 @@ func (bhs *blockHeaderStore) initializeCount(dbContext model.DBReader) error { } // Stage stages the given block header for the given blockHash -func (bhs *blockHeaderStore) Stage(blockHash *externalapi.DomainHash, blockHeader *externalapi.DomainBlockHeader) error { - clone, err := bhs.cloneHeader(blockHeader) - if err != nil { - return err - } - - bhs.staging[*blockHash] = clone - return nil +func (bhs *blockHeaderStore) Stage(blockHash *externalapi.DomainHash, blockHeader *externalapi.DomainBlockHeader) { + bhs.staging[*blockHash] = blockHeader.Clone() } func (bhs *blockHeaderStore) IsStaged() bool { @@ -169,15 +163,6 @@ func (bhs *blockHeaderStore) deserializeHeader(headerBytes []byte) (*externalapi return serialization.DbBlockHeaderToDomainBlockHeader(dbBlockHeader) } -func (bhs *blockHeaderStore) cloneHeader(header *externalapi.DomainBlockHeader) (*externalapi.DomainBlockHeader, error) { - serialized, err := bhs.serializeHeader(header) - if err != nil { - return nil, err - } - - return bhs.deserializeHeader(serialized) -} - func (bhs *blockHeaderStore) Count() uint64 { return bhs.count + uint64(len(bhs.staging)) - uint64(len(bhs.toDelete)) } diff --git a/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go b/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go index 284b32162..8389628fd 100644 --- a/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go +++ b/domain/consensus/datastructures/blockrelationstore/blockrelationstore.go @@ -22,14 +22,8 @@ func New() model.BlockRelationStore { } } -func (brs *blockRelationStore) StageBlockRelation(blockHash *externalapi.DomainHash, blockRelations *model.BlockRelations) error { - clone, err := brs.clone(blockRelations) - if err != nil { - return err - } - - brs.staging[*blockHash] = clone - return nil +func (brs *blockRelationStore) StageBlockRelation(blockHash *externalapi.DomainHash, blockRelations *model.BlockRelations) { + brs.staging[*blockHash] = blockRelations.Clone() } func (brs *blockRelationStore) IsStaged() bool { @@ -94,12 +88,3 @@ func (brs *blockRelationStore) deserializeBlockRelations(blockRelationsBytes []b } return serialization.DbBlockRelationsToDomainBlockRelations(dbBlockRelations) } - -func (brs *blockRelationStore) clone(blockRelations *model.BlockRelations) (*model.BlockRelations, error) { - serialized, err := brs.serializeBlockRelations(blockRelations) - if err != nil { - return nil, err - } - - return brs.deserializeBlockRelations(serialized) -} diff --git a/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go b/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go index 4b62be445..4a9438129 100644 --- a/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go +++ b/domain/consensus/datastructures/blockstatusstore/blockstatusstore.go @@ -24,7 +24,7 @@ func New() model.BlockStatusStore { // Stage stages the given blockStatus for the given blockHash func (bss *blockStatusStore) Stage(blockHash *externalapi.DomainHash, blockStatus externalapi.BlockStatus) { - bss.staging[*blockHash] = blockStatus + bss.staging[*blockHash] = blockStatus.Clone() } func (bss *blockStatusStore) IsStaged() bool { diff --git a/domain/consensus/datastructures/blockstore/blockstore.go b/domain/consensus/datastructures/blockstore/blockstore.go index 6824e11d8..b87660677 100644 --- a/domain/consensus/datastructures/blockstore/blockstore.go +++ b/domain/consensus/datastructures/blockstore/blockstore.go @@ -54,14 +54,8 @@ func (bs *blockStore) initializeCount(dbContext model.DBReader) error { } // Stage stages the given block for the given blockHash -func (bs *blockStore) Stage(blockHash *externalapi.DomainHash, block *externalapi.DomainBlock) error { - clone, err := bs.clone(block) - if err != nil { - return err - } - - bs.staging[*blockHash] = clone - return nil +func (bs *blockStore) Stage(blockHash *externalapi.DomainHash, block *externalapi.DomainBlock) { + bs.staging[*blockHash] = block.Clone() } func (bs *blockStore) IsStaged() bool { @@ -169,15 +163,6 @@ func (bs *blockStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey { return bucket.Key(hash[:]) } -func (bs *blockStore) clone(block *externalapi.DomainBlock) (*externalapi.DomainBlock, error) { - serialized, err := bs.serializeBlock(block) - if err != nil { - return nil, err - } - - return bs.deserializeBlock(serialized) -} - func (bs *blockStore) Count() uint64 { return bs.count + uint64(len(bs.staging)) - uint64(len(bs.toDelete)) } diff --git a/domain/consensus/datastructures/consensusstatestore/tips.go b/domain/consensus/datastructures/consensusstatestore/tips.go index 60fab19e3..11d4cdebb 100644 --- a/domain/consensus/datastructures/consensusstatestore/tips.go +++ b/domain/consensus/datastructures/consensusstatestore/tips.go @@ -23,14 +23,8 @@ func (c *consensusStateStore) Tips(dbContext model.DBReader) ([]*externalapi.Dom return c.deserializeTips(tipsBytes) } -func (c *consensusStateStore) StageTips(tipHashes []*externalapi.DomainHash) error { - clone, err := c.cloneTips(tipHashes) - if err != nil { - return err - } - - c.stagedTips = clone - return nil +func (c *consensusStateStore) StageTips(tipHashes []*externalapi.DomainHash) { + c.stagedTips = externalapi.CloneHashes(tipHashes) } func (c *consensusStateStore) commitTips(dbTx model.DBTransaction) error { @@ -67,14 +61,3 @@ func (c *consensusStateStore) deserializeTips(tipsBytes []byte) ([]*externalapi. return serialization.DBTipsToTips(dbTips) } - -func (c *consensusStateStore) cloneTips(tips []*externalapi.DomainHash, -) ([]*externalapi.DomainHash, error) { - - serialized, err := c.serializeTips(tips) - if err != nil { - return nil, err - } - - return c.deserializeTips(serialized) -} diff --git a/domain/consensus/datastructures/consensusstatestore/utxo.go b/domain/consensus/datastructures/consensusstatestore/utxo.go index f51dc6b9d..a6d6fd8a8 100644 --- a/domain/consensus/datastructures/consensusstatestore/utxo.go +++ b/domain/consensus/datastructures/consensusstatestore/utxo.go @@ -23,7 +23,7 @@ func (c *consensusStateStore) StageVirtualUTXODiff(virtualUTXODiff *model.UTXODi return errors.New("cannot stage virtual UTXO diff while virtual UTXO set is staged") } - c.stagedVirtualUTXODiff = c.cloneUTXODiff(virtualUTXODiff) + c.stagedVirtualUTXODiff = virtualUTXODiff.Clone() return nil } @@ -227,35 +227,3 @@ func (c *consensusStateStore) StageVirtualUTXOSet(virtualUTXOSetIterator model.R return nil } - -func (c *consensusStateStore) cloneUTXODiff(diff *model.UTXODiff) *model.UTXODiff { - utxoDiffCopy := &model.UTXODiff{ - ToAdd: make(model.UTXOCollection, len(diff.ToAdd)), - ToRemove: make(model.UTXOCollection, len(diff.ToRemove)), - } - - for outpoint, entry := range diff.ToAdd { - scriptPublicKeyCopy := make([]byte, len(entry.ScriptPublicKey)) - copy(scriptPublicKeyCopy, entry.ScriptPublicKey) - utxoDiffCopy.ToAdd[outpoint] = cloneUTXOEntry(entry) - } - - for outpoint, entry := range diff.ToRemove { - scriptPublicKeyCopy := make([]byte, len(entry.ScriptPublicKey)) - copy(scriptPublicKeyCopy, entry.ScriptPublicKey) - utxoDiffCopy.ToRemove[outpoint] = cloneUTXOEntry(entry) - } - - return diff -} - -func cloneUTXOEntry(entry *externalapi.UTXOEntry) *externalapi.UTXOEntry { - scriptPublicKeyCopy := make([]byte, len(entry.ScriptPublicKey)) - copy(scriptPublicKeyCopy, entry.ScriptPublicKey) - return &externalapi.UTXOEntry{ - Amount: entry.Amount, - ScriptPublicKey: scriptPublicKeyCopy, - BlockBlueScore: entry.BlockBlueScore, - IsCoinbase: entry.IsCoinbase, - } -} diff --git a/domain/consensus/datastructures/consensusstatestore/virtual_diff_parents.go b/domain/consensus/datastructures/consensusstatestore/virtual_diff_parents.go index 006353479..eca0b09c0 100644 --- a/domain/consensus/datastructures/consensusstatestore/virtual_diff_parents.go +++ b/domain/consensus/datastructures/consensusstatestore/virtual_diff_parents.go @@ -23,14 +23,8 @@ func (c *consensusStateStore) VirtualDiffParents(dbContext model.DBReader) ([]*e return c.deserializeVirtualDiffParents(virtualDiffParentsBytes) } -func (c *consensusStateStore) StageVirtualDiffParents(tipHashes []*externalapi.DomainHash) error { - clone, err := c.cloneVirtualDiffParents(tipHashes) - if err != nil { - return err - } - - c.stagedVirtualDiffParents = clone - return nil +func (c *consensusStateStore) StageVirtualDiffParents(tipHashes []*externalapi.DomainHash) { + c.stagedVirtualDiffParents = externalapi.CloneHashes(tipHashes) } func (c *consensusStateStore) commitVirtualDiffParents(dbTx model.DBTransaction) error { @@ -67,14 +61,3 @@ func (c *consensusStateStore) deserializeVirtualDiffParents(virtualDiffParentsBy return serialization.DBVirtualDiffParentsToVirtualDiffParents(dbVirtualDiffParents) } - -func (c *consensusStateStore) cloneVirtualDiffParents(virtualDiffParents []*externalapi.DomainHash, -) ([]*externalapi.DomainHash, error) { - - serialized, err := c.serializeVirtualDiffParents(virtualDiffParents) - if err != nil { - return nil, err - } - - return c.deserializeVirtualDiffParents(serialized) -} diff --git a/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go b/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go index b84f213c7..16f88c4a6 100644 --- a/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go +++ b/domain/consensus/datastructures/ghostdagdatastore/ghostdagdatastore.go @@ -23,14 +23,8 @@ func New() model.GHOSTDAGDataStore { } // Stage stages the given blockGHOSTDAGData for the given blockHash -func (gds *ghostdagDataStore) Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData *model.BlockGHOSTDAGData) error { - clone, err := gds.clone(blockGHOSTDAGData) - if err != nil { - return err - } - - gds.staging[*blockHash] = clone - return nil +func (gds *ghostdagDataStore) Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData *model.BlockGHOSTDAGData) { + gds.staging[*blockHash] = blockGHOSTDAGData.Clone() } func (gds *ghostdagDataStore) IsStaged() bool { @@ -89,12 +83,3 @@ func (gds *ghostdagDataStore) deserializeBlockGHOSTDAGData(blockGHOSTDAGDataByte return serialization.DBBlockGHOSTDAGDataToBlockGHOSTDAGData(dbBlockGHOSTDAGData) } - -func (gds *ghostdagDataStore) clone(blockGHOSTDAGData *model.BlockGHOSTDAGData) (*model.BlockGHOSTDAGData, error) { - serialized, err := gds.serializeBlockGHOSTDAGData(blockGHOSTDAGData) - if err != nil { - return nil, err - } - - return gds.deserializeBlockGHOSTDAGData(serialized) -} diff --git a/domain/consensus/datastructures/headertipsstore/headertipsstore.go b/domain/consensus/datastructures/headertipsstore/headertipsstore.go index c404a4318..73da742c9 100644 --- a/domain/consensus/datastructures/headertipsstore/headertipsstore.go +++ b/domain/consensus/datastructures/headertipsstore/headertipsstore.go @@ -45,14 +45,8 @@ func (h *headerTipsStore) Commit(dbTx model.DBTransaction) error { return nil } -func (h *headerTipsStore) Stage(tips []*externalapi.DomainHash) error { - clone, err := h.clone(tips) - if err != nil { - return err - } - - h.staging = clone - return nil +func (h *headerTipsStore) Stage(tips []*externalapi.DomainHash) { + h.staging = externalapi.CloneHashes(tips) } func (h *headerTipsStore) IsStaged() bool { @@ -87,17 +81,6 @@ func (h *headerTipsStore) deserializeTips(tipsBytes []byte) ([]*externalapi.Doma return serialization.DBHeaderTipsToHeaderTips(dbTips) } -func (h *headerTipsStore) clone(tips []*externalapi.DomainHash, -) ([]*externalapi.DomainHash, error) { - - serialized, err := h.serializeTips(tips) - if err != nil { - return nil, err - } - - return h.deserializeTips(serialized) -} - // New instantiates a new HeaderTipsStore func New() model.HeaderTipsStore { return &headerTipsStore{} diff --git a/domain/consensus/datastructures/multisetstore/multisetstore.go b/domain/consensus/datastructures/multisetstore/multisetstore.go index 176a1bfef..7b00e8e0f 100644 --- a/domain/consensus/datastructures/multisetstore/multisetstore.go +++ b/domain/consensus/datastructures/multisetstore/multisetstore.go @@ -26,7 +26,7 @@ func New() model.MultisetStore { // Stage stages the given multiset for the given blockHash func (ms *multisetStore) Stage(blockHash *externalapi.DomainHash, multiset model.Multiset) { - ms.staging[*blockHash] = multiset + ms.staging[*blockHash] = multiset.Clone() } func (ms *multisetStore) IsStaged() bool { @@ -65,7 +65,7 @@ func (ms *multisetStore) Commit(dbTx model.DBTransaction) error { // Get gets the multiset associated with the given blockHash func (ms *multisetStore) Get(dbContext model.DBReader, blockHash *externalapi.DomainHash) (model.Multiset, error) { if multiset, ok := ms.staging[*blockHash]; ok { - return multiset.Clone() + return multiset.Clone(), nil } multisetBytes, err := dbContext.Get(ms.hashAsKey(blockHash)) diff --git a/domain/consensus/datastructures/pruningstore/pruningstore.go b/domain/consensus/datastructures/pruningstore/pruningstore.go index e72f531af..0554df00a 100644 --- a/domain/consensus/datastructures/pruningstore/pruningstore.go +++ b/domain/consensus/datastructures/pruningstore/pruningstore.go @@ -27,7 +27,7 @@ func New() model.PruningStore { // Stage stages the pruning state func (ps *pruningStore) Stage(pruningPointBlockHash *externalapi.DomainHash, pruningPointUTXOSetBytes []byte) { - ps.pruningPointStaging = &(*pruningPointBlockHash) + ps.pruningPointStaging = pruningPointBlockHash.Clone() ps.serializedUTXOSetStaging = pruningPointUTXOSetBytes } diff --git a/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go b/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go index e7f996cf8..5a8ff74d8 100644 --- a/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go +++ b/domain/consensus/datastructures/reachabilitydatastore/reachabilitydatastore.go @@ -27,14 +27,8 @@ func New() model.ReachabilityDataStore { // StageReachabilityData stages the given reachabilityData for the given blockHash func (rds *reachabilityDataStore) StageReachabilityData(blockHash *externalapi.DomainHash, - reachabilityData *model.ReachabilityData) error { - clone, err := rds.cloneReachabilityData(reachabilityData) - if err != nil { - return err - } - - rds.reachabilityDataStaging[*blockHash] = clone - return nil + reachabilityData *model.ReachabilityData) { + rds.reachabilityDataStaging[*blockHash] = reachabilityData.Clone() } // StageReachabilityReindexRoot stages the given reachabilityReindexRoot @@ -151,12 +145,3 @@ func (rds *reachabilityDataStore) deserializeReachabilityReindexRoot(reachabilit return serialization.DbHashToDomainHash(dbHash) } - -func (rds *reachabilityDataStore) cloneReachabilityData(reachabilityData *model.ReachabilityData) (*model.ReachabilityData, error) { - serialized, err := rds.serializeReachabilityData(reachabilityData) - if err != nil { - return nil, err - } - - return rds.deserializeReachabilityData(serialized) -} diff --git a/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go b/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go index 584424009..ce70ecce2 100644 --- a/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go +++ b/domain/consensus/datastructures/utxodiffstore/utxodiffstore.go @@ -29,18 +29,12 @@ func New() model.UTXODiffStore { } // Stage stages the given utxoDiff for the given blockHash -func (uds *utxoDiffStore) Stage(blockHash *externalapi.DomainHash, utxoDiff *model.UTXODiff, utxoDiffChild *externalapi.DomainHash) error { - utxoDiffClone, err := uds.cloneUTXODiff(utxoDiff) - if err != nil { - return err - } - uds.utxoDiffStaging[*blockHash] = utxoDiffClone +func (uds *utxoDiffStore) Stage(blockHash *externalapi.DomainHash, utxoDiff *model.UTXODiff, utxoDiffChild *externalapi.DomainHash) { + uds.utxoDiffStaging[*blockHash] = utxoDiff.Clone() if utxoDiffChild != nil { - utxoDiffChildClone := uds.cloneUTXODiffChild(utxoDiffChild) - uds.utxoDiffChildStaging[*blockHash] = utxoDiffChildClone + uds.utxoDiffChildStaging[*blockHash] = utxoDiffChild.Clone() } - return nil } func (uds *utxoDiffStore) IsStaged() bool { @@ -203,16 +197,3 @@ func (uds *utxoDiffStore) deserializeUTXODiffChild(utxoDiffChildBytes []byte) (* return serialization.DbHashToDomainHash(dbHash) } - -func (uds *utxoDiffStore) cloneUTXODiff(diff *model.UTXODiff) (*model.UTXODiff, error) { - serialized, err := uds.serializeUTXODiff(diff) - if err != nil { - return nil, err - } - - return uds.deserializeUTXODiff(serialized) -} - -func (uds *utxoDiffStore) cloneUTXODiffChild(diffChild *externalapi.DomainHash) *externalapi.DomainHash { - return diffChild.Clone() -} diff --git a/domain/consensus/model/acceptancedata.go b/domain/consensus/model/acceptancedata.go index 923e715ce..27f79c329 100644 --- a/domain/consensus/model/acceptancedata.go +++ b/domain/consensus/model/acceptancedata.go @@ -6,12 +6,39 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // It's ordered in the same way as the block merge set blues. type AcceptanceData []*BlockAcceptanceData +// Clone clones the AcceptanceData +func (ad AcceptanceData) Clone() AcceptanceData { + if ad == nil { + return nil + } + clone := make(AcceptanceData, len(ad)) + for i, blockAcceptanceData := range ad { + clone[i] = blockAcceptanceData.Clone() + } + + return clone +} + // BlockAcceptanceData stores all transactions in a block with an indication // if they were accepted or not by some other block type BlockAcceptanceData struct { TransactionAcceptanceData []*TransactionAcceptanceData } +// Clone returns a clone of BlockAcceptanceData +func (bad *BlockAcceptanceData) Clone() *BlockAcceptanceData { + if bad == nil { + return nil + } + + clone := &BlockAcceptanceData{TransactionAcceptanceData: make([]*TransactionAcceptanceData, len(bad.TransactionAcceptanceData))} + for i, acceptanceData := range bad.TransactionAcceptanceData { + clone.TransactionAcceptanceData[i] = acceptanceData.Clone() + } + + return clone +} + // TransactionAcceptanceData stores a transaction together with an indication // if it was accepted or not by some block type TransactionAcceptanceData struct { @@ -19,3 +46,16 @@ type TransactionAcceptanceData struct { Fee uint64 IsAccepted bool } + +// Clone returns a clone of TransactionAcceptanceData +func (tad *TransactionAcceptanceData) Clone() *TransactionAcceptanceData { + if tad == nil { + return nil + } + + return &TransactionAcceptanceData{ + Transaction: tad.Transaction.Clone(), + Fee: tad.Fee, + IsAccepted: tad.IsAccepted, + } +} diff --git a/domain/consensus/model/blockrelations.go b/domain/consensus/model/blockrelations.go index 5f326ef82..2ed402d46 100644 --- a/domain/consensus/model/blockrelations.go +++ b/domain/consensus/model/blockrelations.go @@ -7,3 +7,15 @@ type BlockRelations struct { Parents []*externalapi.DomainHash Children []*externalapi.DomainHash } + +// Clone returns a clone of BlockRelations +func (br *BlockRelations) Clone() *BlockRelations { + if br == nil { + return nil + } + + return &BlockRelations{ + Parents: externalapi.CloneHashes(br.Parents), + Children: externalapi.CloneHashes(br.Children), + } +} diff --git a/domain/consensus/model/externalapi/block.go b/domain/consensus/model/externalapi/block.go index 522465c47..da4990620 100644 --- a/domain/consensus/model/externalapi/block.go +++ b/domain/consensus/model/externalapi/block.go @@ -6,6 +6,23 @@ type DomainBlock struct { Transactions []*DomainTransaction } +// Clone returns a clone of DomainBlock +func (block *DomainBlock) Clone() *DomainBlock { + if block == nil { + return nil + } + + transactionClone := make([]*DomainTransaction, len(block.Transactions)) + for i, tx := range block.Transactions { + transactionClone[i] = tx.Clone() + } + + return &DomainBlock{ + Header: block.Header.Clone(), + Transactions: transactionClone, + } +} + // DomainBlockHeader represents the header part of a Kaspa block type DomainBlockHeader struct { Version int32 @@ -17,3 +34,21 @@ type DomainBlockHeader struct { Bits uint32 Nonce uint64 } + +// Clone returns a clone of DomainBlockHeader +func (header *DomainBlockHeader) Clone() *DomainBlockHeader { + if header == nil { + return nil + } + + return &DomainBlockHeader{ + Version: header.Version, + ParentHashes: CloneHashes(header.ParentHashes), + HashMerkleRoot: *header.HashMerkleRoot.Clone(), + AcceptedIDMerkleRoot: *header.AcceptedIDMerkleRoot.Clone(), + UTXOCommitment: *header.UTXOCommitment.Clone(), + TimeInMilliseconds: header.TimeInMilliseconds, + Bits: header.Bits, + Nonce: header.Nonce, + } +} diff --git a/domain/consensus/model/externalapi/blockstatus.go b/domain/consensus/model/externalapi/blockstatus.go index 50a9b848b..8fc15cf3f 100644 --- a/domain/consensus/model/externalapi/blockstatus.go +++ b/domain/consensus/model/externalapi/blockstatus.go @@ -3,6 +3,11 @@ package externalapi // BlockStatus represents the validation state of the block. type BlockStatus byte +// Clone returns a clone of BlockStatus +func (bs BlockStatus) Clone() BlockStatus { + return bs +} + const ( // StatusInvalid indicates that the block is invalid. StatusInvalid BlockStatus = iota diff --git a/domain/consensus/model/externalapi/hash.go b/domain/consensus/model/externalapi/hash.go index eb19869b6..40446d6d1 100644 --- a/domain/consensus/model/externalapi/hash.go +++ b/domain/consensus/model/externalapi/hash.go @@ -22,7 +22,18 @@ func (hash *DomainHash) Clone() *DomainHash { if hash == nil { return nil } - return &*hash + + hashClone := *hash + return &hashClone +} + +// CloneHashes returns a clone of the given hashes slice +func CloneHashes(hashes []*DomainHash) []*DomainHash { + clone := make([]*DomainHash, len(hashes)) + for i, hash := range hashes { + clone[i] = hash.Clone() + } + return clone } // DomainHashesToStrings returns a slice of strings representing the hashes in the given slice of hashes diff --git a/domain/consensus/model/externalapi/subnetworkid.go b/domain/consensus/model/externalapi/subnetworkid.go index 51f580841..8a948dff0 100644 --- a/domain/consensus/model/externalapi/subnetworkid.go +++ b/domain/consensus/model/externalapi/subnetworkid.go @@ -15,3 +15,13 @@ func (id DomainSubnetworkID) String() string { } return hex.EncodeToString(id[:]) } + +// Clone returns a clone of DomainSubnetworkID +func (id *DomainSubnetworkID) Clone() *DomainSubnetworkID { + if id == nil { + return nil + } + + idClone := *id + return &idClone +} diff --git a/domain/consensus/model/externalapi/transaction.go b/domain/consensus/model/externalapi/transaction.go index 63e4a10c3..32959ec6d 100644 --- a/domain/consensus/model/externalapi/transaction.go +++ b/domain/consensus/model/externalapi/transaction.go @@ -19,6 +19,39 @@ type DomainTransaction struct { Mass uint64 } +// Clone returns a clone of DomainTransaction +func (tx *DomainTransaction) Clone() *DomainTransaction { + if tx == nil { + return nil + } + + payloadClone := make([]byte, len(tx.Payload)) + copy(payloadClone, tx.Payload) + + inputsClone := make([]*DomainTransactionInput, len(tx.Inputs)) + for i, input := range tx.Inputs { + inputsClone[i] = input.Clone() + } + + outputsClone := make([]*DomainTransactionOutput, len(tx.Outputs)) + for i, output := range tx.Outputs { + outputsClone[i] = output.Clone() + } + + return &DomainTransaction{ + Version: tx.Version, + Inputs: inputsClone, + Outputs: outputsClone, + LockTime: tx.LockTime, + SubnetworkID: *tx.SubnetworkID.Clone(), + Gas: tx.Gas, + PayloadHash: *tx.PayloadHash.Clone(), + Payload: payloadClone, + Fee: tx.Fee, + Mass: tx.Mass, + } +} + // DomainTransactionInput represents a Kaspa transaction input type DomainTransactionInput struct { PreviousOutpoint DomainOutpoint @@ -28,12 +61,41 @@ type DomainTransactionInput struct { UTXOEntry *UTXOEntry } +// Clone returns a clone of DomainTransactionInput +func (input *DomainTransactionInput) Clone() *DomainTransactionInput { + if input == nil { + return nil + } + + signatureScriptClone := make([]byte, len(input.SignatureScript)) + copy(signatureScriptClone, input.SignatureScript) + + return &DomainTransactionInput{ + PreviousOutpoint: *input.PreviousOutpoint.Clone(), + SignatureScript: signatureScriptClone, + Sequence: input.Sequence, + UTXOEntry: input.UTXOEntry.Clone(), + } +} + // DomainOutpoint represents a Kaspa transaction outpoint type DomainOutpoint struct { TransactionID DomainTransactionID Index uint32 } +// Clone returns a clone of DomainOutpoint +func (op *DomainOutpoint) Clone() *DomainOutpoint { + if op == nil { + return nil + } + + return &DomainOutpoint{ + TransactionID: *op.TransactionID.Clone(), + Index: op.Index, + } +} + // String stringifies an outpoint. func (op DomainOutpoint) String() string { return fmt.Sprintf("(%s: %d)", op.TransactionID, op.Index) @@ -53,6 +115,21 @@ type DomainTransactionOutput struct { ScriptPublicKey []byte } +// Clone returns a clone of DomainTransactionOutput +func (output *DomainTransactionOutput) Clone() *DomainTransactionOutput { + if output == nil { + return nil + } + + scriptPublicKeyClone := make([]byte, len(output.ScriptPublicKey)) + copy(scriptPublicKeyClone, output.ScriptPublicKey) + + return &DomainTransactionOutput{ + Value: output.Value, + ScriptPublicKey: scriptPublicKeyClone, + } +} + // DomainTransactionID represents the ID of a Kaspa transaction type DomainTransactionID DomainHash @@ -60,3 +137,13 @@ type DomainTransactionID DomainHash func (id DomainTransactionID) String() string { return DomainHash(id).String() } + +// Clone returns a clone of DomainTransactionID +func (id *DomainTransactionID) Clone() *DomainTransactionID { + if id == nil { + return nil + } + + idClone := *id + return &idClone +} diff --git a/domain/consensus/model/externalapi/utxoentry.go b/domain/consensus/model/externalapi/utxoentry.go index 9aa98c310..69f5a4756 100644 --- a/domain/consensus/model/externalapi/utxoentry.go +++ b/domain/consensus/model/externalapi/utxoentry.go @@ -11,6 +11,23 @@ type UTXOEntry struct { IsCoinbase bool } +// Clone returns a clone of UTXOEntry +func (entry *UTXOEntry) Clone() *UTXOEntry { + if entry == nil { + return nil + } + + scriptPublicKeyClone := make([]byte, len(entry.ScriptPublicKey)) + copy(scriptPublicKeyClone, entry.ScriptPublicKey) + + return &UTXOEntry{ + Amount: entry.Amount, + ScriptPublicKey: scriptPublicKeyClone, + BlockBlueScore: entry.BlockBlueScore, + IsCoinbase: entry.IsCoinbase, + } +} + // NewUTXOEntry creates a new utxoEntry representing the given txOut func NewUTXOEntry(amount uint64, scriptPubKey []byte, isCoinbase bool, blockBlueScore uint64) *UTXOEntry { return &UTXOEntry{ diff --git a/domain/consensus/model/ghostdag.go b/domain/consensus/model/ghostdag.go index 335d634af..d649c34aa 100644 --- a/domain/consensus/model/ghostdag.go +++ b/domain/consensus/model/ghostdag.go @@ -11,5 +11,25 @@ type BlockGHOSTDAGData struct { BluesAnticoneSizes map[externalapi.DomainHash]KType } +// Clone returns a clone of BlockGHOSTDAGData +func (bgd *BlockGHOSTDAGData) Clone() *BlockGHOSTDAGData { + if bgd == nil { + return nil + } + + bluesAnticoneSizesClone := make(map[externalapi.DomainHash]KType, len(bgd.BluesAnticoneSizes)) + for hash, size := range bgd.BluesAnticoneSizes { + bluesAnticoneSizesClone[hash] = size + } + + return &BlockGHOSTDAGData{ + BlueScore: bgd.BlueScore, + SelectedParent: bgd.SelectedParent.Clone(), + MergeSetBlues: externalapi.CloneHashes(bgd.MergeSetBlues), + MergeSetReds: externalapi.CloneHashes(bgd.MergeSetReds), + BluesAnticoneSizes: bluesAnticoneSizesClone, + } +} + // KType defines the size of GHOSTDAG consensus algorithm K parameter. type KType byte diff --git a/domain/consensus/model/interface_datastructures_acceptancedatastore.go b/domain/consensus/model/interface_datastructures_acceptancedatastore.go index db656cd49..4d75e1225 100644 --- a/domain/consensus/model/interface_datastructures_acceptancedatastore.go +++ b/domain/consensus/model/interface_datastructures_acceptancedatastore.go @@ -5,7 +5,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // AcceptanceDataStore represents a store of AcceptanceData type AcceptanceDataStore interface { Store - Stage(blockHash *externalapi.DomainHash, acceptanceData AcceptanceData) error + Stage(blockHash *externalapi.DomainHash, acceptanceData AcceptanceData) IsStaged() bool Get(dbContext DBReader, blockHash *externalapi.DomainHash) (AcceptanceData, error) Delete(blockHash *externalapi.DomainHash) diff --git a/domain/consensus/model/interface_datastructures_blockheaderstore.go b/domain/consensus/model/interface_datastructures_blockheaderstore.go index e6d5be9b0..20edf9c08 100644 --- a/domain/consensus/model/interface_datastructures_blockheaderstore.go +++ b/domain/consensus/model/interface_datastructures_blockheaderstore.go @@ -5,7 +5,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // BlockHeaderStore represents a store of block headers type BlockHeaderStore interface { Store - Stage(blockHash *externalapi.DomainHash, blockHeader *externalapi.DomainBlockHeader) error + Stage(blockHash *externalapi.DomainHash, blockHeader *externalapi.DomainBlockHeader) IsStaged() bool BlockHeader(dbContext DBReader, blockHash *externalapi.DomainHash) (*externalapi.DomainBlockHeader, error) HasBlockHeader(dbContext DBReader, blockHash *externalapi.DomainHash) (bool, error) diff --git a/domain/consensus/model/interface_datastructures_blockrelationstore.go b/domain/consensus/model/interface_datastructures_blockrelationstore.go index e34cca75a..b4274c68e 100644 --- a/domain/consensus/model/interface_datastructures_blockrelationstore.go +++ b/domain/consensus/model/interface_datastructures_blockrelationstore.go @@ -5,7 +5,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // BlockRelationStore represents a store of BlockRelations type BlockRelationStore interface { Store - StageBlockRelation(blockHash *externalapi.DomainHash, blockRelations *BlockRelations) error + StageBlockRelation(blockHash *externalapi.DomainHash, blockRelations *BlockRelations) IsStaged() bool BlockRelation(dbContext DBReader, blockHash *externalapi.DomainHash) (*BlockRelations, error) Has(dbContext DBReader, blockHash *externalapi.DomainHash) (bool, error) diff --git a/domain/consensus/model/interface_datastructures_blockstore.go b/domain/consensus/model/interface_datastructures_blockstore.go index 0ebc8dc69..f2aadb566 100644 --- a/domain/consensus/model/interface_datastructures_blockstore.go +++ b/domain/consensus/model/interface_datastructures_blockstore.go @@ -5,7 +5,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // BlockStore represents a store of blocks type BlockStore interface { Store - Stage(blockHash *externalapi.DomainHash, block *externalapi.DomainBlock) error + Stage(blockHash *externalapi.DomainHash, block *externalapi.DomainBlock) IsStaged() bool Block(dbContext DBReader, blockHash *externalapi.DomainHash) (*externalapi.DomainBlock, error) HasBlock(dbContext DBReader, blockHash *externalapi.DomainHash) (bool, error) diff --git a/domain/consensus/model/interface_datastructures_consensusstatestore.go b/domain/consensus/model/interface_datastructures_consensusstatestore.go index 9be748079..022f8c547 100644 --- a/domain/consensus/model/interface_datastructures_consensusstatestore.go +++ b/domain/consensus/model/interface_datastructures_consensusstatestore.go @@ -13,9 +13,9 @@ type ConsensusStateStore interface { HasUTXOByOutpoint(dbContext DBReader, outpoint *externalapi.DomainOutpoint) (bool, error) VirtualUTXOSetIterator(dbContext DBReader) (ReadOnlyUTXOSetIterator, error) - StageVirtualDiffParents(virtualDiffParents []*externalapi.DomainHash) error + StageVirtualDiffParents(virtualDiffParents []*externalapi.DomainHash) VirtualDiffParents(dbContext DBReader) ([]*externalapi.DomainHash, error) - StageTips(tipHashes []*externalapi.DomainHash) error + StageTips(tipHashes []*externalapi.DomainHash) Tips(dbContext DBReader) ([]*externalapi.DomainHash, error) } diff --git a/domain/consensus/model/interface_datastructures_ghostdagdatastore.go b/domain/consensus/model/interface_datastructures_ghostdagdatastore.go index 7d8f4c041..13522feb1 100644 --- a/domain/consensus/model/interface_datastructures_ghostdagdatastore.go +++ b/domain/consensus/model/interface_datastructures_ghostdagdatastore.go @@ -5,7 +5,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // GHOSTDAGDataStore represents a store of BlockGHOSTDAGData type GHOSTDAGDataStore interface { Store - Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData *BlockGHOSTDAGData) error + Stage(blockHash *externalapi.DomainHash, blockGHOSTDAGData *BlockGHOSTDAGData) IsStaged() bool Get(dbContext DBReader, blockHash *externalapi.DomainHash) (*BlockGHOSTDAGData, error) } diff --git a/domain/consensus/model/interface_datastructures_headertipsstore.go b/domain/consensus/model/interface_datastructures_headertipsstore.go index b285599b6..df3bc6dca 100644 --- a/domain/consensus/model/interface_datastructures_headertipsstore.go +++ b/domain/consensus/model/interface_datastructures_headertipsstore.go @@ -5,7 +5,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // HeaderTipsStore represents a store of the header tips type HeaderTipsStore interface { Store - Stage(tips []*externalapi.DomainHash) error + Stage(tips []*externalapi.DomainHash) IsStaged() bool Tips(dbContext DBReader) ([]*externalapi.DomainHash, error) HasTips(dbContext DBReader) (bool, error) diff --git a/domain/consensus/model/interface_datastructures_reachabilitydatastore.go b/domain/consensus/model/interface_datastructures_reachabilitydatastore.go index 5d82c1384..e1225b19e 100644 --- a/domain/consensus/model/interface_datastructures_reachabilitydatastore.go +++ b/domain/consensus/model/interface_datastructures_reachabilitydatastore.go @@ -5,7 +5,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // ReachabilityDataStore represents a store of ReachabilityData type ReachabilityDataStore interface { Store - StageReachabilityData(blockHash *externalapi.DomainHash, reachabilityData *ReachabilityData) error + StageReachabilityData(blockHash *externalapi.DomainHash, reachabilityData *ReachabilityData) StageReachabilityReindexRoot(reachabilityReindexRoot *externalapi.DomainHash) IsAnythingStaged() bool ReachabilityData(dbContext DBReader, blockHash *externalapi.DomainHash) (*ReachabilityData, error) diff --git a/domain/consensus/model/interface_datastructures_utxodiffstore.go b/domain/consensus/model/interface_datastructures_utxodiffstore.go index 4388d4b32..4d7ab3101 100644 --- a/domain/consensus/model/interface_datastructures_utxodiffstore.go +++ b/domain/consensus/model/interface_datastructures_utxodiffstore.go @@ -5,7 +5,7 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" // UTXODiffStore represents a store of UTXODiffs type UTXODiffStore interface { Store - Stage(blockHash *externalapi.DomainHash, utxoDiff *UTXODiff, utxoDiffChild *externalapi.DomainHash) error + Stage(blockHash *externalapi.DomainHash, utxoDiff *UTXODiff, utxoDiffChild *externalapi.DomainHash) IsStaged() bool UTXODiff(dbContext DBReader, blockHash *externalapi.DomainHash) (*UTXODiff, error) UTXODiffChild(dbContext DBReader, blockHash *externalapi.DomainHash) (*externalapi.DomainHash, error) diff --git a/domain/consensus/model/multiset.go b/domain/consensus/model/multiset.go index bf176d0b4..086c42e0e 100644 --- a/domain/consensus/model/multiset.go +++ b/domain/consensus/model/multiset.go @@ -8,5 +8,5 @@ type Multiset interface { Remove(data []byte) Hash() *externalapi.DomainHash Serialize() []byte - Clone() (Multiset, error) + Clone() Multiset } diff --git a/domain/consensus/model/reachabilitydata.go b/domain/consensus/model/reachabilitydata.go index 0efb7b62a..93ffd3b20 100644 --- a/domain/consensus/model/reachabilitydata.go +++ b/domain/consensus/model/reachabilitydata.go @@ -12,6 +12,18 @@ type ReachabilityData struct { FutureCoveringSet FutureCoveringTreeNodeSet } +// Clone returns a clone of ReachabilityData +func (rd *ReachabilityData) Clone() *ReachabilityData { + if rd == nil { + return nil + } + + return &ReachabilityData{ + TreeNode: rd.TreeNode.Clone(), + FutureCoveringSet: externalapi.CloneHashes(rd.FutureCoveringSet), + } +} + // ReachabilityTreeNode represents a node in the reachability tree // of some DAG block. It mainly provides the ability to query *tree* // reachability with O(1) query time. It does so by managing an @@ -36,6 +48,19 @@ type ReachabilityTreeNode struct { Interval *ReachabilityInterval } +// Clone returns a clone of ReachabilityTreeNode +func (rtn *ReachabilityTreeNode) Clone() *ReachabilityTreeNode { + if rtn == nil { + return nil + } + + return &ReachabilityTreeNode{ + Children: externalapi.CloneHashes(rtn.Children), + Parent: rtn.Parent.Clone(), + Interval: rtn.Interval.Clone(), + } +} + // ReachabilityInterval represents an interval to be used within the // tree reachability algorithm. See ReachabilityTreeNode for further // details. @@ -44,6 +69,18 @@ type ReachabilityInterval struct { End uint64 } +// Clone returns a clone of ReachabilityInterval +func (ri *ReachabilityInterval) Clone() *ReachabilityInterval { + if ri == nil { + return nil + } + + return &ReachabilityInterval{ + Start: ri.Start, + End: ri.End, + } +} + func (ri *ReachabilityInterval) String() string { return fmt.Sprintf("[%d,%d]", ri.Start, ri.End) } diff --git a/domain/consensus/model/utxodiff.go b/domain/consensus/model/utxodiff.go index 00f619783..7448f1c0f 100644 --- a/domain/consensus/model/utxodiff.go +++ b/domain/consensus/model/utxodiff.go @@ -11,18 +11,18 @@ import ( // UTXOCollection represents a set of UTXOs indexed by their outpoints type UTXOCollection map[externalapi.DomainOutpoint]*externalapi.UTXOEntry -// UTXODiff represents a diff between two UTXO Sets. -type UTXODiff struct { - ToAdd UTXOCollection - ToRemove UTXOCollection -} - -// NewUTXODiff instantiates an empty UTXODiff -func NewUTXODiff() *UTXODiff { - return &UTXODiff{ - ToAdd: UTXOCollection{}, - ToRemove: UTXOCollection{}, +// Clone returns a clone of UTXOCollection +func (uc UTXOCollection) Clone() UTXOCollection { + if uc == nil { + return nil } + + clone := make(UTXOCollection, len(uc)) + for outpoint, entry := range uc { + clone[outpoint] = entry.Clone() + } + + return clone } func (uc UTXOCollection) String() string { @@ -41,6 +41,32 @@ func (uc UTXOCollection) String() string { return fmt.Sprintf("[ %s ]", strings.Join(utxoStrings, ", ")) } +// UTXODiff represents a diff between two UTXO Sets. +type UTXODiff struct { + ToAdd UTXOCollection + ToRemove UTXOCollection +} + +// Clone returns a clone of UTXODiff +func (d *UTXODiff) Clone() *UTXODiff { + if d == nil { + return nil + } + + return &UTXODiff{ + ToAdd: d.ToAdd.Clone(), + ToRemove: d.ToRemove.Clone(), + } +} + func (d UTXODiff) String() string { return fmt.Sprintf("ToAdd: %s; ToRemove: %s", d.ToAdd, d.ToRemove) } + +// NewUTXODiff instantiates an empty UTXODiff +func NewUTXODiff() *UTXODiff { + return &UTXODiff{ + ToAdd: UTXOCollection{}, + ToRemove: UTXOCollection{}, + } +} diff --git a/domain/consensus/processes/blockbuilder/test_block_builder.go b/domain/consensus/processes/blockbuilder/test_block_builder.go index 1521a1079..667dd23e9 100644 --- a/domain/consensus/processes/blockbuilder/test_block_builder.go +++ b/domain/consensus/processes/blockbuilder/test_block_builder.go @@ -83,12 +83,9 @@ func (bb *testBlockBuilder) buildBlockWithParents( } } - err := bb.blockRelationStore.StageBlockRelation(tempBlockHash, &model.BlockRelations{Parents: parentHashes}) - if err != nil { - return nil, err - } + bb.blockRelationStore.StageBlockRelation(tempBlockHash, &model.BlockRelations{Parents: parentHashes}) - err = bb.ghostdagManager.GHOSTDAG(tempBlockHash) + err := bb.ghostdagManager.GHOSTDAG(tempBlockHash) if err != nil { return nil, err } @@ -111,10 +108,8 @@ func (bb *testBlockBuilder) buildBlockWithParents( if err != nil { return nil, err } - err = bb.acceptanceDataStore.Stage(tempBlockHash, acceptanceData) - if err != nil { - return nil, err - } + + bb.acceptanceDataStore.Stage(tempBlockHash, acceptanceData) coinbase, err := bb.coinbaseManager.ExpectedCoinbaseTransaction(tempBlockHash, coinbaseData) if err != nil { diff --git a/domain/consensus/processes/blockprocessor/validateandinsertblock.go b/domain/consensus/processes/blockprocessor/validateandinsertblock.go index d7c4c5c00..911a06e01 100644 --- a/domain/consensus/processes/blockprocessor/validateandinsertblock.go +++ b/domain/consensus/processes/blockprocessor/validateandinsertblock.go @@ -129,10 +129,7 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock) if err != nil { return err } - err = bp.headerTipsStore.Stage(tips) - if err != nil { - return err - } + bp.headerTipsStore.Stage(tips) } if syncInfo.State != externalapi.SyncStateMissingGenesis { @@ -216,10 +213,7 @@ func (bp *blockProcessor) validateBlock(block *externalapi.DomainBlock, mode *ex } if !hasHeader { - err = bp.blockHeaderStore.Stage(blockHash, block.Header) - if err != nil { - return err - } + bp.blockHeaderStore.Stage(blockHash, block.Header) } // If any validation until (included) proof-of-work fails, simply @@ -276,12 +270,9 @@ func (bp *blockProcessor) validatePostProofOfWork(block *externalapi.DomainBlock blockHash := consensusserialization.BlockHash(block) if mode.State != externalapi.SyncStateHeadersFirst { - err := bp.blockStore.Stage(blockHash, block) - if err != nil { - return err - } + bp.blockStore.Stage(blockHash, block) - err = bp.blockValidator.ValidateBodyInIsolation(blockHash) + err := bp.blockValidator.ValidateBodyInIsolation(blockHash) if err != nil { return err } diff --git a/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go b/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go index 29f2588a7..3fe1177a1 100644 --- a/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go +++ b/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go @@ -91,10 +91,7 @@ func TestCheckBlockSanity(t *testing.T) { t.Fatalf("Too few transactions in block, expect at least 3, got %v", len(exampleValidBlock.Transactions)) } - err = consensus.BlockStore().Stage(blockHash, &exampleValidBlock) - if err != nil { - t.Fatalf("Failed storing block: %v", err) - } + consensus.BlockStore().Stage(blockHash, &exampleValidBlock) err = consensus.BlockValidator().ValidateBodyInIsolation(blockHash) if err != nil { @@ -103,10 +100,7 @@ func TestCheckBlockSanity(t *testing.T) { // Test with block with wrong transactions sorting order blockHash = consensusserialization.BlockHash(&blockWithWrongTxOrder) - err = consensus.BlockStore().Stage(blockHash, &blockWithWrongTxOrder) - if err != nil { - t.Fatalf("Failed storing block: %v", err) - } + consensus.BlockStore().Stage(blockHash, &blockWithWrongTxOrder) err = consensus.BlockValidator().ValidateBodyInIsolation(blockHash) if !errors.Is(err, ruleerrors.ErrTransactionsNotSorted) { t.Errorf("CheckBlockSanity: Expected ErrTransactionsNotSorted error, instead got %v", err) @@ -115,10 +109,7 @@ func TestCheckBlockSanity(t *testing.T) { // Test a block with invalid parents order // We no longer require blocks to have ordered parents blockHash = consensusserialization.BlockHash(&unOrderedParentsBlock) - err = consensus.BlockStore().Stage(blockHash, &unOrderedParentsBlock) - if err != nil { - t.Fatalf("Failed storing block: %v", err) - } + consensus.BlockStore().Stage(blockHash, &unOrderedParentsBlock) err = consensus.BlockValidator().ValidateBodyInIsolation(blockHash) if err != nil { t.Errorf("CheckBlockSanity: Expected block to be be body in isolation valid, got error instead: %v", err) diff --git a/domain/consensus/processes/blockvalidator/block_header_in_context_test.go b/domain/consensus/processes/blockvalidator/block_header_in_context_test.go index 781a15e26..fab862ba2 100644 --- a/domain/consensus/processes/blockvalidator/block_header_in_context_test.go +++ b/domain/consensus/processes/blockvalidator/block_header_in_context_test.go @@ -38,13 +38,10 @@ func TestValidateMedianTime(t *testing.T) { pastMedianTime := func(parents ...*externalapi.DomainHash) int64 { var tempHash externalapi.DomainHash - err := tc.BlockRelationStore().StageBlockRelation(&tempHash, &model.BlockRelations{ + tc.BlockRelationStore().StageBlockRelation(&tempHash, &model.BlockRelations{ Parents: parents, Children: nil, }) - if err != nil { - t.Fatalf("StageBlockRelation: %+v", err) - } defer tc.BlockRelationStore().Discard() err = tc.GHOSTDAGManager().GHOSTDAG(&tempHash) diff --git a/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go b/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go index 6eca25669..1f60fed01 100644 --- a/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go +++ b/domain/consensus/processes/consensusstatemanager/add_block_to_virtual.go @@ -101,10 +101,7 @@ func (csm *consensusStateManager) addTip(newTipHash *externalapi.DomainHash) (ne } log.Tracef("The new tips are: %s", newTips) - err = csm.consensusStateStore.StageTips(newTips) - if err != nil { - return nil, err - } + csm.consensusStateStore.StageTips(newTips) log.Tracef("Staged the new tips %s", newTips) return newTips, nil diff --git a/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go b/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go index c2e2ffdba..1b33df786 100644 --- a/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go +++ b/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go @@ -127,7 +127,7 @@ func (csm *consensusStateManager) applyBlueBlocks(blockHash *externalapi.DomainH log.Tracef("The past median time for block %s is: %d", blockHash, selectedParentMedianTime) multiblockAcceptanceData := make(model.AcceptanceData, len(blueBlocks)) - accumulatedUTXODiff := utxoalgebra.DiffClone(selectedParentPastUTXODiff) + accumulatedUTXODiff := selectedParentPastUTXODiff.Clone() accumulatedMass := uint64(0) for i, blueBlock := range blueBlocks { diff --git a/domain/consensus/processes/consensusstatemanager/resolve_block_status.go b/domain/consensus/processes/consensusstatemanager/resolve_block_status.go index 57c45e4e7..eb6998f22 100644 --- a/domain/consensus/processes/consensusstatemanager/resolve_block_status.go +++ b/domain/consensus/processes/consensusstatemanager/resolve_block_status.go @@ -132,10 +132,7 @@ func (csm *consensusStateManager) resolveSingleBlockStatus(blockHash *externalap } log.Tracef("Staging the calculated acceptance data of block %s", blockHash) - err = csm.acceptanceDataStore.Stage(blockHash, acceptanceData) - if err != nil { - return 0, err - } + csm.acceptanceDataStore.Stage(blockHash, acceptanceData) block, err := csm.blockStore.Block(csm.databaseContext, blockHash) if err != nil { diff --git a/domain/consensus/processes/consensusstatemanager/set_pruning_utxo_set.go b/domain/consensus/processes/consensusstatemanager/set_pruning_utxo_set.go index 9f8f58913..83e37e6f4 100644 --- a/domain/consensus/processes/consensusstatemanager/set_pruning_utxo_set.go +++ b/domain/consensus/processes/consensusstatemanager/set_pruning_utxo_set.go @@ -67,10 +67,7 @@ func (csm *consensusStateManager) setPruningPointUTXOSet(serializedUTXOSet []byt log.Tracef("Header tip pruning point multiset validation passed") log.Tracef("Staging the parent hashes for the header tips pruning point as the DAG tips") - err = csm.consensusStateStore.StageTips(headerTipsPruningPointHeader.ParentHashes) - if err != nil { - return err - } + csm.consensusStateStore.StageTips(headerTipsPruningPointHeader.ParentHashes) log.Tracef("Setting the parent hashes for the header tips pruning point as the virtual parents") err = csm.dagTopologyManager.SetParents(model.VirtualBlockHash, headerTipsPruningPointHeader.ParentHashes) @@ -159,12 +156,10 @@ func (csm *consensusStateManager) HeaderTipsPruningPoint() (*externalapi.DomainH log.Tracef("The current header tips are: %s", headerTips) log.Tracef("Temporarily staging the parents of the virtual header to be the header tips: %s", headerTips) - err = csm.blockRelationStore.StageBlockRelation(virtualHeaderHash, &model.BlockRelations{ + csm.blockRelationStore.StageBlockRelation(virtualHeaderHash, &model.BlockRelations{ Parents: headerTips, }) - if err != nil { - return nil, err - } + defer csm.blockRelationStore.Discard() err = csm.ghostdagManager.GHOSTDAG(virtualHeaderHash) diff --git a/domain/consensus/processes/consensusstatemanager/update_virtual.go b/domain/consensus/processes/consensusstatemanager/update_virtual.go index 3a5a36382..001b675c8 100644 --- a/domain/consensus/processes/consensusstatemanager/update_virtual.go +++ b/domain/consensus/processes/consensusstatemanager/update_virtual.go @@ -35,10 +35,7 @@ func (csm *consensusStateManager) updateVirtual(newBlockHash *externalapi.Domain } log.Tracef("Staging new acceptance data for the virtual block") - err = csm.acceptanceDataStore.Stage(model.VirtualBlockHash, virtualAcceptanceData) - if err != nil { - return err - } + csm.acceptanceDataStore.Stage(model.VirtualBlockHash, virtualAcceptanceData) log.Tracef("Staging new multiset for the virtual block") csm.multisetStore.Stage(model.VirtualBlockHash, virtualMultiset) diff --git a/domain/consensus/processes/consensusstatemanager/utxo_diffs.go b/domain/consensus/processes/consensusstatemanager/utxo_diffs.go index 385f577ab..1f55fb333 100644 --- a/domain/consensus/processes/consensusstatemanager/utxo_diffs.go +++ b/domain/consensus/processes/consensusstatemanager/utxo_diffs.go @@ -13,10 +13,7 @@ func (csm *consensusStateManager) stageDiff(blockHash *externalapi.DomainHash, defer log.Tracef("stageDiff end for block %s", blockHash) log.Tracef("Staging block %s as the diff child of %s", utxoDiffChild, blockHash) - err := csm.utxoDiffStore.Stage(blockHash, utxoDiff, utxoDiffChild) - if err != nil { - return err - } + csm.utxoDiffStore.Stage(blockHash, utxoDiff, utxoDiffChild) if utxoDiffChild == nil { log.Tracef("Adding block %s to the virtual diff parents", blockHash) @@ -55,7 +52,8 @@ func (csm *consensusStateManager) addToVirtualDiffParents(blockHash *externalapi newVirtualDiffParents := append([]*externalapi.DomainHash{blockHash}, oldVirtualDiffParents...) log.Tracef("Staging virtual diff parents after adding %s to it", blockHash) - return csm.consensusStateStore.StageVirtualDiffParents(newVirtualDiffParents) + csm.consensusStateStore.StageVirtualDiffParents(newVirtualDiffParents) + return nil } func (csm *consensusStateManager) removeFromVirtualDiffParents(blockHash *externalapi.DomainHash) error { @@ -80,5 +78,6 @@ func (csm *consensusStateManager) removeFromVirtualDiffParents(blockHash *extern } log.Tracef("Staging virtual diff parents after removing %s from it", blockHash) - return csm.consensusStateStore.StageVirtualDiffParents(newVirtualDiffParents) + csm.consensusStateStore.StageVirtualDiffParents(newVirtualDiffParents) + return nil } diff --git a/domain/consensus/processes/consensusstatemanager/utxoalgebra/collection_helpers.go b/domain/consensus/processes/consensusstatemanager/utxoalgebra/collection_helpers.go index 78624d3bc..148ea9269 100644 --- a/domain/consensus/processes/consensusstatemanager/utxoalgebra/collection_helpers.go +++ b/domain/consensus/processes/consensusstatemanager/utxoalgebra/collection_helpers.go @@ -48,13 +48,3 @@ func collectionContainsWithBlueScore(collection model.UTXOCollection, outpoint * entry, ok := CollectionGet(collection, outpoint) return ok && entry.BlockBlueScore == blueScore } - -// clone returns a clone of this collection -func collectionClone(collection model.UTXOCollection) model.UTXOCollection { - clone := make(model.UTXOCollection, len(collection)) - for outpoint, entry := range collection { - collectionAdd(clone, &outpoint, entry) - } - - return clone -} diff --git a/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_algebra.go b/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_algebra.go index 58bb13f81..9bcaf3f01 100644 --- a/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_algebra.go +++ b/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_algebra.go @@ -242,7 +242,7 @@ func WithDiffInPlace(this *model.UTXODiff, diff *model.UTXODiff) error { // WithDiff applies provided diff to this diff, creating a new utxoDiff, that would be the result if // first d, and than diff were applied to some base func WithDiff(this *model.UTXODiff, diff *model.UTXODiff) (*model.UTXODiff, error) { - clone := DiffClone(this) + clone := this.Clone() err := WithDiffInPlace(clone, diff) if err != nil { diff --git a/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_algebra_test.go b/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_algebra_test.go index 43c1a954f..e42e9514e 100644 --- a/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_algebra_test.go +++ b/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_algebra_test.go @@ -58,7 +58,7 @@ func TestUTXOCollection(t *testing.T) { } // Test model.UTXOCollection cloning - collectionClone := collectionClone(test.collection) + collectionClone := test.collection.Clone() if reflect.ValueOf(collectionClone).Pointer() == reflect.ValueOf(test.collection).Pointer() { t.Errorf("collection is reference-equal to its clone in test \"%s\". ", test.name) } @@ -95,7 +95,7 @@ func TestUTXODiff(t *testing.T) { } // Test utxoDiff cloning - clonedDiff := DiffClone(diff) + clonedDiff := diff.Clone() if clonedDiff == diff { t.Errorf("cloned diff is reference-equal to the original") } @@ -576,7 +576,7 @@ func TestUTXODiffRules(t *testing.T) { } // Repeat WithDiff check test.this time using withDiffInPlace - thisClone := DiffClone(test.this) + thisClone := test.this.Clone() err = WithDiffInPlace(thisClone, test.other) // Test whether withDiffInPlace returned an error diff --git a/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_helpers.go b/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_helpers.go index fc7b5bd05..2eb45829d 100644 --- a/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_helpers.go +++ b/domain/consensus/processes/consensusstatemanager/utxoalgebra/diff_helpers.go @@ -12,15 +12,6 @@ import ( "github.com/pkg/errors" ) -// DiffClone returns a new UTXODiff which is identical to the given diff -func DiffClone(diff *model.UTXODiff) *model.UTXODiff { - clone := &model.UTXODiff{ - ToAdd: collectionClone(diff.ToAdd), - ToRemove: collectionClone(diff.ToRemove), - } - return clone -} - // DiffAddTransaction modifies the provided utxoDiff with provided transaction. func DiffAddTransaction(utxoDiff *model.UTXODiff, transaction *externalapi.DomainTransaction, blockBlueScore uint64) error { for _, input := range transaction.Inputs { diff --git a/domain/consensus/processes/dagtopologymanager/dagtopologymanager.go b/domain/consensus/processes/dagtopologymanager/dagtopologymanager.go index cc1a30519..1c430c8af 100644 --- a/domain/consensus/processes/dagtopologymanager/dagtopologymanager.go +++ b/domain/consensus/processes/dagtopologymanager/dagtopologymanager.go @@ -127,10 +127,7 @@ func (dtm *dagTopologyManager) SetParents(blockHash *externalapi.DomainHash, par for i, parentChild := range parentRelations.Children { if *parentChild == *blockHash { parentRelations.Children = append(parentRelations.Children[:i], parentRelations.Children[i+1:]...) - err = dtm.blockRelationStore.StageBlockRelation(currentParent, parentRelations) - if err != nil { - return err - } + dtm.blockRelationStore.StageBlockRelation(currentParent, parentRelations) break } @@ -153,21 +150,15 @@ func (dtm *dagTopologyManager) SetParents(blockHash *externalapi.DomainHash, par } if !isBlockAlreadyInChildren { parentRelations.Children = append(parentRelations.Children, blockHash) - err = dtm.blockRelationStore.StageBlockRelation(parent, parentRelations) - if err != nil { - return err - } + dtm.blockRelationStore.StageBlockRelation(parent, parentRelations) } } // Finally - create the relations for the block itself - err = dtm.blockRelationStore.StageBlockRelation(blockHash, &model.BlockRelations{ + dtm.blockRelationStore.StageBlockRelation(blockHash, &model.BlockRelations{ Parents: parentHashes, Children: []*externalapi.DomainHash{}, }) - if err != nil { - return err - } return nil } diff --git a/domain/consensus/processes/ghostdagmanager/ghostdag.go b/domain/consensus/processes/ghostdagmanager/ghostdag.go index 230377761..c510959a5 100644 --- a/domain/consensus/processes/ghostdagmanager/ghostdag.go +++ b/domain/consensus/processes/ghostdagmanager/ghostdag.go @@ -82,10 +82,7 @@ func (gm *ghostdagManager) GHOSTDAG(blockHash *externalapi.DomainHash) error { newBlockData.BlueScore = 0 } - err = gm.ghostdagDataStore.Stage(blockHash, newBlockData) - if err != nil { - return err - } + gm.ghostdagDataStore.Stage(blockHash, newBlockData) return nil } diff --git a/domain/consensus/processes/headertipsmanager/headertipsmanager.go b/domain/consensus/processes/headertipsmanager/headertipsmanager.go index 96ba6544d..5ad81bdbf 100644 --- a/domain/consensus/processes/headertipsmanager/headertipsmanager.go +++ b/domain/consensus/processes/headertipsmanager/headertipsmanager.go @@ -53,10 +53,7 @@ func (h headerTipsManager) AddHeaderTip(hash *externalapi.DomainHash) error { } newTips = append(newTips, hash) - err = h.headerTipsStore.Stage(newTips) - if err != nil { - return err - } + h.headerTipsStore.Stage(newTips) return nil } diff --git a/domain/consensus/processes/reachabilitymanager/reachability_test.go b/domain/consensus/processes/reachabilitymanager/reachability_test.go index 6b473d101..448ebb031 100644 --- a/domain/consensus/processes/reachabilitymanager/reachability_test.go +++ b/domain/consensus/processes/reachabilitymanager/reachability_test.go @@ -23,10 +23,9 @@ func (r *reachabilityDataStoreMock) Commit(_ model.DBTransaction) error { panic("implement me") } -func (r *reachabilityDataStoreMock) StageReachabilityData(blockHash *externalapi.DomainHash, reachabilityData *model.ReachabilityData) error { +func (r *reachabilityDataStoreMock) StageReachabilityData(blockHash *externalapi.DomainHash, reachabilityData *model.ReachabilityData) { r.reachabilityDataStaging[*blockHash] = reachabilityData r.recorder[*blockHash] = struct{}{} - return nil } func (r *reachabilityDataStoreMock) StageReachabilityReindexRoot(reachabilityReindexRoot *externalapi.DomainHash) { diff --git a/domain/consensus/processes/reachabilitymanager/stage.go b/domain/consensus/processes/reachabilitymanager/stage.go index 563b42c57..0c38d61d8 100644 --- a/domain/consensus/processes/reachabilitymanager/stage.go +++ b/domain/consensus/processes/reachabilitymanager/stage.go @@ -5,8 +5,8 @@ import ( "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" ) -func (rt *reachabilityManager) stageData(blockHash *externalapi.DomainHash, data *model.ReachabilityData) error { - return rt.reachabilityDataStore.StageReachabilityData(blockHash, data) +func (rt *reachabilityManager) stageData(blockHash *externalapi.DomainHash, data *model.ReachabilityData) { + rt.reachabilityDataStore.StageReachabilityData(blockHash, data) } func (rt *reachabilityManager) stageFutureCoveringSet(blockHash *externalapi.DomainHash, set model.FutureCoveringTreeNodeSet) error { @@ -16,7 +16,8 @@ func (rt *reachabilityManager) stageFutureCoveringSet(blockHash *externalapi.Dom } data.FutureCoveringSet = set - return rt.reachabilityDataStore.StageReachabilityData(blockHash, data) + rt.reachabilityDataStore.StageReachabilityData(blockHash, data) + return nil } func (rt *reachabilityManager) stageTreeNode(blockHash *externalapi.DomainHash, node *model.ReachabilityTreeNode) error { @@ -26,7 +27,8 @@ func (rt *reachabilityManager) stageTreeNode(blockHash *externalapi.DomainHash, } data.TreeNode = node - return rt.reachabilityDataStore.StageReachabilityData(blockHash, data) + rt.reachabilityDataStore.StageReachabilityData(blockHash, data) + return nil } func (rt *reachabilityManager) stageReindexRoot(blockHash *externalapi.DomainHash) { diff --git a/domain/consensus/utils/multiset/multiset.go b/domain/consensus/utils/multiset/multiset.go index cea53eee0..efda18f91 100644 --- a/domain/consensus/utils/multiset/multiset.go +++ b/domain/consensus/utils/multiset/multiset.go @@ -34,8 +34,9 @@ func (m multiset) Serialize() []byte { return m.ms.Serialize()[:] } -func (m multiset) Clone() (model.Multiset, error) { - return FromBytes(m.Serialize()) +func (m multiset) Clone() model.Multiset { + msClone := *m.ms + return &multiset{ms: &msClone} } // FromBytes deserializes the given bytes slice and returns a multiset.