mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-05-22 14:56:44 +00:00

* Increase size of reachability cache * Change DomainHash to struct with unexported hashArray * Fixing compilation errors stemming from new DomainHash structure * Remove obsolete Read/WriteElement methods in appmessage * Fix all tests * Fix all tests * Add comments * A few renamings * go mod tidy
131 lines
4.5 KiB
Go
131 lines
4.5 KiB
Go
package blockbuilder
|
|
|
|
import (
|
|
"github.com/kaspanet/kaspad/domain/consensus/model"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/testapi"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
|
|
"github.com/kaspanet/kaspad/infrastructure/logger"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type testBlockBuilder struct {
|
|
*blockBuilder
|
|
testConsensus testapi.TestConsensus
|
|
nonceCounter uint64
|
|
}
|
|
|
|
var tempBlockHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})
|
|
|
|
// NewTestBlockBuilder creates an instance of a TestBlockBuilder
|
|
func NewTestBlockBuilder(baseBlockBuilder model.BlockBuilder, testConsensus testapi.TestConsensus) testapi.TestBlockBuilder {
|
|
return &testBlockBuilder{
|
|
blockBuilder: baseBlockBuilder.(*blockBuilder),
|
|
testConsensus: testConsensus,
|
|
}
|
|
}
|
|
|
|
// BuildBlockWithParents builds a block with provided parents, coinbaseData and transactions,
|
|
// and returns the block together with its past UTXO-diff from the virtual.
|
|
func (bb *testBlockBuilder) BuildBlockWithParents(parentHashes []*externalapi.DomainHash,
|
|
coinbaseData *externalapi.DomainCoinbaseData, transactions []*externalapi.DomainTransaction) (
|
|
*externalapi.DomainBlock, model.UTXODiff, error) {
|
|
|
|
onEnd := logger.LogAndMeasureExecutionTime(log, "BuildBlockWithParents")
|
|
defer onEnd()
|
|
|
|
return bb.buildBlockWithParents(parentHashes, coinbaseData, transactions)
|
|
}
|
|
|
|
func (bb *testBlockBuilder) buildHeaderWithParents(parentHashes []*externalapi.DomainHash,
|
|
transactions []*externalapi.DomainTransaction, acceptanceData externalapi.AcceptanceData, multiset model.Multiset) (
|
|
*externalapi.DomainBlockHeader, error) {
|
|
|
|
timeInMilliseconds, err := bb.minBlockTime(tempBlockHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bits, err := bb.difficultyManager.RequiredDifficulty(tempBlockHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
hashMerkleRoot := bb.newBlockHashMerkleRoot(transactions)
|
|
acceptedIDMerkleRoot, err := bb.calculateAcceptedIDMerkleRoot(acceptanceData)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
utxoCommitment := multiset.Hash()
|
|
|
|
bb.nonceCounter++
|
|
return &externalapi.DomainBlockHeader{
|
|
Version: constants.BlockVersion,
|
|
ParentHashes: parentHashes,
|
|
HashMerkleRoot: *hashMerkleRoot,
|
|
AcceptedIDMerkleRoot: *acceptedIDMerkleRoot,
|
|
UTXOCommitment: *utxoCommitment,
|
|
TimeInMilliseconds: timeInMilliseconds,
|
|
Bits: bits,
|
|
Nonce: bb.nonceCounter,
|
|
}, nil
|
|
}
|
|
|
|
func (bb *testBlockBuilder) buildBlockWithParents(parentHashes []*externalapi.DomainHash, coinbaseData *externalapi.DomainCoinbaseData, transactions []*externalapi.DomainTransaction) (*externalapi.DomainBlock, model.UTXODiff, error) {
|
|
|
|
defer bb.testConsensus.DiscardAllStores()
|
|
|
|
if coinbaseData == nil {
|
|
scriptPublicKey, _ := testutils.OpTrueScript()
|
|
coinbaseData = &externalapi.DomainCoinbaseData{
|
|
ScriptPublicKey: scriptPublicKey,
|
|
ExtraData: []byte{},
|
|
}
|
|
}
|
|
|
|
bb.blockRelationStore.StageBlockRelation(tempBlockHash, &model.BlockRelations{Parents: parentHashes})
|
|
|
|
err := bb.ghostdagManager.GHOSTDAG(tempBlockHash)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
ghostdagData, err := bb.ghostdagDataStore.Get(bb.databaseContext, tempBlockHash)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
selectedParentStatus, err := bb.testConsensus.ConsensusStateManager().ResolveBlockStatus(ghostdagData.SelectedParent())
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
if selectedParentStatus == externalapi.StatusDisqualifiedFromChain {
|
|
return nil, nil, errors.Errorf("Error building block with selectedParent %s with status DisqualifiedFromChain",
|
|
ghostdagData.SelectedParent())
|
|
}
|
|
|
|
pastUTXO, acceptanceData, multiset, err := bb.consensusStateManager.CalculatePastUTXOAndAcceptanceData(tempBlockHash)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
bb.acceptanceDataStore.Stage(tempBlockHash, acceptanceData)
|
|
|
|
coinbase, err := bb.coinbaseManager.ExpectedCoinbaseTransaction(tempBlockHash, coinbaseData)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
transactionsWithCoinbase := append([]*externalapi.DomainTransaction{coinbase}, transactions...)
|
|
|
|
header, err := bb.buildHeaderWithParents(parentHashes, transactionsWithCoinbase, acceptanceData, multiset)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return &externalapi.DomainBlock{
|
|
Header: header,
|
|
Transactions: transactionsWithCoinbase,
|
|
}, pastUTXO, nil
|
|
}
|