// New blocks available, or we've switched to a different branch. All change.
// TODO: Find most recent state dump and replay what's left.
// (Most recent state dump might end up being genesis.)
std::vector<u256>l=_bc.blockChain();// TODO: take u256Set "restorePoints" argument so it needs only give us the chain up until some restore point in the past where we stored the state.
if(l.back()==BlockInfo::genesis().hash)
{
// Reset to genesis block.
m_current.clear();
m_previousBlock=BlockInfo::genesis();
}
else
{
// TODO: Begin at a restore point.
}
// Iterate through in reverse, playing back each of the blocks.
for(autoit=next(l.cbegin());it!=l.cend();++it)
playback(_bc.block(*it));
m_transactions.clear();
}
// TRANSACTIONS
autots=_tq.transactions();
for(autoconst&i:ts)
if(!m_transactions.count(i.first))
// don't have it yet! Execute it now.
try
{
Transactiont(i.second);
execute(t,t.sender());
}
catch(InvalidNoncein)
{
if(in.required>in.candidate)
// too old
_tq.drop(i.first);
}
catch(...)
{
}
}
voidState::playback(bytesConstRef_block)
{
BlockInfobi;
try
{
bi.populate(_block,m_previousBlock.number+1);
bi.verifyInternals(_block);
if(bi.parentHash!=m_previousBlock.hash)
throwInvalidParentHash();
// All ok with the block generally. Play back the transactions now...
RLPtxs=_block[1];
for(autoconst&i:txs)
execute(i.data());
}
catch(...)
{
// TODO: Slightly nicer handling? :-)
cerr<<"ERROR: Corrupt block-chain! Delete your block-chain DB and restart."<<endl;
// Check validity of _block as a transaction. To do this we just deserialise and attempt to determine the sender. If it doesn't work, the signature is bad.
// The transaction's nonce may yet be invalid (or, it could be "valid" but we may be missing a marginally older transaction).