本文整理汇总了C++中BlockInfo::populate方法的典型用法代码示例。如果您正苦于以下问题:C++ BlockInfo::populate方法的具体用法?C++ BlockInfo::populate怎么用?C++ BlockInfo::populate使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BlockInfo
的用法示例。
在下文中一共展示了BlockInfo::populate方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: sync
bool State::sync(BlockChain const& _bc, h256 _block)
{
bool ret = false;
// BLOCK
BlockInfo bi;
try
{
auto b = _bc.block(_block);
bi.populate(b);
bi.verifyInternals(_bc.block(_block));
}
catch (...)
{
// TODO: Slightly nicer handling? :-)
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
exit(1);
}
if (bi == m_currentBlock)
{
// We mined the last block.
// Our state is good - we just need to move on to next.
m_previousBlock = m_currentBlock;
resetCurrent();
m_currentNumber++;
ret = true;
}
else if (bi == m_previousBlock)
{
// No change since last sync.
// Carry on as we were.
}
else
{
// New blocks available, or we've switched to a different branch. All change.
// Find most recent state dump and replay what's left.
// (Most recent state dump might end up being genesis.)
std::vector<h256> chain;
while (bi.stateRoot != BlockInfo::genesis().hash && m_db.lookup(bi.stateRoot).empty()) // while we don't have the state root of the latest block...
{
chain.push_back(bi.hash); // push back for later replay.
bi.populate(_bc.block(bi.parentHash)); // move to parent.
}
m_previousBlock = bi;
resetCurrent();
// Iterate through in reverse, playing back each of the blocks.
for (auto it = chain.rbegin(); it != chain.rend(); ++it)
playback(_bc.block(*it), true);
m_currentNumber = _bc.details(_block).number + 1;
resetCurrent();
ret = true;
}
return ret;
}
示例2:
State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h):
m_db(_db),
m_state(&m_db),
m_blockReward(c_blockReward)
{
// TODO THINK: is this necessary?
m_state.init();
auto b = _bc.block(_h);
BlockInfo bi;
BlockInfo bip;
if (_h)
bi.populate(b);
if (bi && bi.number)
bip.populate(_bc.block(bi.parentHash));
if (!_h || !bip)
return;
m_ourAddress = bi.coinbaseAddress;
sync(_bc, bi.parentHash, bip);
enact(&b, _bc);
}
示例3: enactOn
u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const& _bc)
{
// Check family:
BlockInfo biParent(_bc.block(_bi.parentHash));
_bi.verifyParent(biParent);
BlockInfo biGrandParent;
if (biParent.number)
biGrandParent.populate(_bc.block(biParent.parentHash));
sync(_bc, _bi.parentHash);
resetCurrent();
m_previousBlock = biParent;
return enact(_block, _bc);
}
示例4: import
void BlockChain::import(bytes const& _block)
{
try
{
// VERIFY: populates from the block and checks the block is internally coherent.
BlockInfo bi(&_block);
bi.verifyInternals(&_block);
auto newHash = eth::sha3(_block);
// Check block doesn't already exist first!
if (m_details.count(newHash))
return;
// Work out its number as the parent's number + 1
auto it = m_details.find(bi.parentHash);
if (it == m_details.end())
// 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.
return;
// 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);
s.sync(*this, bi.parentHash);
// Get total difficulty increase and update state, checking it.
BlockInfo biGrandParent;
if (it->second.number)
biGrandParent.populate(block(it->second.parent));
u256 td = it->second.totalDifficulty + s.playback(&_block, bi, biParent, biGrandParent);
// All ok - insert into DB
m_details[newHash] = BlockDetails{(uint)it->second.number + 1, bi.parentHash, td};
m_details[bi.parentHash].children.push_back(newHash);
m_db->Put(m_writeOptions, ldb::Slice(toBigEndianString(newHash)), (ldb::Slice)ref(_block));
// This might be the new last block...
if (td > m_details[m_lastBlockHash].totalDifficulty)
m_lastBlockHash = newHash;
}
catch (...)
{
// Exit silently on exception(?)
return;
}
}
示例5: populateFromChain
PopulationStatistics State::populateFromChain(BlockChain const& _bc, h256 const& _h, ImportRequirements::value _ir)
{
PopulationStatistics ret { 0.0, 0.0 };
if (!_bc.isKnown(_h))
{
// Might be worth throwing here.
cwarn << "Invalid block given for state population: " << _h;
return ret;
}
auto b = _bc.block(_h);
BlockInfo bi(b);
if (bi.number)
{
// Non-genesis:
// 1. Start at parent's end state (state root).
BlockInfo bip;
bip.populate(_bc.block(bi.parentHash));
sync(_bc, bi.parentHash, bip, _ir);
// 2. Enact the block's transactions onto this state.
m_ourAddress = bi.coinbaseAddress;
Timer t;
auto vb = BlockChain::verifyBlock(b);
ret.verify = t.elapsed();
t.restart();
enact(vb, _bc, _ir);
ret.enact = t.elapsed();
}
else
{
// Genesis required:
// We know there are no transactions, so just populate directly.
m_state.init();
sync(_bc, _h, bi, _ir);
}
return ret;
}
示例6: sync
bool Block::sync(BlockChain const& _bc, h256 const& _block, BlockInfo const& _bi)
{
bool ret = false;
// BLOCK
BlockInfo bi = _bi ? _bi : _bc.info(_block);
#if ETH_PARANOIA
if (!bi)
while (1)
{
try
{
auto b = _bc.block(_block);
bi.populate(b);
break;
}
catch (Exception const& _e)
{
// TODO: Slightly nicer handling? :-)
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
cerr << diagnostic_information(_e) << endl;
}
catch (std::exception const& _e)
{
// TODO: Slightly nicer handling? :-)
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
cerr << _e.what() << endl;
}
}
#endif
if (bi == m_currentBlock)
{
// We mined the last block.
// Our state is good - we just need to move on to next.
m_previousBlock = m_currentBlock;
resetCurrent();
ret = true;
}
else if (bi == m_previousBlock)
{
// No change since last sync.
// Carry on as we were.
}
else
{
// New blocks available, or we've switched to a different branch. All change.
// Find most recent state dump and replay what's left.
// (Most recent state dump might end up being genesis.)
if (m_state.db().lookup(bi.stateRoot()).empty()) // TODO: API in State for this?
{
cwarn << "Unable to sync to" << bi.hash() << "; state root" << bi.stateRoot() << "not found in database.";
cwarn << "Database corrupt: contains block without stateRoot:" << bi;
cwarn << "Try rescuing the database by running: eth --rescue";
BOOST_THROW_EXCEPTION(InvalidStateRoot() << errinfo_target(bi.stateRoot()));
}
m_previousBlock = bi;
resetCurrent();
ret = true;
}
#if ALLOW_REBUILD
else
{
示例7: import
void BlockChain::import(bytes const& _block, Overlay const& _db)
{
// VERIFY: populates from the block and checks the block is internally coherent.
BlockInfo bi(&_block);
bi.verifyInternals(&_block);
auto newHash = eth::sha3(_block);
// Check block doesn't already exist first!
if (details(newHash))
{
clog(BlockChainChat) << newHash << ": Not new.";
throw AlreadyHaveBlock();
}
// Work out its number as the parent's number + 1
auto pd = details(bi.parentHash);
if (!pd)
{
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();
}
clog(BlockChainNote) << "Attempting import of " << newHash << "...";
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.";
// 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. Has" << details(bi.parentHash).children.size() << "siblings.";
}
else
{
clog(BlockChainNote) << " Imported but not best (oTD:" << m_details[m_lastBlockHash].totalDifficulty << ", TD:" << td << ")";
}
}
示例8: import
ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc)
{
// Check if we already know this block.
h256 h = BlockInfo::headerHash(_block);
cblockq << "Queuing block" << h.abridged() << "for import...";
UpgradableGuard l(m_lock);
if (m_readySet.count(h) || m_drainingSet.count(h) || m_unknownSet.count(h))
{
// Already know about this one.
cblockq << "Already known.";
return ImportResult::AlreadyKnown;
}
// VERIFY: populates from the block and checks the block is internally coherent.
BlockInfo bi;
#if ETH_CATCH
try
#endif
{
bi.populate(_block);
bi.verifyInternals(_block);
}
#if ETH_CATCH
catch (Exception const& _e)
{
cwarn << "Ignoring malformed block: " << diagnostic_information(_e);
return false;
return ImportResult::Malformed;
}
#endif
// Check block doesn't already exist first!
if (_bc.details(h))
{
cblockq << "Already known in chain.";
return ImportResult::AlreadyInChain;
}
UpgradeGuard ul(l);
// Check it's not in the future
if (bi.timestamp > (u256)time(0))
{
m_future.insert(make_pair((unsigned)bi.timestamp, _block.toBytes()));
cblockq << "OK - queued for future.";
return ImportResult::FutureTime;
}
else
{
// We now know it.
if (!m_readySet.count(bi.parentHash) && !m_drainingSet.count(bi.parentHash) && !_bc.isKnown(bi.parentHash))
{
// We don't know the parent (yet) - queue it up for later. It'll get resent to us if we find out about its ancestry later on.
cblockq << "OK - queued as unknown parent:" << bi.parentHash.abridged();
m_unknown.insert(make_pair(bi.parentHash, make_pair(h, _block.toBytes())));
m_unknownSet.insert(h);
return ImportResult::UnknownParent;
}
else
{
// If valid, append to blocks.
cblockq << "OK - ready for chain insertion.";
m_ready.push_back(_block.toBytes());
m_readySet.insert(h);
noteReadyWithoutWriteGuard(h);
return ImportResult::Success;
}
}
}
示例9: sync
bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi)
{
bool ret = false;
// BLOCK
BlockInfo bi = _bi;
if (!bi)
while (1)
{
try
{
auto b = _bc.block(_block);
bi.populate(b);
// bi.verifyInternals(_bc.block(_block)); // Unneeded - we already verify on import into the blockchain.
break;
}
catch (Exception const& _e)
{
// TODO: Slightly nicer handling? :-)
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
cerr << diagnostic_information(_e) << endl;
}
catch (std::exception const& _e)
{
// TODO: Slightly nicer handling? :-)
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
cerr << _e.what() << endl;
}
}
if (bi == m_currentBlock)
{
// We mined the last block.
// Our state is good - we just need to move on to next.
m_previousBlock = m_currentBlock;
resetCurrent();
ret = true;
}
else if (bi == m_previousBlock)
{
// No change since last sync.
// Carry on as we were.
}
else
{
// New blocks available, or we've switched to a different branch. All change.
// Find most recent state dump and replay what's left.
// (Most recent state dump might end up being genesis.)
std::vector<h256> chain;
while (bi.number != 0 && m_db.lookup(bi.stateRoot).empty()) // while we don't have the state root of the latest block...
{
chain.push_back(bi.hash); // push back for later replay.
bi.populate(_bc.block(bi.parentHash)); // move to parent.
}
m_previousBlock = bi;
resetCurrent();
// Iterate through in reverse, playing back each of the blocks.
try
{
for (auto it = chain.rbegin(); it != chain.rend(); ++it)
{
auto b = _bc.block(*it);
enact(&b, _bc);
cleanup(true);
}
}
catch (...)
{
// TODO: Slightly nicer handling? :-)
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
cerr << boost::current_exception_diagnostic_information() << endl;
exit(1);
}
resetCurrent();
ret = true;
}
return ret;
}
示例10: import
ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, bool _isOurs)
{
clog(BlockQueueTraceChannel) << std::this_thread::get_id();
// Check if we already know this block.
h256 h = BlockInfo::headerHash(_block);
clog(BlockQueueTraceChannel) << "Queuing block" << h << "for import...";
UpgradableGuard l(m_lock);
if (m_readySet.count(h) || m_drainingSet.count(h) || m_unknownSet.count(h) || m_knownBad.count(h))
{
// Already know about this one.
clog(BlockQueueTraceChannel) << "Already known.";
return ImportResult::AlreadyKnown;
}
// VERIFY: populates from the block and checks the block is internally coherent.
BlockInfo bi;
try
{
// TODO: quick verify
bi.populate(_block);
bi.verifyInternals(_block);
}
catch (Exception const& _e)
{
cwarn << "Ignoring malformed block: " << diagnostic_information(_e);
return ImportResult::Malformed;
}
clog(BlockQueueTraceChannel) << "Block" << h << "is" << bi.number << "parent is" << bi.parentHash;
// Check block doesn't already exist first!
if (_bc.isKnown(h))
{
cblockq << "Already known in chain.";
return ImportResult::AlreadyInChain;
}
UpgradeGuard ul(l);
DEV_INVARIANT_CHECK;
// Check it's not in the future
(void)_isOurs;
if (bi.timestamp > (u256)time(0)/* && !_isOurs*/)
{
m_future.insert(make_pair((unsigned)bi.timestamp, make_pair(h, _block.toBytes())));
char buf[24];
time_t bit = (unsigned)bi.timestamp;
if (strftime(buf, 24, "%X", localtime(&bit)) == 0)
buf[0] = '\0'; // empty if case strftime fails
clog(BlockQueueTraceChannel) << "OK - queued for future [" << bi.timestamp << "vs" << time(0) << "] - will wait until" << buf;
m_unknownSize += _block.size();
m_unknownCount++;
m_difficulty += bi.difficulty;
bool unknown = !m_readySet.count(bi.parentHash) && !m_drainingSet.count(bi.parentHash) && !_bc.isKnown(bi.parentHash);
return unknown ? ImportResult::FutureTimeUnknown : ImportResult::FutureTimeKnown;
}
else
{
// We now know it.
if (m_knownBad.count(bi.parentHash))
{
m_knownBad.insert(bi.hash());
updateBad_WITH_LOCK(bi.hash());
// bad parent; this is bad too, note it as such
return ImportResult::BadChain;
}
else if (!m_readySet.count(bi.parentHash) && !m_drainingSet.count(bi.parentHash) && !_bc.isKnown(bi.parentHash))
{
// We don't know the parent (yet) - queue it up for later. It'll get resent to us if we find out about its ancestry later on.
clog(BlockQueueTraceChannel) << "OK - queued as unknown parent:" << bi.parentHash;
m_unknown.insert(make_pair(bi.parentHash, make_pair(h, _block.toBytes())));
m_unknownSet.insert(h);
m_unknownSize += _block.size();
m_difficulty += bi.difficulty;
m_unknownCount++;
return ImportResult::UnknownParent;
}
else
{
// If valid, append to blocks.
clog(BlockQueueTraceChannel) << "OK - ready for chain insertion.";
DEV_GUARDED(m_verification)
m_unverified.push_back(UnverifiedBlock { h, bi.parentHash, _block.toBytes() });
m_moreToVerify.notify_one();
m_readySet.insert(h);
m_knownSize += _block.size();
m_difficulty += bi.difficulty;
m_knownCount++;
noteReady_WITH_LOCK(h);
return ImportResult::Success;
}
}
}