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. 62
      libethereum/BlockChain.cpp
  10. 18
      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. 10
      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. 40
      mix/ClientModel.cpp
  24. 2
      mix/ContractCallDataEncoder.cpp
  25. 2
      mix/DebuggingStateWrapper.cpp
  26. 222
      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/util.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/CommonJS.h>
#include <libethcore/CommonJS.h>
#include <liblll/Compiler.h>
#include <liblll/CodeFragment.h>
#include <libsolidity/Scanner.h>
@ -41,7 +41,7 @@
#include <libsolidity/SourceReferenceFormatter.h>
#include <libevm/VM.h>
#include <libevm/VMFactory.h>
#include <libethereum/BlockChain.h>
#include <libethereum/CanonBlockChain.h>
#include <libethereum/ExtVM.h>
#include <libethereum/Client.h>
#include <libethereum/Utility.h>
@ -136,9 +136,9 @@ Main::Main(QWidget *parent) :
#endif
m_servers.append(QString::fromStdString(Host::pocHost() + ":30303"));
cerr << "State root: " << BlockChain::genesis().stateRoot << endl;
auto block = BlockChain::createGenesisBlock();
cerr << "Block Hash: " << BlockChain::genesis().hash << endl;
cerr << "State root: " << CanonBlockChain::genesis().stateRoot << endl;
auto block = CanonBlockChain::createGenesisBlock();
cerr << "Block Hash: " << CanonBlockChain::genesis().hash << endl;
cerr << "Block RLP: " << RLP(block) << endl;
cerr << "Block Hex: " << toHex(block) << 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"));
}
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
{
@ -1186,7 +1186,10 @@ void Main::timerEvent(QTimerEvent*)
{
auto ls = ethereum()->checkWatch(i.first);
if (ls.size())
{
cnote << "FIRING WATCH" << i.first << ls.size();
i.second(ls);
}
}
}
@ -1199,7 +1202,7 @@ string Main::renderDiff(StateDiff const& _d) const
{
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>";
if (!ad.exist.to())
continue;
@ -1207,7 +1210,7 @@ string Main::renderDiff(StateDiff const& _d) const
if (ad.balance)
{
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>";
}
if (ad.nonce)

4
alethzero/OurWebThreeStubServer.h

@ -20,7 +20,7 @@
*/
#include <QtCore/QObject>
#include <libdevcore/CommonJS.h>
#include <libethcore/CommonJS.h>
#include <libdevcrypto/Common.h>
#include <libweb3jsonrpc/WebThreeStubServer.h>
@ -35,7 +35,7 @@ public:
std::vector<dev::KeyPair> const& _accounts, Main* main);
virtual std::string shh_newIdentity() override;
virtual bool authenticate(dev::TransactionSkeleton const& _t);
virtual bool authenticate(dev::eth::TransactionSkeleton const& _t);
signals:
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
{
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.
* This version uses an database backend.
* This version uses a database backend.
* Usage:
* @code
* GenericTrieDB<MyDB> t(&myDB);

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

@ -72,6 +72,31 @@ bytes unpadLeft(bytes _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)
{
unsigned inc = 0;
@ -98,31 +123,6 @@ std::string prettyU256(u256 _n)
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)
{
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
#include <string>
#include <libethereum/Interface.h>
#include "Common.h"
#include "CommonData.h"
#include <libdevcore/Common.h>
#include <libdevcore/FixedHash.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/CommonIO.h>
#include "CommonEth.h"
namespace dev
{
@ -94,16 +96,8 @@ template <unsigned N> boost::multiprecision::number<boost::multiprecision::cpp_i
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 std::string jsToBinary(std::string const& _s)
{
return dev::toString(unpadded(jsToBytes(_s)));
}
inline std::string jsToDecimal(std::string const& _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);
}
}
// 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
{
Address from;
@ -136,3 +153,4 @@ struct TransactionSkeleton
};
}
}

2
libethereum/All.h

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

62
libethereum/BlockChain.cpp

@ -53,30 +53,6 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc)
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)
{
#if ALL_COMPILERS_ARE_CPP11_COMPLIANT
@ -91,31 +67,11 @@ ldb::Slice dev::eth::toSlice(h256 _h, unsigned _sub)
#endif
}
bytes BlockChain::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();
}
BlockChain::BlockChain(std::string _path, bool _killExisting)
BlockChain::BlockChain(bytes const& _genesisBlock, std::string _path, bool _killExisting)
{
// Initialise with the genesis as the last block on the longest chain.
m_genesisHash = BlockChain::genesis().hash;
m_genesisBlock = BlockChain::createGenesisBlock();
m_genesisBlock = _genesisBlock;
m_genesisHash = sha3(RLP(m_genesisBlock)[0].data());
open(_path, _killExisting);
}
@ -353,7 +309,7 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
}
#endif
// cnote << "Parent " << bi.parentHash << " has " << details(bi.parentHash).children.size() << " children.";
// cnote << "Parent " << bi.parentHash << " has " << details(bi.parentHash).children.size() << " children.";
h256s ret;
// This might be the new best block...
@ -377,7 +333,7 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, bool _post) const
{
// cdebug << "treeRoute" << _from.abridged() << "..." << _to.abridged();
// cdebug << "treeRoute" << _from.abridged() << "..." << _to.abridged();
if (!_from || !_to)
{
return h256s();
@ -386,14 +342,14 @@ h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, boo
h256s back;
unsigned fn = details(_from).number;
unsigned tn = details(_to).number;
// cdebug << "treeRoute" << fn << "..." << tn;
// cdebug << "treeRoute" << fn << "..." << tn;
while (fn > tn)
{
if (_pre)
ret.push_back(_from);
_from = details(_from).parent;
fn--;
// cdebug << "from:" << fn << _from.abridged();
// cdebug << "from:" << fn << _from.abridged();
}
while (fn < tn)
{
@ -401,7 +357,7 @@ h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, boo
back.push_back(_to);
_to = details(_to).parent;
tn--;
// cdebug << "to:" << tn << _to.abridged();
// cdebug << "to:" << tn << _to.abridged();
}
while (_from != _to)
{
@ -415,7 +371,7 @@ h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, boo
back.push_back(_to);
fn--;
tn--;
// cdebug << "from:" << fn << _from.abridged() << "; to:" << tn << _to.abridged();
// cdebug << "from:" << fn << _from.abridged() << "; to:" << tn << _to.abridged();
}
if (o_common)
*o_common = _from;

18
libethereum/BlockChain.h

@ -69,8 +69,7 @@ ldb::Slice toSlice(h256 _h, unsigned _sub = 0);
class BlockChain
{
public:
BlockChain(bool _killExisting = false): BlockChain(std::string(), _killExisting) {}
BlockChain(std::string _path, bool _killExisting = false);
BlockChain(bytes const& _genesisBlock, std::string _path, bool _killExisting);
~BlockChain();
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
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.
h256s attemptImport(bytes const& _block, OverlayDB const& _stateDB) noexcept;
@ -131,13 +130,6 @@ public:
/// togther with all their quoted uncles.
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
* blocks that are parent-to-child, then two sibling blocks, then a number of blocks that are child-to-parent.
*
@ -171,7 +163,7 @@ private:
m_extrasDB->Get(m_readOptions, toSlice(_h, N), &s);
if (s.empty())
{
// cout << "Not found in DB: " << _h << endl;
// cout << "Not found in DB: " << _h << endl;
return _n;
}
@ -208,10 +200,6 @@ private:
ldb::WriteOptions m_writeOptions;
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);

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"
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;
}
CanonBlockChain::~CanonBlockChain()
std::unique_ptr<BlockInfo> CanonBlockChain::s_genesis;
boost::shared_mutex CanonBlockChain::x_genesis;
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:
CanonBlockChain();
~CanonBlockChain();
CanonBlockChain(bool _killExisting = false): CanonBlockChain(std::string(), _killExisting) {}
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 <libevm/FeeStructure.h>
#include <libp2p/Common.h>
#include "BlockChain.h"
#include "CanonBlockChain.h"
#include "TransactionQueue.h"
#include "State.h"
#include "CommonNet.h"
@ -228,7 +228,7 @@ public:
/// Get the object representing the current state of Ethereum.
dev::eth::State postState() const { ReadGuard l(x_stateDB); return m_postMine; }
/// Get the object representing the current canonical blockchain.
BlockChain const& blockChain() const { return m_bc; }
CanonBlockChain const& blockChain() const { return m_bc; }
// Mining stuff:
@ -308,7 +308,7 @@ private:
State asOf(unsigned _h) const;
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.
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 "Executive.h"
#include "CachedAddressState.h"
#include "CanonBlockChain.h"
using namespace std;
using namespace dev;
using namespace dev::eth;
@ -74,18 +75,16 @@ State::State(Address _coinbaseAddress, OverlayDB const& _db, BaseState _bs):
paranoia("beginning of normal construction.", true);
if (_bs == BaseState::Genesis)
if (_bs == BaseState::CanonGenesis)
{
dev::eth::commit(genesisState(), m_db, m_state);
m_db.commit();
paranoia("after DB commit of normal construction.", true);
m_previousBlock = BlockChain::genesis();
m_previousBlock = CanonBlockChain::genesis();
}
else
{
m_previousBlock.setEmpty();
}
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.)
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.
bi.populate(_bc.block(bi.parentHash)); // move to parent.
@ -698,7 +697,7 @@ void State::commitToMine(BlockChain const& _bc)
RLPStream unclesData;
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.
// 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 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.
@ -68,7 +68,7 @@ class State
public:
/// 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.
State(OverlayDB const& _db, BlockChain const& _bc, h256 _hash);

10
libp2p/Host.cpp

@ -387,9 +387,15 @@ string Host::pocHost()
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)
cwarn << "Non-standard port being recorded: " << _tcpPeerPort;
if (_tcpPeerPort >= /*49152*/32768)
{
cwarn << "Private port being recorded - setting to 0";
@ -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)
{
while (isWorking() && !m_run)
this_thread::sleep_for(chrono::milliseconds(50));
if (!m_run)
return;

92
libserpent/compiler.cpp

@ -77,43 +77,12 @@ Node popwrap(Node node) {
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
programData opcodeify(Node node,
programAux aux=Aux(),
programVerticalAux vaux=verticalAux()) {
std::string symb = "_"+mkUniqueToken();
Metadata m = node.metadata;
// Get variables
if (!aux.vars.size()) {
aux.vars = getVariables(node);
aux.nextVarMem = aux.vars.size() * 32 + 32;
}
// Numbers
if (node.type == TOKEN) {
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") {
std::string varname = node.args[0].val;
// 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);
//std::cerr << varname << " " << printSimple(varNode) << "\n";
// Set variable
@ -173,8 +146,7 @@ programData opcodeify(Node node,
}
// Comments do nothing
else if (node.val == "comment") {
Node* nodelist = nullptr;
return pd(aux, multiToken(nodelist, 0, m), 0);
return pd(aux, astnode("_", m), 0);
}
// Custom operation sequence
// 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
programAux buildDict(Node program, programAux aux, int labelLength) {
void buildDict(Node program, programAux &aux, int labelLength) {
Metadata m = program.metadata;
// Token
if (program.type == TOKEN) {
@ -388,30 +360,24 @@ programAux buildDict(Node program, programAux aux, int labelLength) {
}
// A sub-program (ie. LLL)
else if (program.val == "____CODE") {
programAux auks = Aux();
int step = aux.step;
aux.step = 0;
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
else {
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
Node substDict(Node program, programAux aux, int labelLength) {
void substDict(Node program, programAux aux, int labelLength, std::vector<Node> &out) {
Metadata m = program.metadata;
std::vector<Node> out;
std::vector<Node> inner;
if (program.type == TOKEN) {
if (program.val[0] == '$') {
@ -428,46 +394,32 @@ Node substDict(Node program, programAux aux, int labelLength) {
dist = decimalSub(end, start);
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 (isNumberLike(program)) {
inner = toByteArr(program.val, m);
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 {
for (unsigned i = 0; i < program.args.size(); i++) {
Node n = substDict(program.args[i], aux, labelLength);
if (n.type == TOKEN || n.args.size()) out.push_back(n);
substDict(program.args[i], aux, labelLength, out);
}
}
return astnode("_", out, m);
}
// Compiled fragtree -> compiled fragtree without labels
Node dereference(Node program) {
std::vector<Node> dereference(Node program) {
int sz = treeSize(program) * 4;
int labelLength = 1;
while (sz >= 256) { labelLength += 1; sz /= 256; }
programAux aux = buildDict(program, Aux(), labelLength);
return substDict(program, aux, labelLength);
}
// Dereferenced fragtree -> opcodes
std::vector<Node> flatten(Node derefed) {
programAux aux = Aux();
buildDict(program, aux, labelLength);
std::vector<Node> o;
if (derefed.type == TOKEN) {
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]);
}
}
substDict(program, aux, labelLength, o);
return o;
}
@ -512,12 +464,12 @@ std::vector<Node> deserialize(std::string ser) {
// Fragtree -> bin
std::string assemble(Node fragTree) {
return serialize(flatten(dereference(fragTree)));
return serialize(dereference(fragTree));
}
// Fragtree -> tokens
std::vector<Node> prettyAssemble(Node fragTree) {
return flatten(dereference(fragTree));
return dereference(fragTree);
}
// LLL -> bin

5
libserpent/compiler.h

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

3
libserpent/util.cpp

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

2
libsolidity/AST.cpp

@ -505,7 +505,7 @@ void FunctionCall::checkTypeRequirements()
// check duplicate names
for (size_t i = 0; i < m_names.size(); i++) {
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."));
}
}

7
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -28,7 +28,7 @@
#include <liblll/Compiler.h>
#include <libethereum/Client.h>
#include <libwebthree/WebThree.h>
#include <libdevcore/CommonJS.h>
#include <libethcore/CommonJS.h>
#include <libwhisper/Message.h>
#include <libwhisper/WhisperHost.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)
{
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)

4
libweb3jsonrpc/WebThreeStubServerBase.h

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

40
mix/ClientModel.cpp

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

2
mix/ContractCallDataEncoder.cpp

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

2
mix/DebuggingStateWrapper.cpp

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

222
mix/MixClient.cpp

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

30
mix/MixClient.h

@ -24,8 +24,10 @@
#pragma once
#include <vector>
#include <string>
#include <libethereum/Interface.h>
#include <libethereum/Client.h>
#include <libethereum/CanonBlockChain.h>
#include "MachineStates.h"
namespace dev
@ -33,26 +35,18 @@ namespace dev
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
{
public:
MixClient();
MixClient(std::string const& _dbPath);
virtual ~MixClient();
/// Reset state to the empty state with given balance.
void resetState(u256 _balance);
KeyPair const& userAccount() const { return m_userAccount; }
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
void transact(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) override;
@ -94,18 +88,22 @@ public:
private:
void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state);
void validateBlock(int _block) const;
void noteChanged(h256Set const& _filters);
dev::eth::State const& asOf(int _block) const;
dev::eth::State asOf(int _block) const;
KeyPair m_userAccount;
eth::State m_state;
eth::State m_startState;
OverlayDB m_stateDB;
eth::CanonBlockChain m_bc;
mutable boost::shared_mutex x_state;
mutable std::mutex m_filterLock;
std::map<h256, dev::eth::InstalledFilter> m_filters;
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.hpp>
#include <libdevcore/CommonJS.h>
#include <libethcore/CommonJS.h>
#include "QBigInt.h"
using namespace dev;

2
mix/QBigInt.h

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

2
mix/QVariableDefinition.cpp

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

3
mix/qml/MainContent.qml

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

5
pullSerpent.sh

@ -2,10 +2,11 @@
opwd="$PWD"
cd ../serpent
git stash
git pull
git stash pop
cp bignum.* compiler.* funcs.* lllparser.* opcodes.h parser.* rewriter.* tokenize.* util.* ../cpp-ethereum/libserpent/
cp cmdline.* "$opwd/sc/"
cp pyserpent.* "$opwd/libpyserpent/"
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";
}
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") {
std::cout << printTokens(prettyAssemble(parseLLL(input, true))) <<"\n";
@ -88,9 +88,6 @@ int main(int argv, char** argc) {
else if (command == "serialize") {
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") {
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_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()
}

5
test/commonjs.cpp

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

2
test/fork.cpp

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

8
test/genesis.cpp

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

2
test/jsonrpc.cpp

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

2
test/state.cpp

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

4
test/stateOriginal.cpp

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

2
test/txTest.cpp

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

6
third/MainWin.cpp

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

Loading…
Cancel
Save