Browse Source

Accounts all the same "type".

cl-refactor
Gav Wood 11 years ago
parent
commit
5f6e533169
  1. 2
      libethcore/FixedHash.cpp
  2. 2
      libethcore/FixedHash.h
  3. 4
      libethereum/AddressState.cpp
  4. 43
      libethereum/AddressState.h
  5. 27
      libethereum/State.cpp
  6. 47
      libethereum/State.h

2
libethcore/FixedHash.cpp

@ -25,6 +25,8 @@
using namespace std;
using namespace eth;
h256 eth::EmptySHA3 = sha3(bytesConstRef());
std::string eth::sha3(std::string const& _input, bool _hex)
{
if (!_hex)

2
libethcore/FixedHash.h

@ -212,6 +212,8 @@ inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef((bytes*)&_inpu
/// Calculate SHA3-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash.
inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); }
extern h256 EmptySHA3;
}
namespace std

4
libethereum/AddressState.cpp

@ -25,9 +25,9 @@ using namespace std;
using namespace eth;
AddressState::AddressState(u256 _balance, u256 _nonce, bytesConstRef _code):
m_type(AddressType::Contract),
m_isAlive(true),
m_isComplete(true),
m_balance(_balance),
m_nonce(_nonce),
m_isComplete(true),
m_code(_code.toBytes())
{}

43
libethereum/AddressState.h

@ -27,49 +27,48 @@
namespace eth
{
enum class AddressType
{
Dead,
Normal,
Contract
};
// TODO: Don't pre-cache all of storage.
class AddressState
{
public:
AddressState(): m_type(AddressType::Dead), m_balance(0), m_nonce(0), m_isComplete(false) {}
AddressState(u256 _balance, u256 _nonce, AddressType _type = AddressType::Normal): m_type(_type), m_balance(_balance), m_nonce(_nonce), m_isComplete(true) {}
AddressState(u256 _balance, u256 _nonce, h256 _contractRoot, h256 _codeHash): m_type(AddressType::Contract), m_balance(_balance), m_nonce(_nonce), m_isComplete(false), m_contractRoot(_contractRoot), m_codeHash(_codeHash) {}
AddressState(): m_isAlive(false), m_isComplete(false), m_balance(0), m_nonce(0) {}
AddressState(u256 _balance, u256 _nonce, h256 _contractRoot, h256 _codeHash): m_isAlive(true), m_isComplete(_codeHash == EmptySHA3 && !_contractRoot), m_balance(_balance), m_nonce(_nonce), m_storageRoot(_contractRoot), m_codeHash(_codeHash) {}
AddressState(u256 _balance, u256 _nonce, bytesConstRef _code);
void incNonce() { m_nonce++; }
void addBalance(bigint _i) { m_balance = (u256)((bigint)m_balance + _i); }
void kill() { m_type = AddressType::Dead; m_memory.clear(); m_contractRoot = h256(); m_balance = 0; m_nonce = 0; }
void kill() { m_isAlive = false; m_storage.clear(); m_codeHash = EmptySHA3; m_storageRoot = h256(); m_balance = 0; m_nonce = 0; }
bool isAlive() const { return m_isAlive; }
AddressType type() const { return m_type; }
u256& balance() { return m_balance; }
u256 const& balance() const { return m_balance; }
void addBalance(bigint _i) { m_balance = (u256)((bigint)m_balance + _i); }
u256& nonce() { return m_nonce; }
u256 const& nonce() const { return m_nonce; }
void incNonce() { m_nonce++; }
bool isComplete() const { return m_isComplete; }
std::map<u256, u256>& setIsComplete(bytesConstRef _code) { assert(m_type == AddressType::Contract); m_isComplete = true; m_contractRoot = h256(); m_code = _code.toBytes(); return m_memory; }
h256 oldRoot() const { assert(!isComplete()); return m_contractRoot; }
std::map<u256, u256>& setIsComplete(bytesConstRef _code) { m_isComplete = true; m_storageRoot = h256(); m_code = _code.toBytes(); return m_storage; }
h256 oldRoot() const { assert(!isComplete()); return m_storageRoot; }
std::map<u256, u256>& memory() { return m_storage; }
std::map<u256, u256> const& memory() const { assert(isComplete()); return m_storage; }
h256 codeHash() const { assert(m_codeHash); return m_codeHash; }
std::map<u256, u256>& memory() { assert(m_type == AddressType::Contract && isComplete()); return m_memory; }
std::map<u256, u256> const& memory() const { assert(m_type == AddressType::Contract && isComplete()); return m_memory; }
bytes const& code() const { assert(m_type == AddressType::Contract && isComplete()); return m_code; }
bytes const& code() const { assert(isComplete()); return m_code; }
bool freshCode() const { return !m_codeHash && m_isComplete; }
void setCode(bytesConstRef _code) { assert(freshCode()); m_code = _code.toBytes(); }
private:
AddressType m_type;
bool m_isAlive;
bool m_isComplete;
bool m_gotCode;
u256 m_balance;
u256 m_nonce;
bool m_isComplete;
h256 m_contractRoot;
h256 m_storageRoot;
h256 m_codeHash; // if 0 and m_isComplete, has been created and needs to be inserted.
// TODO: change to unordered_map.
std::map<u256, u256> m_memory;
std::map<u256, u256> m_storage;
bytes m_code;
};

27
libethereum/State.cpp

@ -42,10 +42,10 @@ std::map<Address, AddressState> const& eth::genesisState()
if (s_ret.empty())
{
// Initialise.
s_ret[Address(fromHex("8a40bfaa73256b60764c1bf40675a99083efb075"))] = AddressState(u256(1) << 200, 0, AddressType::Normal);
s_ret[Address(fromHex("e6716f9544a56c530d868e4bfbacb172315bdead"))] = AddressState(u256(1) << 200, 0, AddressType::Normal);
s_ret[Address(fromHex("1e12515ce3e0f817a4ddef9ca55788a1d66bd2df"))] = AddressState(u256(1) << 200, 0, AddressType::Normal);
s_ret[Address(fromHex("1a26338f0d905e295fccb71fa9ea849ffa12aaf4"))] = AddressState(u256(1) << 200, 0, AddressType::Normal);
s_ret[Address(fromHex("8a40bfaa73256b60764c1bf40675a99083efb075"))] = AddressState(u256(1) << 200, 0, h256(), EmptySHA3);
s_ret[Address(fromHex("e6716f9544a56c530d868e4bfbacb172315bdead"))] = AddressState(u256(1) << 200, 0, h256(), EmptySHA3);
s_ret[Address(fromHex("1e12515ce3e0f817a4ddef9ca55788a1d66bd2df"))] = AddressState(u256(1) << 200, 0, h256(), EmptySHA3);
s_ret[Address(fromHex("1a26338f0d905e295fccb71fa9ea849ffa12aaf4"))] = AddressState(u256(1) << 200, 0, h256(), EmptySHA3);
}
return s_ret;
}
@ -133,9 +133,7 @@ void State::ensureCached(std::map<Address, AddressState>& _cache, Address _a, bo
RLP state(stateBack);
AddressState s;
if (state.isNull())
s = AddressState(0, 0);
else if (state.itemCount() == 2)
s = AddressState(state[0].toInt<u256>(), state[1].toInt<u256>());
s = AddressState(0, 0, h256(), EmptySHA3);
else
s = AddressState(state[0].toInt<u256>(), state[1].toInt<u256>(), state[2].toHash<h256>(), state[3].toHash<h256>());
bool ok;
@ -144,9 +142,8 @@ void State::ensureCached(std::map<Address, AddressState>& _cache, Address _a, bo
if (_requireMemory && !it->second.isComplete())
{
// Populate memory.
assert(it->second.type() == AddressType::Contract);
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&m_db), it->second.oldRoot()); // promise we won't alter the overlay! :)
map<u256, u256>& mem = it->second.setIsComplete(bytesConstRef(m_db.lookup(it->second.codeHash())));
map<u256, u256>& mem = it->second.setIsComplete(it->second.codeHash() == EmptySHA3 ? bytesConstRef() : bytesConstRef(m_db.lookup(it->second.codeHash())));
for (auto const& i: memdb)
mem[i.first] = RLP(i.second).toInt<u256>();
}
@ -226,7 +223,7 @@ map<Address, u256> State::addresses() const
{
map<Address, u256> ret;
for (auto i: m_cache)
if (i.second.type() != AddressType::Dead)
if (i.second.isAlive())
ret[i.first] = i.second.balance();
for (auto const& i: m_state)
if (m_cache.find(i.first) == m_cache.end())
@ -505,7 +502,7 @@ bool State::isNormalAddress(Address _id) const
auto it = m_cache.find(_id);
if (it == m_cache.end())
return false;
return it->second.type() == AddressType::Normal;
return it->second.codeHash() == EmptySHA3;
}
bool State::isContractAddress(Address _id) const
@ -514,7 +511,7 @@ bool State::isContractAddress(Address _id) const
auto it = m_cache.find(_id);
if (it == m_cache.end())
return false;
return it->second.type() == AddressType::Contract;
return it->second.codeHash() != EmptySHA3;
}
u256 State::balance(Address _id) const
@ -531,7 +528,7 @@ void State::noteSending(Address _id)
ensureCached(_id, false, false);
auto it = m_cache.find(_id);
if (it == m_cache.end())
m_cache[_id] = AddressState(0, 1);
m_cache[_id] = AddressState(0, 1, h256(), EmptySHA3);
else
it->second.incNonce();
}
@ -541,7 +538,7 @@ void State::addBalance(Address _id, u256 _amount)
ensureCached(_id, false, false);
auto it = m_cache.find(_id);
if (it == m_cache.end())
m_cache[_id] = AddressState(_amount, 0);
m_cache[_id] = AddressState(_amount, 0, h256(), EmptySHA3);
else
it->second.addBalance(_amount);
}
@ -570,7 +567,7 @@ u256 State::contractStorage(Address _id, u256 _memory) const
{
ensureCached(_id, false, false);
auto it = m_cache.find(_id);
if (it == m_cache.end() || it->second.type() != AddressType::Contract)
if (it == m_cache.end() || it->second.codeHash() == EmptySHA3)
return 0;
else if (it->second.isComplete())
{

47
libethereum/State.h

@ -354,8 +354,8 @@ inline std::ostream& operator<<(std::ostream& _out, State const& _s)
if (it == _s.m_cache.end())
{
RLP r(i.second);
_out << "[ " << (r.itemCount() == 3 ? "CONTRACT] " : " NORMAL] ") << i.first << ": " << std::dec << r[1].toInt<u256>() << "@" << r[0].toInt<u256>();
if (r.itemCount() == 3)
_out << "[ ]" << i.first << ": " << std::dec << r[1].toInt<u256>() << "@" << r[0].toInt<u256>();
if (r.itemCount() == 4)
{
_out << " *" << r[2].toHash<h256>();
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&_s.m_db), r[2].toHash<h256>()); // promise we won't alter the overlay! :)
@ -373,12 +373,12 @@ inline std::ostream& operator<<(std::ostream& _out, State const& _s)
d.insert(i.first);
}
for (auto i: _s.m_cache)
if (i.second.type() == AddressType::Dead)
if (!i.second.isAlive())
_out << "[XXX " << i.first << std::endl;
else
{
_out << (d.count(i.first) ? "[ ! " : "[ * ") << (i.second.type() == AddressType::Contract ? "CONTRACT] " : " NORMAL] ") << i.first << ": " << std::dec << i.second.nonce() << "@" << i.second.balance();
if (i.second.type() == AddressType::Contract)
_out << (d.count(i.first) ? "[ ! " : "[ * ") << "]" << i.first << ": " << std::dec << i.second.nonce() << "@" << i.second.balance();
if (i.second.codeHash() != EmptySHA3)
{
if (i.second.isComplete())
{
@ -406,34 +406,37 @@ template <class DB>
void commit(std::map<Address, AddressState> const& _cache, DB& _db, TrieDB<Address, DB>& _state)
{
for (auto const& i: _cache)
if (i.second.type() == AddressType::Dead)
if (!i.second.isAlive())
_state.remove(i.first);
else
{
RLPStream s(i.second.type() == AddressType::Contract ? 3 : 2);
RLPStream s(4);
s << i.second.balance() << i.second.nonce();
if (i.second.type() == AddressType::Contract)
if (i.second.isComplete())
{
if (i.second.isComplete())
if (i.second.memory().empty())
s << h256();
else
{
TrieDB<h256, DB> memdb(&_db);
memdb.init();
TrieDB<h256, DB> storageDB(&_db);
storageDB.init();
for (auto const& j: i.second.memory())
if (j.second)
memdb.insert(j.first, rlp(j.second));
s << memdb.root();
if (i.second.freshCode())
{
h256 ch = sha3(i.second.code());
_db.insert(ch, &i.second.code());
s << ch;
}
else
s << i.second.codeHash();
storageDB.insert(j.first, rlp(j.second));
s << storageDB.root();
}
if (i.second.freshCode())
{
h256 ch = sha3(i.second.code());
_db.insert(ch, &i.second.code());
s << ch;
}
else
s << i.second.oldRoot() << i.second.codeHash();
s << i.second.codeHash();
}
else
s << i.second.oldRoot() << i.second.codeHash();
_state.insert(i.first, &s.out());
}
}

Loading…
Cancel
Save