Browse Source

Merge branch 'develop' into p2p

Conflicts:
	libp2p/Host.cpp
cl-refactor
subtly 10 years ago
parent
commit
ee9b8cea45
  1. 19
      alethzero/MainWin.cpp
  2. 4
      alethzero/OurWebThreeStubServer.h
  3. 27
      build.py
  4. 2
      libdevcore/Common.cpp
  5. 2
      libdevcrypto/TrieDB.h
  6. 51
      libethcore/CommonJS.cpp
  7. 40
      libethcore/CommonJS.h
  8. 2
      libethereum/All.h
  9. 50
      libethereum/BlockChain.cpp
  10. 16
      libethereum/BlockChain.h
  11. 80
      libethereum/CanonBlockChain.cpp
  12. 76
      libethereum/CanonBlockChain.h
  13. 6
      libethereum/Client.h
  14. 11
      libethereum/State.cpp
  15. 4
      libethereum/State.h
  16. 8
      libp2p/Host.cpp
  17. 92
      libserpent/compiler.cpp
  18. 5
      libserpent/compiler.h
  19. 3
      libserpent/util.cpp
  20. 2
      libsolidity/AST.cpp
  21. 7
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  22. 4
      libweb3jsonrpc/WebThreeStubServerBase.h
  23. 36
      mix/ClientModel.cpp
  24. 2
      mix/ContractCallDataEncoder.cpp
  25. 2
      mix/DebuggingStateWrapper.cpp
  26. 210
      mix/MixClient.cpp
  27. 30
      mix/MixClient.h
  28. 2
      mix/QBigInt.cpp
  29. 2
      mix/QBigInt.h
  30. 2
      mix/QVariableDefinition.cpp
  31. 3
      mix/qml/MainContent.qml
  32. 5
      pullSerpent.sh
  33. 5
      sc/cmdline.cpp
  34. 36
      test/SolidityNameAndTypeResolution.cpp
  35. 5
      test/commonjs.cpp
  36. 2
      test/fork.cpp
  37. 8
      test/genesis.cpp
  38. 2
      test/jsonrpc.cpp
  39. 2
      test/state.cpp
  40. 4
      test/stateOriginal.cpp
  41. 2
      test/txTest.cpp
  42. 6
      third/MainWin.cpp

19
alethzero/MainWin.cpp

@ -33,7 +33,7 @@
#include <libserpent/funcs.h> #include <libserpent/funcs.h>
#include <libserpent/util.h> #include <libserpent/util.h>
#include <libdevcrypto/FileSystem.h> #include <libdevcrypto/FileSystem.h>
#include <libdevcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include <liblll/Compiler.h> #include <liblll/Compiler.h>
#include <liblll/CodeFragment.h> #include <liblll/CodeFragment.h>
#include <libsolidity/Scanner.h> #include <libsolidity/Scanner.h>
@ -41,7 +41,7 @@
#include <libsolidity/SourceReferenceFormatter.h> #include <libsolidity/SourceReferenceFormatter.h>
#include <libevm/VM.h> #include <libevm/VM.h>
#include <libevm/VMFactory.h> #include <libevm/VMFactory.h>
#include <libethereum/BlockChain.h> #include <libethereum/CanonBlockChain.h>
#include <libethereum/ExtVM.h> #include <libethereum/ExtVM.h>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include <libethereum/Utility.h> #include <libethereum/Utility.h>
@ -136,9 +136,9 @@ Main::Main(QWidget *parent) :
#endif #endif
m_servers.append(QString::fromStdString(Host::pocHost() + ":30303")); m_servers.append(QString::fromStdString(Host::pocHost() + ":30303"));
cerr << "State root: " << BlockChain::genesis().stateRoot << endl; cerr << "State root: " << CanonBlockChain::genesis().stateRoot << endl;
auto block = BlockChain::createGenesisBlock(); auto block = CanonBlockChain::createGenesisBlock();
cerr << "Block Hash: " << BlockChain::genesis().hash << endl; cerr << "Block Hash: " << CanonBlockChain::genesis().hash << endl;
cerr << "Block RLP: " << RLP(block) << endl; cerr << "Block RLP: " << RLP(block) << endl;
cerr << "Block Hex: " << toHex(block) << endl; cerr << "Block Hex: " << toHex(block) << endl;
cerr << "Network protocol version: " << c_protocolVersion << endl; cerr << "Network protocol version: " << c_protocolVersion << endl;
@ -1044,7 +1044,7 @@ void Main::refreshBlockCount()
ui->blockCount->setText(QString("%6 #%1 @%3 T%2 PV%4 D%5").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff)).arg(c_protocolVersion).arg(c_databaseVersion).arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet")); ui->blockCount->setText(QString("%6 #%1 @%3 T%2 PV%4 D%5").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff)).arg(c_protocolVersion).arg(c_databaseVersion).arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet"));
} }
static bool blockMatch(string const& _f, BlockDetails const& _b, h256 _h, BlockChain const& _bc) static bool blockMatch(string const& _f, BlockDetails const& _b, h256 _h, CanonBlockChain const& _bc)
{ {
try try
{ {
@ -1186,9 +1186,12 @@ void Main::timerEvent(QTimerEvent*)
{ {
auto ls = ethereum()->checkWatch(i.first); auto ls = ethereum()->checkWatch(i.first);
if (ls.size()) if (ls.size())
{
cnote << "FIRING WATCH" << i.first << ls.size();
i.second(ls); i.second(ls);
} }
} }
}
string Main::renderDiff(StateDiff const& _d) const string Main::renderDiff(StateDiff const& _d) const
{ {
@ -1199,7 +1202,7 @@ string Main::renderDiff(StateDiff const& _d) const
{ {
s << "<hr/>"; s << "<hr/>";
AccountDiff const& ad = i.second; AccountDiff ad = i.second;
s << "<code style=\"white-space: pre; font-weight: bold\">" << lead(ad.changeType()) << " </code>" << " <b>" << render(i.first).toStdString() << "</b>"; s << "<code style=\"white-space: pre; font-weight: bold\">" << lead(ad.changeType()) << " </code>" << " <b>" << render(i.first).toStdString() << "</b>";
if (!ad.exist.to()) if (!ad.exist.to())
continue; continue;
@ -1207,7 +1210,7 @@ string Main::renderDiff(StateDiff const& _d) const
if (ad.balance) if (ad.balance)
{ {
s << "<br/>" << indent << "Balance " << dec << ad.balance.to() << " [=" << formatBalance(ad.balance.to()) << "]"; s << "<br/>" << indent << "Balance " << dec << ad.balance.to() << " [=" << formatBalance(ad.balance.to()) << "]";
auto d = (((dev::bigint)ad.balance.to()) - ((dev::bigint)ad.balance.from())); bigint d = (dev::bigint)ad.balance.to() - (dev::bigint)ad.balance.from();
s << " <b>" << showpos << dec << d << " [=" << formatBalance(d) << "]" << noshowpos << "</b>"; s << " <b>" << showpos << dec << d << " [=" << formatBalance(d) << "]" << noshowpos << "</b>";
} }
if (ad.nonce) if (ad.nonce)

4
alethzero/OurWebThreeStubServer.h

@ -20,7 +20,7 @@
*/ */
#include <QtCore/QObject> #include <QtCore/QObject>
#include <libdevcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include <libdevcrypto/Common.h> #include <libdevcrypto/Common.h>
#include <libweb3jsonrpc/WebThreeStubServer.h> #include <libweb3jsonrpc/WebThreeStubServer.h>
@ -35,7 +35,7 @@ public:
std::vector<dev::KeyPair> const& _accounts, Main* main); std::vector<dev::KeyPair> const& _accounts, Main* main);
virtual std::string shh_newIdentity() override; virtual std::string shh_newIdentity() override;
virtual bool authenticate(dev::TransactionSkeleton const& _t); virtual bool authenticate(dev::eth::TransactionSkeleton const& _t);
signals: signals:
void onNewId(QString _s); void onNewId(QString _s);

27
build.py

@ -1,27 +0,0 @@
#!/usr/bin/python
# cpp-ethereum build script
# to be used from CI server, or to build locally
# uses python instead of bash script for better cross-platform support
# TODO Initial version. Needs much more improvements
import argparse
import os
import subprocess
def build_dependencies():
if os.path.exists("extdep"):
os.chdir("extdep")
if not os.path.exists("build"):
os.makedirs("build")
os.chdir("build")
subprocess.check_call(["cmake", ".."])
subprocess.check_call("make")
parser = argparse.ArgumentParser()
parser.add_argument("cmd", help="what to build")
args = parser.parse_args()
if args.cmd == "dep":
build_dependencies()

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
namespace dev namespace dev
{ {
char const* Version = "0.8.0"; char const* Version = "0.8.1";
} }

2
libdevcrypto/TrieDB.h

@ -49,7 +49,7 @@ extern const h256 EmptyTrie;
/** /**
* @brief Merkle Patricia Tree "Trie": a modifed base-16 Radix tree. * @brief Merkle Patricia Tree "Trie": a modifed base-16 Radix tree.
* This version uses an database backend. * This version uses a database backend.
* Usage: * Usage:
* @code * @code
* GenericTrieDB<MyDB> t(&myDB); * GenericTrieDB<MyDB> t(&myDB);

51
libdevcore/CommonJS.cpp → libethcore/CommonJS.cpp

@ -72,6 +72,31 @@ bytes unpadLeft(bytes _b)
return _b; return _b;
} }
std::string fromRaw(h256 _n, unsigned* _inc)
{
if (_n)
{
std::string s((char const*)_n.data(), 32);
auto l = s.find_first_of('\0');
if (!l)
return "";
if (l != std::string::npos)
{
auto p = s.find_first_not_of('\0', l);
if (!(p == std::string::npos || (_inc && p == 31)))
return "";
if (_inc)
*_inc = (byte)s[31];
s.resize(l);
}
for (auto i: s)
if (i < 32)
return "";
return s;
}
return "";
}
std::string prettyU256(u256 _n) std::string prettyU256(u256 _n)
{ {
unsigned inc = 0; unsigned inc = 0;
@ -98,31 +123,6 @@ std::string prettyU256(u256 _n)
return s.str(); return s.str();
} }
std::string fromRaw(h256 _n, unsigned* _inc)
{
if (_n)
{
std::string s((char const*)_n.data(), 32);
auto l = s.find_first_of('\0');
if (!l)
return "";
if (l != std::string::npos)
{
auto p = s.find_first_not_of('\0', l);
if (!(p == std::string::npos || (_inc && p == 31)))
return "";
if (_inc)
*_inc = (byte)s[31];
s.resize(l);
}
for (auto i: s)
if (i < 32)
return "";
return s;
}
return "";
}
Address fromString(std::string const& _sn) Address fromString(std::string const& _sn)
{ {
if (_sn.size() == 40) if (_sn.size() == 40)
@ -132,3 +132,4 @@ Address fromString(std::string const& _sn)
} }
} }

40
libdevcore/CommonJS.h → libethcore/CommonJS.h

@ -24,9 +24,11 @@
#pragma once #pragma once
#include <string> #include <string>
#include <libethereum/Interface.h> #include <libdevcore/Common.h>
#include "Common.h" #include <libdevcore/FixedHash.h>
#include "CommonData.h" #include <libdevcore/CommonData.h>
#include <libdevcore/CommonIO.h>
#include "CommonEth.h"
namespace dev namespace dev
{ {
@ -94,16 +96,8 @@ template <unsigned N> boost::multiprecision::number<boost::multiprecision::cpp_i
return 0; // FAIL return 0; // FAIL
} }
inline Address jsToAddress(std::string const& _s) { return jsToFixed<sizeof(dev::Address)>(_s); }
inline Public jsToPublic(std::string const& _s) { return jsToFixed<sizeof(dev::Public)>(_s); }
inline Secret jsToSecret(std::string const& _s) { return jsToFixed<sizeof(dev::Secret)>(_s); }
inline u256 jsToU256(std::string const& _s) { return jsToInt<32>(_s); } inline u256 jsToU256(std::string const& _s) { return jsToInt<32>(_s); }
inline std::string jsToBinary(std::string const& _s)
{
return dev::toString(unpadded(jsToBytes(_s)));
}
inline std::string jsToDecimal(std::string const& _s) inline std::string jsToDecimal(std::string const& _s)
{ {
return dev::toString(jsToU256(_s)); return dev::toString(jsToU256(_s));
@ -125,6 +119,29 @@ inline double jsFromFixed(std::string const& _s)
return (double)jsToU256(_s) / (double)(dev::u256(1) << 128); return (double)jsToU256(_s) / (double)(dev::u256(1) << 128);
} }
}
// devcrypto
#include <libdevcrypto/Common.h>
namespace dev
{
inline Public jsToPublic(std::string const& _s) { return jsToFixed<sizeof(dev::Public)>(_s); }
inline Secret jsToSecret(std::string const& _s) { return jsToFixed<sizeof(dev::Secret)>(_s); }
}
// ethcore
namespace dev
{
namespace eth
{
inline Address jsToAddress(std::string const& _s) { return jsToFixed<sizeof(dev::Address)>(_s); }
struct TransactionSkeleton struct TransactionSkeleton
{ {
Address from; Address from;
@ -136,3 +153,4 @@ struct TransactionSkeleton
}; };
} }
}

2
libethereum/All.h

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "Account.h" #include "Account.h"
#include "BlockChain.h" #include "CanonBlockChain.h"
#include "Client.h" #include "Client.h"
#include "Defaults.h" #include "Defaults.h"
#include "Executive.h" #include "Executive.h"

50
libethereum/BlockChain.cpp

@ -53,30 +53,6 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc)
return _out; return _out;
} }
std::map<Address, Account> const& dev::eth::genesisState()
{
static std::map<Address, Account> s_ret;
if (s_ret.empty())
{
// Initialise.
for (auto i: vector<string>({
"dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6",
"e6716f9544a56c530d868e4bfbacb172315bdead",
"b9c015918bdaba24b4ff057a92a3873d6eb201be",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"6c386a4b26f73c802f34673f7248bb118f97424a",
"e4157b34ea9615cfbde6b4fda419828124b70c78"
}))
s_ret[Address(fromHex(i))] = Account(u256(1) << 200, Account::NormalCreation);
}
return s_ret;
}
std::unique_ptr<BlockInfo> BlockChain::s_genesis;
boost::shared_mutex BlockChain::x_genesis;
ldb::Slice dev::eth::toSlice(h256 _h, unsigned _sub) ldb::Slice dev::eth::toSlice(h256 _h, unsigned _sub)
{ {
#if ALL_COMPILERS_ARE_CPP11_COMPLIANT #if ALL_COMPILERS_ARE_CPP11_COMPLIANT
@ -91,31 +67,11 @@ ldb::Slice dev::eth::toSlice(h256 _h, unsigned _sub)
#endif #endif
} }
bytes BlockChain::createGenesisBlock() BlockChain::BlockChain(bytes const& _genesisBlock, std::string _path, bool _killExisting)
{
RLPStream block(3);
h256 stateRoot;
{
MemoryDB db;
TrieDB<Address, MemoryDB> state(&db);
state.init();
dev::eth::commit(genesisState(), db, state);
stateRoot = state.root();
}
block.appendList(14)
<< h256() << EmptyListSHA3 << h160() << stateRoot << EmptyTrie << EmptyTrie << LogBloom() << c_genesisDifficulty << 0 << 1000000 << 0 << (unsigned)0 << string() << sha3(bytes(1, 42));
block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList);
return block.out();
}
BlockChain::BlockChain(std::string _path, bool _killExisting)
{ {
// Initialise with the genesis as the last block on the longest chain. // Initialise with the genesis as the last block on the longest chain.
m_genesisHash = BlockChain::genesis().hash; m_genesisBlock = _genesisBlock;
m_genesisBlock = BlockChain::createGenesisBlock(); m_genesisHash = sha3(RLP(m_genesisBlock)[0].data());
open(_path, _killExisting); open(_path, _killExisting);
} }

16
libethereum/BlockChain.h

@ -69,8 +69,7 @@ ldb::Slice toSlice(h256 _h, unsigned _sub = 0);
class BlockChain class BlockChain
{ {
public: public:
BlockChain(bool _killExisting = false): BlockChain(std::string(), _killExisting) {} BlockChain(bytes const& _genesisBlock, std::string _path, bool _killExisting);
BlockChain(std::string _path, bool _killExisting = false);
~BlockChain(); ~BlockChain();
void reopen(std::string _path, bool _killExisting = false) { close(); open(_path, _killExisting); } void reopen(std::string _path, bool _killExisting = false) { close(); open(_path, _killExisting); }
@ -82,7 +81,7 @@ public:
/// Sync the chain with any incoming blocks. All blocks should, if processed in order /// Sync the chain with any incoming blocks. All blocks should, if processed in order
h256s sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max); h256s sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max);
/// Attempt to import the given block directly into the BlockChain and sync with the state DB. /// Attempt to import the given block directly into the CanonBlockChain and sync with the state DB.
/// @returns the block hashes of any blocks that came into/went out of the canonical block chain. /// @returns the block hashes of any blocks that came into/went out of the canonical block chain.
h256s attemptImport(bytes const& _block, OverlayDB const& _stateDB) noexcept; h256s attemptImport(bytes const& _block, OverlayDB const& _stateDB) noexcept;
@ -131,13 +130,6 @@ public:
/// togther with all their quoted uncles. /// togther with all their quoted uncles.
h256Set allUnclesFrom(h256 _parent) const; h256Set allUnclesFrom(h256 _parent) const;
/// @returns the genesis block header.
static BlockInfo const& genesis() { UpgradableGuard l(x_genesis); if (!s_genesis) { auto gb = createGenesisBlock(); UpgradeGuard ul(l); s_genesis.reset(new BlockInfo); s_genesis->populate(&gb); } return *s_genesis; }
/// @returns the genesis block as its RLP-encoded byte array.
/// @note This is slow as it's constructed anew each call. Consider genesis() instead.
static bytes createGenesisBlock();
/** @returns the hash of all blocks between @a _from and @a _to, all blocks are ordered first by a number of /** @returns the hash of all blocks between @a _from and @a _to, all blocks are ordered first by a number of
* blocks that are parent-to-child, then two sibling blocks, then a number of blocks that are child-to-parent. * blocks that are parent-to-child, then two sibling blocks, then a number of blocks that are child-to-parent.
* *
@ -208,10 +200,6 @@ private:
ldb::WriteOptions m_writeOptions; ldb::WriteOptions m_writeOptions;
friend std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc); friend std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc);
/// Static genesis info and its lock.
static boost::shared_mutex x_genesis;
static std::unique_ptr<BlockInfo> s_genesis;
}; };
std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc); std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc);

80
libethereum/CanonBlockChain.cpp

@ -1,12 +1,86 @@
/*
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 CanonBlockChain.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "CanonBlockChain.h" #include "CanonBlockChain.h"
CanonBlockChain::CanonBlockChain() #include <boost/filesystem.hpp>
{ #include <libdevcore/Common.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/FileSystem.h>
#include <libethcore/Exceptions.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/BlockInfo.h>
#include <liblll/Compiler.h>
#include "State.h"
#include "Defaults.h"
using namespace std;
using namespace dev;
using namespace dev::eth;
#define ETH_CATCH 1
std::map<Address, Account> const& dev::eth::genesisState()
{
static std::map<Address, Account> s_ret;
if (s_ret.empty())
{
// Initialise.
for (auto i: vector<string>({
"dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6",
"e6716f9544a56c530d868e4bfbacb172315bdead",
"b9c015918bdaba24b4ff057a92a3873d6eb201be",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"6c386a4b26f73c802f34673f7248bb118f97424a",
"e4157b34ea9615cfbde6b4fda419828124b70c78"
}))
s_ret[Address(fromHex(i))] = Account(u256(1) << 200, Account::NormalCreation);
} }
return s_ret;
}
std::unique_ptr<BlockInfo> CanonBlockChain::s_genesis;
boost::shared_mutex CanonBlockChain::x_genesis;
CanonBlockChain::~CanonBlockChain() bytes CanonBlockChain::createGenesisBlock()
{ {
RLPStream block(3);
h256 stateRoot;
{
MemoryDB db;
TrieDB<Address, MemoryDB> state(&db);
state.init();
dev::eth::commit(genesisState(), db, state);
stateRoot = state.root();
} }
block.appendList(14)
<< h256() << EmptyListSHA3 << h160() << stateRoot << EmptyTrie << EmptyTrie << LogBloom() << c_genesisDifficulty << 0 << 1000000 << 0 << (unsigned)0 << string() << sha3(bytes(1, 42));
block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList);
return block.out();
}
CanonBlockChain::CanonBlockChain(std::string _path, bool _killExisting): BlockChain(CanonBlockChain::createGenesisBlock(), _path, _killExisting)
{
}

76
libethereum/CanonBlockChain.h

@ -1,12 +1,76 @@
#ifndef CANONBLOCKCHAIN_H /*
#define CANONBLOCKCHAIN_H 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.
class CanonBlockChain 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 CanonBlockChain.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#pragma warning(push)
#pragma warning(disable: 4100 4267)
#include <leveldb/db.h>
#pragma warning(pop)
#include <mutex>
#include <libdevcore/Log.h>
#include <libdevcore/Exceptions.h>
#include <libethcore/CommonEth.h>
#include <libethcore/BlockInfo.h>
#include <libdevcore/Guards.h>
#include "BlockDetails.h"
#include "Account.h"
#include "BlockQueue.h"
#include "BlockChain.h"
namespace ldb = leveldb;
namespace dev
{
namespace eth
{
// TODO: Move all this Genesis stuff into Genesis.h/.cpp
std::map<Address, Account> const& genesisState();
/**
* @brief Implements the blockchain database. All data this gives is disk-backed.
* @threadsafe
* @todo Make not memory hog (should actually act as a cache and deallocate old entries).
*/
class CanonBlockChain: public BlockChain
{ {
public: public:
CanonBlockChain(); CanonBlockChain(bool _killExisting = false): CanonBlockChain(std::string(), _killExisting) {}
~CanonBlockChain(); CanonBlockChain(std::string _path, bool _killExisting = false);
~CanonBlockChain() {}
/// @returns the genesis block header.
static BlockInfo const& genesis() { UpgradableGuard l(x_genesis); if (!s_genesis) { auto gb = createGenesisBlock(); UpgradeGuard ul(l); s_genesis.reset(new BlockInfo); s_genesis->populate(&gb); } return *s_genesis; }
/// @returns the genesis block as its RLP-encoded byte array.
/// @note This is slow as it's constructed anew each call. Consider genesis() instead.
static bytes createGenesisBlock();
private:
/// Static genesis info and its lock.
static boost::shared_mutex x_genesis;
static std::unique_ptr<BlockInfo> s_genesis;
}; };
#endif // CANONBLOCKCHAIN_H }
}

6
libethereum/Client.h

@ -34,7 +34,7 @@
#include <libdevcore/Worker.h> #include <libdevcore/Worker.h>
#include <libevm/FeeStructure.h> #include <libevm/FeeStructure.h>
#include <libp2p/Common.h> #include <libp2p/Common.h>
#include "BlockChain.h" #include "CanonBlockChain.h"
#include "TransactionQueue.h" #include "TransactionQueue.h"
#include "State.h" #include "State.h"
#include "CommonNet.h" #include "CommonNet.h"
@ -228,7 +228,7 @@ public:
/// Get the object representing the current state of Ethereum. /// Get the object representing the current state of Ethereum.
dev::eth::State postState() const { ReadGuard l(x_stateDB); return m_postMine; } dev::eth::State postState() const { ReadGuard l(x_stateDB); return m_postMine; }
/// Get the object representing the current canonical blockchain. /// Get the object representing the current canonical blockchain.
BlockChain const& blockChain() const { return m_bc; } CanonBlockChain const& blockChain() const { return m_bc; }
// Mining stuff: // Mining stuff:
@ -308,7 +308,7 @@ private:
State asOf(unsigned _h) const; State asOf(unsigned _h) const;
VersionChecker m_vc; ///< Dummy object to check & update the protocol version. VersionChecker m_vc; ///< Dummy object to check & update the protocol version.
BlockChain m_bc; ///< Maintains block database. CanonBlockChain m_bc; ///< Maintains block database.
TransactionQueue m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. TransactionQueue m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain.
BlockQueue m_bq; ///< Maintains a list of incoming blocks not yet on the blockchain (to be imported). BlockQueue m_bq; ///< Maintains a list of incoming blocks not yet on the blockchain (to be imported).

11
libethereum/State.cpp

@ -35,6 +35,7 @@
#include "ExtVM.h" #include "ExtVM.h"
#include "Executive.h" #include "Executive.h"
#include "CachedAddressState.h" #include "CachedAddressState.h"
#include "CanonBlockChain.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
@ -74,18 +75,16 @@ State::State(Address _coinbaseAddress, OverlayDB const& _db, BaseState _bs):
paranoia("beginning of normal construction.", true); paranoia("beginning of normal construction.", true);
if (_bs == BaseState::Genesis) if (_bs == BaseState::CanonGenesis)
{ {
dev::eth::commit(genesisState(), m_db, m_state); dev::eth::commit(genesisState(), m_db, m_state);
m_db.commit(); m_db.commit();
paranoia("after DB commit of normal construction.", true); paranoia("after DB commit of normal construction.", true);
m_previousBlock = BlockChain::genesis(); m_previousBlock = CanonBlockChain::genesis();
} }
else else
{
m_previousBlock.setEmpty(); m_previousBlock.setEmpty();
}
resetCurrent(); resetCurrent();
@ -304,7 +303,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi)
// (Most recent state dump might end up being genesis.) // (Most recent state dump might end up being genesis.)
std::vector<h256> chain; std::vector<h256> chain;
while (bi.stateRoot != BlockChain::genesis().hash && m_db.lookup(bi.stateRoot).empty()) // while we don't have the state root of the latest block... while (bi.number != 0 && m_db.lookup(bi.stateRoot).empty()) // while we don't have the state root of the latest block...
{ {
chain.push_back(bi.hash); // push back for later replay. chain.push_back(bi.hash); // push back for later replay.
bi.populate(_bc.block(bi.parentHash)); // move to parent. bi.populate(_bc.block(bi.parentHash)); // move to parent.
@ -698,7 +697,7 @@ void State::commitToMine(BlockChain const& _bc)
RLPStream unclesData; RLPStream unclesData;
unsigned unclesCount = 0; unsigned unclesCount = 0;
if (m_previousBlock != BlockChain::genesis()) if (m_previousBlock.number != 0)
{ {
// Find great-uncles (or second-cousins or whatever they are) - children of great-grandparents, great-great-grandparents... that were not already uncles in previous generations. // Find great-uncles (or second-cousins or whatever they are) - children of great-grandparents, great-great-grandparents... that were not already uncles in previous generations.
// cout << "Checking " << m_previousBlock.hash << ", parent=" << m_previousBlock.parentHash << endl; // cout << "Checking " << m_previousBlock.hash << ", parent=" << m_previousBlock.parentHash << endl;

4
libethereum/State.h

@ -53,7 +53,7 @@ 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 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 StateSafeExceptions: public LogChannel { static const char* name() { return "(S)"; } static const int verbosity = 21; };
enum class BaseState { Empty, Genesis }; enum class BaseState { Empty, CanonGenesis };
/** /**
* @brief Model of the current state of the ledger. * @brief Model of the current state of the ledger.
@ -68,7 +68,7 @@ class State
public: public:
/// Construct state object. /// Construct state object.
State(Address _coinbaseAddress = Address(), OverlayDB const& _db = OverlayDB(), BaseState _bs = BaseState::Genesis); State(Address _coinbaseAddress = Address(), OverlayDB const& _db = OverlayDB(), BaseState _bs = BaseState::CanonGenesis);
/// Construct state object from arbitrary point in blockchain. /// Construct state object from arbitrary point in blockchain.
State(OverlayDB const& _db, BlockChain const& _bc, h256 _hash); State(OverlayDB const& _db, BlockChain const& _bc, h256 _hash);

8
libp2p/Host.cpp

@ -387,6 +387,12 @@ string Host::pocHost()
void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPeerPort, unsigned short _udpNodePort) void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short _tcpPeerPort, unsigned short _udpNodePort)
{ {
// TODO: p2p clean this up (bring tested acceptor code over from network branch)
while (isWorking() && !m_run)
this_thread::sleep_for(chrono::milliseconds(50));
if (!m_run)
return;
if (_tcpPeerPort < 30300 || _tcpPeerPort > 30305) if (_tcpPeerPort < 30300 || _tcpPeerPort > 30305)
cwarn << "Non-standard port being recorded: " << _tcpPeerPort; cwarn << "Non-standard port being recorded: " << _tcpPeerPort;
@ -415,6 +421,8 @@ void Host::addNode(NodeId const& _node, std::string const& _addr, unsigned short
void Host::connect(std::shared_ptr<Peer> const& _p) void Host::connect(std::shared_ptr<Peer> const& _p)
{ {
while (isWorking() && !m_run)
this_thread::sleep_for(chrono::milliseconds(50));
if (!m_run) if (!m_run)
return; return;

92
libserpent/compiler.cpp

@ -77,43 +77,12 @@ Node popwrap(Node node) {
return multiToken(nodelist, 2, node.metadata); return multiToken(nodelist, 2, node.metadata);
} }
// Grabs variables
mss getVariables(Node node, mss cur=mss()) {
Metadata m = node.metadata;
// Tokens don't contain any variables
if (node.type == TOKEN)
return cur;
// Don't descend into call fragments
else if (node.val == "lll")
return getVariables(node.args[1], cur);
// At global scope get/set/ref also declare
else if (node.val == "get" || node.val == "set" || node.val == "ref") {
if (node.args[0].type != TOKEN)
err("Variable name must be simple token,"
" not complex expression! " + printSimple(node.args[0]), m);
if (!cur.count(node.args[0].val)) {
cur[node.args[0].val] = utd(cur.size() * 32 + 32);
//std::cerr << node.args[0].val << " " << cur[node.args[0].val] << "\n";
}
}
// Recursively process children
for (unsigned i = 0; i < node.args.size(); i++) {
cur = getVariables(node.args[i], cur);
}
return cur;
}
// Turns LLL tree into tree of code fragments // Turns LLL tree into tree of code fragments
programData opcodeify(Node node, programData opcodeify(Node node,
programAux aux=Aux(), programAux aux=Aux(),
programVerticalAux vaux=verticalAux()) { programVerticalAux vaux=verticalAux()) {
std::string symb = "_"+mkUniqueToken(); std::string symb = "_"+mkUniqueToken();
Metadata m = node.metadata; Metadata m = node.metadata;
// Get variables
if (!aux.vars.size()) {
aux.vars = getVariables(node);
aux.nextVarMem = aux.vars.size() * 32 + 32;
}
// Numbers // Numbers
if (node.type == TOKEN) { if (node.type == TOKEN) {
return pd(aux, nodeToNumeric(node), 1); return pd(aux, nodeToNumeric(node), 1);
@ -121,6 +90,10 @@ programData opcodeify(Node node,
else if (node.val == "ref" || node.val == "get" || node.val == "set") { else if (node.val == "ref" || node.val == "get" || node.val == "set") {
std::string varname = node.args[0].val; std::string varname = node.args[0].val;
// Determine reference to variable // Determine reference to variable
if (!aux.vars.count(node.args[0].val)) {
aux.vars[node.args[0].val] = utd(aux.nextVarMem);
aux.nextVarMem += 32;
}
Node varNode = tkn(aux.vars[varname], m); Node varNode = tkn(aux.vars[varname], m);
//std::cerr << varname << " " << printSimple(varNode) << "\n"; //std::cerr << varname << " " << printSimple(varNode) << "\n";
// Set variable // Set variable
@ -173,8 +146,7 @@ programData opcodeify(Node node,
} }
// Comments do nothing // Comments do nothing
else if (node.val == "comment") { else if (node.val == "comment") {
Node* nodelist = nullptr; return pd(aux, astnode("_", m), 0);
return pd(aux, multiToken(nodelist, 0, m), 0);
} }
// Custom operation sequence // Custom operation sequence
// eg. (ops bytez id msize swap1 msize add 0 swap1 mstore) == alloc // eg. (ops bytez id msize swap1 msize add 0 swap1 mstore) == alloc
@ -371,7 +343,7 @@ Node buildFragmentTree(Node node) {
// Builds a dictionary mapping labels to variable names // Builds a dictionary mapping labels to variable names
programAux buildDict(Node program, programAux aux, int labelLength) { void buildDict(Node program, programAux &aux, int labelLength) {
Metadata m = program.metadata; Metadata m = program.metadata;
// Token // Token
if (program.type == TOKEN) { if (program.type == TOKEN) {
@ -388,30 +360,24 @@ programAux buildDict(Node program, programAux aux, int labelLength) {
} }
// A sub-program (ie. LLL) // A sub-program (ie. LLL)
else if (program.val == "____CODE") { else if (program.val == "____CODE") {
programAux auks = Aux(); int step = aux.step;
aux.step = 0;
for (unsigned i = 0; i < program.args.size(); i++) { for (unsigned i = 0; i < program.args.size(); i++) {
auks = buildDict(program.args[i], auks, labelLength); buildDict(program.args[i], aux, labelLength);
}
for (std::map<std::string,std::string>::iterator it=auks.vars.begin();
it != auks.vars.end();
it++) {
aux.vars[(*it).first] = (*it).second;
} }
aux.step += auks.step; aux.step += step;
} }
// Normal sub-block // Normal sub-block
else { else {
for (unsigned i = 0; i < program.args.size(); i++) { for (unsigned i = 0; i < program.args.size(); i++) {
aux = buildDict(program.args[i], aux, labelLength); buildDict(program.args[i], aux, labelLength);
} }
} }
return aux;
} }
// Applies that dictionary // Applies that dictionary
Node substDict(Node program, programAux aux, int labelLength) { void substDict(Node program, programAux aux, int labelLength, std::vector<Node> &out) {
Metadata m = program.metadata; Metadata m = program.metadata;
std::vector<Node> out;
std::vector<Node> inner; std::vector<Node> inner;
if (program.type == TOKEN) { if (program.type == TOKEN) {
if (program.val[0] == '$') { if (program.val[0] == '$') {
@ -428,46 +394,32 @@ Node substDict(Node program, programAux aux, int labelLength) {
dist = decimalSub(end, start); dist = decimalSub(end, start);
inner = toByteArr(dist, m, labelLength); inner = toByteArr(dist, m, labelLength);
} }
out.push_back(astnode("_", inner, m)); for (unsigned i = 0; i < inner.size(); i++) out.push_back(inner[i]);
} }
else if (program.val[0] == '~') { } else if (program.val[0] == '~') { }
else if (isNumberLike(program)) { else if (isNumberLike(program)) {
inner = toByteArr(program.val, m); inner = toByteArr(program.val, m);
out.push_back(token("PUSH"+unsignedToDecimal(inner.size()))); out.push_back(token("PUSH"+unsignedToDecimal(inner.size())));
out.push_back(astnode("_", inner, m)); for (unsigned i = 0; i < inner.size(); i++) out.push_back(inner[i]);
} }
else return program; else out.push_back(program);
} }
else { else {
for (unsigned i = 0; i < program.args.size(); i++) { for (unsigned i = 0; i < program.args.size(); i++) {
Node n = substDict(program.args[i], aux, labelLength); substDict(program.args[i], aux, labelLength, out);
if (n.type == TOKEN || n.args.size()) out.push_back(n);
} }
} }
return astnode("_", out, m);
} }
// Compiled fragtree -> compiled fragtree without labels // Compiled fragtree -> compiled fragtree without labels
Node dereference(Node program) { std::vector<Node> dereference(Node program) {
int sz = treeSize(program) * 4; int sz = treeSize(program) * 4;
int labelLength = 1; int labelLength = 1;
while (sz >= 256) { labelLength += 1; sz /= 256; } while (sz >= 256) { labelLength += 1; sz /= 256; }
programAux aux = buildDict(program, Aux(), labelLength); programAux aux = Aux();
return substDict(program, aux, labelLength); buildDict(program, aux, labelLength);
}
// Dereferenced fragtree -> opcodes
std::vector<Node> flatten(Node derefed) {
std::vector<Node> o; std::vector<Node> o;
if (derefed.type == TOKEN) { substDict(program, aux, labelLength, o);
o.push_back(derefed);
}
else {
for (unsigned i = 0; i < derefed.args.size(); i++) {
std::vector<Node> oprime = flatten(derefed.args[i]);
for (unsigned j = 0; j < oprime.size(); j++) o.push_back(oprime[j]);
}
}
return o; return o;
} }
@ -512,12 +464,12 @@ std::vector<Node> deserialize(std::string ser) {
// Fragtree -> bin // Fragtree -> bin
std::string assemble(Node fragTree) { std::string assemble(Node fragTree) {
return serialize(flatten(dereference(fragTree))); return serialize(dereference(fragTree));
} }
// Fragtree -> tokens // Fragtree -> tokens
std::vector<Node> prettyAssemble(Node fragTree) { std::vector<Node> prettyAssemble(Node fragTree) {
return flatten(dereference(fragTree)); return dereference(fragTree);
} }
// LLL -> bin // LLL -> bin

5
libserpent/compiler.h

@ -8,14 +8,11 @@
#include "util.h" #include "util.h"
// Compiled fragtree -> compiled fragtree without labels // Compiled fragtree -> compiled fragtree without labels
Node dereference(Node program); std::vector<Node> dereference(Node program);
// LLL -> fragtree // LLL -> fragtree
Node buildFragmentTree(Node program); Node buildFragmentTree(Node program);
// Dereferenced fragtree -> opcodes
std::vector<Node> flatten(Node derefed);
// opcodes -> bin // opcodes -> bin
std::string serialize(std::vector<Node> codons); std::string serialize(std::vector<Node> codons);

3
libserpent/util.cpp

@ -5,7 +5,6 @@
#include "util.h" #include "util.h"
#include "bignum.h" #include "bignum.h"
#include <fstream> #include <fstream>
#include <string>
#include <cerrno> #include <cerrno>
//Token or value node constructor //Token or value node constructor
@ -260,7 +259,7 @@ std::string get_file_contents(std::string filename)
{ {
std::string contents; std::string contents;
in.seekg(0, std::ios::end); in.seekg(0, std::ios::end);
contents.resize((unsigned)in.tellg()); contents.resize(in.tellg());
in.seekg(0, std::ios::beg); in.seekg(0, std::ios::beg);
in.read(&contents[0], contents.size()); in.read(&contents[0], contents.size());
in.close(); in.close();

2
libsolidity/AST.cpp

@ -505,7 +505,7 @@ void FunctionCall::checkTypeRequirements()
// check duplicate names // check duplicate names
for (size_t i = 0; i < m_names.size(); i++) { for (size_t i = 0; i < m_names.size(); i++) {
for (size_t j = i + 1; j < m_names.size(); j++) { for (size_t j = i + 1; j < m_names.size(); j++) {
if (m_names[i] == m_names[j]) if (*m_names[i] == *m_names[j])
BOOST_THROW_EXCEPTION(createTypeError("Duplicate named argument.")); BOOST_THROW_EXCEPTION(createTypeError("Duplicate named argument."));
} }
} }

7
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -28,7 +28,7 @@
#include <liblll/Compiler.h> #include <liblll/Compiler.h>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include <libwebthree/WebThree.h> #include <libwebthree/WebThree.h>
#include <libdevcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include <libwhisper/Message.h> #include <libwhisper/Message.h>
#include <libwhisper/WhisperHost.h> #include <libwhisper/WhisperHost.h>
#include <libserpent/funcs.h> #include <libserpent/funcs.h>
@ -342,7 +342,10 @@ std::string WebThreeStubServerBase::eth_call(Json::Value const& _json)
Json::Value WebThreeStubServerBase::eth_changed(int const& _id) Json::Value WebThreeStubServerBase::eth_changed(int const& _id)
{ {
return toJson(client()->checkWatch(_id)); auto entries = client()->checkWatch(_id);
if (entries.size())
cnote << "FIRING WATCH" << _id << entries.size();
return toJson(entries);
} }
std::string WebThreeStubServerBase::eth_codeAt(string const& _address) std::string WebThreeStubServerBase::eth_codeAt(string const& _address)

4
libweb3jsonrpc/WebThreeStubServerBase.h

@ -36,9 +36,9 @@ namespace dev
{ {
class WebThreeNetworkFace; class WebThreeNetworkFace;
class KeyPair; class KeyPair;
struct TransactionSkeleton;
namespace eth namespace eth
{ {
struct TransactionSkeleton;
class Interface; class Interface;
} }
namespace shh namespace shh
@ -122,7 +122,7 @@ public:
std::map<dev::Public, dev::Secret> const& ids() const { return m_ids; } std::map<dev::Public, dev::Secret> const& ids() const { return m_ids; }
protected: protected:
virtual bool authenticate(dev::TransactionSkeleton const& _t); virtual bool authenticate(dev::eth::TransactionSkeleton const& _t);
protected: protected:
virtual dev::eth::Interface* client() = 0; virtual dev::eth::Interface* client() = 0;

36
mix/ClientModel.cpp

@ -22,8 +22,9 @@
#include <QDebug> #include <QDebug>
#include <QQmlContext> #include <QQmlContext>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include <QStandardPaths>
#include <jsonrpccpp/server.h> #include <jsonrpccpp/server.h>
#include <libdevcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include <libethereum/Transaction.h> #include <libethereum/Transaction.h>
#include "AppContext.h" #include "AppContext.h"
#include "DebuggingStateWrapper.h" #include "DebuggingStateWrapper.h"
@ -84,7 +85,7 @@ ClientModel::ClientModel(AppContext* _context):
qRegisterMetaType<TransactionLogEntry*>("TransactionLogEntry"); qRegisterMetaType<TransactionLogEntry*>("TransactionLogEntry");
connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection); connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection);
m_client.reset(new MixClient()); m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString()));
m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), std::vector<dev::KeyPair> { m_client->userAccount() }, m_client.get())); m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), std::vector<dev::KeyPair> { m_client->userAccount() }, m_client.get()));
connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection); connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection);
@ -111,10 +112,27 @@ QString ClientModel::apiCall(QString const& _message)
} }
void ClientModel::mine() void ClientModel::mine()
{
if (m_running)
BOOST_THROW_EXCEPTION(ExecutionStateException());
m_running = true;
emit runStarted();
emit runStateChanged();
QtConcurrent::run([=]()
{
try
{ {
m_client->mine(); m_client->mine();
newBlock(); newBlock();
} }
catch (...)
{
std::cerr << boost::current_exception_diagnostic_information();
emit runFailed(QString::fromStdString(boost::current_exception_diagnostic_information()));
}
m_running = false;
});
}
QString ClientModel::contractAddress() const QString ClientModel::contractAddress() const
{ {
@ -146,7 +164,7 @@ void ClientModel::setupState(QVariantMap _state)
TransactionSettings transactionSettings(functionId, transaction.value("url").toString()); TransactionSettings transactionSettings(functionId, transaction.value("url").toString());
transactionSettings.gasPrice = 10000000000000; transactionSettings.gasPrice = 10000000000000;
transactionSettings.gas = 125000; transactionSettings.gas = 125000;
transactionSettings.value = 100; transactionSettings.value = 0;
transactionSequence.push_back(transactionSettings); transactionSequence.push_back(transactionSettings);
} }
else else
@ -243,11 +261,13 @@ void ClientModel::executeSequence(std::vector<TransactionSettings> const& _seque
} }
catch(boost::exception const&) catch(boost::exception const&)
{ {
std::cerr << boost::current_exception_diagnostic_information();
emit runFailed(QString::fromStdString(boost::current_exception_diagnostic_information())); emit runFailed(QString::fromStdString(boost::current_exception_diagnostic_information()));
} }
catch(std::exception const& e) catch(std::exception const& e)
{ {
std::cerr << boost::current_exception_diagnostic_information();
emit runFailed(e.what()); emit runFailed(e.what());
} }
m_running = false; m_running = false;
@ -257,7 +277,7 @@ void ClientModel::executeSequence(std::vector<TransactionSettings> const& _seque
void ClientModel::showDebugger() void ClientModel::showDebugger()
{ {
ExecutionResult const& last = m_client->record().back().transactions.back(); ExecutionResult const& last = m_client->lastExecution();
showDebuggerForTransaction(last); showDebuggerForTransaction(last);
} }
@ -290,7 +310,7 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t)
void ClientModel::debugTransaction(unsigned _block, unsigned _index) void ClientModel::debugTransaction(unsigned _block, unsigned _index)
{ {
auto const& t = m_client->record().at(_block).transactions.at(_index); auto const& t = m_client->execution(_block, _index);
showDebuggerForTransaction(t); showDebuggerForTransaction(t);
} }
@ -321,9 +341,9 @@ void ClientModel::onStateReset()
void ClientModel::onNewTransaction() void ClientModel::onNewTransaction()
{ {
unsigned block = m_client->number(); unsigned block = m_client->number() + 1;
unsigned index = m_client->record().back().transactions.size() - 1; unsigned index = m_client->pendingExecutions().size() - 1;
ExecutionResult const& tr = m_client->record().back().transactions.back(); ExecutionResult const& tr = m_client->lastExecution();
QString address = QString::fromStdString(toJS(tr.address)); QString address = QString::fromStdString(toJS(tr.address));
QString value = QString::fromStdString(dev::toString(tr.value)); QString value = QString::fromStdString(dev::toString(tr.value));
QString contract = address; QString contract = address;

2
mix/ContractCallDataEncoder.cpp

@ -23,7 +23,7 @@
#include <QDebug> #include <QDebug>
#include <QMap> #include <QMap>
#include <QStringList> #include <QStringList>
#include <libdevcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include <libsolidity/AST.h> #include <libsolidity/AST.h>
#include "QVariableDeclaration.h" #include "QVariableDeclaration.h"
#include "QVariableDefinition.h" #include "QVariableDefinition.h"

2
mix/DebuggingStateWrapper.cpp

@ -26,7 +26,7 @@
#include <QQmlEngine> #include <QQmlEngine>
#include <QVariantList> #include <QVariantList>
#include <libevmcore/Instruction.h> #include <libevmcore/Instruction.h>
#include <libdevcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include <libdevcrypto/Common.h> #include <libdevcrypto/Common.h>
#include <libevmcore/Instruction.h> #include <libevmcore/Instruction.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>

210
mix/MixClient.cpp

@ -23,7 +23,7 @@
#include <vector> #include <vector>
#include <libdevcore/Exceptions.h> #include <libdevcore/Exceptions.h>
#include <libethereum/BlockChain.h> #include <libethereum/CanonBlockChain.h>
#include <libethereum/Transaction.h> #include <libethereum/Transaction.h>
#include <libethereum/Executive.h> #include <libethereum/Executive.h>
#include <libethereum/ExtVM.h> #include <libethereum/ExtVM.h>
@ -36,35 +36,50 @@ using namespace dev;
using namespace dev::eth; using namespace dev::eth;
using namespace dev::mix; using namespace dev::mix;
const Secret c_stdSecret = Secret("cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074"); const Secret c_userAccountSecret = Secret("cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074");
MixClient::MixClient(): MixClient::MixClient(std::string const& _dbPath):
m_userAccount(c_stdSecret) m_userAccount(c_userAccountSecret), m_bc(_dbPath, true), m_dbPath(_dbPath), m_minigThreads(0)
{
//TODO: put this into genesis block somehow
//resetState(10000000 * ether);
}
MixClient::~MixClient()
{ {
resetState(10000000 * ether);
} }
void MixClient::resetState(u256 _balance) void MixClient::resetState(u256 _balance)
{
(void) _balance;
{ {
WriteGuard l(x_state); WriteGuard l(x_state);
Guard fl(m_filterLock); Guard fl(m_filterLock);
m_filters.clear(); m_filters.clear();
m_watches.clear(); m_watches.clear();
m_state = eth::State(m_userAccount.address(), m_stateDB, BaseState::Genesis); m_bc.reopen(m_dbPath, true);
m_state.addBalance(m_userAccount.address(), _balance); m_state = eth::State();
Block genesis; m_stateDB = OverlayDB();
genesis.state = m_state; m_state = eth::State(m_userAccount.address(), m_stateDB, BaseState::CanonGenesis);
Block open; m_state.sync(m_bc);
m_blocks = Blocks { genesis, open }; //last block contains a list of pending transactions to be finalized m_startState = m_state;
// m_lastHashes.clear(); m_pendingExecutions.clear();
// m_lastHashes.resize(256); }
// m_lastHashes[0] = genesis.hash; mine();
} }
void MixClient::executeTransaction(Transaction const& _t, State& _state) void MixClient::executeTransaction(Transaction const& _t, State& _state)
{ {
bytes rlp = _t.rlp(); bytes rlp = _t.rlp();
Executive execution(_state, LastHashes(), 0);
// do debugging run first
LastHashes lastHashes(256);
lastHashes[0] = m_bc.numberHash(m_bc.number());
for (unsigned i = 1; i < 256; ++i)
lastHashes[i] = lastHashes[i - 1] ? m_bc.details(lastHashes[i - 1]).parent : h256();
State execState = _state;
Executive execution(execState, lastHashes, 0);
execution.setup(&rlp); execution.setup(&rlp);
std::vector<MachineState> machineStates; std::vector<MachineState> machineStates;
std::vector<unsigned> levels; std::vector<unsigned> levels;
@ -130,21 +145,25 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state)
d.value = _t.value(); d.value = _t.value();
if (_t.isCreation()) if (_t.isCreation())
d.contractAddress = right160(sha3(rlpList(_t.sender(), _t.nonce()))); d.contractAddress = right160(sha3(rlpList(_t.sender(), _t.nonce())));
d.receipt = TransactionReceipt(m_state.rootHash(), execution.gasUsed(), execution.logs()); //TODO: track gas usage d.receipt = TransactionReceipt(execState.rootHash(), execution.gasUsed(), execution.logs()); //TODO: track gas usage
m_blocks.back().transactions.emplace_back(d); m_pendingExecutions.emplace_back(std::move(d));
// execute on a state
_state.execute(lastHashes, rlp, nullptr, true);
// collect watches
h256Set changed; h256Set changed;
Guard l(m_filterLock); Guard l(m_filterLock);
for (std::pair<h256 const, eth::InstalledFilter>& i: m_filters) for (std::pair<h256 const, eth::InstalledFilter>& i: m_filters)
if ((unsigned)i.second.filter.latest() > m_blocks.size() - 1) if ((unsigned)i.second.filter.latest() > m_bc.number())
{ {
// acceptable number. // acceptable number.
auto m = i.second.filter.matches(d.receipt); auto m = i.second.filter.matches(_state.receipt(_state.pending().size() - 1));
if (m.size()) if (m.size())
{ {
// filter catches them // filter catches them
for (LogEntry const& l: m) for (LogEntry const& l: m)
i.second.changes.push_back(LocalisedLogEntry(l, m_blocks.size())); i.second.changes.push_back(LocalisedLogEntry(l, m_bc.number() + 1));
changed.insert(i.first); changed.insert(i.first);
} }
} }
@ -152,44 +171,56 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state)
noteChanged(changed); noteChanged(changed);
} }
void MixClient::validateBlock(int _block) const
{
if (_block != -1 && _block != 0 && (unsigned)_block >= m_blocks.size() - 1)
BOOST_THROW_EXCEPTION(InvalidBlockException() << BlockIndex(_block));
}
void MixClient::mine() void MixClient::mine()
{ {
WriteGuard l(x_state); WriteGuard l(x_state);
Block& block = m_blocks.back(); m_state.commitToMine(m_bc);
m_state.mine(0, true); while (!m_state.mine(100, true).completed) {}
m_state.completeMine(); m_state.completeMine();
m_state.commitToMine(BlockChain()); m_bc.import(m_state.blockData(), m_stateDB);
m_state.cleanup(true); m_state.sync(m_bc);
block.state = m_state; //m_state.cleanup(true);
block.info = m_state.info(); m_startState = m_state;
block.hash = block.info.hash; m_executions.emplace_back(std::move(m_pendingExecutions));
m_blocks.push_back(Block());
h256Set changed { dev::eth::PendingChangedFilter, dev::eth::ChainChangedFilter }; h256Set changed { dev::eth::PendingChangedFilter, dev::eth::ChainChangedFilter };
noteChanged(changed); noteChanged(changed);
} }
State const& MixClient::asOf(int _block) const ExecutionResult const& MixClient::execution(unsigned _block, unsigned _transaction) const
{
if (_block == m_bc.number() + 1)
return m_pendingExecutions.at(_transaction);
return m_executions.at(_block).at(_transaction);
}
ExecutionResult const& MixClient::lastExecution() const
{ {
validateBlock(_block); if (m_pendingExecutions.size() > 0)
return m_pendingExecutions.back();
return m_executions.back().back();
}
ExecutionResults const& MixClient::pendingExecutions() const
{
return m_pendingExecutions;
}
State MixClient::asOf(int _block) const
{
ReadGuard l(x_state);
if (_block == 0) if (_block == 0)
return m_blocks[m_blocks.size() - 2].state;
else if (_block == -1)
return m_state; return m_state;
else if (_block == -1)
return m_startState;
else else
return m_blocks[_block].state; return State(m_stateDB, m_bc, m_bc.numberHash(_block));
} }
void MixClient::transact(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) void MixClient::transact(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice)
{ {
WriteGuard l(x_state); WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_secret)); u256 n = m_state.transactionsFrom(toAddress(_secret));
_gasPrice = 0; //TODO: remove after fixing setBalance
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret);
executeTransaction(t, m_state); executeTransaction(t, m_state);
} }
@ -198,6 +229,7 @@ Address MixClient::transact(Secret _secret, u256 _endowment, bytes const& _init,
{ {
WriteGuard l(x_state); WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_secret)); u256 n = m_state.transactionsFrom(toAddress(_secret));
_gasPrice = 0; //TODO: remove after fixing setBalance
eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret);
executeTransaction(t, m_state); executeTransaction(t, m_state);
Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); Address address = right160(sha3(rlpList(t.sender(), t.nonce())));
@ -228,36 +260,31 @@ bytes MixClient::call(Secret _secret, u256 _value, Address _dest, bytes const& _
bytes rlp = t.rlp(); bytes rlp = t.rlp();
WriteGuard lw(x_state); //TODO: lock is required only for last execution state WriteGuard lw(x_state); //TODO: lock is required only for last execution state
executeTransaction(t, temp); executeTransaction(t, temp);
return m_blocks.back().transactions.back().returnValue; return m_pendingExecutions.back().returnValue;
} }
u256 MixClient::balanceAt(Address _a, int _block) const u256 MixClient::balanceAt(Address _a, int _block) const
{ {
ReadGuard l(x_state);
return asOf(_block).balance(_a); return asOf(_block).balance(_a);
} }
u256 MixClient::countAt(Address _a, int _block) const u256 MixClient::countAt(Address _a, int _block) const
{ {
ReadGuard l(x_state);
return asOf(_block).transactionsFrom(_a); return asOf(_block).transactionsFrom(_a);
} }
u256 MixClient::stateAt(Address _a, u256 _l, int _block) const u256 MixClient::stateAt(Address _a, u256 _l, int _block) const
{ {
ReadGuard l(x_state);
return asOf(_block).storage(_a, _l); return asOf(_block).storage(_a, _l);
} }
bytes MixClient::codeAt(Address _a, int _block) const bytes MixClient::codeAt(Address _a, int _block) const
{ {
ReadGuard l(x_state);
return asOf(_block).code(_a); return asOf(_block).code(_a);
} }
std::map<u256, u256> MixClient::storageAt(Address _a, int _block) const std::map<u256, u256> MixClient::storageAt(Address _a, int _block) const
{ {
ReadGuard l(x_state);
return asOf(_block).storage(_a); return asOf(_block).storage(_a);
} }
@ -274,23 +301,40 @@ eth::LocalisedLogEntries MixClient::logs(unsigned _watchId) const
eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const
{ {
LocalisedLogEntries ret; LocalisedLogEntries ret;
unsigned lastBlock = m_blocks.size() - 1; //last block contains pending transactions unsigned lastBlock = m_bc.number();
unsigned block = std::min<unsigned>(lastBlock, (unsigned)_f.latest()); unsigned block = std::min<unsigned>(lastBlock, (unsigned)_f.latest());
unsigned end = std::min(lastBlock, std::min(block, (unsigned)_f.earliest())); unsigned end = std::min(lastBlock, std::min(block, (unsigned)_f.earliest()));
for (; ret.size() != _f.max() && block != end; block--) unsigned skip = _f.skip();
{ // Pending transactions
bool pendingBlock = (block == lastBlock); if (block > m_bc.number())
if (pendingBlock || _f.matches(m_blocks[block].info.logBloom))
for (ExecutionResult const& t: m_blocks[block].transactions)
if (pendingBlock || _f.matches(t.receipt.bloom()))
{ {
LogEntries logEntries = _f.matches(t.receipt); ReadGuard l(x_state);
if (logEntries.size()) for (unsigned i = 0; i < m_state.pending().size(); ++i)
{ {
for (unsigned entry = _f.skip(); entry < logEntries.size() && ret.size() != _f.max(); ++entry) // Might have a transaction that contains a matching log.
TransactionReceipt const& tr = m_state.receipt(i);
LogEntries logEntries = _f.matches(tr);
for (unsigned entry = 0; entry < logEntries.size() && ret.size() != _f.max(); ++entry)
ret.insert(ret.begin(), LocalisedLogEntry(logEntries[entry], block)); ret.insert(ret.begin(), LocalisedLogEntry(logEntries[entry], block));
skip -= std::min(skip, static_cast<unsigned>(logEntries.size()));
} }
block = m_bc.number();
} }
// The rest
auto h = m_bc.numberHash(block);
for (; ret.size() != block && block != end; block--)
{
if (_f.matches(m_bc.info(h).logBloom))
for (TransactionReceipt receipt: m_bc.receipts(h).receipts)
if (_f.matches(receipt.bloom()))
{
LogEntries logEntries = _f.matches(receipt);
for (unsigned entry = skip; entry < logEntries.size() && ret.size() != _f.max(); ++entry)
ret.insert(ret.begin(), LocalisedLogEntry(logEntries[entry], block));
skip -= std::min(skip, static_cast<unsigned>(logEntries.size()));
}
h = m_bc.details(h).parent;
} }
return ret; return ret;
} }
@ -372,66 +416,65 @@ LocalisedLogEntries MixClient::checkWatch(unsigned _watchId)
h256 MixClient::hashFromNumber(unsigned _number) const h256 MixClient::hashFromNumber(unsigned _number) const
{ {
validateBlock(_number); return m_bc.numberHash(_number);
return m_blocks[_number].hash;
} }
eth::BlockInfo MixClient::blockInfo(h256 _hash) const eth::BlockInfo MixClient::blockInfo(h256 _hash) const
{ {
(void)_hash; return BlockInfo(m_bc.block(_hash));
BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::Interface::blockInfo"));
} }
eth::BlockDetails MixClient::blockDetails(h256 _hash) const eth::BlockDetails MixClient::blockDetails(h256 _hash) const
{ {
(void)_hash; return m_bc.details(_hash);
BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::Interface::blockDetails"));
} }
eth::Transaction MixClient::transaction(h256 _blockHash, unsigned _i) const eth::Transaction MixClient::transaction(h256 _blockHash, unsigned _i) const
{ {
(void)_blockHash; auto bl = m_bc.block(_blockHash);
(void)_i; RLP b(bl);
BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::Interface::transaction")); if (_i < b[1].itemCount())
return Transaction(b[1][_i].data(), CheckSignature::Range);
else
return Transaction();
} }
eth::BlockInfo MixClient::uncle(h256 _blockHash, unsigned _i) const eth::BlockInfo MixClient::uncle(h256 _blockHash, unsigned _i) const
{ {
(void)_blockHash; auto bl = m_bc.block(_blockHash);
(void)_i; RLP b(bl);
BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::Interface::uncle")); if (_i < b[2].itemCount())
return BlockInfo::fromHeader(b[2][_i].data());
else
return BlockInfo();
} }
unsigned MixClient::number() const unsigned MixClient::number() const
{ {
return m_blocks.size() - 1; return m_bc.number();
} }
eth::Transactions MixClient::pending() const eth::Transactions MixClient::pending() const
{ {
return eth::Transactions(); return m_state.pending();
} }
eth::StateDiff MixClient::diff(unsigned _txi, h256 _block) const eth::StateDiff MixClient::diff(unsigned _txi, h256 _block) const
{ {
(void)_txi; State st(m_stateDB, m_bc, _block);
(void)_block; return st.fromPending(_txi).diff(st.fromPending(_txi + 1));
BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::Interface::diff"));
} }
eth::StateDiff MixClient::diff(unsigned _txi, int _block) const eth::StateDiff MixClient::diff(unsigned _txi, int _block) const
{ {
(void)_txi; State st = asOf(_block);
(void)_block; return st.fromPending(_txi).diff(st.fromPending(_txi + 1));
BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::Interface::diff"));
} }
Addresses MixClient::addresses(int _block) const Addresses MixClient::addresses(int _block) const
{ {
validateBlock(_block);
ReadGuard l(x_state);
Addresses ret; Addresses ret;
for (auto const& i: m_state.addresses()) for (auto const& i: asOf(_block).addresses())
ret.push_back(i.first); ret.push_back(i.first);
return ret; return ret;
} }
@ -456,23 +499,22 @@ Address MixClient::address() const
void MixClient::setMiningThreads(unsigned _threads) void MixClient::setMiningThreads(unsigned _threads)
{ {
(void)_threads; m_minigThreads = _threads;
BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::Interface::setMiningThreads"));
} }
unsigned MixClient::miningThreads() const unsigned MixClient::miningThreads() const
{ {
return 0; return m_minigThreads;
} }
void MixClient::startMining() void MixClient::startMining()
{ {
BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::Interface::startMining")); //no-op
} }
void MixClient::stopMining() void MixClient::stopMining()
{ {
BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::Interface::stopMining")); //no-op
} }
bool MixClient::isMining() bool MixClient::isMining()

30
mix/MixClient.h

@ -24,8 +24,10 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include <string>
#include <libethereum/Interface.h> #include <libethereum/Interface.h>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include <libethereum/CanonBlockChain.h>
#include "MachineStates.h" #include "MachineStates.h"
namespace dev namespace dev
@ -33,26 +35,18 @@ namespace dev
namespace mix namespace mix
{ {
struct Block
{
ExecutionResults transactions;
h256 hash;
dev::eth::State state;
dev::eth::BlockInfo info;
};
using Blocks = std::vector<Block>;
class MixClient: public dev::eth::Interface class MixClient: public dev::eth::Interface
{ {
public: public:
MixClient(); MixClient(std::string const& _dbPath);
virtual ~MixClient();
/// Reset state to the empty state with given balance. /// Reset state to the empty state with given balance.
void resetState(u256 _balance); void resetState(u256 _balance);
KeyPair const& userAccount() const { return m_userAccount; } KeyPair const& userAccount() const { return m_userAccount; }
void mine(); void mine();
Blocks const& record() const { return m_blocks; } ExecutionResult const& execution(unsigned _block, unsigned _transaction) const;
ExecutionResult const& lastExecution() const;
ExecutionResults const& pendingExecutions() const;
//dev::eth::Interface //dev::eth::Interface
void transact(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) override; void transact(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) override;
@ -94,18 +88,22 @@ public:
private: private:
void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state); void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state);
void validateBlock(int _block) const;
void noteChanged(h256Set const& _filters); void noteChanged(h256Set const& _filters);
dev::eth::State const& asOf(int _block) const; dev::eth::State asOf(int _block) const;
KeyPair m_userAccount; KeyPair m_userAccount;
eth::State m_state; eth::State m_state;
eth::State m_startState;
OverlayDB m_stateDB; OverlayDB m_stateDB;
eth::CanonBlockChain m_bc;
mutable boost::shared_mutex x_state; mutable boost::shared_mutex x_state;
mutable std::mutex m_filterLock; mutable std::mutex m_filterLock;
std::map<h256, dev::eth::InstalledFilter> m_filters; std::map<h256, dev::eth::InstalledFilter> m_filters;
std::map<unsigned, dev::eth::ClientWatch> m_watches; std::map<unsigned, dev::eth::ClientWatch> m_watches;
Blocks m_blocks; std::vector<ExecutionResults> m_executions;
ExecutionResults m_pendingExecutions;
std::string m_dbPath;
unsigned m_minigThreads;
}; };
} }

2
mix/QBigInt.cpp

@ -21,7 +21,7 @@
#include <boost/variant/multivisitors.hpp> #include <boost/variant/multivisitors.hpp>
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <libdevcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include "QBigInt.h" #include "QBigInt.h"
using namespace dev; using namespace dev;

2
mix/QBigInt.h

@ -26,7 +26,7 @@
#include "boost/variant/multivisitors.hpp" #include "boost/variant/multivisitors.hpp"
#include <QObject> #include <QObject>
#include <QQmlEngine> #include <QQmlEngine>
#include <libdevcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
using namespace dev; using namespace dev;

2
mix/QVariableDefinition.cpp

@ -20,7 +20,7 @@
*/ */
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <libdevcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include "QVariableDefinition.h" #include "QVariableDefinition.h"
using namespace dev::mix; using namespace dev::mix;

3
mix/qml/MainContent.qml

@ -59,8 +59,7 @@ Rectangle {
} }
function hideRightView() { function hideRightView() {
if (rightView.visible) rightView.visible = false;
rightView.hide();
} }
function toggleWebPreview() { function toggleWebPreview() {

5
pullSerpent.sh

@ -2,10 +2,11 @@
opwd="$PWD" opwd="$PWD"
cd ../serpent cd ../serpent
git stash
git pull git pull
git stash pop
cp bignum.* compiler.* funcs.* lllparser.* opcodes.h parser.* rewriter.* tokenize.* util.* ../cpp-ethereum/libserpent/ cp bignum.* compiler.* funcs.* lllparser.* opcodes.h parser.* rewriter.* tokenize.* util.* ../cpp-ethereum/libserpent/
cp cmdline.* "$opwd/sc/" cp cmdline.* "$opwd/sc/"
cp pyserpent.* "$opwd/libpyserpent/"
cd "$opwd" cd "$opwd"
perl -i -p -e 's:include "funcs.h":include <libserpent/funcs.h>:gc' sc/* libpyserpent/* perl -i -p -e 's:include "funcs.h":include <libserpent/funcs.h>:gc' sc/*

5
sc/cmdline.cpp

@ -68,7 +68,7 @@ int main(int argv, char** argc) {
std::cout << binToHex(compileLLL(parseLLL(input, true))) << "\n"; std::cout << binToHex(compileLLL(parseLLL(input, true))) << "\n";
} }
else if (command == "dereference") { else if (command == "dereference") {
std::cout << printAST(dereference(parseLLL(input, true)), haveSec) <<"\n"; std::cout << printTokens(dereference(parseLLL(input, true))) <<"\n";
} }
else if (command == "pretty_assemble") { else if (command == "pretty_assemble") {
std::cout << printTokens(prettyAssemble(parseLLL(input, true))) <<"\n"; std::cout << printTokens(prettyAssemble(parseLLL(input, true))) <<"\n";
@ -88,9 +88,6 @@ int main(int argv, char** argc) {
else if (command == "serialize") { else if (command == "serialize") {
std::cout << binToHex(serialize(tokenize(input, Metadata(), false))) << "\n"; std::cout << binToHex(serialize(tokenize(input, Metadata(), false))) << "\n";
} }
else if (command == "flatten") {
std::cout << printTokens(flatten(parseLLL(input, true))) << "\n";
}
else if (command == "deserialize") { else if (command == "deserialize") {
std::cout << printTokens(deserialize(hexToBin(input))) << "\n"; std::cout << printTokens(deserialize(hexToBin(input))) << "\n";
} }

36
test/SolidityNameAndTypeResolution.cpp

@ -868,6 +868,42 @@ BOOST_AUTO_TEST_CASE(access_to_protected_state_variable)
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
} }
BOOST_AUTO_TEST_CASE(error_count_in_named_args)
{
char const* sourceCode = "contract test {\n"
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
" function b() returns (uint r) { r = a({a: 1}); }\n"
"}\n";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(empty_in_named_args)
{
char const* sourceCode = "contract test {\n"
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
" function b() returns (uint r) { r = a({}); }\n"
"}\n";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(duplicate_parameter_names_in_named_args)
{
char const* sourceCode = "contract test {\n"
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
" function b() returns (uint r) { r = a({a: 1, a: 2}); }\n"
"}\n";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(invalid_parameter_names_in_named_args)
{
char const* sourceCode = "contract test {\n"
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
" function b() returns (uint r) { r = a({a: 1, c: 2}); }\n"
"}\n";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

5
test/commonjs.cpp

@ -20,7 +20,8 @@
*/ */
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <libdevcore/CommonJS.h> #include <libdevcore/Log.h>
#include <libethcore/CommonJS.h>
BOOST_AUTO_TEST_SUITE(commonjs) BOOST_AUTO_TEST_SUITE(commonjs)
using namespace std; using namespace std;
@ -41,7 +42,7 @@ BOOST_AUTO_TEST_CASE(jsToAddress)
cnote << "Testing jsToPublic..."; cnote << "Testing jsToPublic...";
KeyPair kp = KeyPair::create(); KeyPair kp = KeyPair::create();
string string = toJS(kp.address()); string string = toJS(kp.address());
Address address = dev::jsToAddress(string); Address address = dev::eth::jsToAddress(string);
BOOST_CHECK_EQUAL(kp.address(), address); BOOST_CHECK_EQUAL(kp.address(), address);
} }

2
test/fork.cpp

@ -23,7 +23,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include <libethereum/BlockChain.h> #include <libethereum/CanonBlockChain.h>
#include <libethereum/EthereumHost.h> #include <libethereum/EthereumHost.h>
#include "TestHelper.h" #include "TestHelper.h"
using namespace std; using namespace std;

8
test/genesis.cpp

@ -24,7 +24,7 @@
#include <random> #include <random>
#include "JsonSpiritHeaders.h" #include "JsonSpiritHeaders.h"
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libethereum/BlockChain.h> #include <libethereum/CanonBlockChain.h>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include "TestHelper.h" #include "TestHelper.h"
@ -58,9 +58,9 @@ BOOST_AUTO_TEST_CASE(genesis_tests)
js::mObject o = v.get_obj(); js::mObject o = v.get_obj();
BOOST_CHECK_EQUAL(BlockChain::genesis().stateRoot, h256(o["genesis_state_root"].get_str())); BOOST_CHECK_EQUAL(CanonBlockChain::genesis().stateRoot, h256(o["genesis_state_root"].get_str()));
BOOST_CHECK_EQUAL(toHex(BlockChain::createGenesisBlock()), toHex(fromHex(o["genesis_rlp_hex"].get_str()))); BOOST_CHECK_EQUAL(toHex(CanonBlockChain::createGenesisBlock()), toHex(fromHex(o["genesis_rlp_hex"].get_str())));
BOOST_CHECK_EQUAL(BlockInfo::headerHash(BlockChain::createGenesisBlock()), h256(o["genesis_hash"].get_str())); BOOST_CHECK_EQUAL(BlockInfo::headerHash(CanonBlockChain::createGenesisBlock()), h256(o["genesis_hash"].get_str()));
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

2
test/jsonrpc.cpp

@ -28,7 +28,7 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libdevcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include <libwebthree/WebThree.h> #include <libwebthree/WebThree.h>
#include <libweb3jsonrpc/WebThreeStubServer.h> #include <libweb3jsonrpc/WebThreeStubServer.h>
#include <jsonrpccpp/server/connectors/httpserver.h> #include <jsonrpccpp/server/connectors/httpserver.h>

2
test/state.cpp

@ -24,7 +24,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include "JsonSpiritHeaders.h" #include "JsonSpiritHeaders.h"
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libethereum/BlockChain.h> #include <libethereum/CanonBlockChain.h>
#include <libethereum/State.h> #include <libethereum/State.h>
#include <libethereum/ExtVM.h> #include <libethereum/ExtVM.h>
#include <libethereum/Defaults.h> #include <libethereum/Defaults.h>

4
test/stateOriginal.cpp

@ -22,7 +22,7 @@
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <secp256k1/secp256k1.h> #include <secp256k1/secp256k1.h>
#include <libethereum/BlockChain.h> #include <libethereum/CanonBlockChain.h>
#include <libethereum/State.h> #include <libethereum/State.h>
#include <libethereum/Defaults.h> #include <libethereum/Defaults.h>
using namespace std; using namespace std;
@ -40,7 +40,7 @@ int stateTest()
Defaults::setDBPath(boost::filesystem::temp_directory_path().string()); Defaults::setDBPath(boost::filesystem::temp_directory_path().string());
OverlayDB stateDB = State::openDB(); OverlayDB stateDB = State::openDB();
BlockChain bc; CanonBlockChain bc;
State s(myMiner.address(), stateDB); State s(myMiner.address(), stateDB);
cout << bc; cout << bc;

2
test/txTest.cpp

@ -23,7 +23,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include <libethereum/BlockChain.h> #include <libethereum/CanonBlockChain.h>
#include <libethereum/EthereumHost.h> #include <libethereum/EthereumHost.h>
#include "TestHelper.h" #include "TestHelper.h"
using namespace std; using namespace std;

6
third/MainWin.cpp

@ -34,7 +34,7 @@
#include <liblll/Compiler.h> #include <liblll/Compiler.h>
#include <liblll/CodeFragment.h> #include <liblll/CodeFragment.h>
#include <libevm/VM.h> #include <libevm/VM.h>
#include <libethereum/BlockChain.h> #include <libethereum/CanonBlockChain.h>
#include <libethereum/ExtVM.h> #include <libethereum/ExtVM.h>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include <libethereum/EthereumHost.h> #include <libethereum/EthereumHost.h>
@ -97,8 +97,8 @@ Main::Main(QWidget *parent) :
setWindowFlags(Qt::Window); setWindowFlags(Qt::Window);
ui->setupUi(this); ui->setupUi(this);
cerr << "State root: " << BlockChain::genesis().stateRoot << endl; cerr << "State root: " << CanonBlockChain::genesis().stateRoot << endl;
auto gb = BlockChain::createGenesisBlock(); auto gb = CanonBlockChain::createGenesisBlock();
cerr << "Block Hash: " << sha3(gb) << endl; cerr << "Block Hash: " << sha3(gb) << endl;
cerr << "Block RLP: " << RLP(gb) << endl; cerr << "Block RLP: " << RLP(gb) << endl;
cerr << "Block Hex: " << toHex(gb) << endl; cerr << "Block Hex: " << toHex(gb) << endl;

Loading…
Cancel
Save