Browse Source

Merge branch 'develop' of github.com:ethereum/cpp-ethereum into develop

cl-refactor
Gav Wood 10 years ago
parent
commit
33e9ec32bc
  1. 100
      mix/MixClient.cpp
  2. 7
      mix/MixClient.h

100
mix/MixClient.cpp

@ -27,6 +27,7 @@
#include <libethereum/Transaction.h> #include <libethereum/Transaction.h>
#include <libethereum/Executive.h> #include <libethereum/Executive.h>
#include <libethereum/ExtVM.h> #include <libethereum/ExtVM.h>
#include <libethereum/BlockChain.h>
#include <libevm/VM.h> #include <libevm/VM.h>
#include "Exceptions.h" #include "Exceptions.h"
@ -34,15 +35,37 @@
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
using namespace dev::mix;
namespace dev
{
namespace mix
{
const Secret c_userAccountSecret = Secret("cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074"); const Secret c_userAccountSecret = Secret("cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074");
const u256 c_mixGenesisDifficulty = (u256) 1 << 4;
class MixBlockChain: public dev::eth::BlockChain
{
public:
MixBlockChain(std::string const& _path, h256 _stateRoot): BlockChain(createGenesisBlock(_stateRoot), _path, true)
{
}
static bytes createGenesisBlock(h256 _stateRoot)
{
RLPStream block(3);
block.appendList(14)
<< h256() << EmptyListSHA3 << h160() << _stateRoot << EmptyTrie << EmptyTrie << LogBloom() << c_mixGenesisDifficulty << 0 << 1000000 << 0 << (unsigned)0 << std::string() << sha3(bytes(1, 42));
block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList);
return block.out();
}
};
MixClient::MixClient(std::string const& _dbPath): MixClient::MixClient(std::string const& _dbPath):
m_userAccount(c_userAccountSecret), m_bc(_dbPath, true), m_dbPath(_dbPath), m_minigThreads(0) m_userAccount(c_userAccountSecret), m_dbPath(_dbPath), m_minigThreads(0)
{ {
//TODO: put this into genesis block somehow resetState(10000000 * ether);
//resetState(10000000 * ether);
} }
MixClient::~MixClient() MixClient::~MixClient()
@ -50,23 +73,25 @@ MixClient::~MixClient()
} }
void MixClient::resetState(u256 _balance) void MixClient::resetState(u256 _balance)
{
(void) _balance;
{ {
WriteGuard l(x_state); WriteGuard l(x_state);
Guard fl(m_filterLock); Guard fl(m_filterLock);
m_filters.clear(); m_filters.clear();
m_watches.clear(); m_watches.clear();
m_bc.reopen(m_dbPath, true);
m_state = eth::State();
m_stateDB = OverlayDB(); m_stateDB = OverlayDB();
m_state = eth::State(m_userAccount.address(), m_stateDB, BaseState::CanonGenesis); TrieDB<Address, MemoryDB> accountState(&m_stateDB);
m_state.sync(m_bc); accountState.init();
std::map<Address, Account> genesisState = { std::make_pair(KeyPair(c_userAccountSecret).address(), Account(_balance, Account::NormalCreation)) };
dev::eth::commit(genesisState, static_cast<MemoryDB&>(m_stateDB), accountState);
h256 stateRoot = accountState.root();
m_bc.reset();
m_bc.reset(new MixBlockChain(m_dbPath, stateRoot));
m_state = eth::State(m_userAccount.address(), m_stateDB, BaseState::Empty);
m_state.sync(bc());
m_startState = m_state; m_startState = m_state;
m_pendingExecutions.clear(); m_pendingExecutions.clear();
} }
mine();
}
void MixClient::executeTransaction(Transaction const& _t, State& _state) void MixClient::executeTransaction(Transaction const& _t, State& _state)
{ {
@ -74,9 +99,9 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state)
// do debugging run first // do debugging run first
LastHashes lastHashes(256); LastHashes lastHashes(256);
lastHashes[0] = m_bc.numberHash(m_bc.number()); lastHashes[0] = bc().numberHash(bc().number());
for (unsigned i = 1; i < 256; ++i) for (unsigned i = 1; i < 256; ++i)
lastHashes[i] = lastHashes[i - 1] ? m_bc.details(lastHashes[i - 1]).parent : h256(); lastHashes[i] = lastHashes[i - 1] ? bc().details(lastHashes[i - 1]).parent : h256();
State execState = _state; State execState = _state;
Executive execution(execState, lastHashes, 0); Executive execution(execState, lastHashes, 0);
@ -155,7 +180,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state)
h256Set changed; h256Set changed;
Guard l(m_filterLock); Guard l(m_filterLock);
for (std::pair<h256 const, eth::InstalledFilter>& i: m_filters) for (std::pair<h256 const, eth::InstalledFilter>& i: m_filters)
if ((unsigned)i.second.filter.latest() > m_bc.number()) if ((unsigned)i.second.filter.latest() > bc().number())
{ {
// acceptable number. // acceptable number.
auto m = i.second.filter.matches(_state.receipt(_state.pending().size() - 1)); auto m = i.second.filter.matches(_state.receipt(_state.pending().size() - 1));
@ -163,7 +188,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state)
{ {
// filter catches them // filter catches them
for (LogEntry const& l: m) for (LogEntry const& l: m)
i.second.changes.push_back(LocalisedLogEntry(l, m_bc.number() + 1)); i.second.changes.push_back(LocalisedLogEntry(l, bc().number() + 1));
changed.insert(i.first); changed.insert(i.first);
} }
} }
@ -174,11 +199,11 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state)
void MixClient::mine() void MixClient::mine()
{ {
WriteGuard l(x_state); WriteGuard l(x_state);
m_state.commitToMine(m_bc); m_state.commitToMine(bc());
while (!m_state.mine(100, true).completed) {} while (!m_state.mine(100, true).completed) {}
m_state.completeMine(); m_state.completeMine();
m_bc.import(m_state.blockData(), m_stateDB); bc().import(m_state.blockData(), m_stateDB);
m_state.sync(m_bc); m_state.sync(bc());
//m_state.cleanup(true); //m_state.cleanup(true);
m_startState = m_state; m_startState = m_state;
m_executions.emplace_back(std::move(m_pendingExecutions)); m_executions.emplace_back(std::move(m_pendingExecutions));
@ -188,7 +213,7 @@ void MixClient::mine()
ExecutionResult const& MixClient::execution(unsigned _block, unsigned _transaction) const ExecutionResult const& MixClient::execution(unsigned _block, unsigned _transaction) const
{ {
if (_block == m_bc.number() + 1) if (_block == bc().number() + 1)
return m_pendingExecutions.at(_transaction); return m_pendingExecutions.at(_transaction);
return m_executions.at(_block).at(_transaction); return m_executions.at(_block).at(_transaction);
} }
@ -213,14 +238,13 @@ State MixClient::asOf(int _block) const
else if (_block == -1) else if (_block == -1)
return m_startState; return m_startState;
else else
return State(m_stateDB, m_bc, m_bc.numberHash(_block)); return State(m_stateDB, bc(), bc().numberHash(_block));
} }
void MixClient::transact(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) void MixClient::transact(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice)
{ {
WriteGuard l(x_state); WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_secret)); u256 n = m_state.transactionsFrom(toAddress(_secret));
_gasPrice = 0; //TODO: remove after fixing setBalance
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret);
executeTransaction(t, m_state); executeTransaction(t, m_state);
} }
@ -229,7 +253,6 @@ Address MixClient::transact(Secret _secret, u256 _endowment, bytes const& _init,
{ {
WriteGuard l(x_state); WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_secret)); u256 n = m_state.transactionsFrom(toAddress(_secret));
_gasPrice = 0; //TODO: remove after fixing setBalance
eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret);
executeTransaction(t, m_state); executeTransaction(t, m_state);
Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); Address address = right160(sha3(rlpList(t.sender(), t.nonce())));
@ -301,12 +324,12 @@ eth::LocalisedLogEntries MixClient::logs(unsigned _watchId) const
eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const
{ {
LocalisedLogEntries ret; LocalisedLogEntries ret;
unsigned lastBlock = m_bc.number(); unsigned lastBlock = bc().number();
unsigned block = std::min<unsigned>(lastBlock, (unsigned)_f.latest()); unsigned block = std::min<unsigned>(lastBlock, (unsigned)_f.latest());
unsigned end = std::min(lastBlock, std::min(block, (unsigned)_f.earliest())); unsigned end = std::min(lastBlock, std::min(block, (unsigned)_f.earliest()));
unsigned skip = _f.skip(); unsigned skip = _f.skip();
// Pending transactions // Pending transactions
if (block > m_bc.number()) if (block > bc().number())
{ {
ReadGuard l(x_state); ReadGuard l(x_state);
for (unsigned i = 0; i < m_state.pending().size(); ++i) for (unsigned i = 0; i < m_state.pending().size(); ++i)
@ -318,15 +341,15 @@ eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const
ret.insert(ret.begin(), LocalisedLogEntry(logEntries[entry], block)); ret.insert(ret.begin(), LocalisedLogEntry(logEntries[entry], block));
skip -= std::min(skip, static_cast<unsigned>(logEntries.size())); skip -= std::min(skip, static_cast<unsigned>(logEntries.size()));
} }
block = m_bc.number(); block = bc().number();
} }
// The rest // The rest
auto h = m_bc.numberHash(block); auto h = bc().numberHash(block);
for (; ret.size() != block && block != end; block--) for (; ret.size() != block && block != end; block--)
{ {
if (_f.matches(m_bc.info(h).logBloom)) if (_f.matches(bc().info(h).logBloom))
for (TransactionReceipt receipt: m_bc.receipts(h).receipts) for (TransactionReceipt receipt: bc().receipts(h).receipts)
if (_f.matches(receipt.bloom())) if (_f.matches(receipt.bloom()))
{ {
LogEntries logEntries = _f.matches(receipt); LogEntries logEntries = _f.matches(receipt);
@ -334,7 +357,7 @@ eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const
ret.insert(ret.begin(), LocalisedLogEntry(logEntries[entry], block)); ret.insert(ret.begin(), LocalisedLogEntry(logEntries[entry], block));
skip -= std::min(skip, static_cast<unsigned>(logEntries.size())); skip -= std::min(skip, static_cast<unsigned>(logEntries.size()));
} }
h = m_bc.details(h).parent; h = bc().details(h).parent;
} }
return ret; return ret;
} }
@ -416,22 +439,22 @@ LocalisedLogEntries MixClient::checkWatch(unsigned _watchId)
h256 MixClient::hashFromNumber(unsigned _number) const h256 MixClient::hashFromNumber(unsigned _number) const
{ {
return m_bc.numberHash(_number); return bc().numberHash(_number);
} }
eth::BlockInfo MixClient::blockInfo(h256 _hash) const eth::BlockInfo MixClient::blockInfo(h256 _hash) const
{ {
return BlockInfo(m_bc.block(_hash)); return BlockInfo(bc().block(_hash));
} }
eth::BlockDetails MixClient::blockDetails(h256 _hash) const eth::BlockDetails MixClient::blockDetails(h256 _hash) const
{ {
return m_bc.details(_hash); return bc().details(_hash);
} }
eth::Transaction MixClient::transaction(h256 _blockHash, unsigned _i) const eth::Transaction MixClient::transaction(h256 _blockHash, unsigned _i) const
{ {
auto bl = m_bc.block(_blockHash); auto bl = bc().block(_blockHash);
RLP b(bl); RLP b(bl);
if (_i < b[1].itemCount()) if (_i < b[1].itemCount())
return Transaction(b[1][_i].data(), CheckSignature::Range); return Transaction(b[1][_i].data(), CheckSignature::Range);
@ -441,7 +464,7 @@ eth::Transaction MixClient::transaction(h256 _blockHash, unsigned _i) const
eth::BlockInfo MixClient::uncle(h256 _blockHash, unsigned _i) const eth::BlockInfo MixClient::uncle(h256 _blockHash, unsigned _i) const
{ {
auto bl = m_bc.block(_blockHash); auto bl = bc().block(_blockHash);
RLP b(bl); RLP b(bl);
if (_i < b[2].itemCount()) if (_i < b[2].itemCount())
return BlockInfo::fromHeader(b[2][_i].data()); return BlockInfo::fromHeader(b[2][_i].data());
@ -451,7 +474,7 @@ eth::BlockInfo MixClient::uncle(h256 _blockHash, unsigned _i) const
unsigned MixClient::number() const unsigned MixClient::number() const
{ {
return m_bc.number(); return bc().number();
} }
eth::Transactions MixClient::pending() const eth::Transactions MixClient::pending() const
@ -461,7 +484,7 @@ eth::Transactions MixClient::pending() const
eth::StateDiff MixClient::diff(unsigned _txi, h256 _block) const eth::StateDiff MixClient::diff(unsigned _txi, h256 _block) const
{ {
State st(m_stateDB, m_bc, _block); State st(m_stateDB, bc(), _block);
return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); return st.fromPending(_txi).diff(st.fromPending(_txi + 1));
} }
@ -526,3 +549,6 @@ eth::MineProgress MixClient::miningProgress() const
{ {
return eth::MineProgress(); return eth::MineProgress();
} }
}
}

7
mix/MixClient.h

@ -27,7 +27,6 @@
#include <string> #include <string>
#include <libethereum/Interface.h> #include <libethereum/Interface.h>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include <libethereum/CanonBlockChain.h>
#include "MachineStates.h" #include "MachineStates.h"
namespace dev namespace dev
@ -35,6 +34,8 @@ namespace dev
namespace mix namespace mix
{ {
class MixBlockChain;
class MixClient: public dev::eth::Interface class MixClient: public dev::eth::Interface
{ {
public: public:
@ -90,12 +91,14 @@ private:
void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state); void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state);
void noteChanged(h256Set const& _filters); void noteChanged(h256Set const& _filters);
dev::eth::State asOf(int _block) const; dev::eth::State asOf(int _block) const;
MixBlockChain& bc() { return *m_bc; }
MixBlockChain const& bc() const { return *m_bc; }
KeyPair m_userAccount; KeyPair m_userAccount;
eth::State m_state; eth::State m_state;
eth::State m_startState; eth::State m_startState;
OverlayDB m_stateDB; OverlayDB m_stateDB;
eth::CanonBlockChain m_bc; std::auto_ptr<MixBlockChain> m_bc;
mutable boost::shared_mutex x_state; mutable boost::shared_mutex x_state;
mutable std::mutex m_filterLock; mutable std::mutex m_filterLock;
std::map<h256, dev::eth::InstalledFilter> m_filters; std::map<h256, dev::eth::InstalledFilter> m_filters;

Loading…
Cancel
Save