mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-05-24 15:56:42 +00:00

* [NOD-1575] Implement Clone and Equal for all model types * [NOD-1575] Add assertion for transaction ID equality * [NOD-1575] Use DomainTransaction.Equal to compare to expected coinbase transaction * [NOD-1575] Add TestDomainBlockHeader_Clone * [NOD-1575] Don't clone nil values * [NOD-1575] Add type assertions * [NOD-1575] Don't clone nil values * [NOD-1575] Add missing Equals * [NOD-1575] Add length checks * [NOD-1575] Update comment * [NOD-1575] Check length for TransactionAcceptanceData * [NOD-1575] Explicitly clone nils where needed * [NOD-1575] Clone tx id * [NOD-1575] Flip condition * Nod 1576 make coverage tests for equal clone inside model externalapi (#1177) * [NOD-1576] Make coverage tests for equal and clone inside model and externalapi * Some formatting and naming fixes * Made transactionToCompare type exported * Added some tests and made some changes to the tests code * No changes made * Some formatting and naming changes made * Made better test coverage for externalapi clone and equal functions * Changed expected result for two cases * Added equal and clone functions tests for ghostdag and utxodiff * Added tests * [NOD-1576] Implement reachabilitydata equal/clone unit tests * [NOD-1576] Full coverage of reachabilitydata equal/clone unit tests * Made changes and handling panic to transaction_equal_clone_test.go and formating of utxodiff_equal_clone_test.go * Added recoverForEqual2 for handling panic to transaction_equal_clone_test.go * [NOD-1576] Full coverage of transaction equal unit test * [NOD-1576] Add expects panic * [NOD-1576] Allow composites in go vet * [NOD-1576] Code review fixes (#1223) * [NOD-1576] Code review fixes * [NOD-1576] Code review fixes part 2 * [NOD-1576] Fix wrong name Co-authored-by: karim1king <karimkaspersky@yahoo.com> Co-authored-by: Ori Newman <orinewman1@gmail.com> Co-authored-by: Karim <karim1king@users.noreply.github.com> * Fix merge errors * Use Equal where possible * Use Equal where possible * Use Equal where possible Co-authored-by: andrey-hash <74914043+andrey-hash@users.noreply.github.com> Co-authored-by: karim1king <karimkaspersky@yahoo.com> Co-authored-by: Karim <karim1king@users.noreply.github.com>
120 lines
3.7 KiB
Go
120 lines
3.7 KiB
Go
package finalitymanager
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"github.com/kaspanet/kaspad/domain/consensus/model"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/infrastructure/db/database"
|
|
)
|
|
|
|
type finalityManager struct {
|
|
databaseContext model.DBReader
|
|
dagTopologyManager model.DAGTopologyManager
|
|
finalityStore model.FinalityStore
|
|
ghostdagDataStore model.GHOSTDAGDataStore
|
|
genesisHash *externalapi.DomainHash
|
|
finalityDepth uint64
|
|
}
|
|
|
|
// New instantiates a new FinalityManager
|
|
func New(databaseContext model.DBReader,
|
|
dagTopologyManager model.DAGTopologyManager,
|
|
finalityStore model.FinalityStore,
|
|
ghostdagDataStore model.GHOSTDAGDataStore,
|
|
genesisHash *externalapi.DomainHash,
|
|
finalityDepth uint64) model.FinalityManager {
|
|
|
|
return &finalityManager{
|
|
databaseContext: databaseContext,
|
|
genesisHash: genesisHash,
|
|
dagTopologyManager: dagTopologyManager,
|
|
finalityStore: finalityStore,
|
|
ghostdagDataStore: ghostdagDataStore,
|
|
finalityDepth: finalityDepth,
|
|
}
|
|
}
|
|
|
|
func (fm *finalityManager) VirtualFinalityPoint() (*externalapi.DomainHash, error) {
|
|
log.Tracef("virtualFinalityPoint start")
|
|
defer log.Tracef("virtualFinalityPoint end")
|
|
|
|
virtualFinalityPoint, err := fm.calculateFinalityPoint(model.VirtualBlockHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
log.Tracef("The current virtual finality block is: %s", virtualFinalityPoint)
|
|
|
|
return virtualFinalityPoint, nil
|
|
}
|
|
|
|
func (fm *finalityManager) FinalityPoint(blockHash *externalapi.DomainHash) (*externalapi.DomainHash, error) {
|
|
log.Tracef("FinalityPoint start")
|
|
defer log.Tracef("FinalityPoint end")
|
|
if blockHash.Equal(model.VirtualBlockHash) {
|
|
return fm.VirtualFinalityPoint()
|
|
}
|
|
finalityPoint, err := fm.finalityStore.FinalityPoint(fm.databaseContext, blockHash)
|
|
if err != nil {
|
|
log.Tracef("%s finality point not found in store - calculating", blockHash)
|
|
if errors.Is(err, database.ErrNotFound) {
|
|
return fm.calculateAndStageFinalityPoint(blockHash)
|
|
}
|
|
return nil, err
|
|
}
|
|
return finalityPoint, nil
|
|
}
|
|
|
|
func (fm *finalityManager) calculateAndStageFinalityPoint(blockHash *externalapi.DomainHash) (*externalapi.DomainHash, error) {
|
|
finalityPoint, err := fm.calculateFinalityPoint(blockHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fm.finalityStore.StageFinalityPoint(blockHash, finalityPoint)
|
|
return finalityPoint, nil
|
|
}
|
|
|
|
func (fm *finalityManager) calculateFinalityPoint(blockHash *externalapi.DomainHash) (*externalapi.DomainHash, error) {
|
|
log.Tracef("calculateFinalityPoint start")
|
|
defer log.Tracef("calculateFinalityPoint end")
|
|
ghostdagData, err := fm.ghostdagDataStore.Get(fm.databaseContext, blockHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if ghostdagData.BlueScore() < fm.finalityDepth {
|
|
log.Tracef("%s blue score lower then finality depth - returning genesis as finality point", blockHash)
|
|
return fm.genesisHash, nil
|
|
}
|
|
|
|
selectedParent := ghostdagData.SelectedParent()
|
|
if selectedParent.Equal(fm.genesisHash) {
|
|
return fm.genesisHash, nil
|
|
}
|
|
|
|
current, err := fm.finalityStore.FinalityPoint(fm.databaseContext, ghostdagData.SelectedParent())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
requiredBlueScore := ghostdagData.BlueScore() - fm.finalityDepth
|
|
log.Tracef("%s's finality point is the one having the highest blue score lower then %d", blockHash, requiredBlueScore)
|
|
|
|
var next *externalapi.DomainHash
|
|
for {
|
|
next, err = fm.dagTopologyManager.ChildInSelectedParentChainOf(current, blockHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
nextGHOSTDAGData, err := fm.ghostdagDataStore.Get(fm.databaseContext, next)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if nextGHOSTDAGData.BlueScore() >= requiredBlueScore {
|
|
log.Tracef("%s's finality point is %s", blockHash, current)
|
|
return current, nil
|
|
}
|
|
|
|
current = next
|
|
}
|
|
}
|