Browse Source

Faster State diffs.

Support canary contract to stop mining.
Manage rude nodes.
cl-refactor
Gav Wood 10 years ago
parent
commit
7bff0d1f7d
  1. 9
      eth/main.cpp
  2. 8
      libdevcore/Log.cpp
  3. 3
      libdevcore/Log.h
  4. 57
      libethereum/Client.cpp
  5. 19
      libethereum/Client.h
  6. 5
      libethereum/ClientBase.cpp
  7. 1
      libethereum/ClientBase.h
  8. 17
      libethereum/EthereumHost.cpp
  9. 7
      libethereum/EthereumHost.h
  10. 14
      libethereum/EthereumPeer.cpp
  11. 10
      libethereum/EthereumPeer.h
  12. 2
      libethereum/Interface.h
  13. 30
      libethereum/State.cpp
  14. 12
      libethereum/State.h

9
eth/main.cpp

@ -138,6 +138,7 @@ void help()
<< " -a,--address <addr> Set the coinbase (mining payout) address to addr (default: auto)." << endl << " -a,--address <addr> Set the coinbase (mining payout) address to addr (default: auto)." << endl
<< " -m,--mining <on/off/number> Enable mining, optionally for a specified number of blocks (default: off)" << endl << " -m,--mining <on/off/number> Enable mining, optionally for a specified number of blocks (default: off)" << endl
<< " -f,--force-mining Mine even when there are no transactions to mine (default: off)" << endl << " -f,--force-mining Mine even when there are no transactions to mine (default: off)" << endl
<< " --mine-on-wrong-chain Mine even when we know it's the wrong chain (default: off)" << endl
<< " -C,--cpu When mining, use the CPU." << endl << " -C,--cpu When mining, use the CPU." << endl
<< " -G,--opencl When mining use the GPU via OpenCL." << endl << " -G,--opencl When mining use the GPU via OpenCL." << endl
<< " --opencl-platform <n> When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl << " --opencl-platform <n> When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl
@ -279,6 +280,7 @@ int main(int argc, char** argv)
bool upnp = true; bool upnp = true;
WithExisting killChain = WithExisting::Trust; WithExisting killChain = WithExisting::Trust;
bool jit = false; bool jit = false;
string sentinel;
/// Networking params. /// Networking params.
string clientName; string clientName;
@ -294,6 +296,7 @@ int main(int argc, char** argv)
/// Mining params /// Mining params
unsigned mining = 0; unsigned mining = 0;
bool forceMining = false; bool forceMining = false;
bool mineOnWrongChain = false;
Address signingKey; Address signingKey;
Address sessionKey; Address sessionKey;
Address beneficiary = signingKey; Address beneficiary = signingKey;
@ -376,6 +379,10 @@ int main(int argc, char** argv)
mode = OperationMode::Export; mode = OperationMode::Export;
filename = argv[++i]; filename = argv[++i];
} }
else if (arg == "--sentinel" && i + 1 < argc)
sentinel = argv[++i];
else if (arg == "--mine-on-wrong-chain")
mineOnWrongChain = true;
else if (arg == "--format" && i + 1 < argc) else if (arg == "--format" && i + 1 < argc)
{ {
string m = argv[++i]; string m = argv[++i];
@ -671,6 +678,8 @@ int main(int argc, char** argv)
nodeMode == NodeMode::Full ? set<string>{"eth"/*, "shh"*/} : set<string>(), nodeMode == NodeMode::Full ? set<string>{"eth"/*, "shh"*/} : set<string>(),
netPrefs, netPrefs,
&nodesState); &nodesState);
web3.ethereum()->setMineOnBadChain(mineOnWrongChain);
web3.ethereum()->setSentinel(sentinel);
auto toNumber = [&](string const& s) -> unsigned { auto toNumber = [&](string const& s) -> unsigned {
if (s == "latest") if (s == "latest")

8
libdevcore/Log.cpp

@ -40,6 +40,14 @@ mutex x_logOverride;
/// or equal to the currently output verbosity (g_logVerbosity). /// or equal to the currently output verbosity (g_logVerbosity).
static map<type_info const*, bool> s_logOverride; static map<type_info const*, bool> s_logOverride;
bool isLogVisible(std::type_info const* _ch, bool _default)
{
Guard l(x_logOverride);
if (s_logOverride.count(_ch))
return s_logOverride[_ch];
return _default;
}
LogOverrideAux::LogOverrideAux(std::type_info const* _ch, bool _value): LogOverrideAux::LogOverrideAux(std::type_info const* _ch, bool _value):
m_ch(_ch) m_ch(_ch)
{ {

3
libdevcore/Log.h

@ -73,6 +73,9 @@ public:
LogOverride(bool _value): LogOverrideAux(&typeid(Channel), _value) {} LogOverride(bool _value): LogOverrideAux(&typeid(Channel), _value) {}
}; };
bool isChannelVisible(std::type_info const* _ch, bool _default);
template <class Channel> bool isChannelVisible() { return isChannelVisible(&typeid(Channel), Channel::verbosity <= g_logVerbosity); }
/// Temporary changes system's verbosity for specific function. Restores the old verbosity when function returns. /// Temporary changes system's verbosity for specific function. Restores the old verbosity when function returns.
/// Not thread-safe, use with caution! /// Not thread-safe, use with caution!
struct VerbosityHolder struct VerbosityHolder

57
libethereum/Client.cpp

@ -310,6 +310,18 @@ Client::~Client()
stopWorking(); stopWorking();
} }
static const Address c_canary("0x");
bool Client::isChainBad() const
{
return stateAt(c_canary, 0) != 0;
}
bool Client::isUpgradeNeeded() const
{
return stateAt(c_canary, 0) == 2;
}
void Client::setNetworkId(u256 _n) void Client::setNetworkId(u256 _n)
{ {
if (auto h = m_host.lock()) if (auto h = m_host.lock())
@ -552,6 +564,9 @@ ProofOfWork::WorkPackage Client::getWork()
bool oldShould = shouldServeWork(); bool oldShould = shouldServeWork();
m_lastGetWork = chrono::system_clock::now(); m_lastGetWork = chrono::system_clock::now();
if (!m_mineOnBadChain && isChainBad())
return ProofOfWork::WorkPackage();
// if this request has made us bother to serve work, prep it now. // if this request has made us bother to serve work, prep it now.
if (!oldShould && shouldServeWork()) if (!oldShould && shouldServeWork())
onPostStateChanged(); onPostStateChanged();
@ -709,11 +724,22 @@ bool Client::remoteActive() const
void Client::onPostStateChanged() void Client::onPostStateChanged()
{ {
cnote << "Post state changed"; cnote << "Post state changed.";
rejigMining();
m_remoteWorking = false;
}
void Client::startMining()
{
m_wouldMine = true;
rejigMining();
}
if (m_bq.items().first == 0 && (isMining() || remoteActive())) void Client::rejigMining()
{
if ((wouldMine() || remoteActive()) && !m_bq.items().first && (!isChainBad() || mineOnBadChain()) /*&& (forceMining() || transactionsWaiting())*/)
{ {
cnote << "Restarting mining..."; cnote << "Rejigging mining...";
DEV_WRITE_GUARDED(x_working) DEV_WRITE_GUARDED(x_working)
m_working.commitToMine(m_bc); m_working.commitToMine(m_bc);
DEV_READ_GUARDED(x_working) DEV_READ_GUARDED(x_working)
@ -722,20 +748,21 @@ void Client::onPostStateChanged()
m_postMine = m_working; m_postMine = m_working;
m_miningInfo = m_postMine.info(); m_miningInfo = m_postMine.info();
} }
m_farm.setWork(m_miningInfo);
Ethash::ensurePrecomputed(m_bc.number()); if (m_wouldMine)
} {
m_remoteWorking = false; m_farm.setWork(m_miningInfo);
} if (m_turboMining)
m_farm.startGPU();
else
m_farm.startCPU();
void Client::startMining() m_farm.setWork(m_miningInfo);
{ Ethash::ensurePrecomputed(m_bc.number());
if (m_turboMining) }
m_farm.startGPU(); }
else if (!m_wouldMine)
m_farm.startCPU(); m_farm.stop();
onPostStateChanged();
} }
void Client::noteChanged(h256Hash const& _filters) void Client::noteChanged(h256Hash const& _filters)

19
libethereum/Client.h

@ -174,14 +174,26 @@ public:
/// Enable/disable GPU mining. /// Enable/disable GPU mining.
void setTurboMining(bool _enable = true) { m_turboMining = _enable; if (isMining()) startMining(); } void setTurboMining(bool _enable = true) { m_turboMining = _enable; if (isMining()) startMining(); }
/// Check to see if we'd mine on an apparently bad chain.
bool mineOnBadChain() const { return m_mineOnBadChain; }
/// Set true if you want to mine even when the canary says you're on the wrong chain.
void setMineOnBadChain(bool _v) { m_mineOnBadChain = _v; }
/// @returns true if the canary says that the chain is bad.
bool isChainBad() const;
/// @returns true if the canary says that the client should be upgraded.
bool isUpgradeNeeded() const;
/// Start mining. /// Start mining.
/// NOT thread-safe - call it & stopMining only from a single thread /// NOT thread-safe - call it & stopMining only from a single thread
void startMining() override; void startMining() override;
/// Stop mining. /// Stop mining.
/// NOT thread-safe /// NOT thread-safe
void stopMining() override { m_farm.stop(); } void stopMining() override { m_wouldMine = false; rejigMining(); }
/// Are we mining now? /// Are we mining now?
bool isMining() const override { return m_farm.isMining(); } bool isMining() const override { return m_farm.isMining(); }
/// Are we mining now?
bool wouldMine() const override { return m_wouldMine; }
/// The hashrate... /// The hashrate...
uint64_t hashrate() const override; uint64_t hashrate() const override;
/// Check the progress of the mining. /// Check the progress of the mining.
@ -251,6 +263,9 @@ private:
/// Called when Worker is exiting. /// Called when Worker is exiting.
void doneWorking() override; void doneWorking() override;
/// Called when wouldMine(), turboMining(), isChainBad(), forceMining(), pendingTransactions() have changed.
void rejigMining();
/// Magically called when the chain has changed. An import route is provided. /// Magically called when the chain has changed. An import route is provided.
/// Called by either submitWork() or in our main thread through syncBlockQueue(). /// Called by either submitWork() or in our main thread through syncBlockQueue().
void onChainChanged(ImportRoute const& _ir); void onChainChanged(ImportRoute const& _ir);
@ -308,8 +323,10 @@ private:
Handler m_tqReady; Handler m_tqReady;
Handler m_bqReady; Handler m_bqReady;
bool m_wouldMine = false; ///< True if we /should/ be mining.
bool m_turboMining = false; ///< Don't squander all of our time mining actually just sleeping. bool m_turboMining = false; ///< Don't squander all of our time mining actually just sleeping.
bool m_forceMining = false; ///< Mine even when there are no transactions pending? bool m_forceMining = false; ///< Mine even when there are no transactions pending?
bool m_mineOnBadChain = false; ///< Mine even when the canary says it's a bad chain.
bool m_paranoia = false; ///< Should we be paranoid about our state? bool m_paranoia = false; ///< Should we be paranoid about our state?
mutable std::chrono::system_clock::time_point m_lastGarbageCollection; mutable std::chrono::system_clock::time_point m_lastGarbageCollection;

5
libethereum/ClientBase.cpp

@ -400,17 +400,16 @@ h256s ClientBase::pendingHashes() const
return h256s() + postMine().pendingHashes(); return h256s() + postMine().pendingHashes();
} }
StateDiff ClientBase::diff(unsigned _txi, h256 _block) const StateDiff ClientBase::diff(unsigned _txi, h256 _block) const
{ {
State st = asOf(_block); State st = asOf(_block);
return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); return st.fromPending(_txi).diff(st.fromPending(_txi + 1), true);
} }
StateDiff ClientBase::diff(unsigned _txi, BlockNumber _block) const StateDiff ClientBase::diff(unsigned _txi, BlockNumber _block) const
{ {
State st = asOf(_block); State st = asOf(_block);
return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); return st.fromPending(_txi).diff(st.fromPending(_txi + 1), true);
} }
Addresses ClientBase::addresses(BlockNumber _block) const Addresses ClientBase::addresses(BlockNumber _block) const

1
libethereum/ClientBase.h

@ -154,6 +154,7 @@ public:
virtual void startMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::startMining")); } virtual void startMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::startMining")); }
virtual void stopMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::stopMining")); } virtual void stopMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::stopMining")); }
virtual bool isMining() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::isMining")); } virtual bool isMining() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::isMining")); }
virtual bool wouldMine() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::wouldMine")); }
virtual uint64_t hashrate() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::hashrate")); } virtual uint64_t hashrate() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::hashrate")); }
virtual MiningProgress miningProgress() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::miningProgress")); } virtual MiningProgress miningProgress() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::miningProgress")); }
virtual ProofOfWork::WorkPackage getWork() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::getWork")); } virtual ProofOfWork::WorkPackage getWork() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::getWork")); }

17
libethereum/EthereumHost.cpp

@ -276,6 +276,13 @@ void EthereumHost::estimatePeerHashes(EthereumPeer* _peer)
_peer->m_expectedHashes = blockCount; _peer->m_expectedHashes = blockCount;
} }
void EthereumHost::noteRude(p2p::NodeId const& _id, std::string const& _client)
{
cwarn << "RUDE node/client: " << _id << _client;
m_rudeNodes.insert(_id);
m_rudeClients.insert(_client);
}
void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes) void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes)
{ {
Guard l(x_sync); Guard l(x_sync);
@ -574,7 +581,7 @@ void EthereumHost::continueSync(EthereumPeer* _peer)
}); });
if (otherPeerSync) if (otherPeerSync)
{ {
/// Downloading from other peer with v60 protocol, nothing ese we can do /// Downloading from other peer with v60 protocol, nothing else we can do
_peer->setIdle(); _peer->setIdle();
return; return;
} }
@ -599,6 +606,10 @@ void EthereumHost::continueSync(EthereumPeer* _peer)
bool EthereumHost::peerShouldGrabBlocks(EthereumPeer* _peer) const bool EthereumHost::peerShouldGrabBlocks(EthereumPeer* _peer) const
{ {
// Early exit if this peer has proved unreliable.
if (_peer->isRude())
return false;
auto td = _peer->m_totalDifficulty; auto td = _peer->m_totalDifficulty;
auto lh = m_syncingLatestHash; auto lh = m_syncingLatestHash;
auto ctd = m_chain.details().totalDifficulty; auto ctd = m_chain.details().totalDifficulty;
@ -611,6 +622,10 @@ bool EthereumHost::peerShouldGrabBlocks(EthereumPeer* _peer) const
bool EthereumHost::peerShouldGrabChain(EthereumPeer* _peer) const bool EthereumHost::peerShouldGrabChain(EthereumPeer* _peer) const
{ {
// Early exit if this peer has proved unreliable.
if (_peer->isRude())
return false;
h256 c = m_chain.currentHash(); h256 c = m_chain.currentHash();
unsigned n = m_chain.number(); unsigned n = m_chain.number();
u256 td = m_chain.details().totalDifficulty; u256 td = m_chain.details().totalDifficulty;

7
libethereum/EthereumHost.h

@ -71,7 +71,9 @@ public:
DownloadMan const& downloadMan() const { return m_man; } DownloadMan const& downloadMan() const { return m_man; }
bool isSyncing() const { Guard l(x_sync); return isSyncing_UNSAFE(); } bool isSyncing() const { Guard l(x_sync); return isSyncing_UNSAFE(); }
bool isBanned(p2p::NodeId _id) const { return !!m_banned.count(_id); } bool isBanned(p2p::NodeId const& _id) const { return !!m_banned.count(_id); }
void noteRude(p2p::NodeId const& _id, std::string const& _client);
bool isRude(p2p::NodeId const& _id, std::string const& _client) const { return m_rudeClients.count(_client) && m_rudeNodes.count(_id); }
void noteNewTransactions() { m_newTransactions = true; } void noteNewTransactions() { m_newTransactions = true; }
void noteNewBlocks() { m_newBlocks = true; } void noteNewBlocks() { m_newBlocks = true; }
@ -147,6 +149,9 @@ private:
h256 m_syncingLatestHash; ///< Latest block's hash, as of the current sync. h256 m_syncingLatestHash; ///< Latest block's hash, as of the current sync.
u256 m_syncingTotalDifficulty; ///< Latest block's total difficulty, as of the current sync. u256 m_syncingTotalDifficulty; ///< Latest block's total difficulty, as of the current sync.
h256s m_hashes; ///< List of hashes with unknown block numbers. Used for v60 chain downloading and catching up to a particular unknown h256s m_hashes; ///< List of hashes with unknown block numbers. Used for v60 chain downloading and catching up to a particular unknown
std::unordered_set<p2p::NodeId> m_rudeNodes; ///< Nodes that were impolite while syncing. We avoid syncing from these if possible.
std::unordered_set<std::string> m_rudeClients; ///< Nodes that were impolite while syncing. We avoid syncing from these if possible.
}; };
} }

14
libethereum/EthereumPeer.cpp

@ -40,6 +40,8 @@ EthereumPeer::EthereumPeer(Session* _s, HostCapabilityFace* _h, unsigned _i, Cap
m_hashSub(host()->hashDownloadMan()), m_hashSub(host()->hashDownloadMan()),
m_peerCapabilityVersion(_cap.second) m_peerCapabilityVersion(_cap.second)
{ {
m_isRude = host()->isRude(session()->id(), session()->info().clientVersion);
session()->addNote("manners", m_isRude ? "RUDE" : "nice");
m_syncHashNumber = host()->chain().number() + 1; m_syncHashNumber = host()->chain().number() + 1;
requestStatus(); requestStatus();
} }
@ -52,8 +54,16 @@ EthereumPeer::~EthereumPeer()
void EthereumPeer::abortSync() void EthereumPeer::abortSync()
{ {
if (isSyncing()) if (m_asking != Asking::Nothing)
setIdle(); setRude();
setIdle();
}
void EthereumPeer::setRude()
{
m_isRude = true;
host()->noteRude(session()->id(), session()->info().clientVersion);
session()->addNote("manners", m_isRude ? "RUDE" : "nice");
} }
EthereumHost* EthereumPeer::host() const EthereumHost* EthereumPeer::host() const

10
libethereum/EthereumPeer.h

@ -82,6 +82,12 @@ public:
/// Request blocks. Uses block download manager. /// Request blocks. Uses block download manager.
void requestBlocks(); void requestBlocks();
/// Check if this node is rude.
bool isRude() const { return m_isRude; }
/// Set that it's a rude node.
void setRude();
private: private:
using p2p::Capability::sealAndSend; using p2p::Capability::sealAndSend;
@ -101,7 +107,7 @@ private:
void setAsking(Asking _g); void setAsking(Asking _g);
/// Do we presently need syncing with this peer? /// Do we presently need syncing with this peer?
bool needsSyncing() const { return !!m_latestHash; } bool needsSyncing() const { return !isRude() && !!m_latestHash; }
/// Are we presently syncing with this peer? /// Are we presently syncing with this peer?
bool isSyncing() const; bool isSyncing() const;
@ -145,6 +151,8 @@ private:
h256Hash m_knownBlocks; ///< Blocks that the peer already knows about (that don't need to be sent to them). h256Hash m_knownBlocks; ///< Blocks that the peer already knows about (that don't need to be sent to them).
Mutex x_knownTransactions; Mutex x_knownTransactions;
h256Hash m_knownTransactions; ///< Transactions that the peer already knows of. h256Hash m_knownTransactions; ///< Transactions that the peer already knows of.
bool m_isRude; ///< True if this node has been rude in the past.
}; };
} }

2
libethereum/Interface.h

@ -196,6 +196,8 @@ public:
virtual void stopMining() = 0; virtual void stopMining() = 0;
/// Are we mining now? /// Are we mining now?
virtual bool isMining() const = 0; virtual bool isMining() const = 0;
/// Would we like to mine now?
virtual bool wouldMine() const = 0;
/// Current hash rate. /// Current hash rate.
virtual uint64_t hashrate() const = 0; virtual uint64_t hashrate() const = 0;

30
libethereum/State.cpp

@ -158,6 +158,7 @@ State::State(State const& _s):
m_transactions(_s.m_transactions), m_transactions(_s.m_transactions),
m_receipts(_s.m_receipts), m_receipts(_s.m_receipts),
m_transactionSet(_s.m_transactionSet), m_transactionSet(_s.m_transactionSet),
m_touched(_s.m_touched),
m_cache(_s.m_cache), m_cache(_s.m_cache),
m_previousBlock(_s.m_previousBlock), m_previousBlock(_s.m_previousBlock),
m_currentBlock(_s.m_currentBlock), m_currentBlock(_s.m_currentBlock),
@ -206,7 +207,7 @@ State::~State()
{ {
} }
StateDiff State::diff(State const& _c) const StateDiff State::diff(State const& _c, bool _quick) const
{ {
StateDiff ret; StateDiff ret;
@ -217,10 +218,20 @@ StateDiff State::diff(State const& _c) const
auto trie = SecureTrieDB<Address, OverlayDB>(const_cast<OverlayDB*>(&m_db), rootHash()); auto trie = SecureTrieDB<Address, OverlayDB>(const_cast<OverlayDB*>(&m_db), rootHash());
auto trieD = SecureTrieDB<Address, OverlayDB>(const_cast<OverlayDB*>(&_c.m_db), _c.rootHash()); auto trieD = SecureTrieDB<Address, OverlayDB>(const_cast<OverlayDB*>(&_c.m_db), _c.rootHash());
for (auto i: trie) if (_quick)
ads.insert(i.first), trieAds.insert(i.first); {
for (auto i: trieD) trieAds = m_touched;
ads.insert(i.first), trieAdsD.insert(i.first); trieAdsD = _c.m_touched;
(ads += m_touched) += _c.m_touched;
}
else
{
for (auto i: trie)
ads.insert(i.first), trieAds.insert(i.first);
for (auto i: trieD)
ads.insert(i.first), trieAdsD.insert(i.first);
}
for (auto i: m_cache) for (auto i: m_cache)
ads.insert(i.first); ads.insert(i.first);
for (auto i: _c.m_cache) for (auto i: _c.m_cache)
@ -272,7 +283,7 @@ void State::ensureCached(std::unordered_map<Address, Account>& _cache, Address _
void State::commit() void State::commit()
{ {
dev::eth::commit(m_cache, m_db, m_state); m_touched += dev::eth::commit(m_cache, m_db, m_state);
m_cache.clear(); m_cache.clear();
} }
@ -450,6 +461,7 @@ void State::resetCurrent()
m_receipts.clear(); m_receipts.clear();
m_transactionSet.clear(); m_transactionSet.clear();
m_cache.clear(); m_cache.clear();
m_touched.clear();
m_currentBlock = BlockInfo(); m_currentBlock = BlockInfo();
m_currentBlock.coinbaseAddress = m_ourAddress; m_currentBlock.coinbaseAddress = m_ourAddress;
m_currentBlock.timestamp = max(m_previousBlock.timestamp + 1, (u256)time(0)); m_currentBlock.timestamp = max(m_previousBlock.timestamp + 1, (u256)time(0));
@ -1219,8 +1231,10 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per
if (!e.execute()) if (!e.execute())
#if ETH_VMTRACE #if ETH_VMTRACE
{ {
(void)_onOp; if (isChannelVisible<VMTraceChannel>())
e.go(e.simpleTrace()); e.go(e.simpleTrace());
else
e.go(_onOp);
} }
#else #else
e.go(_onOp); e.go(_onOp);

12
libethereum/State.h

@ -310,10 +310,12 @@ public:
State fromPending(unsigned _i) const; State fromPending(unsigned _i) const;
/// @returns the StateDiff caused by the pending transaction of index @a _i. /// @returns the StateDiff caused by the pending transaction of index @a _i.
StateDiff pendingDiff(unsigned _i) const { return fromPending(_i).diff(fromPending(_i + 1)); } StateDiff pendingDiff(unsigned _i) const { return fromPending(_i).diff(fromPending(_i + 1), true); }
/// @return the difference between this state (origin) and @a _c (destination). /// @return the difference between this state (origin) and @a _c (destination).
StateDiff diff(State const& _c) const; /// @param _quick if true doesn't check all addresses possible (/very/ slow for a full chain)
/// but rather only those touched by the transactions in creating the two States.
StateDiff diff(State const& _c, bool _quick = false) const;
/// Sync our state with the block chain. /// Sync our state with the block chain.
/// This basically involves wiping ourselves if we've been superceded and rebuilding from the transaction queue. /// This basically involves wiping ourselves if we've been superceded and rebuilding from the transaction queue.
@ -387,6 +389,7 @@ private:
TransactionReceipts m_receipts; ///< The corresponding list of transaction receipts. TransactionReceipts m_receipts; ///< The corresponding list of transaction receipts.
h256Hash m_transactionSet; ///< The set of transaction hashes that we've included in the state. h256Hash m_transactionSet; ///< The set of transaction hashes that we've included in the state.
OverlayDB m_lastTx; OverlayDB m_lastTx;
AddressHash m_touched; ///< Tracks all addresses touched by transactions so far.
mutable std::unordered_map<Address, Account> m_cache; ///< Our address cache. This stores the states of each address that has (or at least might have) been changed. mutable std::unordered_map<Address, Account> m_cache; ///< Our address cache. This stores the states of each address that has (or at least might have) been changed.
@ -410,8 +413,9 @@ private:
std::ostream& operator<<(std::ostream& _out, State const& _s); std::ostream& operator<<(std::ostream& _out, State const& _s);
template <class DB> template <class DB>
void commit(std::unordered_map<Address, Account> const& _cache, DB& _db, SecureTrieDB<Address, DB>& _state) AddressHash commit(std::unordered_map<Address, Account> const& _cache, DB& _db, SecureTrieDB<Address, DB>& _state)
{ {
AddressHash ret;
for (auto const& i: _cache) for (auto const& i: _cache)
if (i.second.isDirty()) if (i.second.isDirty())
{ {
@ -450,7 +454,9 @@ void commit(std::unordered_map<Address, Account> const& _cache, DB& _db, SecureT
_state.insert(i.first, &s.out()); _state.insert(i.first, &s.out());
} }
ret.insert(i.first);
} }
return ret;
} }
} }

Loading…
Cancel
Save