Browse Source

Merge pull request #952 from arkpar/mix_blockchain

mix: Custom genesis state
cl-refactor
Gav Wood 10 years ago
parent
commit
0927a7a3a8
  1. 114
      mix/MixClient.cpp
  2. 7
      mix/MixClient.h

114
mix/MixClient.cpp

@ -27,6 +27,7 @@
#include <libethereum/Transaction.h>
#include <libethereum/Executive.h>
#include <libethereum/ExtVM.h>
#include <libethereum/BlockChain.h>
#include <libevm/VM.h>
#include "Exceptions.h"
@ -34,15 +35,37 @@
using namespace dev;
using namespace dev::eth;
using namespace dev::mix;
namespace dev
{
namespace mix
{
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):
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()
@ -51,21 +74,23 @@ MixClient::~MixClient()
void MixClient::resetState(u256 _balance)
{
(void) _balance;
{
WriteGuard l(x_state);
Guard fl(m_filterLock);
m_filters.clear();
m_watches.clear();
m_bc.reopen(m_dbPath, true);
m_state = eth::State();
m_stateDB = OverlayDB();
m_state = eth::State(m_userAccount.address(), m_stateDB, BaseState::CanonGenesis);
m_state.sync(m_bc);
m_startState = m_state;
m_pendingExecutions.clear();
}
mine();
WriteGuard l(x_state);
Guard fl(m_filterLock);
m_filters.clear();
m_watches.clear();
m_stateDB = OverlayDB();
TrieDB<Address, MemoryDB> accountState(&m_stateDB);
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_pendingExecutions.clear();
}
void MixClient::executeTransaction(Transaction const& _t, State& _state)
@ -74,9 +99,9 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state)
// do debugging run first
LastHashes lastHashes(256);
lastHashes[0] = m_bc.numberHash(m_bc.number());
lastHashes[0] = bc().numberHash(bc().number());
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;
Executive execution(execState, lastHashes, 0);
@ -155,7 +180,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state)
h256Set changed;
Guard l(m_filterLock);
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.
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
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);
}
}
@ -174,11 +199,11 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state)
void MixClient::mine()
{
WriteGuard l(x_state);
m_state.commitToMine(m_bc);
m_state.commitToMine(bc());
while (!m_state.mine(100, true).completed) {}
m_state.completeMine();
m_bc.import(m_state.blockData(), m_stateDB);
m_state.sync(m_bc);
bc().import(m_state.blockData(), m_stateDB);
m_state.sync(bc());
//m_state.cleanup(true);
m_startState = m_state;
m_executions.emplace_back(std::move(m_pendingExecutions));
@ -188,7 +213,7 @@ void MixClient::mine()
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_executions.at(_block).at(_transaction);
}
@ -213,14 +238,13 @@ State MixClient::asOf(int _block) const
else if (_block == -1)
return m_startState;
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)
{
WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_secret));
_gasPrice = 0; //TODO: remove after fixing setBalance
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret);
executeTransaction(t, m_state);
}
@ -229,7 +253,6 @@ Address MixClient::transact(Secret _secret, u256 _endowment, bytes const& _init,
{
WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_secret));
_gasPrice = 0; //TODO: remove after fixing setBalance
eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret);
executeTransaction(t, m_state);
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
{
LocalisedLogEntries ret;
unsigned lastBlock = m_bc.number();
unsigned lastBlock = bc().number();
unsigned block = std::min<unsigned>(lastBlock, (unsigned)_f.latest());
unsigned end = std::min(lastBlock, std::min(block, (unsigned)_f.earliest()));
unsigned skip = _f.skip();
// Pending transactions
if (block > m_bc.number())
if (block > bc().number())
{
ReadGuard l(x_state);
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));
skip -= std::min(skip, static_cast<unsigned>(logEntries.size()));
}
block = m_bc.number();
block = bc().number();
}
// The rest
auto h = m_bc.numberHash(block);
auto h = bc().numberHash(block);
for (; ret.size() != block && block != end; block--)
{
if (_f.matches(m_bc.info(h).logBloom))
for (TransactionReceipt receipt: m_bc.receipts(h).receipts)
if (_f.matches(bc().info(h).logBloom))
for (TransactionReceipt receipt: bc().receipts(h).receipts)
if (_f.matches(receipt.bloom()))
{
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));
skip -= std::min(skip, static_cast<unsigned>(logEntries.size()));
}
h = m_bc.details(h).parent;
h = bc().details(h).parent;
}
return ret;
}
@ -416,22 +439,22 @@ LocalisedLogEntries MixClient::checkWatch(unsigned _watchId)
h256 MixClient::hashFromNumber(unsigned _number) const
{
return m_bc.numberHash(_number);
return bc().numberHash(_number);
}
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
{
return m_bc.details(_hash);
return bc().details(_hash);
}
eth::Transaction MixClient::transaction(h256 _blockHash, unsigned _i) const
{
auto bl = m_bc.block(_blockHash);
auto bl = bc().block(_blockHash);
RLP b(bl);
if (_i < b[1].itemCount())
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
{
auto bl = m_bc.block(_blockHash);
auto bl = bc().block(_blockHash);
RLP b(bl);
if (_i < b[2].itemCount())
return BlockInfo::fromHeader(b[2][_i].data());
@ -451,7 +474,7 @@ eth::BlockInfo MixClient::uncle(h256 _blockHash, unsigned _i) const
unsigned MixClient::number() const
{
return m_bc.number();
return bc().number();
}
eth::Transactions MixClient::pending() const
@ -461,7 +484,7 @@ eth::Transactions MixClient::pending() 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));
}
@ -526,3 +549,6 @@ eth::MineProgress MixClient::miningProgress() const
{
return eth::MineProgress();
}
}
}

7
mix/MixClient.h

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

Loading…
Cancel
Save