Browse Source

Core repotting.

cl-refactor
Gav Wood 10 years ago
parent
commit
a1a6dcab34
  1. 5
      libdevcrypto/Common.h
  2. 4
      libethcore/BlockInfo.h
  3. 3
      libethcore/CommonEth.h
  4. 101
      libethereum/CachedAddressState.cpp
  5. 60
      libethereum/CachedAddressState.h
  6. 5
      libethereum/Executive.cpp
  7. 88
      libethereum/Precompiled.cpp
  8. 44
      libethereum/Precompiled.h
  9. 137
      libethereum/State.cpp
  10. 11
      libethereum/State.h
  11. 2
      libevm/ExtVMFace.h

5
libdevcrypto/Common.h

@ -45,6 +45,11 @@ using Signature = h520;
struct SignatureStruct
{
SignatureStruct() {}
SignatureStruct(Signature const& _s) { *(h520*)this = _s; }
SignatureStruct(h256 _r, h256 _s, byte _v): r(_r), s(_s), v(_v) {}
operator Signature() const { return *(h520 const*)this; }
/// @returns true if r,s,v values are valid, otherwise false
bool isValid();

4
libethcore/BlockInfo.h

@ -69,7 +69,7 @@ public:
h256 stateRoot;
h256 transactionsRoot;
h256 receiptsRoot;
h512 logBloom; // TODO LogBloom - get include
LogBloom logBloom;
u256 difficulty;
u256 number;
u256 gasLimit;
@ -118,7 +118,7 @@ public:
u256 calculateDifficulty(BlockInfo const& _parent) const;
u256 calculateGasLimit(BlockInfo const& _parent) const;
/// No-nonce sha3 of the header only.
/// sha3 of the header only.
h256 headerHash(IncludeNonce _n) const;
void streamRLP(RLPStream& _s, IncludeNonce _n) const;
};

3
libethcore/CommonEth.h

@ -44,6 +44,9 @@ std::string formatBalance(u256 _b);
/// Get information concerning the currency denominations.
std::vector<std::pair<u256, std::string>> const& units();
/// The log bloom's size (512 bit).
using LogBloom = h512;
// The various denominations; here for ease of use where needed within code.
static const u256 Uether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000;
static const u256 Vether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000;

101
libethereum/CachedAddressState.cpp

@ -0,0 +1,101 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file CachedAddressState.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "CachedAddressState.h"
#include <libdevcrypto/Common.h>
#include <libdevcrypto/TrieDB.h>
#include "Account.h"
using namespace std;
using namespace dev;
using namespace dev::eth;
bool CachedAddressState::exists() const
{
return (m_r && (!m_s || m_s->isAlive())) || (m_s && m_s->isAlive());
}
u256 CachedAddressState::balance() const
{
return m_r ? m_s ? m_s->balance() : m_r[1].toInt<u256>() : 0;
}
u256 CachedAddressState::nonce() const
{
return m_r ? m_s ? m_s->nonce() : m_r[0].toInt<u256>() : 0;
}
bytes CachedAddressState::code() const
{
if (m_s && m_s->codeCacheValid())
return m_s->code();
h256 h = m_r ? m_s ? m_s->codeHash() : m_r[3].toHash<h256>() : EmptySHA3;
return h == EmptySHA3 ? bytes() : asBytes(m_o->lookup(h));
}
std::map<u256, u256> CachedAddressState::storage() const
{
std::map<u256, u256> ret;
if (m_r)
{
TrieDB<h256, OverlayDB> memdb(const_cast<OverlayDB*>(m_o), m_r[2].toHash<h256>()); // promise we won't alter the overlay! :)
for (auto const& j: memdb)
ret[j.first] = RLP(j.second).toInt<u256>();
}
if (m_s)
for (auto const& j: m_s->storageOverlay())
if ((!ret.count(j.first) && j.second) || (ret.count(j.first) && ret.at(j.first) != j.second))
ret[j.first] = j.second;
return ret;
}
AccountDiff CachedAddressState::diff(CachedAddressState const& _c)
{
AccountDiff ret;
ret.exist = Diff<bool>(exists(), _c.exists());
ret.balance = Diff<u256>(balance(), _c.balance());
ret.nonce = Diff<u256>(nonce(), _c.nonce());
ret.code = Diff<bytes>(code(), _c.code());
auto st = storage();
auto cst = _c.storage();
auto it = st.begin();
auto cit = cst.begin();
while (it != st.end() || cit != cst.end())
{
if (it != st.end() && cit != cst.end() && it->first == cit->first && (it->second || cit->second) && (it->second != cit->second))
ret.storage[it->first] = Diff<u256>(it->second, cit->second);
else if (it != st.end() && (cit == cst.end() || it->first < cit->first) && it->second)
ret.storage[it->first] = Diff<u256>(it->second, 0);
else if (cit != cst.end() && (it == st.end() || it->first > cit->first) && cit->second)
ret.storage[cit->first] = Diff<u256>(0, cit->second);
if (it == st.end())
++cit;
else if (cit == cst.end())
++it;
else if (it->first < cit->first)
++it;
else if (it->first > cit->first)
++cit;
else
++it, ++cit;
}
return ret;
}

60
libethereum/CachedAddressState.h

@ -0,0 +1,60 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file CachedAddressState.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <string>
#include <libdevcore/Common.h>
#include <libdevcore/RLP.h>
#include "AccountDiff.h"
namespace dev
{
class OverlayDB;
namespace eth
{
class Account;
class CachedAddressState
{
public:
CachedAddressState(std::string const& _rlp, Account const* _s, OverlayDB const* _o): m_rS(_rlp), m_r(m_rS), m_s(_s), m_o(_o) {}
bool exists() const;
u256 balance() const;
u256 nonce() const;
bytes code() const;
std::map<u256, u256> storage() const;
AccountDiff diff(CachedAddressState const& _c);
private:
std::string m_rS;
RLP m_r;
Account const* m_s;
OverlayDB const* m_o;
};
}
}

5
libethereum/Executive.cpp

@ -28,6 +28,7 @@
#include "Interface.h"
#include "State.h"
#include "ExtVM.h"
#include "Precompiled.h"
using namespace std;
using namespace dev;
using namespace dev::eth;
@ -98,8 +99,8 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen
// cnote << "Transferring" << formatBalance(_value) << "to receiver.";
m_s.addBalance(_receiveAddress, _value);
auto it = !(_codeAddress & ~h160(0xffffffff)) ? State::precompiled().find((unsigned)(u160)_codeAddress) : State::precompiled().end();
if (it != State::precompiled().end())
auto it = !(_codeAddress & ~h160(0xffffffff)) ? precompiled().find((unsigned)(u160)_codeAddress) : precompiled().end();
if (it != precompiled().end())
{
bigint g = it->second.gas(_data);
if (_gas < g)

88
libethereum/Precompiled.cpp

@ -0,0 +1,88 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Precompiled.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Precompiled.h"
#include <libdevcrypto/SHA3.h>
#include <libdevcrypto/Common.h>
#include <libethcore/CommonEth.h>
using namespace std;
using namespace dev;
using namespace dev::eth;
static bytes ecrecoverCode(bytesConstRef _in)
{
struct inType
{
h256 hash;
h256 v;
h256 r;
h256 s;
} in;
memcpy(&in, _in.data(), min(_in.size(), sizeof(in)));
h256 ret;
if ((u256)in.v > 28)
return ret.asBytes();
SignatureStruct sig(in.r, in.s, (byte)((int)(u256)in.v - 27));
if (!sig.isValid())
return ret.asBytes();
try
{
ret = dev::sha3(recover(sig, in.hash));
}
catch (...) {}
memset(ret.data(), 0, 12);
return ret.asBytes();
}
static bytes sha256Code(bytesConstRef _in)
{
bytes ret(32);
sha256(_in, &ret);
return ret;
}
static bytes ripemd160Code(bytesConstRef _in)
{
bytes ret(32);
ripemd160(_in, &ret);
// leaves the 20-byte hash left-aligned. we want it right-aligned:
memmove(ret.data() + 12, ret.data(), 20);
memset(ret.data(), 0, 12);
return ret;
}
static const std::map<unsigned, PrecompiledAddress> c_precompiled =
{
{ 1, { [](bytesConstRef) -> bigint { return (bigint)500; }, ecrecoverCode }},
{ 2, { [](bytesConstRef i) -> bigint { return (bigint)50 + (i.size() + 31) / 32 * 50; }, sha256Code }},
{ 3, { [](bytesConstRef i) -> bigint { return (bigint)50 + (i.size() + 31) / 32 * 50; }, ripemd160Code }}
};
std::map<unsigned, PrecompiledAddress> const& dev::eth::precompiled()
{
return c_precompiled;
}

44
libethereum/Precompiled.h

@ -0,0 +1,44 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Precompiled.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <map>
#include <functional>
#include <libdevcore/CommonData.h>
namespace dev
{
namespace eth
{
/// Information structure regarding an account that is precompiled (i.e. 1, 2, 3).
struct PrecompiledAddress
{
std::function<bigint(bytesConstRef)> gas;
std::function<bytes(bytesConstRef)> exec;
};
/// Info on precompiled contract accounts baked into the protocol.
std::map<unsigned, PrecompiledAddress> const& precompiled();
}
}

137
libethereum/State.cpp

@ -34,6 +34,7 @@
#include "Defaults.h"
#include "ExtVM.h"
#include "Executive.h"
#include "CachedAddressState.h"
using namespace std;
using namespace dev;
using namespace dev::eth;
@ -42,59 +43,6 @@ using namespace dev::eth;
static const u256 c_blockReward = 1500 * finney;
bytes ecrecoverCode(bytesConstRef _in)
{
struct inType
{
h256 hash;
h256 v;
h256 r;
h256 s;
} in;
memcpy(&in, _in.data(), min(_in.size(), sizeof(in)));
h256 ret;
if ((u256)in.v > 28)
return ret.asBytes();
SignatureStruct sig{in.r, in.s, (byte)((int)(u256)in.v - 27)};
if (!sig.isValid())
return ret.asBytes();
byte pubkey[65];
int pubkeylen = 65;
secp256k1_start();
if (secp256k1_ecdsa_recover_compact(in.hash.data(), 32, in.r.data(), pubkey, &pubkeylen, 0, (int)(u256)in.v - 27))
ret = dev::sha3(bytesConstRef(&(pubkey[1]), 64));
memset(ret.data(), 0, 12);
return ret.asBytes();
}
bytes sha256Code(bytesConstRef _in)
{
bytes ret(32);
sha256(_in, &ret);
return ret;
}
bytes ripemd160Code(bytesConstRef _in)
{
bytes ret(32);
ripemd160(_in, &ret);
// leaves the 20-byte hash left-aligned. we want it right-aligned:
memmove(ret.data() + 12, ret.data(), 20);
memset(ret.data(), 0, 12);
return ret;
}
const std::map<unsigned, PrecompiledAddress> State::c_precompiled =
{
{ 1, { [](bytesConstRef) -> bigint { return (bigint)500; }, ecrecoverCode }},
{ 2, { [](bytesConstRef i) -> bigint { return (bigint)50 + (i.size() + 31) / 32 * 50; }, sha256Code }},
{ 3, { [](bytesConstRef i) -> bigint { return (bigint)50 + (i.size() + 31) / 32 * 50; }, ripemd160Code }}
};
OverlayDB State::openDB(std::string _path, bool _killExisting)
{
if (_path.empty())
@ -226,89 +174,6 @@ Address State::nextActiveAddress(Address _a) const
return (*it).first;
}
// TODO: repot
struct CachedAddressState
{
CachedAddressState(std::string const& _rlp, Account const* _s, OverlayDB const* _o): rS(_rlp), r(rS), s(_s), o(_o) {}
bool exists() const
{
return (r && (!s || s->isAlive())) || (s && s->isAlive());
}
u256 balance() const
{
return r ? s ? s->balance() : r[1].toInt<u256>() : 0;
}
u256 nonce() const
{
return r ? s ? s->nonce() : r[0].toInt<u256>() : 0;
}
bytes code() const
{
if (s && s->codeCacheValid())
return s->code();
h256 h = r ? s ? s->codeHash() : r[3].toHash<h256>() : EmptySHA3;
return h == EmptySHA3 ? bytes() : asBytes(o->lookup(h));
}
std::map<u256, u256> storage() const
{
std::map<u256, u256> ret;
if (r)
{
TrieDB<h256, OverlayDB> memdb(const_cast<OverlayDB*>(o), r[2].toHash<h256>()); // promise we won't alter the overlay! :)
for (auto const& j: memdb)
ret[j.first] = RLP(j.second).toInt<u256>();
}
if (s)
for (auto const& j: s->storageOverlay())
if ((!ret.count(j.first) && j.second) || (ret.count(j.first) && ret.at(j.first) != j.second))
ret[j.first] = j.second;
return ret;
}
AccountDiff diff(CachedAddressState const& _c)
{
AccountDiff ret;
ret.exist = Diff<bool>(exists(), _c.exists());
ret.balance = Diff<u256>(balance(), _c.balance());
ret.nonce = Diff<u256>(nonce(), _c.nonce());
ret.code = Diff<bytes>(code(), _c.code());
auto st = storage();
auto cst = _c.storage();
auto it = st.begin();
auto cit = cst.begin();
while (it != st.end() || cit != cst.end())
{
if (it != st.end() && cit != cst.end() && it->first == cit->first && (it->second || cit->second) && (it->second != cit->second))
ret.storage[it->first] = Diff<u256>(it->second, cit->second);
else if (it != st.end() && (cit == cst.end() || it->first < cit->first) && it->second)
ret.storage[it->first] = Diff<u256>(it->second, 0);
else if (cit != cst.end() && (it == st.end() || it->first > cit->first) && cit->second)
ret.storage[cit->first] = Diff<u256>(0, cit->second);
if (it == st.end())
++cit;
else if (cit == cst.end())
++it;
else if (it->first < cit->first)
++it;
else if (it->first > cit->first)
++cit;
else
++it, ++cit;
}
return ret;
}
std::string rS;
RLP r;
Account const* s;
OverlayDB const* o;
};
StateDiff State::diff(State const& _c) const
{
StateDiff ret;

11
libethereum/State.h

@ -53,12 +53,6 @@ struct StateTrace: public LogChannel { static const char* name() { return "=S=";
struct StateDetail: public LogChannel { static const char* name() { return "/S/"; } static const int verbosity = 14; };
struct StateSafeExceptions: public LogChannel { static const char* name() { return "(S)"; } static const int verbosity = 21; };
struct PrecompiledAddress
{
std::function<bigint(bytesConstRef)> gas;
std::function<bytes(bytesConstRef)> exec;
};
/**
* @brief Model of the current state of the ledger.
* Maintains current ledger (m_current) as a fast hash-map. This is hashed only when required (i.e. to create or verify a block).
@ -250,9 +244,6 @@ public:
/// the block since all state changes are ultimately reversed.
void cleanup(bool _fullCommit);
/// Info on precompiled contract accounts baked into the protocol.
static std::map<unsigned, PrecompiledAddress> const& precompiled() { return c_precompiled; }
private:
/// Undo the changes to the state for committing to mine.
void uncommitToMine();
@ -311,8 +302,6 @@ private:
static std::string c_defaultPath;
static const std::map<unsigned, PrecompiledAddress> c_precompiled;
friend std::ostream& operator<<(std::ostream& _out, State const& _s);
};

2
libevm/ExtVMFace.h

@ -36,8 +36,6 @@ namespace dev
namespace eth
{
using LogBloom = h512;
struct LogEntry
{
LogEntry() {}

Loading…
Cancel
Save