Browse Source

State and Client minor cleanup

cl-refactor
arkpar 10 years ago
parent
commit
3db5d95716
  1. 4
      libdevcore/TrieDB.h
  2. 1
      libethcore/Exceptions.h
  3. 22
      libethereum/Client.cpp
  4. 1
      libethereum/Client.h
  5. 57
      libethereum/State.cpp

4
libdevcore/TrieDB.h

@ -158,8 +158,6 @@ public:
iterator lower_bound(bytesConstRef _key) const { return iterator(this, _key); } iterator lower_bound(bytesConstRef _key) const { return iterator(this, _key); }
void debugPrint() {}
/// Used for debugging, scans the whole trie. /// Used for debugging, scans the whole trie.
void descendKey(h256 const& _k, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent = 0) const void descendKey(h256 const& _k, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent = 0) const
{ {
@ -332,6 +330,7 @@ public:
void insert(KeyType _k, bytesConstRef _value) { Generic::insert(bytesConstRef((byte const*)&_k, sizeof(KeyType)), _value); } void insert(KeyType _k, bytesConstRef _value) { Generic::insert(bytesConstRef((byte const*)&_k, sizeof(KeyType)), _value); }
void insert(KeyType _k, bytes const& _value) { insert(_k, bytesConstRef(&_value)); } void insert(KeyType _k, bytes const& _value) { insert(_k, bytesConstRef(&_value)); }
void remove(KeyType _k) { Generic::remove(bytesConstRef((byte const*)&_k, sizeof(KeyType))); } void remove(KeyType _k) { Generic::remove(bytesConstRef((byte const*)&_k, sizeof(KeyType))); }
void debugStructure(std::ostream& _out) const { Generic::debugStructure(_out); }
class iterator: public Generic::iterator class iterator: public Generic::iterator
{ {
@ -386,6 +385,7 @@ public:
using Super::leftOvers; using Super::leftOvers;
using Super::check; using Super::check;
using Super::debugStructure;
std::string at(bytesConstRef _key) const { return Super::at(sha3(_key)); } std::string at(bytesConstRef _key) const { return Super::at(sha3(_key)); }
bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); } bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); }

1
libethcore/Exceptions.h

@ -71,6 +71,7 @@ DEV_SIMPLE_EXCEPTION(InvalidBlockHeaderItemCount);
DEV_SIMPLE_EXCEPTION(InvalidBlockNonce); DEV_SIMPLE_EXCEPTION(InvalidBlockNonce);
DEV_SIMPLE_EXCEPTION(InvalidParentHash); DEV_SIMPLE_EXCEPTION(InvalidParentHash);
DEV_SIMPLE_EXCEPTION(InvalidNumber); DEV_SIMPLE_EXCEPTION(InvalidNumber);
DEV_SIMPLE_EXCEPTION(BlockNotFound);
DEV_SIMPLE_EXCEPTION(DatabaseAlreadyOpen); DEV_SIMPLE_EXCEPTION(DatabaseAlreadyOpen);
DEV_SIMPLE_EXCEPTION(DAGCreationFailure); DEV_SIMPLE_EXCEPTION(DAGCreationFailure);

22
libethereum/Client.cpp

@ -38,6 +38,8 @@
#include "Executive.h" #include "Executive.h"
#include "EthereumHost.h" #include "EthereumHost.h"
#include "Utility.h" #include "Utility.h"
#include "TransactionQueue.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
@ -459,20 +461,8 @@ uint64_t Client::hashrate() const
std::list<MineInfo> Client::miningHistory() std::list<MineInfo> Client::miningHistory()
{ {
std::list<MineInfo> ret; //TODO: reimplement for CPU/GPU miner
/* ReadGuard l(x_localMiners); return std::list<MineInfo> {};
if (m_localMiners.empty())
return ret;
ret = m_localMiners[0].miningHistory();
for (unsigned i = 1; i < m_localMiners.size(); ++i)
{
auto l = m_localMiners[i].miningHistory();
auto ri = ret.begin();
auto li = l.begin();
for (; ri != ret.end() && li != l.end(); ++ri, ++li)
ri->combine(*li);
}*/
return ret;
} }
ExecutionResult Client::call(Address _dest, bytes const& _data, u256 _gas, u256 _value, u256 _gasPrice, Address const& _from) ExecutionResult Client::call(Address _dest, bytes const& _data, u256 _gas, u256 _value, u256 _gasPrice, Address const& _from)
@ -481,7 +471,7 @@ ExecutionResult Client::call(Address _dest, bytes const& _data, u256 _gas, u256
try try
{ {
State temp; State temp;
// clog(ClientTrace) << "Nonce at " << toAddress(_secret) << " pre:" << m_preMine.transactionsFrom(toAddress(_secret)) << " post:" << m_postMine.transactionsFrom(toAddress(_secret)); clog(ClientDetail) << "Nonce at " << _dest << " pre:" << m_preMine.transactionsFrom(_dest) << " post:" << m_postMine.transactionsFrom(_dest);
DEV_READ_GUARDED(x_postMine) DEV_READ_GUARDED(x_postMine)
temp = m_postMine; temp = m_postMine;
temp.addBalance(_from, _value + _gasPrice * _gas); temp.addBalance(_from, _value + _gasPrice * _gas);
@ -493,7 +483,7 @@ ExecutionResult Client::call(Address _dest, bytes const& _data, u256 _gas, u256
} }
catch (...) catch (...)
{ {
// TODO: Some sort of notification of failure. cwarn << "Client::call failed: " << boost::current_exception_diagnostic_information();
} }
return ret; return ret;
} }

1
libethereum/Client.h

@ -40,7 +40,6 @@
#include <libethcore/Farm.h> #include <libethcore/Farm.h>
#include <libp2p/Common.h> #include <libp2p/Common.h>
#include "CanonBlockChain.h" #include "CanonBlockChain.h"
#include "TransactionQueue.h"
#include "State.h" #include "State.h"
#include "CommonNet.h" #include "CommonNet.h"
#include "ClientBase.h" #include "ClientBase.h"

57
libethereum/State.cpp

@ -72,8 +72,8 @@ OverlayDB State::openDB(std::string const& _basePath, WithExisting _we)
o.max_open_files = 256; o.max_open_files = 256;
o.create_if_missing = true; o.create_if_missing = true;
ldb::DB* db = nullptr; ldb::DB* db = nullptr;
ldb::DB::Open(o, path + "/state", &db); ldb::Status status = ldb::DB::Open(o, path + "/state", &db);
if (!db) if (!status.ok() || !db)
{ {
if (boost::filesystem::space(path + "/state").available < 1024) if (boost::filesystem::space(path + "/state").available < 1024)
{ {
@ -82,6 +82,7 @@ OverlayDB State::openDB(std::string const& _basePath, WithExisting _we)
} }
else else
{ {
cwarn << status.ToString();
cwarn << "Database already open. You appear to have another instance of ethereum running. Bailing."; cwarn << "Database already open. You appear to have another instance of ethereum running. Bailing.";
BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen()); BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen());
} }
@ -129,7 +130,7 @@ PopulationStatistics State::populateFromChain(BlockChain const& _bc, h256 const&
{ {
// Might be worth throwing here. // Might be worth throwing here.
cwarn << "Invalid block given for state population: " << _h; cwarn << "Invalid block given for state population: " << _h;
return ret; BOOST_THROW_EXCEPTION(BlockNotFound() << errinfo_target(_h));
} }
auto b = _bc.block(_h); auto b = _bc.block(_h);
@ -244,9 +245,6 @@ StateDiff State::diff(State const& _c, bool _quick) const
for (auto const& i: _c.m_cache) for (auto const& i: _c.m_cache)
ads.insert(i.first); ads.insert(i.first);
// cnote << *this;
// cnote << _c;
for (auto const& i: ads) for (auto const& i: ads)
{ {
auto it = m_cache.find(i); auto it = m_cache.find(i);
@ -305,14 +303,14 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, Impor
bool ret = false; bool ret = false;
// BLOCK // BLOCK
BlockInfo bi = _bi ? _bi : _bc.info(_block); BlockInfo bi = _bi ? _bi : _bc.info(_block);
/* if (!bi) #if ETH_PARANOIA
if (!bi)
while (1) while (1)
{ {
try try
{ {
auto b = _bc.block(_block); auto b = _bc.block(_block);
bi.populate(b); bi.populate(b);
// bi.verifyInternals(_bc.block(_block)); // Unneeded - we already verify on import into the blockchain.
break; break;
} }
catch (Exception const& _e) catch (Exception const& _e)
@ -327,7 +325,8 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, Impor
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl; cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
cerr << _e.what() << endl; cerr << _e.what() << endl;
} }
}*/ }
#endif
if (bi == m_currentBlock) if (bi == m_currentBlock)
{ {
// We mined the last block. // We mined the last block.
@ -352,7 +351,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, Impor
cwarn << "Unable to sync to" << bi.hash() << "; state root" << bi.stateRoot << "not found in database."; cwarn << "Unable to sync to" << bi.hash() << "; state root" << bi.stateRoot << "not found in database.";
cwarn << "Database corrupt: contains block without stateRoot:" << bi; cwarn << "Database corrupt: contains block without stateRoot:" << bi;
cwarn << "Bailing."; cwarn << "Bailing.";
exit(-1); BOOST_THROW_EXCEPTION(InvalidStateRoot() << errinfo_target(bi.stateRoot));
} }
m_previousBlock = bi; m_previousBlock = bi;
resetCurrent(); resetCurrent();
@ -477,7 +476,6 @@ void State::resetCurrent()
m_currentBlock.sha3Uncles = h256(); m_currentBlock.sha3Uncles = h256();
m_currentBlock.populateFromParent(m_previousBlock); m_currentBlock.populateFromParent(m_previousBlock);
// Update timestamp according to clock.
// TODO: check. // TODO: check.
m_lastTx = m_db; m_lastTx = m_db;
@ -557,7 +555,6 @@ pair<TransactionReceipts, bool> State::sync(BlockChain const& _bc, TransactionQu
// Temporarily no gas left in current block. // Temporarily no gas left in current block.
// OPTIMISE: could note this and then we don't evaluate until a block that does have the gas left. // OPTIMISE: could note this and then we don't evaluate until a block that does have the gas left.
// for now, just leave alone. // for now, just leave alone.
// _tq.setFuture(t.sha3());
} }
} }
catch (Exception const& _e) catch (Exception const& _e)
@ -782,7 +779,8 @@ void State::cleanup(bool _fullCommit)
if (isChannelVisible<StateTrace>()) // Avoid calling toHex if not needed if (isChannelVisible<StateTrace>()) // Avoid calling toHex if not needed
clog(StateTrace) << "Committing to disk: stateRoot" << m_currentBlock.stateRoot << "=" << rootHash() << "=" << toHex(asBytes(m_db.lookup(rootHash()))); clog(StateTrace) << "Committing to disk: stateRoot" << m_currentBlock.stateRoot << "=" << rootHash() << "=" << toHex(asBytes(m_db.lookup(rootHash())));
try { try
{
EnforceRefs er(m_db, true); EnforceRefs er(m_db, true);
rootHash(); rootHash();
} }
@ -835,12 +833,6 @@ void State::commitToMine(BlockChain const& _bc, bytes const& _extraData)
{ {
uncommitToMine(); uncommitToMine();
// cnote << "Committing to mine on block" << m_previousBlock.hash;
#if ETH_PARANOIA && 0
commit();
cnote << "Pre-reward stateRoot:" << m_state.root();
#endif
m_lastTx = m_db; m_lastTx = m_db;
vector<BlockInfo> uncleBlockHeaders; vector<BlockInfo> uncleBlockHeaders;
@ -850,7 +842,7 @@ void State::commitToMine(BlockChain const& _bc, bytes const& _extraData)
if (m_previousBlock.number != 0) if (m_previousBlock.number != 0)
{ {
// Find great-uncles (or second-cousins or whatever they are) - children of great-grandparents, great-great-grandparents... that were not already uncles in previous generations. // Find great-uncles (or second-cousins or whatever they are) - children of great-grandparents, great-great-grandparents... that were not already uncles in previous generations.
// cout << "Checking " << m_previousBlock.hash << ", parent=" << m_previousBlock.parentHash << endl; clog(StateDetail) << "Checking " << m_previousBlock.hash() << ", parent=" << m_previousBlock.parentHash;
h256Hash excluded = _bc.allKinFrom(m_currentBlock.parentHash, 6); h256Hash excluded = _bc.allKinFrom(m_currentBlock.parentHash, 6);
auto p = m_previousBlock.parentHash; auto p = m_previousBlock.parentHash;
for (unsigned gen = 0; gen < 6 && p != _bc.genesisHash() && unclesCount < 2; ++gen, p = _bc.details(p).parent) for (unsigned gen = 0; gen < 6 && p != _bc.genesisHash() && unclesCount < 2; ++gen, p = _bc.details(p).parent)
@ -907,9 +899,9 @@ void State::commitToMine(BlockChain const& _bc, bytes const& _extraData)
// Commit any and all changes to the trie that are in the cache, then update the state root accordingly. // Commit any and all changes to the trie that are in the cache, then update the state root accordingly.
commit(); commit();
// cnote << "Post-reward stateRoot:" << m_state.root(); clog(StateDetail) << "Post-reward stateRoot:" << m_state.root();
// cnote << m_state; clog(StateDetail) << m_state;
// cnote << *this; clog(StateDetail) << *this;
m_currentBlock.gasUsed = gasUsed(); m_currentBlock.gasUsed = gasUsed();
m_currentBlock.stateRoot = m_state.root(); m_currentBlock.stateRoot = m_state.root();
@ -923,7 +915,7 @@ void State::commitToMine(BlockChain const& _bc, bytes const& _extraData)
void State::completeMine() void State::completeMine()
{ {
cdebug << "Completing mine!"; clog(StateDetail) << "Completing mine!";
// Got it! // Got it!
// Compile block: // Compile block:
@ -1086,6 +1078,17 @@ unordered_map<u256, u256> State::storage(Address const& _id) const
return ret; return ret;
} }
h256 State::storageRoot(Address const& _id) const
{
string s = m_state.at(_id);
if (s.size())
{
RLP r(s);
return r[2].toHash<h256>();
}
return EmptyTrie;
}
bytes const& State::code(Address const& _contract) const bytes const& State::code(Address const& _contract) const
{ {
if (!addressHasCode(_contract)) if (!addressHasCode(_contract))
@ -1115,7 +1118,7 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const
cwarn << "LEFTOVERS" << (e ? "[enforced" : "[unenforced") << "refs]"; cwarn << "LEFTOVERS" << (e ? "[enforced" : "[unenforced") << "refs]";
cnote << "Left:" << lo; cnote << "Left:" << lo;
cnote << "Keys:" << m_db.keys(); cnote << "Keys:" << m_db.keys();
// m_state.debugStructure(cerr); m_state.debugStructure(cerr);
return false; return false;
} }
// TODO: Enable once fixed. // TODO: Enable once fixed.
@ -1132,14 +1135,12 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const
{ {
cwarn << "BAD TRIE" << (e ? "[enforced" : "[unenforced") << "refs]"; cwarn << "BAD TRIE" << (e ? "[enforced" : "[unenforced") << "refs]";
cnote << m_db.keys(); cnote << m_db.keys();
// m_state.debugStructure(cerr); m_state.debugStructure(cerr);
return false; return false;
} }
return true; return true;
} }
#define ETH_VMTIMER 1
ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Permanence _p, OnOpFunc const& _onOp) ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Permanence _p, OnOpFunc const& _onOp)
{ {
#if ETH_PARANOIA #if ETH_PARANOIA

Loading…
Cancel
Save