|
|
@ -124,12 +124,10 @@ void BlockChain::import(bytes const& _block, Overlay const& _db) |
|
|
|
|
|
|
|
auto newHash = eth::sha3(_block); |
|
|
|
|
|
|
|
clog(BlockChainChat) << "Attempting import of " << newHash << "..."; |
|
|
|
|
|
|
|
// Check block doesn't already exist first!
|
|
|
|
if (details(newHash)) |
|
|
|
{ |
|
|
|
clog(BlockChainChat) << " Not new."; |
|
|
|
clog(BlockChainChat) << newHash << ": Not new."; |
|
|
|
throw AlreadyHaveBlock(); |
|
|
|
} |
|
|
|
|
|
|
@ -137,47 +135,61 @@ void BlockChain::import(bytes const& _block, Overlay const& _db) |
|
|
|
auto pd = details(bi.parentHash); |
|
|
|
if (!pd) |
|
|
|
{ |
|
|
|
clog(BlockChainNote) << " Unknown parent " << bi.parentHash; |
|
|
|
clog(BlockChainChat) << newHash << ": Unknown parent " << bi.parentHash; |
|
|
|
// We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on.
|
|
|
|
throw UnknownParent(); |
|
|
|
} |
|
|
|
|
|
|
|
// Check family:
|
|
|
|
BlockInfo biParent(block(bi.parentHash)); |
|
|
|
bi.verifyParent(biParent); |
|
|
|
|
|
|
|
// Check transactions are valid and that they result in a state equivalent to our state_root.
|
|
|
|
State s(bi.coinbaseAddress, _db); |
|
|
|
s.sync(*this, bi.parentHash); |
|
|
|
|
|
|
|
// Get total difficulty increase and update state, checking it.
|
|
|
|
BlockInfo biGrandParent; |
|
|
|
if (pd.number) |
|
|
|
biGrandParent.populate(block(pd.parent)); |
|
|
|
auto tdIncrease = s.playback(&_block, bi, biParent, biGrandParent, true); |
|
|
|
u256 td = pd.totalDifficulty + tdIncrease; |
|
|
|
|
|
|
|
checkConsistency(); |
|
|
|
|
|
|
|
// All ok - insert into DB
|
|
|
|
m_details[newHash] = BlockDetails((uint)pd.number + 1, td, bi.parentHash, {}); |
|
|
|
m_detailsDB->Put(m_writeOptions, ldb::Slice((char const*)&newHash, 32), (ldb::Slice)eth::ref(m_details[newHash].rlp())); |
|
|
|
|
|
|
|
m_details[bi.parentHash].children.push_back(newHash); |
|
|
|
m_detailsDB->Put(m_writeOptions, ldb::Slice((char const*)&bi.parentHash, 32), (ldb::Slice)eth::ref(m_details[bi.parentHash].rlp())); |
|
|
|
clog(BlockChainNote) << "Attempting import of " << newHash << "..."; |
|
|
|
|
|
|
|
m_db->Put(m_writeOptions, ldb::Slice((char const*)&newHash, 32), (ldb::Slice)ref(_block)); |
|
|
|
|
|
|
|
checkConsistency(); |
|
|
|
u256 td; |
|
|
|
try |
|
|
|
{ |
|
|
|
// Check family:
|
|
|
|
BlockInfo biParent(block(bi.parentHash)); |
|
|
|
bi.verifyParent(biParent); |
|
|
|
|
|
|
|
// Check transactions are valid and that they result in a state equivalent to our state_root.
|
|
|
|
State s(bi.coinbaseAddress, _db); |
|
|
|
s.sync(*this, bi.parentHash); |
|
|
|
|
|
|
|
// Get total difficulty increase and update state, checking it.
|
|
|
|
BlockInfo biGrandParent; |
|
|
|
if (pd.number) |
|
|
|
biGrandParent.populate(block(pd.parent)); |
|
|
|
auto tdIncrease = s.playback(&_block, bi, biParent, biGrandParent, true); |
|
|
|
td = pd.totalDifficulty + tdIncrease; |
|
|
|
|
|
|
|
#if !NDEBUG |
|
|
|
checkConsistency(); |
|
|
|
#endif |
|
|
|
// All ok - insert into DB
|
|
|
|
m_details[newHash] = BlockDetails((uint)pd.number + 1, td, bi.parentHash, {}); |
|
|
|
m_detailsDB->Put(m_writeOptions, ldb::Slice((char const*)&newHash, 32), (ldb::Slice)eth::ref(m_details[newHash].rlp())); |
|
|
|
|
|
|
|
m_details[bi.parentHash].children.push_back(newHash); |
|
|
|
m_detailsDB->Put(m_writeOptions, ldb::Slice((char const*)&bi.parentHash, 32), (ldb::Slice)eth::ref(m_details[bi.parentHash].rlp())); |
|
|
|
|
|
|
|
m_db->Put(m_writeOptions, ldb::Slice((char const*)&newHash, 32), (ldb::Slice)ref(_block)); |
|
|
|
|
|
|
|
#if !NDEBUG |
|
|
|
checkConsistency(); |
|
|
|
#endif |
|
|
|
} |
|
|
|
catch (...) |
|
|
|
{ |
|
|
|
clog(BlockChainNote) << " Malformed block."; |
|
|
|
throw; |
|
|
|
} |
|
|
|
|
|
|
|
// cnote << "Parent " << bi.parentHash << " has " << details(bi.parentHash).children.size() << " children." << endl;
|
|
|
|
// cnote << "Parent " << bi.parentHash << " has " << details(bi.parentHash).children.size() << " children.";
|
|
|
|
|
|
|
|
// This might be the new last block...
|
|
|
|
if (td > m_details[m_lastBlockHash].totalDifficulty) |
|
|
|
{ |
|
|
|
m_lastBlockHash = newHash; |
|
|
|
m_detailsDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&newHash, 32)); |
|
|
|
clog(BlockChainNote) << " Imported and best."; |
|
|
|
clog(BlockChainNote) << " Imported and best. Has" << details(bi.parentHash).children.size() << "siblings."; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|