MCPcopy Create free account
hub / github.com/WaykiChain/WaykiChain / CheckBlock

Function CheckBlock

src/main.cpp:1819–1880  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1817}
1818
1819bool CheckBlock(const CBlock &block, CValidationState &state, CCacheWrapper &cw, bool fCheckTx, bool fCheckMerkleRoot) {
1820 if (block.vptx.empty() || block.vptx.size() > MAX_BLOCK_SIZE ||
1821 ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
1822 return state.DoS(100, ERRORMSG("size limits failed"), REJECT_INVALID, "bad-blk-length");
1823
1824 if ((block.GetHeight() != 0 || block.GetHash() != SysCfg().GetGenesisBlockHash()) &&
1825 block.GetVersion() != CBlockHeader::CURRENT_VERSION) {
1826 return state.Invalid(ERRORMSG("block version error"), REJECT_INVALID, "block-version-error");
1827 }
1828
1829 // Check timestamp `block interval' + 2 seconds limits
1830 if (block.GetBlockTime() > GetAdjustedTime() + ::GetBlockInterval(block.GetHeight()) + 2)
1831 return state.Invalid(ERRORMSG("block timestamp too far in the future"), REJECT_INVALID,
1832 "time-too-new");
1833
1834 // First transaction must be reward transaction, the rest must not be
1835 if (block.vptx.empty() || !block.vptx[0]->IsBlockRewardTx())
1836 return state.DoS(100, ERRORMSG("first tx is not coinbase"), REJECT_INVALID, "bad-cb-missing");
1837
1838 // Build the merkle tree already. We need it anyway later, and it makes the
1839 // block cache the transaction hashes, which means they don't need to be
1840 // recalculated many times during this block's validation.
1841 block.BuildMerkleTree();
1842
1843 // Check for duplicate txids. This is caught by ConnectInputs(),
1844 // but catching it earlier avoids a potential DoS attack:
1845 set<uint256> uniqueTxSet;
1846 uint32_t priceMedianTxCount = 0;
1847 for (uint32_t i = 0; i < block.vptx.size(); i++) {
1848 uniqueTxSet.insert(block.GetTxid(i));
1849 if (block.GetHeight() != 0 || block.GetHash() != SysCfg().GetGenesisBlockHash()) {
1850 if (i > 0 && block.vptx[i]->IsBlockRewardTx())
1851 return state.DoS(100, ERRORMSG("more than one block reward tx"), REJECT_INVALID,
1852 "bad-block-reward-tx-multiple");
1853 }
1854
1855 if (block.vptx[i]->IsPriceMedianTx())
1856 priceMedianTxCount++;
1857 }
1858
1859
1860 // In stable coin release, every block should have one price median tx only.
1861 if (GetFeatureForkVersion(block.GetHeight()) >= MAJOR_VER_R2 && priceMedianTxCount != 1)
1862 return state.DoS(100, ERRORMSG("price median tx number error"), REJECT_INVALID,
1863 "bad-price-median-tx-number");
1864
1865 if (uniqueTxSet.size() != block.vptx.size())
1866 return state.DoS(100, ERRORMSG("duplicated trx"), REJECT_INVALID, "bad-tx-duplicated", true);
1867
1868 // Check merkle root
1869 if (fCheckMerkleRoot && block.GetMerkleRootHash() != block.vMerkleTree.back())
1870 return state.DoS(100, ERRORMSG("[%d] merkleRootHash mismatch: in-block: #%s vs computed: #%s",
1871 block.GetHeight(), block.GetMerkleRootHash().ToString(), block.vMerkleTree.back().ToString()),
1872 REJECT_INVALID, "bad-merkle-root", true);
1873
1874 // Check nonce
1875 static uint64_t maxNonce = SysCfg().GetBlockMaxNonce();
1876 if (block.GetNonce() > maxNonce)

Callers 4

ConnectBlockFunction · 0.85
ProcessBlockFunction · 0.85
VerifyDBFunction · 0.85
BOOST_AUTO_TEST_CASEFunction · 0.85

Calls 15

GetSerializeSizeFunction · 0.85
GetAdjustedTimeFunction · 0.85
GetBlockIntervalFunction · 0.85
GetFeatureForkVersionFunction · 0.85
DoSMethod · 0.80
GetGenesisBlockHashMethod · 0.80
InvalidMethod · 0.80
IsBlockRewardTxMethod · 0.80
BuildMerkleTreeMethod · 0.80
GetTxidMethod · 0.80
IsPriceMedianTxMethod · 0.80
GetMerkleRootHashMethod · 0.80

Tested by 1

BOOST_AUTO_TEST_CASEFunction · 0.68