Browse Source

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

mix_editor

Conflicts:
	mix/AssemblyDebuggerModel.cpp
cl-refactor
arkpar 10 years ago
parent
commit
09c7bbb1bc
  1. 2
      .gitignore
  2. 68
      alethzero/MainWin.cpp
  3. 15
      docker/Dockerfile
  4. 14
      eth/main.cpp
  5. 2
      evmjit
  6. 4
      exp/main.cpp
  7. 3
      libdevcore/Common.h
  8. 180
      libdevcore/CommonData.cpp
  9. 3
      libdevcore/CommonData.h
  10. 1
      libdevcore/vector_ref.h
  11. 29
      libethereum/Client.cpp
  12. 34
      libethereum/Client.h
  13. 11
      libethereum/Executive.cpp
  14. 6
      libethereum/Executive.h
  15. 4
      libethereum/ExtVM.cpp
  16. 4
      libethereum/ExtVM.h
  17. 78
      libethereum/State.cpp
  18. 14
      libethereum/State.h
  19. 16
      libethereum/TransactionReceipt.cpp
  20. 3
      libethereum/TransactionReceipt.h
  21. 3
      libevm/ExtVMFace.cpp
  22. 10
      libevm/ExtVMFace.h
  23. 30
      libevm/VM.h
  24. 2
      libp2p/Session.cpp
  25. 2
      mix/AssemblyDebuggerModel.cpp
  26. 2
      test/solidityExecutionFramework.h
  27. 205
      test/stInitCodeTestFiller.json
  28. 102
      test/stSystemOperationsTestFiller.json
  29. 135
      test/stTransactionTestFiller.json
  30. 2
      test/state.cpp
  31. 2
      test/stateOriginal.cpp
  32. 2
      test/vm.cpp

2
.gitignore

@ -64,3 +64,5 @@ profile
DerivedData DerivedData
project.pbxproj project.pbxproj
evmjit

68
alethzero/MainWin.cpp

@ -106,6 +106,8 @@ static QString contentsOfQResource(std::string const& res)
} }
Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f"); Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f");
Address c_newConfig = Address("d5f9d8d94886e70b06e474c3fb14fd43e2f23970");
Address c_nameReg = Address("ddd1cea741d548f90d86fb87a3ae6492e18c03a1");
Main::Main(QWidget *parent) : Main::Main(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
@ -448,8 +450,29 @@ static Public stringToPublic(QString const& _a)
return Public(); return Public();
} }
static Address g_newNameReg;
QString Main::pretty(dev::Address _a) const QString Main::pretty(dev::Address _a) const
{ {
static std::map<Address, QString> s_memos;
if (!s_memos.count(_a))
{
if (!g_newNameReg)
g_newNameReg = abiOut<Address>(ethereum()->call(c_newConfig, abiIn(1, (u256)1)));
if (g_newNameReg)
{
QString s = QString::fromStdString(toString(abiOut<string32>(ethereum()->call(g_newNameReg, abiIn(2, _a)))));
s_memos[_a] = s;
if (s.size())
return s;
}
}
else
if (s_memos[_a].size())
return s_memos[_a];
h256 n; h256 n;
if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0)) if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0))
@ -469,19 +492,47 @@ QString Main::render(dev::Address _a) const
return QString::fromStdString(_a.abridged()); return QString::fromStdString(_a.abridged());
} }
Address Main::fromString(QString const& _a) const string32 fromString(std::string const& _s)
{
string32 ret;
for (unsigned i = 0; i < 32 && i <= _s.size(); ++i)
ret[i] = i < _s.size() ? _s[i] : 0;
return ret;
}
Address Main::fromString(QString const& _n) const
{ {
if (_a == "(Create Contract)") if (_n == "(Create Contract)")
return Address(); return Address();
string sn = _a.toStdString(); static std::map<QString, Address> s_memos;
if (!s_memos.count(_n))
{
if (!g_newNameReg)
g_newNameReg = abiOut<Address>(ethereum()->call(c_newConfig, abiIn(1, (u256)1)));
if (g_newNameReg)
{
Address a = abiOut<Address>(ethereum()->call(g_newNameReg, abiIn(0, ::fromString(_n.toStdString()))));
s_memos[_n] = a;
if (a)
return a;
}
}
else
if (s_memos[_n])
return s_memos[_n];
string sn = _n.toStdString();
if (sn.size() > 32) if (sn.size() > 32)
sn.resize(32); sn.resize(32);
h256 n; h256 n;
memcpy(n.data(), sn.data(), sn.size()); memcpy(n.data(), sn.data(), sn.size());
memset(n.data() + sn.size(), 0, 32 - sn.size()); memset(n.data() + sn.size(), 0, 32 - sn.size());
if (_a.size()) if (_n.size())
{ {
if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0)) if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0))
if (h256 a = ethereum()->stateAt(nameReg, n)) if (h256 a = ethereum()->stateAt(nameReg, n))
return right160(a); return right160(a);
@ -489,8 +540,9 @@ Address Main::fromString(QString const& _a) const
if (h256 a = ethereum()->stateAt(m_nameReg, n)) if (h256 a = ethereum()->stateAt(m_nameReg, n))
return right160(a); return right160(a);
} }
if (_a.size() == 40)
return Address(fromHex(_a.toStdString())); if (_n.size() == 40)
return Address(fromHex(_n.toStdString()));
else else
return Address(); return Address();
} }
@ -1350,7 +1402,7 @@ void Main::on_debugCurrent_triggered()
{ {
unsigned txi = item->data(Qt::UserRole + 1).toInt(); unsigned txi = item->data(Qt::UserRole + 1).toInt();
m_executiveState = ethereum()->state(txi + 1, h); m_executiveState = ethereum()->state(txi + 1, h);
m_currentExecution = unique_ptr<Executive>(new Executive(m_executiveState, 0)); m_currentExecution = unique_ptr<Executive>(new Executive(m_executiveState, ethereum()->blockChain(), 0));
Transaction t = m_executiveState.pending()[txi]; Transaction t = m_executiveState.pending()[txi];
m_executiveState = m_executiveState.fromPending(txi); m_executiveState = m_executiveState.fromPending(txi);
auto r = t.rlp(); auto r = t.rlp();
@ -1803,7 +1855,7 @@ void Main::on_debug_clicked()
{ {
Secret s = i.secret(); Secret s = i.secret();
m_executiveState = ethereum()->postState(); m_executiveState = ethereum()->postState();
m_currentExecution = unique_ptr<Executive>(new Executive(m_executiveState, 0)); m_currentExecution = unique_ptr<Executive>(new Executive(m_executiveState, ethereum()->blockChain(), 0));
Transaction t = isCreation() ? Transaction t = isCreation() ?
Transaction(value(), gasPrice(), ui->gas->value(), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s) : Transaction(value(), gasPrice(), ui->gas->value(), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s) :
Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s); Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s);

15
docker/Dockerfile

@ -7,6 +7,7 @@ RUN apt-get upgrade -y
# Ethereum dependencies # Ethereum dependencies
RUN apt-get install -qy build-essential g++-4.8 git cmake libboost-all-dev libcurl4-openssl-dev wget RUN apt-get install -qy build-essential g++-4.8 git cmake libboost-all-dev libcurl4-openssl-dev wget
RUN apt-get install -qy automake unzip libgmp-dev libtool libleveldb-dev yasm libminiupnpc-dev libreadline-dev scons RUN apt-get install -qy automake unzip libgmp-dev libtool libleveldb-dev yasm libminiupnpc-dev libreadline-dev scons
RUN apt-get install -qy libjsoncpp-dev libargtable2-dev
# NCurses based GUI (not optional though for a succesful compilation, see https://github.com/ethereum/cpp-ethereum/issues/452 ) # NCurses based GUI (not optional though for a succesful compilation, see https://github.com/ethereum/cpp-ethereum/issues/452 )
RUN apt-get install -qy libncurses5-dev RUN apt-get install -qy libncurses5-dev
@ -14,15 +15,11 @@ RUN apt-get install -qy libncurses5-dev
# Qt-based GUI # Qt-based GUI
# RUN apt-get install -qy qtbase5-dev qt5-default qtdeclarative5-dev libqt5webkit5-dev # RUN apt-get install -qy qtbase5-dev qt5-default qtdeclarative5-dev libqt5webkit5-dev
# Cryptopp # Ethereum PPA
RUN git clone --depth=1 https://github.com/mmoss/cryptopp.git RUN apt-get install -qy software-properties-common
RUN cd cryptopp && scons --shared --prefix=/usr RUN add-apt-repository ppa:ethereum/ethereum
RUN apt-get update
# JSONRPC (version 0.2.1, see https://github.com/ethereum/cpp-ethereum/issues/453 ) RUN apt-get install -qy libcryptopp-dev libjson-rpc-cpp-dev
RUN apt-get install -qy libjsoncpp-dev libargtable2-dev
RUN git clone --depth=1 --branch=0.2.1 https://github.com/cinemast/libjson-rpc-cpp.git
RUN mkdir -p libjson-rpc-cpp/build
RUN cd libjson-rpc-cpp/build && cmake .. && make && make install
# Build Ethereum (HEADLESS) # Build Ethereum (HEADLESS)
RUN git clone --depth=1 https://github.com/ethereum/cpp-ethereum RUN git clone --depth=1 https://github.com/ethereum/cpp-ethereum

14
eth/main.cpp

@ -89,6 +89,7 @@ void interactiveHelp()
<< " importConfig <path> Import the config (.RLP) from the path provided." <<endl << " importConfig <path> Import the config (.RLP) from the path provided." <<endl
<< " inspect <contract> Dumps a contract to <APPDATA>/<contract>.evm." << endl << " inspect <contract> Dumps a contract to <APPDATA>/<contract>.evm." << endl
<< " dumptrace <block> <index> <filename> <format> Dumps a transaction trace" << endl << "to <filename>. <format> should be one of pretty, standard, standard+." << endl << " dumptrace <block> <index> <filename> <format> Dumps a transaction trace" << endl << "to <filename>. <format> should be one of pretty, standard, standard+." << endl
<< " dumpreceipt <block> <index> Dumps a transation receipt." << endl
<< " exit Exits the application." << endl; << " exit Exits the application." << endl;
} }
@ -606,6 +607,17 @@ int main(int argc, char** argv)
else else
cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX"; cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX";
} }
else if (c && cmd == "dumpreceipt")
{
unsigned block;
unsigned index;
iss >> block >> index;
dev::eth::TransactionReceipt r = c->blockChain().receipts(c->blockChain().numberHash(block)).receipts[index];
auto rb = r.rlp();
cout << "RLP: " << RLP(rb) << endl;
cout << "Hex: " << toHex(rb) << endl;
cout << r << endl;
}
else if (c && cmd == "dumptrace") else if (c && cmd == "dumptrace")
{ {
unsigned block; unsigned block;
@ -619,7 +631,7 @@ int main(int argc, char** argv)
dev::eth::State state =c->state(index + 1,c->blockChain().numberHash(block)); dev::eth::State state =c->state(index + 1,c->blockChain().numberHash(block));
if (index < state.pending().size()) if (index < state.pending().size())
{ {
Executive e(state, 0); Executive e(state, c->blockChain(), 0);
Transaction t = state.pending()[index]; Transaction t = state.pending()[index];
state = state.fromPending(index); state = state.fromPending(index);
bytes r = t.rlp(); bytes r = t.rlp();

2
evmjit

@ -1 +1 @@
Subproject commit 1b490244bf4864b96448d56a7cd20f3d5b0a0b9b Subproject commit 66d5a2b5cdf1361dcf0205b191dd12be090ed224

4
exp/main.cpp

@ -21,13 +21,13 @@
*/ */
#include <functional> #include <functional>
#include <libethereum/AccountDiff.h> #include <libethereum/AccountDiff.h>
#include <libdevcore/RangeMask.h>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libp2p/All.h> #include <libp2p/All.h>
#include <libdevcore/RangeMask.h>
#include <libethereum/DownloadMan.h> #include <libethereum/DownloadMan.h>
#include <libethereum/All.h> #include <libethereum/All.h>
#include <liblll/All.h> #include <liblll/All.h>
@ -91,7 +91,7 @@ int main()
Transaction t(0, 10000, 10000, c, bytes(), 0, u.secret()); Transaction t(0, 10000, 10000, c, bytes(), 0, u.secret());
cnote << "Transaction: " << t; cnote << "Transaction: " << t;
cnote << s.balance(c); cnote << s.balance(c);
s.execute(t.rlp()); s.execute(LastHashes(), t.rlp());
cnote << "State after transaction: " << s; cnote << "State after transaction: " << s;
cnote << before.diff(s); cnote << before.diff(s);
} }

3
libdevcore/Common.h

@ -74,6 +74,9 @@ using StringMap = std::map<std::string, std::string>;
using u256Map = std::map<u256, u256>; using u256Map = std::map<u256, u256>;
using HexMap = std::map<bytes, std::string>; using HexMap = std::map<bytes, std::string>;
// Fixed-length string types.
using string32 = std::array<char, 32>;
// Null/Invalid values for convenience. // Null/Invalid values for convenience.
static const u256 Invalid256 = ~(u256)0; static const u256 Invalid256 = ~(u256)0;
static const bytes NullBytes; static const bytes NullBytes;

180
libdevcore/CommonData.cpp

@ -123,180 +123,10 @@ bytes dev::asNibbles(std::string const& _s)
return ret; return ret;
} }
#if 0 std::string dev::toString(string32 const& _s)
/* Following code is copyright 2012-2014 Luke Dashjr
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the standard MIT license. See COPYING for more details.
*/
#include <cstdbool>
#include <cstddef>
#include <cstdint>
#include <cstring>
static const int8_t b58digits_map[] = {
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
-1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
-1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
};
bool b58tobin(void *bin, size_t *binszp, const char *b58, size_t b58sz)
{
size_t binsz = *binszp;
const unsigned char *b58u = (void*)b58;
unsigned char *binu = bin;
size_t outisz = (binsz + 3) / 4;
uint32_t outi[outisz];
uint64_t t;
uint32_t c;
size_t i, j;
uint8_t bytesleft = binsz % 4;
uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0;
unsigned zerocount = 0;
if (!b58sz)
b58sz = strlen(b58);
memset(outi, 0, outisz * sizeof(*outi));
// Leading zeros, just count
for (i = 0; i < b58sz && !b58digits_map[b58u[i]]; ++i)
++zerocount;
for ( ; i < b58sz; ++i)
{
if (b58u[i] & 0x80)
// High-bit set on invalid digit
return false;
if (b58digits_map[b58u[i]] == -1)
// Invalid base58 digit
return false;
c = (unsigned)b58digits_map[b58u[i]];
for (j = outisz; j--; )
{
t = ((uint64_t)outi[j]) * 58 + c;
c = (t & 0x3f00000000) >> 32;
outi[j] = t & 0xffffffff;
}
if (c)
// Output number too big (carry to the next int32)
return false;
if (outi[0] & zeromask)
// Output number too big (last int32 filled too far)
return false;
}
j = 0;
switch (bytesleft) {
case 3:
*(binu++) = (outi[0] & 0xff0000) >> 16;
case 2:
*(binu++) = (outi[0] & 0xff00) >> 8;
case 1:
*(binu++) = (outi[0] & 0xff);
++j;
default:
break;
}
for (; j < outisz; ++j)
{
*(binu++) = (outi[j] >> 0x18) & 0xff;
*(binu++) = (outi[j] >> 0x10) & 0xff;
*(binu++) = (outi[j] >> 8) & 0xff;
*(binu++) = (outi[j] >> 0) & 0xff;
}
// Count canonical base58 byte count
binu = bin;
for (i = 0; i < binsz; ++i)
{ {
if (binu[i]) std::string ret;
break; for (unsigned i = 0; i < 32 && _s[i]; ++i)
--*binszp; ret.push_back(_s[i]);
} return ret;
*binszp += zerocount;
return true;
}
static
bool my_dblsha256(void *hash, const void *data, size_t datasz)
{
uint8_t buf[0x20];
return b58_sha256_impl(buf, data, datasz) && b58_sha256_impl(hash, buf, sizeof(buf));
}
int b58check(const void *bin, size_t binsz, const char *base58str, size_t b58sz)
{
unsigned char buf[32];
const uint8_t *binc = bin;
unsigned i;
if (binsz < 4)
return -4;
if (!my_dblsha256(buf, bin, binsz - 4))
return -2;
if (memcmp(&binc[binsz - 4], buf, 4))
return -1;
// Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end)
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i)
{} // Just finding the end of zeros, nothing to do in loop
if (binc[i] == '\0' || base58str[i] == '1')
return -3;
return binc[0];
}
static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
{
const uint8_t *bin = data;
int carry;
size_t i, j, high, zcount = 0;
size_t size;
while (zcount < binsz && !bin[zcount])
++zcount;
size = (binsz - zcount) * 138 / 100 + 1;
uint8_t buf[size];
memset(buf, 0, size);
for (i = zcount, high = size - 1; i < binsz; ++i, high = j)
{
for (carry = bin[i], j = size - 1; (j > high) || carry; --j)
{
carry += 256 * buf[j];
buf[j] = carry % 58;
carry /= 58;
}
}
for (j = 0; j < size && !buf[j]; ++j);
if (*b58sz <= zcount + size - j)
{
*b58sz = zcount + size - j + 1;
return false;
}
if (zcount)
memset(b58, '1', zcount);
for (i = zcount; j < size; ++i, ++j)
b58[i] = b58digits_ordered[buf[j]];
b58[i] = '\0';
*b58sz = i + 1;
return true;
} }
#endif

3
libdevcore/CommonData.h

@ -236,4 +236,7 @@ inline std::set<_T> operator+(std::set<_T> const& _a, std::set<_T> const& _b)
return ret += _b; return ret += _b;
} }
/// Make normal string from fixed-length string.
std::string toString(string32 const& _s);
} }

1
libdevcore/vector_ref.h

@ -41,6 +41,7 @@ public:
void retarget(_T const* _d, size_t _s) { m_data = _d; m_count = _s; } void retarget(_T const* _d, size_t _s) { m_data = _d; m_count = _s; }
void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); } void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); }
void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const { memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); } void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const { memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); }
void populate(vector_ref<typename std::remove_const<_T>::type> _t) const { copyTo(_t); memset(_t.data() + m_count, 0, std::max(_t.size(), m_count) - m_count); }
_T* begin() { return m_data; } _T* begin() { return m_data; }
_T* end() { return m_data + m_count; } _T* end() { return m_data + m_count; }

29
libethereum/Client.cpp

@ -27,6 +27,7 @@
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libp2p/Host.h> #include <libp2p/Host.h>
#include "Defaults.h" #include "Defaults.h"
#include "Executive.h"
#include "EthereumHost.h" #include "EthereumHost.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -343,7 +344,7 @@ bytes Client::call(Secret _secret, u256 _value, Address _dest, bytes const& _dat
n = temp.transactionsFrom(toAddress(_secret)); n = temp.transactionsFrom(toAddress(_secret));
} }
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret);
u256 gasUsed = temp.execute(t.rlp(), &out, false); u256 gasUsed = temp.execute(m_bc, t.rlp(), &out, false);
(void)gasUsed; // TODO: do something with gasused which it returns. (void)gasUsed; // TODO: do something with gasused which it returns.
} }
catch (...) catch (...)
@ -353,6 +354,30 @@ bytes Client::call(Secret _secret, u256 _value, Address _dest, bytes const& _dat
return out; return out;
} }
bytes Client::call(Address _dest, bytes const& _data, u256 _gas, u256 _value, u256 _gasPrice)
{
try
{
State temp;
// cdebug << "Nonce at " << toAddress(_secret) << " pre:" << m_preMine.transactionsFrom(toAddress(_secret)) << " post:" << m_postMine.transactionsFrom(toAddress(_secret));
{
ReadGuard l(x_stateDB);
temp = m_postMine;
}
Executive e(temp, LastHashes(), 0);
if (!e.call(_dest, _dest, Address(), _value, _gasPrice, &_data, _gas, Address()))
{
e.go();
return e.out().toBytes();
}
}
catch (...)
{
// TODO: Some sort of notification of failure.
}
return bytes();
}
Address Client::transact(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice) Address Client::transact(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice)
{ {
startWorking(); startWorking();
@ -442,7 +467,7 @@ void Client::doWork()
// returns h256s as blooms, once for each transaction. // returns h256s as blooms, once for each transaction.
cwork << "postSTATE <== TQ"; cwork << "postSTATE <== TQ";
h512s newPendingBlooms = m_postMine.sync(m_tq); h512s newPendingBlooms = m_postMine.sync(m_bc, m_tq);
if (newPendingBlooms.size()) if (newPendingBlooms.size())
{ {
for (auto i: newPendingBlooms) for (auto i: newPendingBlooms)

34
libethereum/Client.h

@ -25,6 +25,8 @@
#include <mutex> #include <mutex>
#include <list> #include <list>
#include <atomic> #include <atomic>
#include <string>
#include <array>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
@ -105,6 +107,35 @@ struct WorkChannel: public LogChannel { static const char* name() { return "-W-"
#define cworkin dev::LogOutputStream<dev::eth::WorkInChannel, true>() #define cworkin dev::LogOutputStream<dev::eth::WorkInChannel, true>()
#define cworkout dev::LogOutputStream<dev::eth::WorkOutChannel, true>() #define cworkout dev::LogOutputStream<dev::eth::WorkOutChannel, true>()
template <class T> struct ABISerialiser {};
template <unsigned N> struct ABISerialiser<FixedHash<N>> { static bytes serialise(FixedHash<N> const& _t) { return _t.asBytes(); } };
template <> struct ABISerialiser<u256> { static bytes serialise(u256 const& _t) { return h256(_t).asBytes(); } };
template <> struct ABISerialiser<u160> { static bytes serialise(u160 const& _t) { return h160(_t).asBytes(); } };
template <> struct ABISerialiser<string32> { static bytes serialise(string32 const& _t) { return bytesConstRef((byte const*)_t.data(), 32).toBytes(); } };
inline bytes abiInAux() { return {}; }
template <class T, class ... U> bytes abiInAux(T const& _t, U const& ... _u)
{
return ABISerialiser<T>::serialise(_t) + abiInAux(_u ...);
}
template <class ... T> bytes abiIn(byte _id, T const& ... _t)
{
return bytes(1, _id) + abiInAux(_t ...);
}
template <class T> struct ABIDeserialiser {};
template <unsigned N> struct ABIDeserialiser<FixedHash<N>> { static FixedHash<N> deserialise(bytesConstRef& io_t) { FixedHash<N> ret; io_t.cropped(0, N).populate(ret.ref()); return ret; } };
template <> struct ABIDeserialiser<u256> { static u256 deserialise(bytesConstRef& io_t) { u256 ret = fromBigEndian<u256>(io_t.cropped(0, 32)); io_t = io_t.cropped(32); return ret; } };
template <> struct ABIDeserialiser<u160> { static u256 deserialise(bytesConstRef& io_t) { u160 ret = fromBigEndian<u160>(io_t.cropped(0, 20)); io_t = io_t.cropped(20); return ret; } };
template <> struct ABIDeserialiser<string32> { static string32 deserialise(bytesConstRef& io_t) { string32 ret; io_t.cropped(0, 32).populate(vector_ref<char>(ret.data(), 32)); io_t = io_t.cropped(32); return ret; } };
template <class T> T abiOut(bytes const& _data)
{
bytesConstRef o(&_data);
return ABIDeserialiser<T>::deserialise(o);
}
/** /**
* @brief Main API hub for interfacing with Ethereum. * @brief Main API hub for interfacing with Ethereum.
*/ */
@ -135,6 +166,9 @@ public:
/// Makes the given call. Nothing is recorded into the state. /// Makes the given call. Nothing is recorded into the state.
virtual bytes call(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo); virtual bytes call(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
/// Makes the given call. Nothing is recorded into the state. This cheats by creating a null address and endowing it with a lot of ETH.
virtual bytes call(Address _dest, bytes const& _data = bytes(), u256 _gas = 125000, u256 _value = 0, u256 _gasPrice = 1 * ether);
// Informational stuff // Informational stuff
// [NEW API] // [NEW API]

11
libethereum/Executive.cpp

@ -26,12 +26,19 @@
#include "State.h" #include "State.h"
#include "ExtVM.h" #include "ExtVM.h"
#include "Precompiled.h" #include "Precompiled.h"
#include "BlockChain.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
#define ETH_VMTRACE 1 #define ETH_VMTRACE 1
Executive::Executive(State& _s, BlockChain const& _bc, unsigned _level):
m_s(_s),
m_lastHashes(_s.getLastHashes(_bc)),
m_depth(_level)
{}
u256 Executive::gasUsed() const u256 Executive::gasUsed() const
{ {
return m_t.gas() - m_endGas; return m_t.gas() - m_endGas;
@ -120,7 +127,7 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen
{ {
m_vm = VMFactory::create(_gas); m_vm = VMFactory::create(_gas);
bytes const& c = m_s.code(_codeAddress); bytes const& c = m_s.code(_codeAddress);
m_ext = make_shared<ExtVM>(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c, m_depth); m_ext = make_shared<ExtVM>(m_s, m_lastHashes, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c, m_depth);
} }
else else
m_endGas = _gas; m_endGas = _gas;
@ -140,7 +147,7 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g
// Execute _init. // Execute _init.
m_vm = VMFactory::create(_gas); m_vm = VMFactory::create(_gas);
m_ext = make_shared<ExtVM>(m_s, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_depth); m_ext = make_shared<ExtVM>(m_s, m_lastHashes, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_depth);
return _init.empty(); return _init.empty();
} }

6
libethereum/Executive.h

@ -31,6 +31,7 @@ namespace eth
{ {
class State; class State;
class BlockChain;
class ExtVM; class ExtVM;
struct Manifest; struct Manifest;
@ -49,7 +50,9 @@ class Executive
{ {
public: public:
/// Basic constructor. /// Basic constructor.
Executive(State& _s, unsigned _level): m_s(_s), m_depth(_level) {} Executive(State& _s, LastHashes const& _lh, unsigned _level): m_s(_s), m_lastHashes(_lh), m_depth(_level) {}
/// Basic constructor.
Executive(State& _s, BlockChain const& _bc, unsigned _level);
/// Basic destructor. /// Basic destructor.
~Executive() = default; ~Executive() = default;
@ -99,6 +102,7 @@ public:
private: private:
State& m_s; ///< The state to which this operation/transaction is applied. State& m_s; ///< The state to which this operation/transaction is applied.
LastHashes m_lastHashes;
std::shared_ptr<ExtVM> m_ext; ///< The VM externality object for the VM execution or null if no VM is required. std::shared_ptr<ExtVM> m_ext; ///< The VM externality object for the VM execution or null if no VM is required.
std::unique_ptr<VMFace> m_vm; ///< The VM object or null if no VM is required. std::unique_ptr<VMFace> m_vm; ///< The VM object or null if no VM is required.
bytes m_precompiledOut; ///< Used for the output when there is no VM for a contract (i.e. precompiled). bytes m_precompiledOut; ///< Used for the output when there is no VM for a contract (i.e. precompiled).

4
libethereum/ExtVM.cpp

@ -28,7 +28,7 @@ using namespace dev::eth;
bool ExtVM::call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp, Address _myAddressOverride, Address _codeAddressOverride) bool ExtVM::call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp, Address _myAddressOverride, Address _codeAddressOverride)
{ {
Executive e(m_s, depth + 1); Executive e(m_s, lastHashes, depth + 1);
if (!e.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin)) if (!e.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin))
{ {
e.go(_onOp); e.go(_onOp);
@ -45,7 +45,7 @@ h160 ExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc
// Increment associated nonce for sender. // Increment associated nonce for sender.
m_s.noteSending(myAddress); m_s.noteSending(myAddress);
Executive e(m_s, depth + 1); Executive e(m_s, lastHashes, depth + 1);
if (!e.create(myAddress, _endowment, gasPrice, io_gas, _code, origin)) if (!e.create(myAddress, _endowment, gasPrice, io_gas, _code, origin))
{ {
e.go(_onOp); e.go(_onOp);

4
libethereum/ExtVM.h

@ -39,8 +39,8 @@ class ExtVM: public ExtVMFace
{ {
public: public:
/// Full constructor. /// Full constructor.
ExtVM(State& _s, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, unsigned _depth = 0): ExtVM(State& _s, LastHashes const& _lh, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, unsigned _depth = 0):
ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code.toBytes(), _s.m_previousBlock, _s.m_currentBlock, _depth), m_s(_s), m_origCache(_s.m_cache) ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code.toBytes(), _s.m_previousBlock, _s.m_currentBlock, _lh, _depth), m_s(_s), m_origCache(_s.m_cache)
{ {
m_s.ensureCached(_myAddress, true, true); m_s.ensureCached(_myAddress, true, true);
} }

78
libethereum/State.cpp

@ -114,7 +114,7 @@ State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h):
m_ourAddress = bi.coinbaseAddress; m_ourAddress = bi.coinbaseAddress;
sync(_bc, bi.parentHash, bip); sync(_bc, bi.parentHash, bip);
enact(&b); enact(&b, _bc);
} }
State::State(State const& _s): State::State(State const& _s):
@ -319,7 +319,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi)
for (auto it = chain.rbegin(); it != chain.rend(); ++it) for (auto it = chain.rbegin(); it != chain.rend(); ++it)
{ {
auto b = _bc.block(*it); auto b = _bc.block(*it);
enact(&b); enact(&b, _bc);
cleanup(true); cleanup(true);
} }
} }
@ -348,7 +348,7 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const
sync(_bc, _bi.parentHash); sync(_bc, _bi.parentHash);
resetCurrent(); resetCurrent();
m_previousBlock = biParent; m_previousBlock = biParent;
return enact(_block, &_bc); return enact(_block, _bc);
} }
map<Address, u256> State::addresses() const map<Address, u256> State::addresses() const
@ -412,12 +412,14 @@ bool State::cull(TransactionQueue& _tq) const
return ret; return ret;
} }
h512s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged) h512s State::sync(BlockChain const& _bc, TransactionQueue& _tq, bool* o_transactionQueueChanged)
{ {
// TRANSACTIONS // TRANSACTIONS
h512s ret; h512s ret;
auto ts = _tq.transactions(); auto ts = _tq.transactions();
auto lh = getLastHashes(_bc);
for (int goodTxs = 1; goodTxs;) for (int goodTxs = 1; goodTxs;)
{ {
goodTxs = 0; goodTxs = 0;
@ -429,7 +431,7 @@ h512s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged)
{ {
uncommitToMine(); uncommitToMine();
// boost::timer t; // boost::timer t;
execute(i.second); execute(lh, i.second);
ret.push_back(m_receipts.back().bloom()); ret.push_back(m_receipts.back().bloom());
_tq.noteGood(i); _tq.noteGood(i);
++goodTxs; ++goodTxs;
@ -467,7 +469,7 @@ h512s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged)
return ret; return ret;
} }
u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce) u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce)
{ {
// m_currentBlock is assumed to be prepopulated and reset. // m_currentBlock is assumed to be prepopulated and reset.
@ -496,6 +498,8 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
GenericTrieDB<MemoryDB> receiptsTrie(&rm); GenericTrieDB<MemoryDB> receiptsTrie(&rm);
receiptsTrie.init(); receiptsTrie.init();
LastHashes lh = getLastHashes(_bc);
// All ok with the block generally. Play back the transactions now... // All ok with the block generally. Play back the transactions now...
unsigned i = 0; unsigned i = 0;
for (auto const& tr: RLP(_block)[1]) for (auto const& tr: RLP(_block)[1])
@ -504,26 +508,11 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
k << i; k << i;
transactionsTrie.insert(&k.out(), tr.data()); transactionsTrie.insert(&k.out(), tr.data());
execute(lh, tr.data());
// cnote << m_state.root() << m_state;
// cnote << *this;
execute(tr.data());
RLPStream receiptrlp; RLPStream receiptrlp;
m_receipts.back().streamRLP(receiptrlp); m_receipts.back().streamRLP(receiptrlp);
receiptsTrie.insert(&k.out(), &receiptrlp.out()); receiptsTrie.insert(&k.out(), &receiptrlp.out());
/*
if (tr[1].toHash<h256>() != m_state.root())
{
// Invalid state root
cnote << m_state.root() << "\n" << m_state;
cnote << *this;
cnote << "INVALID: " << tr[1].toHash<h256>();
BOOST_THROW_EXCEPTION(InvalidTransactionStateRoot());
}
if (tr[2].toInt<u256>() != gasUsed())
BOOST_THROW_EXCEPTION(InvalidTransactionGasUsed());
*/
++i; ++i;
} }
@ -535,7 +524,20 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
if (receiptsTrie.root() != m_currentBlock.receiptsRoot) if (receiptsTrie.root() != m_currentBlock.receiptsRoot)
{ {
cwarn << "Bad receipts state root!"; cwarn << "Bad receipts state root.";
cwarn << "Block:" << toHex(_block);
cwarn << "Block RLP:" << RLP(_block);
cwarn << "Want: " << receiptsTrie.root() << ", got: " << m_currentBlock.receiptsRoot;
for (unsigned j = 0; j < i; ++j)
{
RLPStream k;
k << j;
auto b = asBytes(receiptsTrie.at(&k.out()));
cwarn << j << ": ";
cwarn << "RLP: " << RLP(b);
cwarn << "Hex: " << toHex(b);
cwarn << TransactionReceipt(&b);
}
BOOST_THROW_EXCEPTION(InvalidReceiptsStateRoot()); BOOST_THROW_EXCEPTION(InvalidReceiptsStateRoot());
} }
@ -551,7 +553,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
// Check uncles & apply their rewards to state. // Check uncles & apply their rewards to state.
set<h256> nonces = { m_currentBlock.nonce }; set<h256> nonces = { m_currentBlock.nonce };
Addresses rewarded; Addresses rewarded;
set<h256> knownUncles = _bc ? _bc->allUnclesFrom(m_currentBlock.parentHash) : set<h256>(); set<h256> knownUncles = _bc.allUnclesFrom(m_currentBlock.parentHash);
for (auto const& i: RLP(_block)[2]) for (auto const& i: RLP(_block)[2])
{ {
if (knownUncles.count(sha3(i.data()))) if (knownUncles.count(sha3(i.data())))
@ -560,13 +562,11 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
BlockInfo uncle = BlockInfo::fromHeader(i.data()); BlockInfo uncle = BlockInfo::fromHeader(i.data());
if (nonces.count(uncle.nonce)) if (nonces.count(uncle.nonce))
BOOST_THROW_EXCEPTION(DuplicateUncleNonce()); BOOST_THROW_EXCEPTION(DuplicateUncleNonce());
if (_bc)
{ BlockInfo uncleParent(_bc.block(uncle.parentHash));
BlockInfo uncleParent(_bc->block(uncle.parentHash)); if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 7)
if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 6)
BOOST_THROW_EXCEPTION(UncleTooOld()); BOOST_THROW_EXCEPTION(UncleTooOld());
uncle.verifyParent(uncleParent); uncle.verifyParent(uncleParent);
}
nonces.insert(uncle.nonce); nonces.insert(uncle.nonce);
tdIncrease += uncle.difficulty; tdIncrease += uncle.difficulty;
@ -648,7 +648,7 @@ bool State::amIJustParanoid(BlockChain const& _bc)
cnote << "PARANOIA root:" << s.rootHash(); cnote << "PARANOIA root:" << s.rootHash();
// s.m_currentBlock.populate(&block.out(), false); // s.m_currentBlock.populate(&block.out(), false);
// s.m_currentBlock.verifyInternals(&block.out()); // s.m_currentBlock.verifyInternals(&block.out());
s.enact(&block.out(), &_bc, false); // don't check nonce for this since we haven't mined it yet. s.enact(&block.out(), _bc, false); // don't check nonce for this since we haven't mined it yet.
s.cleanup(false); s.cleanup(false);
return true; return true;
} }
@ -993,9 +993,21 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const
return true; return true;
} }
// TODO: maintain node overlay revisions for stateroots -> each commit gives a stateroot + OverlayDB; allow overlay copying for rewind operations. LastHashes State::getLastHashes(BlockChain const& _bc) const
{
LastHashes ret;
ret.resize(256);
if (c_protocolVersion > 49)
{
unsigned n = (unsigned)m_previousBlock.number;
for (unsigned i = 0; i < 256; ++i)
ret[i] = _bc.numberHash(std::max<unsigned>(n, i) - i);
}
return ret;
}
u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit) // TODO: maintain node overlay revisions for stateroots -> each commit gives a stateroot + OverlayDB; allow overlay copying for rewind operations.
u256 State::execute(LastHashes const& _lh, bytesConstRef _rlp, bytes* o_output, bool _commit)
{ {
#ifndef ETH_RELEASE #ifndef ETH_RELEASE
commit(); // get an updated hash commit(); // get an updated hash
@ -1008,7 +1020,7 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit)
auto h = rootHash(); auto h = rootHash();
#endif #endif
Executive e(*this, 0); Executive e(*this, _lh, 0);
e.setup(_rlp); e.setup(_rlp);
u256 startGasUsed = gasUsed(); u256 startGasUsed = gasUsed();

14
libethereum/State.h

@ -143,14 +143,18 @@ public:
/// @returns a list of bloom filters one for each transaction placed from the queue into the state. /// @returns a list of bloom filters one for each transaction placed from the queue into the state.
/// @a o_transactionQueueChanged boolean pointer, the value of which will be set to true if the transaction queue /// @a o_transactionQueueChanged boolean pointer, the value of which will be set to true if the transaction queue
/// changed and the pointer is non-null /// changed and the pointer is non-null
h512s sync(TransactionQueue& _tq, bool* o_transactionQueueChanged = nullptr); h512s sync(BlockChain const& _bc, TransactionQueue& _tq, bool* o_transactionQueueChanged = nullptr);
/// Like sync but only operate on _tq, killing the invalid/old ones. /// Like sync but only operate on _tq, killing the invalid/old ones.
bool cull(TransactionQueue& _tq) const; bool cull(TransactionQueue& _tq) const;
LastHashes getLastHashes(BlockChain const& _bc) const;
/// Execute a given transaction. /// Execute a given transaction.
/// This will append @a _t to the transaction list and change the state accordingly. /// This will append @a _t to the transaction list and change the state accordingly.
u256 execute(bytes const& _rlp, bytes* o_output = nullptr, bool _commit = true) { return execute(&_rlp, o_output, _commit); } u256 execute(BlockChain const& _bc, bytes const& _rlp, bytes* o_output = nullptr, bool _commit = true) { return execute(getLastHashes(_bc), &_rlp, o_output, _commit); }
u256 execute(bytesConstRef _rlp, bytes* o_output = nullptr, bool _commit = true); u256 execute(BlockChain const& _bc, bytesConstRef _rlp, bytes* o_output = nullptr, bool _commit = true) { return execute(getLastHashes(_bc), _rlp, o_output, _commit); }
u256 execute(LastHashes const& _lh, bytes const& _rlp, bytes* o_output = nullptr, bool _commit = true) { return execute(_lh, &_rlp, o_output, _commit); }
u256 execute(LastHashes const& _lh, bytesConstRef _rlp, bytes* o_output = nullptr, bool _commit = true);
/// Get the remaining gas limit in this block. /// Get the remaining gas limit in this block.
u256 gasLimitRemaining() const { return m_currentBlock.gasLimit - gasUsed(); } u256 gasLimitRemaining() const { return m_currentBlock.gasLimit - gasUsed(); }
@ -268,9 +272,9 @@ private:
/// Retrieve all information about a given address into a cache. /// Retrieve all information about a given address into a cache.
void ensureCached(std::map<Address, Account>& _cache, Address _a, bool _requireCode, bool _forceCreate) const; void ensureCached(std::map<Address, Account>& _cache, Address _a, bool _requireCode, bool _forceCreate) const;
/// Execute the given block, assuming it corresponds to m_currentBlock. If _bc is passed, it will be used to check the uncles. /// Execute the given block, assuming it corresponds to m_currentBlock.
/// Throws on failure. /// Throws on failure.
u256 enact(bytesConstRef _block, BlockChain const* _bc = nullptr, bool _checkNonce = true); u256 enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce = true);
/// Finalise the block, applying the earned rewards. /// Finalise the block, applying the earned rewards.
void applyRewards(Addresses const& _uncleAddresses); void applyRewards(Addresses const& _uncleAddresses);

16
libethereum/TransactionReceipt.cpp

@ -49,3 +49,19 @@ void TransactionReceipt::streamRLP(RLPStream& _s) const
for (LogEntry const& l: m_log) for (LogEntry const& l: m_log)
l.streamRLP(_s); l.streamRLP(_s);
} }
std::ostream& dev::operator<<(std::ostream& _out, TransactionReceipt const& _r)
{
_out << "Root: " << _r.stateRoot() << std::endl;
_out << "Gas used: " << _r.gasUsed() << std::endl;
_out << "Logs: " << _r.log().size() << " entries:" << std::endl;
for (LogEntry const& i: _r.log())
{
_out << "Address " << i.address << ". Topics:" << std::endl;
for (auto const& j: i.topics)
_out << " " << j << std::endl;
_out << " Data: " << toHex(i.data) << std::endl;
}
_out << "Bloom: " << _r.bloom() << std::endl;
return _out;
}

3
libethereum/TransactionReceipt.h

@ -58,4 +58,7 @@ private:
using TransactionReceipts = std::vector<TransactionReceipt>; using TransactionReceipts = std::vector<TransactionReceipt>;
} }
std::ostream& operator<<(std::ostream& _out, eth::TransactionReceipt const& _r);
} }

3
libevm/ExtVMFace.cpp

@ -25,7 +25,7 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth): ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth):
myAddress(_myAddress), myAddress(_myAddress),
caller(_caller), caller(_caller),
origin(_origin), origin(_origin),
@ -33,6 +33,7 @@ ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256
gasPrice(_gasPrice), gasPrice(_gasPrice),
data(_data), data(_data),
code(_code), code(_code),
lastHashes(_lh),
previousBlock(_previousBlock), previousBlock(_previousBlock),
currentBlock(_currentBlock), currentBlock(_currentBlock),
depth(_depth) depth(_depth)

10
libevm/ExtVMFace.h

@ -93,6 +93,8 @@ struct SubState
class ExtVMFace; class ExtVMFace;
class VM; class VM;
using LastHashes = std::vector<h256>;
using OnOpFunc = std::function<void(uint64_t /*steps*/, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, VM*, ExtVMFace const*)>; using OnOpFunc = std::function<void(uint64_t /*steps*/, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, VM*, ExtVMFace const*)>;
/** /**
@ -105,7 +107,7 @@ public:
ExtVMFace() = default; ExtVMFace() = default;
/// Full constructor. /// Full constructor.
ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth); ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth);
virtual ~ExtVMFace() = default; virtual ~ExtVMFace() = default;
@ -145,6 +147,9 @@ public:
/// Revert any changes made (by any of the other calls). /// Revert any changes made (by any of the other calls).
virtual void revert() {} virtual void revert() {}
/// Hash of a block if within the last 256 blocks, or h256() otherwise.
h256 prevhash(u256 _number) { return _number < currentBlock.number && _number > (std::max<u256>(257, currentBlock.number) - 257) ? lastHashes[(unsigned)(currentBlock.number - 1 - _number)] : h256(); } // TODO: CHECK!!!
/// Get the code at the given location in code ROM. /// Get the code at the given location in code ROM.
byte getCode(u256 _n) const { return _n < code.size() ? code[(size_t)_n] : 0; } byte getCode(u256 _n) const { return _n < code.size() ? code[(size_t)_n] : 0; }
@ -155,7 +160,8 @@ public:
u256 gasPrice; ///< Price of gas (that we already paid). u256 gasPrice; ///< Price of gas (that we already paid).
bytesConstRef data; ///< Current input data. bytesConstRef data; ///< Current input data.
bytes code; ///< Current code that is executing. bytes code; ///< Current code that is executing.
BlockInfo previousBlock; ///< The previous block's information. LastHashes lastHashes; ///< Most recent 256 blocks' hashes.
BlockInfo previousBlock; ///< The previous block's information. TODO: PoC-8: REMOVE
BlockInfo currentBlock; ///< The current block's information. BlockInfo currentBlock; ///< The current block's information.
SubState sub; ///< Sub-band VM state (suicides, refund counter, logs). SubState sub; ///< Sub-band VM state (suicides, refund counter, logs).
unsigned depth = 0; ///< Depth of the present call. unsigned depth = 0; ///< Depth of the present call.

30
libevm/VM.h

@ -83,29 +83,9 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st
auto memNeed = [](dev::u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; }; auto memNeed = [](dev::u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; };
if (m_jumpDests.empty()) if (m_jumpDests.empty())
{
std::set<u256> implicit;
for (unsigned i = 0; i < _ext.code.size(); ++i) for (unsigned i = 0; i < _ext.code.size(); ++i)
if (_ext.code[i] == (byte)Instruction::JUMPDEST) if (_ext.code[i] == (byte)Instruction::JUMPDEST)
m_jumpDests.insert(i); m_jumpDests.insert(i);
else if (_ext.code[i] >= (byte)Instruction::PUSH1 && _ext.code[i] <= (byte)Instruction::PUSH32)
{
int in = _ext.code[i] - (unsigned)Instruction::PUSH1 + 1;
u256 p = 0;
for (i++; in--; i++)
p = (p << 8) | _ext.getCode(i);
if ((_ext.getCode(i) == (byte)Instruction::JUMP || _ext.getCode(i) == (byte)Instruction::JUMPI) && !(_ext.getCode(p) == (byte)Instruction::JUMP || _ext.getCode(p) == (byte)Instruction::JUMPI))
if (p >= _ext.code.size())
m_jumpDests.insert(p);
else
implicit.insert(p);
else {}
i--;
}
for (unsigned i = 0; i < _ext.code.size(); i += instructionInfo((Instruction)_ext.getCode(i)).additional + 1)
if (implicit.count(i))
m_jumpDests.insert(i);
}
u256 nextPC = m_curPC + 1; u256 nextPC = m_curPC + 1;
auto osteps = _steps; auto osteps = _steps;
@ -198,7 +178,6 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st
require(1); require(1);
runGas = c_balanceGas; runGas = c_balanceGas;
break; break;
case Instruction::LOG0: case Instruction::LOG0:
case Instruction::LOG1: case Instruction::LOG1:
case Instruction::LOG2: case Instruction::LOG2:
@ -240,6 +219,11 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st
break; break;
} }
case Instruction::PREVHASH:
if (c_protocolVersion > 49)
require(1);
break;
case Instruction::PC: case Instruction::PC:
case Instruction::MSIZE: case Instruction::MSIZE:
case Instruction::GAS: case Instruction::GAS:
@ -251,7 +235,6 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st
case Instruction::CALLDATASIZE: case Instruction::CALLDATASIZE:
case Instruction::CODESIZE: case Instruction::CODESIZE:
case Instruction::GASPRICE: case Instruction::GASPRICE:
case Instruction::PREVHASH:
case Instruction::COINBASE: case Instruction::COINBASE:
case Instruction::TIMESTAMP: case Instruction::TIMESTAMP:
case Instruction::NUMBER: case Instruction::NUMBER:
@ -581,6 +564,9 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st
m_stack.push_back(_ext.gasPrice); m_stack.push_back(_ext.gasPrice);
break; break;
case Instruction::PREVHASH: case Instruction::PREVHASH:
if (c_protocolVersion > 49)
m_stack.back() = (u256)_ext.prevhash(m_stack.back());
else
m_stack.push_back(_ext.previousBlock.hash); m_stack.push_back(_ext.previousBlock.hash);
break; break;
case Instruction::COINBASE: case Instruction::COINBASE:

2
libp2p/Session.cpp

@ -195,7 +195,7 @@ bool Session::interpret(RLP const& _r)
// "'operator<<' should be declared prior to the call site or in an associated namespace of one of its arguments" // "'operator<<' should be declared prior to the call site or in an associated namespace of one of its arguments"
stringstream capslog; stringstream capslog;
for (auto cap: caps) for (auto cap: caps)
capslog << "(" << hex << cap.first << "," << hex << cap.second << ")"; capslog << "(" << cap.first << "," << dec << cap.second << ")";
clogS(NetMessageSummary) << "Hello: " << clientVersion << "V[" << m_protocolVersion << "]" << id.abridged() << showbase << capslog.str() << dec << listenPort; clogS(NetMessageSummary) << "Hello: " << clientVersion << "V[" << m_protocolVersion << "]" << id.abridged() << showbase << capslog.str() << dec << listenPort;

2
mix/AssemblyDebuggerModel.cpp

@ -50,7 +50,7 @@ DebuggingContent AssemblyDebuggerModel::executeTransaction(bytesConstRef const&
{ {
QList<DebuggingState> machineStates; QList<DebuggingState> machineStates;
// Reset the state back to our clean premine. // Reset the state back to our clean premine.
eth::Executive execution(m_executiveState, 0); eth::Executive execution(m_executiveState, LastHashes(), 0);
execution.setup(_rawTransaction); execution.setup(_rawTransaction);
std::vector<DebuggingState const*> levels; std::vector<DebuggingState const*> levels;
bytes code; bytes code;

2
test/solidityExecutionFramework.h

@ -117,7 +117,7 @@ private:
void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0) void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0)
{ {
m_state.addBalance(m_sender, _value); // just in case m_state.addBalance(m_sender, _value); // just in case
eth::Executive executive(m_state, 0); eth::Executive executive(m_state, eth::LastHashes(), 0);
eth::Transaction t = _isCreation ? eth::Transaction(_value, m_gasPrice, m_gas, _data, 0, KeyPair::create().sec()) eth::Transaction t = _isCreation ? eth::Transaction(_value, m_gasPrice, m_gas, _data, 0, KeyPair::create().sec())
: eth::Transaction(_value, m_gasPrice, m_gas, m_contractAddress, _data, 0, KeyPair::create().sec()); : eth::Transaction(_value, m_gasPrice, m_gas, m_contractAddress, _data, 0, KeyPair::create().sec());
bytes transactionRLP = t.rlp(); bytes transactionRLP = t.rlp();

205
test/stInitCodeTestFiller.json

@ -92,6 +92,36 @@
"value" : "1" "value" : "1"
} }
}, },
"StackUnderFlowContractCreation" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x6000f1",
"gasLimit" : "1000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "",
"value" : "0"
}
},
"TransactionSuicideInitCode" : { "TransactionSuicideInitCode" : {
"env" : { "env" : {
@ -262,11 +292,11 @@
} }
}, },
"CallTheContractToCreateContractWithInitCode" : { "CallContractToCreateContractWhichWouldCreateContractInInitCode" : {
"env" : { "env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256", "currentDifficulty" : "45678256",
"currentGasLimit" : "1000000", "currentGasLimit" : "100000000",
"currentNumber" : "0", "currentNumber" : "0",
"currentTimestamp" : 1, "currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
@ -274,14 +304,15 @@
"pre" : "pre" :
{ {
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { "095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"balance": "10000", "balance": "1",
"nonce": 0, "nonce": 0,
"code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}", "//": "{[[0]] 12 (CREATE 0 64 32)}",
"code": "{(MSTORE 0 0x600c600055602060406000f0)(CREATE 0 20 12)}",
"storage": {} "storage": {}
}, },
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000", "balance" : "100000000",
"code" : "", "code" : "",
"nonce" : "0", "nonce" : "0",
"storage" : { "storage" : {
@ -291,12 +322,172 @@
"transaction" : "transaction" :
{ {
"data" : "0x00", "data" : "0x00",
"gasLimit" : "10000", "gasLimit" : "20000000",
"gasPrice" : "1", "gasPrice" : "1",
"nonce" : "0", "nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "1" "value" : "0"
}
},
"CallContractToCreateContractWhichWouldCreateContractIfCalled" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"balance": "1000",
"nonce": 0,
"//": "(CREATE 0 64 32)",
"//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}",
"code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 500 (SLOAD 0) 1 0 0 0 0)}",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x00",
"gasLimit" : "20000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0"
}
},
"CallContractToCreateContractOOG" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"balance": "0",
"nonce": 0,
"//": "(CREATE 0 64 32)",
"//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}",
"code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 0 (SLOAD 0) 0 0 0 0 0)}",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x00",
"gasLimit" : "20000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0"
}
},
"CallContractToCreateContractAndCallItOOG" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"balance": "1000",
"nonce": 0,
"//": "(CREATE 0 64 32)",
"//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}",
"code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 0 (SLOAD 0) 1 0 0 0 0)}",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x00",
"gasLimit" : "20000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0"
}
},
"CallContractToCreateContractNoCash" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"balance": "1000",
"nonce": 0,
"//": "(CREATE 0 64 32)",
"//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}",
"code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1001 11 21)}",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x00",
"gasLimit" : "20000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0"
} }
} }
} }

102
test/stSystemOperationsTestFiller.json

@ -1410,5 +1410,107 @@
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : "" "data" : ""
} }
},
"callValue": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "10000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "{ [[0]] (CALLVALUE) }",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "10000000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"currentAccountBalance": {
"env": {
"previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber": "0",
"currentGasLimit": "10000000",
"currentDifficulty": "256",
"currentTimestamp": 1,
"currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre": {
"095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"balance": "1000000000000000000",
"nonce": 0,
"code": "{ [[0]] (balance (address)) }",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "1000000000000000000",
"nonce": 0,
"code": "",
"storage": {}
}
},
"transaction": {
"nonce": "0",
"gasPrice": "1",
"gasLimit": "10000000",
"to": "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value": "100000",
"secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data": ""
}
},
"callerAccountBalance": {
"env": {
"previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber": "0",
"currentGasLimit": "10000000",
"currentDifficulty": "256",
"currentTimestamp": 1,
"currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre": {
"095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"balance": "1000000000000000000",
"nonce": 0,
"code": "{ [[0]] (balance (caller)) }",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "1000000000000000000",
"nonce": 0,
"code": "",
"storage": {}
}
},
"transaction": {
"nonce": "0",
"gasPrice": "1",
"gasLimit": "10000000",
"to": "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value": "100000",
"secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data": ""
}
} }
} }

135
test/stTransactionTestFiller.json

@ -187,5 +187,140 @@
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"value" : "502" "value" : "502"
} }
},
"ContractStoreClearsSuccess" : {
"env" : {
"currentCoinbase" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"currentDifficulty" : "45678256",
"currentGasLimit" : "10000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "7000",
"code" : "",
"nonce" : "0",
"storage" : {
}
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "0",
"code" : "{(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0)(SSTORE 4 0)(SSTORE 5 0)(SSTORE 6 0)(SSTORE 7 0)(SSTORE 8 0)(SSTORE 9 0)}",
"nonce" : "0",
"storage" : {
"0x" : "0x0c",
"0x01" : "0x0c",
"0x02" : "0x0c",
"0x03" : "0x0c",
"0x04" : "0x0c",
"0x05" : "0x0c",
"0x06" : "0x0c",
"0x07" : "0x0c",
"0x08" : "0x0c",
"0x09" : "0x0c"
}
}
},
"transaction" :
{
"data" : "",
"gasLimit" : "600",
"gasPrice" : "1",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "d2571607e241ecf590ed94b12d87c94babe36db6",
"value" : "10"
}
},
"ContractStoreClearsOOG" : {
"env" : {
"currentCoinbase" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"currentDifficulty" : "45678256",
"currentGasLimit" : "10000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "7000",
"code" : "",
"nonce" : "0",
"storage" : {
} }
},
"d2571607e241ecf590ed94b12d87c94babe36db6" : {
"balance" : "0",
"code" : "{(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0)(SSTORE 4 0)(SSTORE 5 0)(SSTORE 6 0)(SSTORE 7 0)(SSTORE 8 0)(SSTORE 9 12)}",
"nonce" : "0",
"storage" : {
"0x" : "0x0c",
"0x01" : "0x0c",
"0x02" : "0x0c",
"0x03" : "0x0c",
"0x04" : "0x0c",
"0x05" : "0x0c",
"0x06" : "0x0c",
"0x07" : "0x0c",
"0x08" : "0x0c",
"0x09" : "0x0c"
}
}
},
"transaction" :
{
"data" : "",
"gasLimit" : "600",
"gasPrice" : "1",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "d2571607e241ecf590ed94b12d87c94babe36db6",
"value" : "10"
}
},
"TransactionTooManyRlpElements" : {
"env" : {
"currentCoinbase" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"currentDifficulty" : "45678256",
"currentGasLimit" : "10000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "",
"gasLimit" : "600",
"gasLimit" : "1600",
"gasPrice" : "1",
"gasPrice" : "12",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d9",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "d2571607e241ecf590ed94b12d87c94babe36db6",
"value" : "10"
}
},
} }

2
test/state.cpp

@ -62,7 +62,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
try try
{ {
theState.execute(tx, &output); theState.execute(LastHashes(), tx, &output);
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {

2
test/stateOriginal.cpp

@ -69,7 +69,7 @@ int stateTest()
assert(t.sender() == myMiner.address()); assert(t.sender() == myMiner.address());
tx = t.rlp(); tx = t.rlp();
} }
s.execute(tx); s.execute(bc, tx);
cout << s; cout << s;

2
test/vm.cpp

@ -33,7 +33,7 @@ using namespace dev::eth;
using namespace dev::test; using namespace dev::test;
FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix. FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix.
ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), _previousBlock, _currentBlock, _depth) {} ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), _previousBlock, _currentBlock, LastHashes(), _depth) {}
h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpFunc const&) h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpFunc const&)
{ {

Loading…
Cancel
Save