kaspad/domain/consensus/test_consensus.go
Ori Newman d207888b67
Implement pruned headers node (#1787)
* Pruning headers p2p basic structure

* Remove headers-first

* Fix consensus tests except TestValidateAndInsertPruningPointWithSideBlocks and TestValidateAndInsertImportedPruningPoint

* Add virtual genesis

* Implement PruningPointAndItsAnticoneWithMetaData

* Start fixing TestValidateAndInsertImportedPruningPoint

* Fix TestValidateAndInsertImportedPruningPoint

* Fix BlockWindow

* Update p2p and gRPC

* Fix all tests except TestHandleRelayInvs

* Delete TestHandleRelayInvs parts that cover the old IBD flow

* Fix lint errors

* Add p2p_request_ibd_blocks.go

* Clean code

* Make MsgBlockWithMetaData implement its own representation

* Remove redundant check if highest share block is below the pruning point

* Fix TestCheckLockTimeVerifyConditionedByAbsoluteTimeWithWrongLockTime

* Fix comments, errors ane names

* Fix window size to the real value

* Check reindex root after each block at TestUpdateReindexRoot

* Remove irrelevant check

* Renames and comments

* Remove redundant argument from sendGetBlockLocator

* Don't delete staging on non-recoverable errors

* Renames and comments

* Remove redundant code

* Commit changes inside ResolveVirtual

* Add comment to IsRecoverableError

* Remove blocksWithMetaDataGHOSTDAGDataStore

* Increase windows pagefile

* Move DeleteStagingConsensus outside of defer

* Get rid of mustAccepted in receiveBlockWithMetaData

* Ban on invalid pruning point

* Rename interface_datastructures_daawindowstore.go to interface_datastructures_blocks_with_meta_data_daa_window_store.go

* * Change GetVirtualSelectedParentChainFromBlockResponseMessage and VirtualSelectedParentChainChangedNotificationMessage to show only added block hashes
*  Remove ResolveVirtual
* Use externalapi.ConsensusWrapper inside MiningManager
* Fix pruningmanager.blockwithmetadata

* Set pruning point selected child when importing the pruning point UTXO set

* Change virtual genesis hash

* replace the selected parent with virtual genesis on removePrunedBlocksFromGHOSTDAGData

* Get rid of low hash in block locators

* Remove +1 from everywhere we use difficultyAdjustmentWindowSize and increase the default value by one

* Add comments about consensus wrapper

* Don't use separate staging area when resolving resolveBlockStatus

* Fix netsync stability test

* Fix checkResolveVirtual

* Rename ConsensusWrapper->ConsensusReference

* Get rid of blockHeapNode

* Add comment to defaultDifficultyAdjustmentWindowSize

* Add SelectedChild to DAGTraversalManager

* Remove redundant copy

* Rename blockWindowHeap->calculateBlockWindowHeap

* Move isVirtualGenesisOnlyParent to utils

* Change BlockWithMetaData->BlockWithTrustedData

* Get rid of maxReasonLength

* Split IBD to 100 blocks each time

* Fix a bug in calculateBlockWindowHeap

* Switch to trusted data when encountering virtual genesis in blockWithTrustedData

* Move ConsensusReference to domain

* Update ConsensusReference comment

* Add comment

* Rename shouldNotAddGenesis->skipAddingGenesis
2021-07-26 12:24:07 +03:00

200 lines
5.8 KiB
Go

package consensus
import (
"encoding/json"
"io"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/model/testapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/dagconfig"
"github.com/kaspanet/kaspad/infrastructure/db/database"
"github.com/pkg/errors"
)
type testConsensus struct {
*consensus
dagParams *dagconfig.Params
database database.Database
testBlockBuilder testapi.TestBlockBuilder
testReachabilityManager testapi.TestReachabilityManager
testConsensusStateManager testapi.TestConsensusStateManager
testTransactionValidator testapi.TestTransactionValidator
buildBlockConsensus *consensus
}
func (tc *testConsensus) DAGParams() *dagconfig.Params {
return tc.dagParams
}
func (tc *testConsensus) BuildBlockWithParents(parentHashes []*externalapi.DomainHash,
coinbaseData *externalapi.DomainCoinbaseData, transactions []*externalapi.DomainTransaction) (
*externalapi.DomainBlock, externalapi.UTXODiff, error) {
// Require write lock because BuildBlockWithParents stages temporary data
tc.lock.Lock()
defer tc.lock.Unlock()
block, diff, err := tc.testBlockBuilder.BuildBlockWithParents(parentHashes, coinbaseData, transactions)
if err != nil {
return nil, nil, err
}
return block, diff, nil
}
func (tc *testConsensus) AddBlock(parentHashes []*externalapi.DomainHash, coinbaseData *externalapi.DomainCoinbaseData,
transactions []*externalapi.DomainTransaction) (*externalapi.DomainHash, *externalapi.BlockInsertionResult, error) {
// Require write lock because BuildBlockWithParents stages temporary data
tc.lock.Lock()
defer tc.lock.Unlock()
block, _, err := tc.testBlockBuilder.BuildBlockWithParents(parentHashes, coinbaseData, transactions)
if err != nil {
return nil, nil, err
}
blockInsertionResult, err := tc.blockProcessor.ValidateAndInsertBlock(block, true)
if err != nil {
return nil, nil, err
}
return consensushashing.BlockHash(block), blockInsertionResult, nil
}
func (tc *testConsensus) AddUTXOInvalidHeader(parentHashes []*externalapi.DomainHash) (*externalapi.DomainHash,
*externalapi.BlockInsertionResult, error) {
// Require write lock because BuildBlockWithParents stages temporary data
tc.lock.Lock()
defer tc.lock.Unlock()
header, err := tc.testBlockBuilder.BuildUTXOInvalidHeader(parentHashes)
if err != nil {
return nil, nil, err
}
blockInsertionResult, err := tc.blockProcessor.ValidateAndInsertBlock(&externalapi.DomainBlock{
Header: header,
Transactions: nil,
}, true)
if err != nil {
return nil, nil, err
}
return consensushashing.HeaderHash(header), blockInsertionResult, nil
}
func (tc *testConsensus) AddUTXOInvalidBlock(parentHashes []*externalapi.DomainHash) (*externalapi.DomainHash,
*externalapi.BlockInsertionResult, error) {
// Require write lock because BuildBlockWithParents stages temporary data
tc.lock.Lock()
defer tc.lock.Unlock()
block, err := tc.testBlockBuilder.BuildUTXOInvalidBlock(parentHashes)
if err != nil {
return nil, nil, err
}
blockInsertionResult, err := tc.blockProcessor.ValidateAndInsertBlock(block, true)
if err != nil {
return nil, nil, err
}
return consensushashing.BlockHash(block), blockInsertionResult, nil
}
func (tc *testConsensus) MineJSON(r io.Reader, blockType testapi.MineJSONBlockType) (tips []*externalapi.DomainHash, err error) {
// jsonBlock is a json representation of a block in mine format
type jsonBlock struct {
ID string `json:"id"`
Parents []string `json:"parents"`
}
tipSet := map[externalapi.DomainHash]*externalapi.DomainHash{}
tipSet[*tc.dagParams.GenesisHash] = tc.dagParams.GenesisHash
parentsMap := make(map[string]*externalapi.DomainHash)
parentsMap["0"] = tc.dagParams.GenesisHash
decoder := json.NewDecoder(r)
// read open bracket
_, err = decoder.Token()
if err != nil {
return nil, err
}
// while the array contains values
for decoder.More() {
var block jsonBlock
// decode an array value (Message)
err := decoder.Decode(&block)
if err != nil {
return nil, err
}
if block.ID == "0" {
continue
}
parentHashes := make([]*externalapi.DomainHash, len(block.Parents))
var ok bool
for i, parentID := range block.Parents {
parentHashes[i], ok = parentsMap[parentID]
if !ok {
return nil, errors.Errorf("Couldn't find blockID: %s", parentID)
}
delete(tipSet, *parentHashes[i])
}
var blockHash *externalapi.DomainHash
switch blockType {
case testapi.MineJSONBlockTypeUTXOValidBlock:
blockHash, _, err = tc.AddBlock(parentHashes, nil, nil)
if err != nil {
return nil, err
}
case testapi.MineJSONBlockTypeUTXOInvalidBlock:
blockHash, _, err = tc.AddUTXOInvalidBlock(parentHashes)
if err != nil {
return nil, err
}
case testapi.MineJSONBlockTypeUTXOInvalidHeader:
blockHash, _, err = tc.AddUTXOInvalidHeader(parentHashes)
if err != nil {
return nil, err
}
default:
return nil, errors.Errorf("unknwon block type %v", blockType)
}
parentsMap[block.ID] = blockHash
tipSet[*blockHash] = blockHash
}
tips = make([]*externalapi.DomainHash, len(tipSet))
i := 0
for _, v := range tipSet {
tips[i] = v
i++
}
return tips, nil
}
func (tc *testConsensus) BuildUTXOInvalidBlock(parentHashes []*externalapi.DomainHash) (*externalapi.DomainBlock, error) {
// Require write lock because BuildBlockWithParents stages temporary data
tc.lock.Lock()
defer tc.lock.Unlock()
return tc.testBlockBuilder.BuildUTXOInvalidBlock(parentHashes)
}
func (tc *testConsensus) BuildHeaderWithParents(parentHashes []*externalapi.DomainHash) (externalapi.BlockHeader, error) {
// Require write lock because BuildUTXOInvalidHeader stages temporary data
tc.lock.Lock()
defer tc.lock.Unlock()
return tc.testBlockBuilder.BuildUTXOInvalidHeader(parentHashes)
}