|
|
@ -46,7 +46,7 @@ struct TestSubscriber : public CValidationInterface { |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<CBlock> Block(const uint256& prev_hash) |
|
|
|
std::shared_ptr<CBlock> Block(const uint256& prev_hash, int height) |
|
|
|
{ |
|
|
|
{ |
|
|
|
static int i = 0; |
|
|
|
static int i = 0; |
|
|
|
static uint64_t time = Params().GenesisBlock().nTime; |
|
|
|
static uint64_t time = Params().GenesisBlock().nTime; |
|
|
@ -58,6 +58,9 @@ std::shared_ptr<CBlock> Block(const uint256& prev_hash) |
|
|
|
auto pblock = std::make_shared<CBlock>(ptemplate->block); |
|
|
|
auto pblock = std::make_shared<CBlock>(ptemplate->block); |
|
|
|
pblock->hashPrevBlock = prev_hash; |
|
|
|
pblock->hashPrevBlock = prev_hash; |
|
|
|
pblock->nTime = ++time; |
|
|
|
pblock->nTime = ++time; |
|
|
|
|
|
|
|
// Kevacoin use Cryptonight V4 which requires a height parameter.
|
|
|
|
|
|
|
|
// nNonce is no longer used and is repurposed to hold the height value.
|
|
|
|
|
|
|
|
pblock->nNonce = height; |
|
|
|
|
|
|
|
|
|
|
|
CMutableTransaction txCoinbase(*pblock->vtx[0]); |
|
|
|
CMutableTransaction txCoinbase(*pblock->vtx[0]); |
|
|
|
txCoinbase.vout.resize(1); |
|
|
|
txCoinbase.vout.resize(1); |
|
|
@ -81,15 +84,15 @@ std::shared_ptr<CBlock> FinalizeBlock(std::shared_ptr<CBlock> pblock) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// construct a valid block
|
|
|
|
// construct a valid block
|
|
|
|
const std::shared_ptr<const CBlock> GoodBlock(const uint256& prev_hash) |
|
|
|
const std::shared_ptr<const CBlock> GoodBlock(const uint256& prev_hash, int height) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return FinalizeBlock(Block(prev_hash)); |
|
|
|
return FinalizeBlock(Block(prev_hash, height)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// construct an invalid block (but with a valid header)
|
|
|
|
// construct an invalid block (but with a valid header)
|
|
|
|
const std::shared_ptr<const CBlock> BadBlock(const uint256& prev_hash) |
|
|
|
const std::shared_ptr<const CBlock> BadBlock(const uint256& prev_hash, int height) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto pblock = Block(prev_hash); |
|
|
|
auto pblock = Block(prev_hash, height); |
|
|
|
|
|
|
|
|
|
|
|
CMutableTransaction coinbase_spend; |
|
|
|
CMutableTransaction coinbase_spend; |
|
|
|
coinbase_spend.vin.push_back(CTxIn(COutPoint(pblock->vtx[0]->GetHash(), 0), CScript(), 0)); |
|
|
|
coinbase_spend.vin.push_back(CTxIn(COutPoint(pblock->vtx[0]->GetHash(), 0), CScript(), 0)); |
|
|
@ -102,22 +105,22 @@ const std::shared_ptr<const CBlock> BadBlock(const uint256& prev_hash) |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void BuildChain(const uint256& root, int height, const unsigned int invalid_rate, const unsigned int branch_rate, const unsigned int max_size, std::vector<std::shared_ptr<const CBlock>>& blocks) |
|
|
|
void BuildChain(const uint256& root, int height, const unsigned int invalid_rate, const unsigned int branch_rate, const unsigned int max_size, std::vector<std::shared_ptr<const CBlock>>& blocks, int chainHeight) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (height <= 0 || blocks.size() >= max_size) return; |
|
|
|
if (height <= 0 || blocks.size() >= max_size) return; |
|
|
|
|
|
|
|
|
|
|
|
bool gen_invalid = GetRand(100) < invalid_rate; |
|
|
|
bool gen_invalid = GetRand(100) < invalid_rate; |
|
|
|
bool gen_fork = GetRand(100) < branch_rate; |
|
|
|
bool gen_fork = GetRand(100) < branch_rate; |
|
|
|
|
|
|
|
|
|
|
|
const std::shared_ptr<const CBlock> pblock = gen_invalid ? BadBlock(root) : GoodBlock(root); |
|
|
|
const std::shared_ptr<const CBlock> pblock = gen_invalid ? BadBlock(root, chainHeight) : GoodBlock(root, chainHeight); |
|
|
|
blocks.push_back(pblock); |
|
|
|
blocks.push_back(pblock); |
|
|
|
if (!gen_invalid) { |
|
|
|
if (!gen_invalid) { |
|
|
|
BuildChain(pblock->GetHash(), height - 1, invalid_rate, branch_rate, max_size, blocks); |
|
|
|
BuildChain(pblock->GetHash(), height - 1, invalid_rate, branch_rate, max_size, blocks, chainHeight + 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (gen_fork) { |
|
|
|
if (gen_fork) { |
|
|
|
blocks.push_back(GoodBlock(root)); |
|
|
|
blocks.push_back(GoodBlock(root, chainHeight)); |
|
|
|
BuildChain(blocks.back()->GetHash(), height - 1, invalid_rate, branch_rate, max_size, blocks); |
|
|
|
BuildChain(blocks.back()->GetHash(), height - 1, invalid_rate, branch_rate, max_size, blocks, chainHeight + 1); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -127,7 +130,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering) |
|
|
|
std::vector<std::shared_ptr<const CBlock>> blocks; |
|
|
|
std::vector<std::shared_ptr<const CBlock>> blocks; |
|
|
|
while (blocks.size() < 50) { |
|
|
|
while (blocks.size() < 50) { |
|
|
|
blocks.clear(); |
|
|
|
blocks.clear(); |
|
|
|
BuildChain(Params().GenesisBlock().GetHash(), 100, 15, 10, 500, blocks); |
|
|
|
BuildChain(Params().GenesisBlock().GetHash(), 100, 15, 10, 500, blocks, 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool ignored; |
|
|
|
bool ignored; |
|
|
|