From f7fcffe6aaf4fd5c7b839ad5d5e3ac0c0bcca8a7 Mon Sep 17 00:00:00 2001 From: D-Stacks Date: Tue, 13 Sep 2022 22:25:50 +0200 Subject: [PATCH] save changes --- domain/consensus/consensus.go | 16 ++ .../consensus/model/externalapi/consensus.go | 1 + domain/txindex/model.go | 6 + domain/txindex/store.go | 29 ++++ domain/txindex/txindex.go | 154 +++++++++++++++++- 5 files changed, 204 insertions(+), 2 deletions(-) diff --git a/domain/consensus/consensus.go b/domain/consensus/consensus.go index 5ed266ce1..afbe727c0 100644 --- a/domain/consensus/consensus.go +++ b/domain/consensus/consensus.go @@ -395,6 +395,22 @@ func (s *consensus) GetBlock(blockHash *externalapi.DomainHash) (*externalapi.Do return block, nil } +func (s *consensus) GetBlocks(blockHashes []*externalapi.DomainHash) ([]*externalapi.DomainBlock, error) { + s.lock.Lock() + defer s.lock.Unlock() + + stagingArea := model.NewStagingArea() + + blocks, err := s.blockStore.Blocks(s.databaseContext, stagingArea, blockHashes) + if err != nil { + if errors.Is(err, database.ErrNotFound) { + return nil, errors.Wrapf(err, "Quried block %s does not exist") + } + return nil, err + } + return blocks, nil +} + func (s *consensus) GetBlockEvenIfHeaderOnly(blockHash *externalapi.DomainHash) (*externalapi.DomainBlock, error) { s.lock.Lock() defer s.lock.Unlock() diff --git a/domain/consensus/model/externalapi/consensus.go b/domain/consensus/model/externalapi/consensus.go index d7aadc203..7debd6f42 100644 --- a/domain/consensus/model/externalapi/consensus.go +++ b/domain/consensus/model/externalapi/consensus.go @@ -14,6 +14,7 @@ type Consensus interface { ApplyPruningPointProof(pruningPointProof *PruningPointProof) error GetBlock(blockHash *DomainHash) (*DomainBlock, error) + GetBlocks(blockHashes []*DomainHash) (*DomainBlock, error) GetBlockEvenIfHeaderOnly(blockHash *DomainHash) (*DomainBlock, error) GetBlockHeader(blockHash *DomainHash) (BlockHeader, error) GetBlockInfo(blockHash *DomainHash) (*BlockInfo, error) diff --git a/domain/txindex/model.go b/domain/txindex/model.go index f662b2374..ca0dc5c36 100644 --- a/domain/txindex/model.go +++ b/domain/txindex/model.go @@ -13,6 +13,12 @@ type TXAcceptanceChange struct { Removed map[externalapi.DomainTransactionID]*externalapi.DomainHash } +//TxIDsToBlocks is a map of TxIDs to corrospnding blockHashes +type TxIDsToBlockHashes map[*externalapi.DomainTransactionID]*externalapi.DomainHash + +//TxIDsToBlocks is a map of TxIDs to corrospnding blocks +type TxIDsToBlocks map[*externalapi.DomainTransactionID]*externalapi.DomainBlock + // ConvertDomainHashToString converts the given DomainHash to a string func ConvertDomainHashToString(blockHash *externalapi.DomainHash) string { return hex.EncodeToString(blockHash.ByteSlice()) diff --git a/domain/txindex/store.go b/domain/txindex/store.go index 269a812ae..61b7f66ec 100644 --- a/domain/txindex/store.go +++ b/domain/txindex/store.go @@ -231,3 +231,32 @@ func (tis *txIndexStore) getTxAcceptingBlockHash(txID *externalapi.DomainTransac return acceptingBlockHash, true, nil } + +func (tis *txIndexStore) getTxAcceptingBlockHashes(txIDs []*externalapi.DomainTransactionID) (acceptingBlockHashes TxIDsToBlockHashes, found bool, err error) { + + if tis.isAnythingStaged() { + return nil, false, errors.Errorf("cannot get TX accepting Block hash while staging isn't empty") + } + + keys := make([]*database.Key, len(txIDs)) + + acceptingBlockHashes = make(TxIDsToBlockHashes) + + for i, key := range keys { + key = tis.convertTxIDToKey(txAcceptedIndexBucket, *txIDs[i]) + serializedAcceptingBlockHash, err := tis.database.Get(key) + if err != nil { + if database.IsNotFoundError(err) { + return nil, false, nil + } + return nil, false, err + } + acceptingBlockHash, err := externalapi.NewDomainHashFromByteSlice(serializedAcceptingBlockHash) + if err != nil { + return nil, false, err + } + acceptingBlockHashes[txIDs[i]] = acceptingBlockHash + } + + return acceptingBlockHashes, true, nil +} diff --git a/domain/txindex/txindex.go b/domain/txindex/txindex.go index 418215725..207506749 100644 --- a/domain/txindex/txindex.go +++ b/domain/txindex/txindex.go @@ -1,10 +1,13 @@ package txindex import ( + "errors" + "fmt" "sync" "github.com/kaspanet/kaspad/domain" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" + "github.com/kaspanet/kaspad/domain/consensus/processes/dagtraversalmanager" "github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing" "github.com/kaspanet/kaspad/infrastructure/db/database" "github.com/kaspanet/kaspad/infrastructure/logger" @@ -241,18 +244,165 @@ func (ti *TXIndex) removeTXIDs(selectedParentChainChanges *externalapi.SelectedC } // TXAcceptingBlockHash returns the accepting block hash for for the given txID -func (ti *TXIndex) TXAcceptingBlockHash(txID *externalapi.DomainTransactionID) (blockHash *externalapi.DomainHash, found bool, err error) { +func (ti *TXIndex) TXAcceptingBlockHash(txID *externalapi.DomainTransactionID) (acceptingBlockHash *externalapi.DomainHash, found bool, err error) { onEnd := logger.LogAndMeasureExecutionTime(log, "TXIndex.TXAcceptingBlockHash") defer onEnd() ti.mutex.Lock() defer ti.mutex.Unlock() + acceptingBlockHash, found, err = ti.store.getTxAcceptingBlockHash(txID) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + + return acceptingBlockHash, found, nil +} + +func (ti *TXIndex) TXAcceptingBlockHashes(txIDs []*externalapi.DomainTransactionID) (acceptingBlockHashes TxIDsToBlockHashes, found bool, err error) { + onEnd := logger.LogAndMeasureExecutionTime(log, "TXIndex.TXAcceptingBlockHash") + defer onEnd() + + ti.mutex.Lock() + defer ti.mutex.Unlock() + + acceptingBlockHashes, found, err = ti.store.getTxAcceptingBlockHashes(txIDs) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + + return acceptingBlockHashes, found, nil +} + + + +func (ti *TXIndex) TXAcceptingBlock(txID *externalapi.DomainTransactionID) (block *externalapi.DomainBlock, found bool, err error) { + onEnd := logger.LogAndMeasureExecutionTime(log, "TXIndex.TXAcceptingBlock") + defer onEnd() + + ti.mutex.Lock() + defer ti.mutex.Unlock() + acceptingBlockHash, found, err := ti.store.getTxAcceptingBlockHash(txID) if err != nil { return nil, false, err } - return acceptingBlockHash, found, nil + + acceptingBlock, err := ti.domain.Consensus().GetBlock(acceptingBlockHash) + if err != nil { + return nil, false, err + } + return acceptingBlock, true, nil +} + +func (ti *TXIndex) TXAcceptingBlocks(txIDs []*externalapi.DomainTransactionID) (acceptingBlocks TxIDsToBlocks, found bool, err error) { + onEnd := logger.LogAndMeasureExecutionTime(log, "TXIndex.TXAcceptingBlock") + defer onEnd() + + ti.mutex.Lock() + defer ti.mutex.Unlock() + + acceptingBlockHash, found, err := ti.store.getTxAcceptingBlockHashes(txIDs) + if err != nil { + return nil, false, err + } + + acceptingBlocks, err = ti.domain.Consensus().GetBlocks(acceptingBlockHash) + if err != nil { + return nil, false, err + } + return acceptingBlock, true, nil +} + + + +func (ti *TXIndex) GetTX(txID *externalapi.DomainTransactionID) (block *externalapi.DomainTransaction, found bool, err error) { + onEnd := logger.LogAndMeasureExecutionTime(log, "TXIndex.GetTX") + defer onEnd() + + ti.mutex.Lock() + defer ti.mutex.Unlock() + + acceptingBlockHash, found, err := ti.store.getTxAcceptingBlockHash(txID) + if err != nil { + return nil, false, err + } + + acceptingBlock, err := ti.domain.Consensus().GetBlock(acceptingBlockHash) + if err != nil { + return nil, false, err + } + + var transaction *externalapi.DomainTransaction + + for _, tx := range acceptingBlock.Transactions { + if consensushashing.TransactionID(tx).Equal(txID) { + transaction = tx + return transaction, true, nil + } + } + + + return nil, false, fmt.Errorf("Could not find transaction with ID %s in Txindex database", txID.String()) +} + +func (ti *TXIndex) GetTXConfirmations(txID *externalapi.DomainTransactionID) (BlockHashTxIDPair uint64, found bool, err error) { + onEnd := logger.LogAndMeasureExecutionTime(log, "TXIndex.GetTX") + defer onEnd() + + ti.mutex.Lock() + defer ti.mutex.Unlock() + + acceptingBlockHash, found, err := ti.store.getTxAcceptingBlockHash(txID) + if err != nil { + return 0, false, err + } + + acceptingBlockHeader, err := ti.domain.Consensus().GetBlockHeader(acceptingBlockHash) + if err != nil { + return 0, false, err + } + + virtualBlock, err := ti.domain.Consensus().GetVirtualInfo() + if err != nil { + return 0, false, err + } + + return virtualBlock.BlueScore - acceptingBlockHeader.BlueScore(), true, nil +} + +func (ti *TXIndex) TXIncludingBlockHash(txID *externalapi.DomainTransactionID) (includingBlockHash *externalapi.DomainHash, found bool, err error) { + onEnd := logger.LogAndMeasureExecutionTime(log, "TXIndex.TXAcceptingBlock") + defer onEnd() + + ti.mutex.Lock() + defer ti.mutex.Unlock() + + acceptingBlockHash, found, err := ti.store.getTxAcceptingBlockHash(txID) + if err != nil { + return nil, false, err + } + + acceptanceData, err := ti.domain.Consensus().GetBlockAcceptanceData(acceptingBlockHash) + if err != nil { + return nil, false, err + } + + for _, blockAcceptanceData := range acceptanceData { + for _, transactionAcceptanceData := range blockAcceptanceData.TransactionAcceptanceData { + if consensushashing.TransactionID(transactionAcceptanceData.Transaction).Equal(txID) { + return blockAcceptanceData.BlockHash, true, nil + } + } + } + + return nil, false, fmt.Errorf("Could not find including blockHash for transaction with ID %s in Txindex database", txID.String()) } //TO DO: Get Block from TxID