Skip to content

Instantly share code, notes, and snippets.

@mikers1
Created August 1, 2017 16:53
Show Gist options
  • Save mikers1/2e0b1ff80bbe731aa2dd1560eb16fb50 to your computer and use it in GitHub Desktop.
Save mikers1/2e0b1ff80bbe731aa2dd1560eb16fb50 to your computer and use it in GitHub Desktop.
VerifiedBlockRef BlockChain::verifyBlock(bytesConstRef _block, std::function<void(Exception&)> const& _onBad, ImportRequirements::value _ir) const
{
VerifiedBlockRef res;
BlockHeader h;
try
{
h = BlockHeader(_block);
if (!!(_ir & ImportRequirements::PostGenesis) && (!h.parentHash() || h.number() == 0))
BOOST_THROW_EXCEPTION(InvalidParentHash() << errinfo_required_h256(h.parentHash()) << errinfo_currentNumber(h.number()));
BlockHeader parent;
if (!!(_ir & ImportRequirements::Parent))
{
bytes parentHeader(headerData(h.parentHash()));
if (parentHeader.empty())
BOOST_THROW_EXCEPTION(InvalidParentHash() << errinfo_required_h256(h.parentHash()) << errinfo_currentNumber(h.number()));
parent = BlockHeader(parentHeader, HeaderData, h.parentHash());
}
sealEngine()->verify((_ir & ImportRequirements::ValidSeal) ? Strictness::CheckEverything : Strictness::QuickNonce, h, parent, _block);
res.info = h;
}
catch (Exception& ex)
{
ex << errinfo_phase(1);
ex << errinfo_now(time(0));
ex << errinfo_block(_block.toBytes());
// only populate extraData if we actually managed to extract it. otherwise,
// we might be clobbering the existing one.
if (!h.extraData().empty())
ex << errinfo_extraData(h.extraData());
if (_onBad)
_onBad(ex);
throw;
}
RLP r(_block);
unsigned i = 0;
if (_ir & (ImportRequirements::UncleBasic | ImportRequirements::UncleParent | ImportRequirements::UncleSeals))
for (auto const& uncle: r[2])
{
BlockHeader uh(uncle.data(), HeaderData);
try
{
BlockHeader parent;
if (!!(_ir & ImportRequirements::UncleParent))
{
bytes parentHeader(headerData(uh.parentHash()));
if (parentHeader.empty())
BOOST_THROW_EXCEPTION(InvalidUncleParentHash() << errinfo_required_h256(uh.parentHash()) << errinfo_currentNumber(h.number()) << errinfo_uncleNumber(uh.number()));
parent = BlockHeader(parentHeader, HeaderData, uh.parentHash());
}
sealEngine()->verify((_ir & ImportRequirements::UncleSeals) ? Strictness::CheckEverything : Strictness::IgnoreSeal, uh, parent);
}
catch (Exception& ex)
{
ex << errinfo_phase(1);
ex << errinfo_uncleIndex(i);
ex << errinfo_now(time(0));
ex << errinfo_block(_block.toBytes());
// only populate extraData if we actually managed to extract it. otherwise,
// we might be clobbering the existing one.
if (!uh.extraData().empty())
ex << errinfo_extraData(uh.extraData());
if (_onBad)
_onBad(ex);
throw;
}
++i;
}
i = 0;
if (_ir & (ImportRequirements::TransactionBasic | ImportRequirements::TransactionSignatures))
for (RLP const& tr: r[1])
{
bytesConstRef d = tr.data();
try
{
Transaction t(d, (_ir & ImportRequirements::TransactionSignatures) ? CheckTransaction::Everything : CheckTransaction::None);
m_sealEngine->verifyTransaction(_ir, t, h, 0);
res.transactions.push_back(t);
}
catch (Exception& ex)
{
ex << errinfo_phase(1);
ex << errinfo_transactionIndex(i);
ex << errinfo_transaction(d.toBytes());
ex << errinfo_block(_block.toBytes());
// only populate extraData if we actually managed to extract it. otherwise,
// we might be clobbering the existing one.
if (!h.extraData().empty())
ex << errinfo_extraData(h.extraData());
if (_onBad)
_onBad(ex);
throw;
}
++i;
}
res.block = bytesConstRef(_block);
return res;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment