Gav Wood
10 years ago
11 changed files with 307 additions and 153 deletions
@ -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; |
|||
} |
@ -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; |
|||
}; |
|||
|
|||
} |
|||
|
|||
} |
@ -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; |
|||
} |
@ -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(); |
|||
|
|||
} |
|||
} |
Loading…
Reference in new issue