Browse Source

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

cl-refactor
arkpar 10 years ago
parent
commit
0cdf4db425
  1. 1
      exp/main.cpp
  2. 2
      libdevcore/Common.cpp
  3. 2
      libdevcore/CommonIO.cpp
  4. 1
      libdevcore/Exceptions.h
  5. 16
      libdevcrypto/SHA3.cpp
  6. 6
      libdevcrypto/SHA3.h
  7. 35
      libethcore/Exceptions.cpp
  8. 35
      libethcore/Exceptions.h
  9. 23
      libethereum/Client.cpp
  10. 68
      libethereum/Client.h
  11. 4
      libethereum/DownloadMan.cpp
  12. 4
      libethereum/DownloadMan.h
  13. 2
      libethereum/EthereumHost.cpp
  14. 67
      libethereum/EthereumPeer.cpp
  15. 6
      libethereum/Executive.cpp
  16. 18
      libethereum/ExtVM.h
  17. 9
      libethereum/Interface.h
  18. 8
      libethereum/Miner.cpp
  19. 2
      libethereum/Miner.h
  20. 66
      libethereum/State.cpp
  21. 12
      libethereum/State.h
  22. 11
      libevm/ExtVMFace.h
  23. 2
      libevm/VM.cpp
  24. 18
      libevm/VM.h
  25. 1
      libevmface/Instruction.cpp
  26. 31
      liblll/Assembly.cpp
  27. 1
      liblll/CodeFragment.cpp
  28. 3
      libp2p/Capability.cpp
  29. 1
      libp2p/Host.cpp
  30. 12
      libp2p/Session.cpp
  31. 2
      libp2p/Session.h
  32. 1
      libp2p/UPnP.cpp
  33. 87
      libqethereum/QEthereum.cpp
  34. 20
      libqethereum/QEthereum.h
  35. 3
      libwhisper/Interface.cpp
  36. 1
      libwhisper/Message.cpp
  37. 3
      libwhisper/WhisperHost.cpp
  38. 4
      libwhisper/WhisperPeer.cpp
  39. 3
      test/hexPrefix.cpp
  40. 1
      test/rlp.cpp
  41. 1
      test/trie.cpp
  42. 7
      test/vm.cpp

1
exp/main.cpp

@ -24,6 +24,7 @@
#include <libdevcore/Common.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/RLP.h>
#include <libdevcore/CommonIO.h>
#include <libp2p/All.h>
#include <libdevcore/RangeMask.h>
#include <libethereum/DownloadMan.h>

2
libdevcore/Common.cpp

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

2
libdevcore/CommonIO.cpp

@ -19,7 +19,7 @@
* @date 2014
*/
#include "Common.h"
#include "CommonIO.h"
#include <fstream>
#include "Exceptions.h"

1
libdevcore/Exceptions.h

@ -25,7 +25,6 @@
#include <boost/exception/all.hpp>
#include <boost/throw_exception.hpp>
#include <libdevcrypto/Common.h>
#include "CommonIO.h"
#include "CommonData.h"
#include "FixedHash.h"

16
libdevcrypto/SHA3.cpp

@ -58,6 +58,22 @@ void sha3(bytesConstRef _input, bytesRef _output)
ctx.Final(_output.data());
}
void ripemd160(bytesConstRef _input, bytesRef _output)
{
CryptoPP::RIPEMD160 ctx;
ctx.Update((byte*)_input.data(), _input.size());
assert(_output.size() >= 32);
ctx.Final(_output.data());
}
void sha256(bytesConstRef _input, bytesRef _output)
{
CryptoPP::SHA256 ctx;
ctx.Update((byte*)_input.data(), _input.size());
assert(_output.size() >= 32);
ctx.Final(_output.data());
}
bytes sha3Bytes(bytesConstRef _input)
{
bytes ret(32);

6
libdevcrypto/SHA3.h

@ -60,7 +60,13 @@ inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input))
extern h256 EmptySHA3;
// Other crypto convenience routines
bytes aesDecrypt(bytesConstRef _cipher, std::string const& _password, unsigned _rounds = 2000, bytesConstRef _salt = bytesConstRef());
void sha256(bytesConstRef _input, bytesRef _output);
void ripemd160(bytesConstRef _input, bytesRef _output);
}
}

35
libethcore/Exceptions.cpp

@ -0,0 +1,35 @@
/*
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 Exceptions.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Exceptions.h"
#include <libdevcore/CommonIO.h>
using namespace dev;
using namespace dev::eth;
const char* InvalidBlockFormat::what() const noexcept { return ("Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")").c_str(); }
const char* UncleInChain::what() const noexcept { return ("Uncle in block already mentioned: Uncles " + toString(m_uncles) + " (" + m_block.abridged() + ")").c_str(); }
const char* InvalidTransactionsHash::what() const noexcept { return ("Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref())).c_str(); }
const char* InvalidGasLimit::what() const noexcept { return ("Invalid gas limit (provided: " + toString(provided) + " valid:" + toString(valid) + ")").c_str(); }
const char* InvalidMinGasPrice::what() const noexcept { return ("Invalid minimum gas price (provided: " + toString(provided) + " limit:" + toString(limit) + ")").c_str(); }
const char* InvalidNonce::what() const noexcept { return ("Invalid nonce (r: " + toString(required) + " c:" + toString(candidate) + ")").c_str(); }
const char* InvalidBlockNonce::what() const noexcept { return ("Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")").c_str(); }

35
libethcore/Exceptions.h

@ -1,3 +1,24 @@
/*
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 Exceptions.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <libdevcore/Exceptions.h>
@ -23,23 +44,23 @@ struct FeeTooSmall: virtual dev::Exception {};
struct TooMuchGasUsed: virtual dev::Exception {};
struct ExtraDataTooBig: virtual dev::Exception {};
struct InvalidSignature: virtual dev::Exception {};
class InvalidBlockFormat: public dev::Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual const char* what() const noexcept { return ("Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")").c_str(); } };
class InvalidBlockFormat: public dev::Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual const char* what() const noexcept; };
struct InvalidUnclesHash: virtual dev::Exception {};
struct InvalidUncle: virtual dev::Exception {};
struct UncleTooOld: virtual dev::Exception {};
class UncleInChain: public dev::Exception { public: UncleInChain(h256Set _uncles, h256 _block): m_uncles(_uncles), m_block(_block) {} h256Set m_uncles; h256 m_block;virtual const char* what() const noexcept { return ("Uncle in block already mentioned: Uncles " + toString(m_uncles) + " (" + m_block.abridged() + ")").c_str(); } };
class UncleInChain: public dev::Exception { public: UncleInChain(h256Set _uncles, h256 _block): m_uncles(_uncles), m_block(_block) {} h256Set m_uncles; h256 m_block;virtual const char* what() const noexcept; };
struct DuplicateUncleNonce: virtual dev::Exception {};
struct InvalidStateRoot: virtual dev::Exception {};
class InvalidTransactionsHash: public dev::Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual const char* what() const noexcept { return ("Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref())).c_str(); } };
class InvalidTransactionsHash: public dev::Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual const char* what() const noexcept; };
struct InvalidTransaction: virtual dev::Exception {};
struct InvalidDifficulty: virtual dev::Exception {};
class InvalidGasLimit: public dev::Exception { public: InvalidGasLimit(u256 _provided = 0, u256 _valid = 0): provided(_provided), valid(_valid) {} u256 provided; u256 valid; virtual const char* what() const noexcept { return ("Invalid gas limit (provided: " + toString(provided) + " valid:" + toString(valid) + ")").c_str(); } };
class InvalidMinGasPrice: public dev::Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual const char* what() const noexcept { return ("Invalid minimum gas price (provided: " + toString(provided) + " limit:" + toString(limit) + ")").c_str(); } };
class InvalidGasLimit: public dev::Exception { public: InvalidGasLimit(u256 _provided = 0, u256 _valid = 0): provided(_provided), valid(_valid) {} u256 provided; u256 valid; virtual const char* what() const noexcept; };
class InvalidMinGasPrice: public dev::Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual const char* what() const noexcept; };
struct InvalidTransactionGasUsed: virtual dev::Exception {};
struct InvalidTransactionStateRoot: virtual dev::Exception {};
struct InvalidTimestamp: virtual dev::Exception {};
class InvalidNonce: public dev::Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0): required(_required), candidate(_candidate) {} u256 required; u256 candidate; virtual const char* what() const noexcept { return ("Invalid nonce (r: " + toString(required) + " c:" + toString(candidate) + ")").c_str(); } };
class InvalidBlockNonce: public dev::Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0): h(_h), n(_n), d(_d) {} h256 h; h256 n; u256 d; virtual const char* what() const noexcept { return ("Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")").c_str(); } };
class InvalidNonce: public dev::Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0): required(_required), candidate(_candidate) {} u256 required; u256 candidate; virtual const char* what() const noexcept; };
class InvalidBlockNonce: public dev::Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0): h(_h), n(_n), d(_d) {} h256 h; h256 n; u256 d; virtual const char* what() const noexcept; };
struct InvalidParentHash: virtual dev::Exception {};
struct InvalidNumber: virtual dev::Exception {};
struct InvalidContractAddress: virtual dev::Exception {};

23
libethereum/Client.cpp

@ -232,12 +232,9 @@ void Client::appendFromNewBlock(h256 _block, h256Set& o_changed) const
void Client::setForceMining(bool _enable)
{
m_forceMining = _enable;
if (!m_host.lock())
{
ReadGuard l(x_miners);
for (auto& m: m_miners)
m.noteStateChange();
}
ReadGuard l(x_miners);
for (auto& m: m_miners)
m.noteStateChange();
}
void Client::setMiningThreads(unsigned _threads)
@ -550,6 +547,20 @@ bytes Client::codeAt(Address _a, int _block) const
return asOf(_block).code(_a);
}
Transaction Client::transaction(h256 _blockHash, unsigned _i) const
{
auto bl = m_bc.block(_blockHash);
RLP b(bl);
return Transaction(b[1][_i].data());
}
BlockInfo Client::uncle(h256 _blockHash, unsigned _i) const
{
auto bl = m_bc.block(_blockHash);
RLP b(bl);
return BlockInfo::fromHeader(b[2][_i].data());
}
PastMessages Client::messages(MessageFilter const& _f) const
{
PastMessages ret;

68
libethereum/Client.h

@ -119,23 +119,23 @@ public:
explicit Client(p2p::Host* _host, std::string const& _dbPath = std::string(), bool _forceClean = false, u256 _networkId = 0);
/// Destructor.
~Client();
virtual ~Client();
/// Submits the given message-call transaction.
void transact(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
virtual void transact(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
/// Submits a new contract-creation transaction.
/// @returns the new contract's address (assuming it all goes through).
Address transact(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
virtual Address transact(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
/// Injects the RLP-encoded transaction given by the _rlp into the transaction queue directly.
void inject(bytesConstRef _rlp);
virtual void inject(bytesConstRef _rlp);
/// Blocks until all pending transactions have been processed.
void flushTransactions();
virtual void flushTransactions();
/// Makes the given call. Nothing is recorded into the state.
bytes call(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
virtual bytes call(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
// Informational stuff
@ -147,20 +147,20 @@ public:
using Interface::codeAt;
using Interface::storageAt;
u256 balanceAt(Address _a, int _block) const;
u256 countAt(Address _a, int _block) const;
u256 stateAt(Address _a, u256 _l, int _block) const;
bytes codeAt(Address _a, int _block) const;
std::map<u256, u256> storageAt(Address _a, int _block) const;
virtual u256 balanceAt(Address _a, int _block) const;
virtual u256 countAt(Address _a, int _block) const;
virtual u256 stateAt(Address _a, u256 _l, int _block) const;
virtual bytes codeAt(Address _a, int _block) const;
virtual std::map<u256, u256> storageAt(Address _a, int _block) const;
unsigned installWatch(MessageFilter const& _filter);
unsigned installWatch(h256 _filterId);
void uninstallWatch(unsigned _watchId);
bool peekWatch(unsigned _watchId) const { std::lock_guard<std::mutex> l(m_filterLock); try { return m_watches.at(_watchId).changes != 0; } catch (...) { return false; } }
bool checkWatch(unsigned _watchId) { std::lock_guard<std::mutex> l(m_filterLock); bool ret = false; try { ret = m_watches.at(_watchId).changes != 0; m_watches.at(_watchId).changes = 0; } catch (...) {} return ret; }
virtual unsigned installWatch(MessageFilter const& _filter);
virtual unsigned installWatch(h256 _filterId);
virtual void uninstallWatch(unsigned _watchId);
virtual bool peekWatch(unsigned _watchId) const { std::lock_guard<std::mutex> l(m_filterLock); try { return m_watches.at(_watchId).changes != 0; } catch (...) { return false; } }
virtual bool checkWatch(unsigned _watchId) { std::lock_guard<std::mutex> l(m_filterLock); bool ret = false; try { ret = m_watches.at(_watchId).changes != 0; m_watches.at(_watchId).changes = 0; } catch (...) {} return ret; }
PastMessages messages(unsigned _watchId) const { try { std::lock_guard<std::mutex> l(m_filterLock); return messages(m_filters.at(m_watches.at(_watchId).id).filter); } catch (...) { return PastMessages(); } }
PastMessages messages(MessageFilter const& _filter) const;
virtual PastMessages messages(unsigned _watchId) const { try { std::lock_guard<std::mutex> l(m_filterLock); return messages(m_filters.at(m_watches.at(_watchId).id).filter); } catch (...) { return PastMessages(); } }
virtual PastMessages messages(MessageFilter const& _filter) const;
// [EXTRA API]:
@ -169,19 +169,25 @@ public:
/// Get a map containing each of the pending transactions.
/// @TODO: Remove in favour of transactions().
Transactions pending() const { return m_postMine.pending(); }
virtual Transactions pending() const { return m_postMine.pending(); }
virtual h256 hashFromNumber(unsigned _number) const { return m_bc.numberHash(_number); }
virtual BlockInfo blockInfo(h256 _hash) const { return BlockInfo(m_bc.block(_hash)); }
virtual BlockDetails blockDetails(h256 _hash) const { return m_bc.details(_hash); }
virtual Transaction transaction(h256 _blockHash, unsigned _i) const;
virtual BlockInfo uncle(h256 _blockHash, unsigned _i) const;
/// Differences between transactions.
using Interface::diff;
StateDiff diff(unsigned _txi, h256 _block) const;
StateDiff diff(unsigned _txi, int _block) const;
virtual StateDiff diff(unsigned _txi, h256 _block) const;
virtual StateDiff diff(unsigned _txi, int _block) const;
/// Get a list of all active addresses.
using Interface::addresses;
std::vector<Address> addresses(int _block) const;
virtual std::vector<Address> addresses(int _block) const;
/// Get the remaining gas limit in this block.
u256 gasLimitRemaining() const { return m_postMine.gasLimitRemaining(); }
virtual u256 gasLimitRemaining() const { return m_postMine.gasLimitRemaining(); }
// [PRIVATE API - only relevant for base clients, not available in general]
@ -210,23 +216,23 @@ public:
void setTurboMining(bool _enable = true) { m_turboMining = _enable; }
/// Set the coinbase address.
void setAddress(Address _us) { m_preMine.setAddress(_us); }
virtual void setAddress(Address _us) { m_preMine.setAddress(_us); }
/// Get the coinbase address.
Address address() const { return m_preMine.address(); }
virtual Address address() const { return m_preMine.address(); }
/// Stops mining and sets the number of mining threads (0 for automatic).
void setMiningThreads(unsigned _threads = 0);
virtual void setMiningThreads(unsigned _threads = 0);
/// Get the effective number of mining threads.
unsigned miningThreads() const { ReadGuard l(x_miners); return m_miners.size(); }
virtual unsigned miningThreads() const { ReadGuard l(x_miners); return m_miners.size(); }
/// Start mining.
/// NOT thread-safe - call it & stopMining only from a single thread
void startMining() { startWorking(); ReadGuard l(x_miners); for (auto& m: m_miners) m.start(); }
virtual void startMining() { startWorking(); ReadGuard l(x_miners); for (auto& m: m_miners) m.start(); }
/// Stop mining.
/// NOT thread-safe
void stopMining() { ReadGuard l(x_miners); for (auto& m: m_miners) m.stop(); }
virtual void stopMining() { ReadGuard l(x_miners); for (auto& m: m_miners) m.stop(); }
/// Are we mining now?
bool isMining() { ReadGuard l(x_miners); return m_miners.size() && m_miners[0].isRunning(); }
virtual bool isMining() { ReadGuard l(x_miners); return m_miners.size() && m_miners[0].isRunning(); }
/// Check the progress of the mining.
MineProgress miningProgress() const;
virtual MineProgress miningProgress() const;
/// Get and clear the mining history.
std::list<MineInfo> miningHistory();

4
libethereum/DownloadMan.cpp

@ -66,10 +66,12 @@ h256Set DownloadSub::nextFetch(unsigned _n)
return m_remaining;
}
void DownloadSub::noteBlock(h256 _hash)
bool DownloadSub::noteBlock(h256 _hash)
{
Guard l(m_fetch);
if (m_man && m_indices.count(_hash))
m_man->m_blocksGot += m_indices[_hash];
bool ret = !!m_remaining.count(_hash);
m_remaining.erase(_hash);
return ret;
}

4
libethereum/DownloadMan.h

@ -48,8 +48,8 @@ public:
/// Finished last fetch - grab the next bunch of block hashes to download.
h256Set nextFetch(unsigned _n);
/// Note that we've received a particular block.
void noteBlock(h256 _hash);
/// Note that we've received a particular block. @returns true if we had asked for it but haven't received it yet.
bool noteBlock(h256 _hash);
/// Nothing doing here.
void doneFetch() { resetFetch(); }

2
libethereum/EthereumHost.cpp

@ -202,7 +202,7 @@ void EthereumHost::maintainBlocks(h256 _currentHash)
auto p = j->cap<EthereumPeer>();
RLPStream ts;
p->prep(ts, BlocksPacket, hs.size()).appendRaw(bs, hs.size());
p->prep(ts, NewBlockPacket, hs.size()).appendRaw(bs, hs.size());
Guard l(p->x_knownBlocks);
if (!p->m_knownBlocks.count(_currentHash))

67
libethereum/EthereumPeer.cpp

@ -34,6 +34,9 @@ using namespace dev;
using namespace dev::eth;
using namespace p2p;
#if defined(clogS)
#undef clogS
#endif
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
EthereumPeer::EthereumPeer(Session* _s, HostCapabilityFace* _h, unsigned _i):
@ -305,7 +308,7 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
disable("Invalid protocol version.");
else if (m_networkId != host()->networkId())
disable("Invalid network identifier.");
else if (session()->info().clientVersion.find("/v0.6.9/") != string::npos)
else if (session()->info().clientVersion.find("/v0.7.0/") != string::npos)
disable("Blacklisted client version.");
else if (host()->isBanned(session()->id()))
disable("Peer banned for previous bad behaviour.");
@ -422,44 +425,46 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
unsigned future = 0;
unsigned unknown = 0;
unsigned got = 0;
unsigned repeated = 0;
for (unsigned i = 1; i < _r.itemCount(); ++i)
{
auto h = BlockInfo::headerHash(_r[i].data());
m_sub.noteBlock(h);
if (m_sub.noteBlock(h))
{
Guard l(x_knownBlocks);
m_knownBlocks.insert(h);
addRating(10);
switch (host()->m_bq.import(_r[i].data(), host()->m_chain))
{
case ImportResult::Success:
success++;
break;
case ImportResult::Malformed:
disable("Malformed block received.");
return true;
case ImportResult::FutureTime:
future++;
break;
case ImportResult::AlreadyInChain:
case ImportResult::AlreadyKnown:
got++;
break;
case ImportResult::UnknownParent:
unknown++;
break;
}
}
switch (host()->m_bq.import(_r[i].data(), host()->m_chain))
else
{
case ImportResult::Success:
addRating(1);
success++;
break;
case ImportResult::Malformed:
disable("Malformed block received.");
return true;
case ImportResult::FutureTime:
future++;
break;
case ImportResult::AlreadyInChain:
case ImportResult::AlreadyKnown:
got++;
break;
case ImportResult::UnknownParent:
unknown++;
break;
addRating(0); // -1?
repeated++;
}
}
clogS(NetMessageSummary) << dec << success << "imported OK," << unknown << "with unknown parents," << future << "with future timestamps," << got << " already known.";
clogS(NetMessageSummary) << dec << success << "imported OK," << unknown << "with unknown parents," << future << "with future timestamps," << got << " already known," << repeated << " repeats received.";
if (m_asking == Asking::Blocks)
transition(Asking::Blocks);
@ -477,8 +482,10 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
switch (host()->m_bq.import(_r[1].data(), host()->m_chain))
{
case ImportResult::Success:
addRating(100);
break;
case ImportResult::FutureTime:
addRating(1);
//TODO: Rating dependent on how far in future it is.
break;
case ImportResult::Malformed:

6
libethereum/Executive.cpp

@ -20,6 +20,7 @@
*/
#include <boost/timer.hpp>
#include <libdevcore/CommonIO.h>
#include <libevm/VM.h>
#include "Executive.h"
#include "State.h"
@ -217,15 +218,12 @@ u256 Executive::gas() const
return m_vm ? m_vm->gas() : m_endGas;
}
void Executive::finalize(OnOpFunc const& _onOp)
void Executive::finalize(OnOpFunc const&)
{
if (m_t.isCreation() && m_newAddress && m_out.size())
// non-reverted creation - put code in place.
m_s.m_cache[m_newAddress].setCode(m_out);
if (m_ext)
m_endGas += m_ext->doPosts(_onOp);
// cnote << "Refunding" << formatBalance(m_endGas * m_ext->gasPrice) << "to origin (=" << m_endGas << "*" << formatBalance(m_ext->gasPrice) << ")";
m_s.addBalance(m_sender, m_endGas * m_t.gasPrice);

18
libethereum/ExtVM.h

@ -61,7 +61,7 @@ public:
m_s.noteSending(myAddress);
if (m_ms)
m_ms->internal.resize(m_ms->internal.size() + 1);
auto ret = m_s.create(myAddress, _endowment, gasPrice, _gas, _code, origin, &suicides, &posts, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, level + 1);
auto ret = m_s.create(myAddress, _endowment, gasPrice, _gas, _code, origin, &suicides, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, level + 1);
if (m_ms && !m_ms->internal.back().from)
m_ms->internal.pop_back();
return ret;
@ -72,7 +72,7 @@ public:
{
if (m_ms)
m_ms->internal.resize(m_ms->internal.size() + 1);
auto ret = m_s.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, _gas, _out, origin, &suicides, &posts, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, level + 1);
auto ret = m_s.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, _gas, _out, origin, &suicides, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, level + 1);
if (m_ms && !m_ms->internal.back().from)
m_ms->internal.pop_back();
return ret;
@ -98,20 +98,6 @@ public:
/// @TODO check call site for the parent manifest being discarded.
void revert() { if (m_ms) *m_ms = Manifest(); m_s.m_cache = m_origCache; }
/// Execute any posts we have left.
u256 doPosts(OnOpFunc const& _onOp = OnOpFunc())
{
u256 ret;
while (posts.size())
{
Post& p = posts.front();
call(p.to, p.value, &p.data, &p.gas, bytesRef(), _onOp, p.from);
ret += p.gas;
posts.pop_front();
}
return ret;
}
State& state() const { return m_s; }
/// @note not a part of the main API; just for use by tracing/debug stuff.

9
libethereum/Interface.h

@ -29,6 +29,7 @@
#include "MessageFilter.h"
#include "Transaction.h"
#include "AccountDiff.h"
#include "BlockDetails.h"
#include "Miner.h"
namespace dev
@ -95,7 +96,13 @@ public:
virtual bool peekWatch(unsigned _watchId) const = 0;
virtual bool checkWatch(unsigned _watchId) = 0;
// TODO: Block query API.
// [BLOCK QUERY API]
virtual h256 hashFromNumber(unsigned _number) const = 0;
virtual BlockInfo blockInfo(h256 _hash) const = 0;
virtual BlockDetails blockDetails(h256 _hash) const = 0;
virtual Transaction transaction(h256 _blockHash, unsigned _i) const = 0;
virtual BlockInfo uncle(h256 _blockHash, unsigned _i) const = 0;
// [EXTRA API]:

8
libethereum/Miner.cpp

@ -21,6 +21,8 @@
*/
#include "Miner.h"
#include <libdevcore/CommonIO.h>
#include "State.h"
using namespace std;
using namespace dev;
@ -32,6 +34,12 @@ Miner::Miner(MinerHost* _host, unsigned _id):
{
}
void Miner::setup(MinerHost* _host, unsigned _id)
{
m_host = _host;
setName("miner-" + toString(_id));
}
void Miner::doWork()
{
// Do some mining.

2
libethereum/Miner.h

@ -94,7 +94,7 @@ public:
~Miner() { stop(); }
/// Setup its basics.
void setup(MinerHost* _host, unsigned _id = 0) { m_host = _host; setName("miner-" + toString(_id)); }
void setup(MinerHost* _host, unsigned _id = 0);
/// Start mining.
void start() { startWorking(); }

66
libethereum/State.cpp

@ -25,6 +25,7 @@
#include <time.h>
#include <random>
#include <secp256k1/secp256k1.h>
#include <libdevcore/CommonIO.h>
#include <libevmface/Instruction.h>
#include <libethcore/Exceptions.h>
#include <libethcore/Dagger.h>
@ -40,6 +41,50 @@ using namespace dev::eth;
static const u256 c_blockReward = 1500 * finney;
void ecrecoverCode(bytesConstRef _in, bytesRef _out)
{
struct inType
{
h256 hash;
h256 v;
h256 r;
h256 s;
} in;
h256 ret;
memcpy(&in, _in.data(), min(_in.size(), sizeof(in)));
byte pubkey[65];
int pubkeylen = 65;
secp256k1_start();
if (secp256k1_ecdsa_recover_compact(in.hash.data(), 32, in.r.data(), pubkey, &pubkeylen, 0, (int)(u256)in.v - 27))
ret = dev::eth::sha3(bytesConstRef(&(pubkey[1]), 64));
memcpy(_out.data(), &ret, min(_out.size(), sizeof(ret)));
}
void sha256Code(bytesConstRef _in, bytesRef _out)
{
h256 ret;
sha256(_in, bytesRef(ret.data(), 32));
memcpy(_out.data(), &ret, min(_out.size(), sizeof(ret)));
}
void ripemd160Code(bytesConstRef _in, bytesRef _out)
{
h256 ret;
ripemd160(_in, bytesRef(ret.data(), 32));
memcpy(_out.data(), &ret, min(_out.size(), sizeof(ret)));
}
const std::map<unsigned, PrecompiledAddress> State::c_precompiled =
{
{ 1, { 500, ecrecoverCode }},
{ 2, { 100, sha256Code }},
{ 3, { 100, ripemd160Code }}
};
OverlayDB State::openDB(std::string _path, bool _killExisting)
{
if (_path.empty())
@ -1060,7 +1105,7 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit)
return e.gasUsed();
}
bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256* _gas, bytesRef _out, Address _originAddress, std::set<Address>* o_suicides, PostList* o_posts, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level)
bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256* _gas, bytesRef _out, Address _originAddress, std::set<Address>* o_suicides, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level)
{
if (!_originAddress)
_originAddress = _senderAddress;
@ -1076,7 +1121,16 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
o_ms->input = _data.toBytes();
}
if (addressHasCode(_codeAddress))
auto it = !(_codeAddress & ~h160(0xffffffff)) ? c_precompiled.find((unsigned)(u160)_codeAddress) : c_precompiled.end();
if (it != c_precompiled.end())
{
if (*_gas >= it->second.gas)
{
*_gas -= it->second.gas;
it->second.exec(_data, _out);
}
}
else if (addressHasCode(_codeAddress))
{
VM vm(*_gas);
ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_codeAddress), o_ms, _level);
@ -1089,9 +1143,6 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
if (o_suicides)
for (auto i: evm.suicides)
o_suicides->insert(i);
if (o_posts)
for (auto i: evm.posts)
o_posts->push_back(i);
if (o_ms)
o_ms->output = out.toBytes();
}
@ -1124,7 +1175,7 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
return true;
}
h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _origin, std::set<Address>* o_suicides, PostList* o_posts, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level)
h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _origin, std::set<Address>* o_suicides, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level)
{
if (!_origin)
_origin = _sender;
@ -1156,9 +1207,6 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas,
if (o_suicides)
for (auto i: evm.suicides)
o_suicides->insert(i);
if (o_posts)
for (auto i: evm.posts)
o_posts->push_back(i);
}
catch (OutOfGas const& /*_e*/)
{

12
libethereum/State.h

@ -69,6 +69,12 @@ struct TransactionReceipt
Manifest changes;
};
struct PrecompiledAddress
{
unsigned gas;
std::function<void(bytesConstRef, bytesRef)> exec;
};
/**
* @brief Model of the current state of the ledger.
* Maintains current ledger (m_current) as a fast hash-map. This is hashed only when required (i.e. to create or verify a block).
@ -277,12 +283,12 @@ private:
// We assume all instrinsic fees are paid up before this point.
/// Execute a contract-creation transaction.
h160 create(Address _txSender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _originAddress = Address(), std::set<Address>* o_suicides = nullptr, PostList* o_posts = nullptr, Manifest* o_ms = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0);
h160 create(Address _txSender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _originAddress = Address(), std::set<Address>* o_suicides = nullptr, Manifest* o_ms = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0);
/// Execute a call.
/// @a _gas points to the amount of gas to use for the call, and will lower it accordingly.
/// @returns false if the call ran out of gas before completion. true otherwise.
bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256* _gas, bytesRef _out, Address _originAddress = Address(), std::set<Address>* o_suicides = nullptr, PostList* o_posts = nullptr, Manifest* o_ms = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0);
bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256* _gas, bytesRef _out, Address _originAddress = Address(), std::set<Address>* o_suicides = nullptr, Manifest* o_ms = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0);
/// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock).
void resetCurrent();
@ -321,6 +327,8 @@ private:
static std::string c_defaultPath;
static const std::map<unsigned, PrecompiledAddress> c_precompiled;
friend std::ostream& operator<<(std::ostream& _out, State const& _s);
};

11
libevm/ExtVMFace.h

@ -21,6 +21,8 @@
#pragma once
#include <list>
#include <functional>
#include <libdevcore/Common.h>
#include <libevmface/Instruction.h>
#include <libethcore/CommonEth.h>
@ -40,8 +42,6 @@ struct Post
u256 gas;
};
using PostList = std::list<Post>;
using OnOpFunc = std::function<void(uint64_t /*steps*/, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, void/*VM*/*, void/*ExtVM*/ const*)>;
/**
@ -86,15 +86,9 @@ public:
/// Make a new message call.
bool call(Address, u256, bytesConstRef, u256*, bytesRef, OnOpFunc const&, Address, Address) { return false; }
/// Post a new message call.
void post(Address _to, u256 _value, bytesConstRef _data, u256 _gas) { posts.push_back(Post({myAddress, _to, _value, _data.toBytes(), _gas})); }
/// Revert any changes made (by any of the other calls).
void revert() {}
/// Execute any posts that may exist, including those that are incurred as a result of earlier posts.
void doPosts() {}
Address myAddress; ///< Address associated with executing code (a contract, or contract-to-be).
Address caller; ///< Address which sent the message (either equal to origin or a contract).
Address origin; ///< Original transactor.
@ -105,7 +99,6 @@ public:
BlockInfo previousBlock; ///< The previous block's information.
BlockInfo currentBlock; ///< The current block's information.
std::set<Address> suicides; ///< Any accounts that have suicided.
std::list<Post> posts; ///< Any posts that have been made.
};
}

2
libevm/VM.cpp

@ -29,6 +29,4 @@ void VM::reset(u256 _gas)
{
m_gas = _gas;
m_curPC = 0;
m_jumpLatch = false;
m_destinations.clear();
}

18
libevm/VM.h

@ -84,8 +84,6 @@ private:
u256 m_curPC = 0;
bytes m_temp;
u256s m_stack;
bool m_jumpLatch = false;
u256Set m_destinations;
};
}
@ -568,19 +566,19 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
break;
case Instruction::JUMP:
require(1);
m_jumpLatch = true;
if (!m_destinations.count(m_stack.back()))
BOOST_THROW_EXCEPTION(BadJumpDestination());
nextPC = m_stack.back();
if ((Instruction)_ext.getCode(nextPC) != Instruction::JUMPDEST)
BOOST_THROW_EXCEPTION(BadJumpDestination());
m_stack.pop_back();
break;
case Instruction::JUMPI:
require(2);
m_jumpLatch = true;
if (!m_destinations.count(m_stack.back()))
BOOST_THROW_EXCEPTION(BadJumpDestination());
if (m_stack[m_stack.size() - 2])
{
nextPC = m_stack.back();
if ((Instruction)_ext.getCode(nextPC) != Instruction::JUMPDEST)
BOOST_THROW_EXCEPTION(BadJumpDestination());
}
m_stack.pop_back();
m_stack.pop_back();
break;
@ -594,10 +592,6 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
m_stack.push_back(m_gas);
break;
case Instruction::JUMPDEST:
require(1);
if (!m_jumpLatch)
m_destinations.insert(m_stack.back());
m_stack.pop_back();
break;
case Instruction::CREATE:
{

1
libevmface/Instruction.cpp

@ -22,6 +22,7 @@
#include "Instruction.h"
#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libdevcore/Log.h>
using namespace std;
using namespace dev;

31
liblll/Assembly.cpp

@ -129,7 +129,7 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
_out << " PUSH[tag" << i.data() << "]";
break;
case Tag:
_out << " tag" << i.data() << ":";
_out << " tag" << i.data() << ": JUMPDEST";
break;
case PushData:
_out << " PUSH*[" << hex << (unsigned)i.data() << "]";
@ -149,17 +149,6 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
ostream& Assembly::streamOut(ostream& _out, string const& _prefix) const
{
_out << _prefix << ".pre:" << endl;
for (AssemblyItem const& i: m_items)
switch (i.m_type)
{
case PushTag:
_out << _prefix << " PUSH [tag" << i.m_data << "]" << endl;
_out << _prefix << " JUMPDEST" << endl;
break;
default:;
}
_out << _prefix << ".code:" << endl;
for (AssemblyItem const& i: m_items)
switch (i.m_type)
@ -183,7 +172,7 @@ ostream& Assembly::streamOut(ostream& _out, string const& _prefix) const
_out << _prefix << " PUSH #[$" << h256(i.m_data).abridged() << "]" << endl;
break;
case Tag:
_out << _prefix << "tag" << i.m_data << ": " << endl;
_out << _prefix << "tag" << i.m_data << ": " << endl << _prefix << " JUMPDEST" << endl;
break;
case PushData:
_out << _prefix << " PUSH [" << hex << (unsigned)i.m_data << "]" << endl;
@ -364,11 +353,9 @@ bytes Assembly::assemble() const
ret.reserve(totalBytes);
vector<unsigned> tagPos(m_usedTags);
map<unsigned, unsigned> tagRef;
map<unsigned, unsigned> pretagRef;
multimap<h256, unsigned> dataRef;
unsigned bytesPerTag = dev::bytesRequired(totalBytes);
byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag;
bytes preret;
for (auto const& i: m_subs)
m_data[i.first] = i.second.assemble();
@ -406,11 +393,6 @@ bytes Assembly::assemble() const
ret.push_back(tagPush);
tagRef[ret.size()] = (unsigned)i.m_data;
ret.resize(ret.size() + bytesPerTag);
preret.push_back(tagPush);
pretagRef[preret.size()] = (unsigned)i.m_data;
preret.resize(preret.size() + bytesPerTag);
preret.push_back((byte)Instruction::JUMPDEST);
break;
}
case PushData: case PushSub:
@ -432,6 +414,7 @@ bytes Assembly::assemble() const
}
case Tag:
tagPos[(unsigned)i.m_data] = ret.size();
ret.push_back((byte)Instruction::JUMPDEST);
break;
default:;
}
@ -442,12 +425,6 @@ bytes Assembly::assemble() const
toBigEndian(tagPos[i.second], r);
}
for (auto const& i: pretagRef)
{
bytesRef r(preret.data() + i.first, bytesPerTag);
toBigEndian(tagPos[i.second], r);
}
if (m_data.size())
{
ret.push_back(0);
@ -466,5 +443,5 @@ bytes Assembly::assemble() const
}
}
}
return preret + ret;
return ret;
}

1
liblll/CodeFragment.cpp

@ -24,6 +24,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/spirit/include/support_utree.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h>
#include <libevmface/Instruction.h>
#include "CompilerState.h"
#include "Parser.h"

3
libp2p/Capability.cpp

@ -27,6 +27,9 @@ using namespace std;
using namespace dev;
using namespace dev::p2p;
#if defined(clogS)
#undef clogS
#endif
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
Capability::Capability(Session* _s, HostCapabilityFace* _h, unsigned _idOffset): m_session(_s), m_host(_h), m_idOffset(_idOffset)

1
libp2p/Host.cpp

@ -36,6 +36,7 @@
#include <thread>
#include <boost/algorithm/string.hpp>
#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libethcore/Exceptions.h>
#include "Session.h"
#include "Common.h"

12
libp2p/Session.cpp

@ -23,6 +23,7 @@
#include <chrono>
#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libethcore/Exceptions.h>
#include "Host.h"
#include "Capability.h"
@ -30,6 +31,9 @@ using namespace std;
using namespace dev;
using namespace dev::p2p;
#if defined(clogS)
#undef clogS
#endif
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << m_socket.native_handle() << "] "
Session::Session(Host* _s, bi::tcp::socket _socket, bi::address _peerAddress, unsigned short _peerPort):
@ -82,7 +86,13 @@ bool Session::interpret(RLP const& _r)
m_listenPort = _r[4].toInt<unsigned short>();
m_id = _r[5].toHash<h512>();
clogS(NetMessageSummary) << "Hello: " << clientVersion << "V[" << m_protocolVersion << "]" << m_id.abridged() << showbase << hex << caps << dec << m_listenPort;
// clang error (previously: ... << hex << caps ...)
// "'operator<<' should be declared prior to the call site or in an associated namespace of one of its arguments"
stringstream capslog;
for (auto cap: caps)
capslog << "(" << hex << cap.first << "," << hex << cap.second << ")";
clogS(NetMessageSummary) << "Hello: " << clientVersion << "V[" << m_protocolVersion << "]" << m_id.abridged() << showbase << capslog.str() << dec << m_listenPort;
if (m_server->havePeer(m_id))
{

2
libp2p/Session.h

@ -27,6 +27,7 @@
#include <set>
#include <memory>
#include <utility>
#include <libdevcore/Common.h>
#include <libdevcore/RLP.h>
#include "Common.h"
@ -110,6 +111,7 @@ private:
unsigned m_rating;
std::map<CapDesc, std::shared_ptr<Capability>> m_capabilities;
std::set<h512> m_knownPeers;
bool m_willBeDeleted = false; ///< True if we already posted a deleter on the strand.
};

1
libp2p/UPnP.cpp

@ -31,6 +31,7 @@
#endif
#include <libdevcore/Exceptions.h>
#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libdevcore/Log.h>
using namespace std;
using namespace dev;

87
libqethereum/QEthereum.cpp

@ -336,6 +336,93 @@ static QString toJson(dev::eth::PastMessages const& _pms)
return QString::fromUtf8(QJsonDocument(jsonArray).toJson());
}
static QString toJson(dev::eth::BlockInfo const& _bi, dev::eth::BlockDetails const& _bd)
{
QJsonObject v;
v["hash"] = toQJS(_bi.hash);
v["parentHash"] = toQJS(_bi.parentHash);
v["sha3Uncles"] = toQJS(_bi.sha3Uncles);
v["miner"] = toQJS(_bi.coinbaseAddress);
v["stateRoot"] = toQJS(_bi.stateRoot);
v["transactionsRoot"] = toQJS(_bi.transactionsRoot);
v["difficulty"] = toQJS(_bi.difficulty);
v["number"] = (int)_bi.number;
v["minGasPrice"] = toQJS(_bi.minGasPrice);
v["gasLimit"] = (int)_bi.gasLimit;
v["gasUsed"] = (int)_bi.gasUsed;
v["timestamp"] = (int)_bi.timestamp;
v["extraData"] = ::fromBinary(_bi.extraData);
v["nonce"] = toQJS(_bi.nonce);
QJsonArray children;
for (auto c: _bd.children)
children.append(toQJS(c));
v["children"] = children;
v["totalDifficulty"] = toQJS(_bd.totalDifficulty);
v["bloom"] = toQJS(_bd.bloom);
return QString::fromUtf8(QJsonDocument(v).toJson());
}
static QString toJson(dev::eth::BlockInfo const& _bi)
{
QJsonObject v;
v["hash"] = toQJS(_bi.hash);
v["parentHash"] = toQJS(_bi.parentHash);
v["sha3Uncles"] = toQJS(_bi.sha3Uncles);
v["miner"] = toQJS(_bi.coinbaseAddress);
v["stateRoot"] = toQJS(_bi.stateRoot);
v["transactionsRoot"] = toQJS(_bi.transactionsRoot);
v["difficulty"] = toQJS(_bi.difficulty);
v["number"] = (int)_bi.number;
v["minGasPrice"] = toQJS(_bi.minGasPrice);
v["gasLimit"] = (int)_bi.gasLimit;
v["gasUsed"] = (int)_bi.gasUsed;
v["timestamp"] = (int)_bi.timestamp;
v["extraData"] = ::fromBinary(_bi.extraData);
v["nonce"] = toQJS(_bi.nonce);
return QString::fromUtf8(QJsonDocument(v).toJson());
}
static QString toJson(dev::eth::Transaction const& _bi)
{
QJsonObject v;
v["hash"] = toQJS(_bi.sha3());
v["input"] = ::fromBinary(_bi.data);
v["to"] = toQJS(_bi.receiveAddress);
v["from"] = toQJS(_bi.sender());
v["gas"] = (int)_bi.gas;
v["gasPrice"] = toQJS(_bi.gasPrice);
v["nonce"] = toQJS(_bi.nonce);
v["value"] = toQJS(_bi.value);
return QString::fromUtf8(QJsonDocument(v).toJson());
}
QString QEthereum::getUncle(QString _numberOrHash, int _i) const
{
auto n = toU256(_numberOrHash);
auto h = n < m_client->number() ? m_client->hashFromNumber((unsigned)n) : ::toFixed<32>(_numberOrHash);
return m_client ? toJson(m_client->uncle(h, _i)) : "";
}
QString QEthereum::getTransaction(QString _numberOrHash, int _i) const
{
auto n = toU256(_numberOrHash);
auto h = n < m_client->number() ? m_client->hashFromNumber((unsigned)n) : ::toFixed<32>(_numberOrHash);
return m_client ? toJson(m_client->transaction(h, _i)) : "";
}
QString QEthereum::getBlock(QString _numberOrHash) const
{
auto n = toU256(_numberOrHash);
auto h = n < m_client->number() ? m_client->hashFromNumber((unsigned)n) : ::toFixed<32>(_numberOrHash);
return m_client ? toJson(m_client->blockInfo(h), m_client->blockDetails(h)) : "";
}
QString QEthereum::getMessages(QString _json) const
{
return m_client ? toJson(m_client->messages(toMessageFilter(_json))) : "";

20
libqethereum/QEthereum.h

@ -148,6 +148,10 @@ public:
Q_INVOKABLE QString/*dev::u256*/ stateAt(QString/*dev::Address*/ _a, QString/*dev::u256*/ _p) const;
Q_INVOKABLE QString/*dev::u256*/ codeAt(QString/*dev::Address*/ _a) const;
Q_INVOKABLE QString/*json*/ getBlock(QString _numberOrHash/*unsigned if < number(), hash otherwise*/) const;
Q_INVOKABLE QString/*json*/ getTransaction(QString _numberOrHash/*unsigned if < number(), hash otherwise*/, int _index) const;
Q_INVOKABLE QString/*json*/ getUncle(QString _numberOrHash/*unsigned if < number(), hash otherwise*/, int _index) const;
Q_INVOKABLE QString/*json*/ getMessages(QString _attribs/*json*/) const;
Q_INVOKABLE QString doCreate(QString _secret, QString _amount, QString _init, QString _gas, QString _gasPrice);
@ -255,20 +259,12 @@ private:
frame->addToJavaScriptWindowObject("shh", eth, QWebFrame::ScriptOwnership); \
frame->evaluateJavaScript("eth.makeWatch = function(a) { var ww = eth.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { eth.killWatch(w); }; ret.changed = function(f) { eth.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(eth.watchMessages(this.w)) }; return ret; }"); \
frame->evaluateJavaScript("eth.watch = function(a) { return eth.makeWatch(JSON.stringify(a)) }"); \
frame->evaluateJavaScript("eth.watchChain = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.watch('chain') INSTEAD.'); return eth.makeWatch('chain') }"); \
frame->evaluateJavaScript("eth.watchPending = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.watch('pending') INSTEAD.'); return eth.makeWatch('pending') }"); \
frame->evaluateJavaScript("eth.create = function(s, v, c, g, p, f) { env.warn('THIS CALL IS DEPRECATED. USE eth.transact INSTEAD.'); var v = eth.doCreate(s, v, c, g, p); if (f) f(v) }"); \
frame->evaluateJavaScript("eth.transact = function(a_s, f_v, t, d, g, p, f) { if (t == null) { var r = eth.doTransact(JSON.stringify(a_s)); if (f_v) f_v(r); } else { env.warn('THIS FORM OF THIS CALL IS DEPRECATED.'); eth.doTransact(a_s, f_v, t, d, g, p); if (f) f() } }"); \
frame->evaluateJavaScript("eth.transact = function(a, f) { var r = eth.doTransact(JSON.stringify(a)); if (f) f(r); }"); \
frame->evaluateJavaScript("eth.call = function(a, f) { var ret = eth.doCallJson(JSON.stringify(a)); if (f) f(ret); return ret; }"); \
frame->evaluateJavaScript("eth.messages = function(a) { return JSON.parse(eth.getMessages(JSON.stringify(a))); }"); \
frame->evaluateJavaScript("eth.transactions = function(a) { env.warn('THIS CALL IS DEPRECATED. USE eth.messages INSTEAD.'); return JSON.parse(eth.getMessages(JSON.stringify(a))); }"); \
frame->evaluateJavaScript("String.prototype.pad = function(l, r) { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.pad(this, l, r) }"); \
frame->evaluateJavaScript("String.prototype.bin = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.toAscii(this) }"); \
frame->evaluateJavaScript("String.prototype.unbin = function(l) { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.fromAscii(this) }"); \
frame->evaluateJavaScript("String.prototype.unpad = function(l) { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.unpad(this) }"); \
frame->evaluateJavaScript("String.prototype.dec = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.toDecimal(this) }"); \
frame->evaluateJavaScript("String.prototype.fix = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.toFixed(this) }"); \
frame->evaluateJavaScript("String.prototype.sha3 = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.sha3old(this) }"); \
frame->evaluateJavaScript("eth.block = function(a) { return JSON.parse(eth.getBlock(a)); }"); \
frame->evaluateJavaScript("eth.transaction = function(a) { return JSON.parse(eth.getTransaction(a)); }"); \
frame->evaluateJavaScript("eth.uncle = function(a) { return JSON.parse(eth.getUncle(a)); }"); \
frame->evaluateJavaScript("shh.makeWatch = function(a) { var ww = shh.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { shh.killWatch(w); }; ret.changed = function(f) { shh.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(shh.watchMessages(this.w)) }; return ret; }"); \
frame->evaluateJavaScript("shh.watch = function(a) { return shh.makeWatch(JSON.stringify(a)) }"); \
}

3
libwhisper/Interface.cpp

@ -29,6 +29,9 @@ using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;
#if defined(clogS)
#undef clogS
#endif
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
bool MessageFilter::matches(Message const& _m) const

1
libwhisper/Message.cpp

@ -25,4 +25,3 @@ using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "

3
libwhisper/WhisperHost.cpp

@ -28,6 +28,9 @@ using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;
#if defined(clogS)
#undef clogS
#endif
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
WhisperHost::WhisperHost()

4
libwhisper/WhisperPeer.cpp

@ -28,6 +28,10 @@ using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;
#if defined(clogS)
#undef clogS
#endif
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
WhisperPeer::WhisperPeer(Session* _s, HostCapabilityFace* _h, unsigned _i): Capability(_s, _h, _i)

3
test/hexPrefix.cpp

@ -22,8 +22,9 @@
#include <fstream>
#include "JsonSpiritHeaders.h"
#include <libdevcrypto/TrieCommon.h>
#include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h>
#include <libdevcrypto/TrieCommon.h>
#include <boost/test/unit_test.hpp>
using namespace std;

1
test/rlp.cpp

@ -25,6 +25,7 @@
#include <libdevcore/Log.h>
#include <libdevcore/RLP.h>
#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <boost/test/unit_test.hpp>
#include <algorithm>
#include "JsonSpiritHeaders.h"

1
test/trie.cpp

@ -23,6 +23,7 @@
#include <fstream>
#include <random>
#include "JsonSpiritHeaders.h"
#include <libdevcore/CommonIO.h>
#include <libdevcrypto/TrieDB.h>
#include "TrieHash.h"
#include "MemTrie.h"

7
test/vm.cpp

@ -21,6 +21,7 @@
*/
#include "vm.h"
#include <libdevcore/CommonIO.h>
#define FILL_TESTS
@ -44,7 +45,7 @@ h160 FakeExtVM::create(u256 _endowment, u256* _gas, bytesConstRef _init, OnOpFun
m_s.noteSending(myAddress);
m_ms.internal.resize(m_ms.internal.size() + 1);
auto ret = m_s.create(myAddress, _endowment, gasPrice, _gas, _init, origin, &suicides, &posts, &m_ms ? &(m_ms.internal.back()) : nullptr, OnOpFunc(), 1);
auto ret = m_s.create(myAddress, _endowment, gasPrice, _gas, _init, origin, &suicides, &m_ms ? &(m_ms.internal.back()) : nullptr, OnOpFunc(), 1);
if (!m_ms.internal.back().from)
m_ms.internal.pop_back();
@ -82,7 +83,7 @@ bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data,
{
m_s.noteSending(myAddress);
m_ms.internal.resize(m_ms.internal.size() + 1);
auto na = m_s.create(myAddress, 0, gasPrice, _gas, init, origin, &suicides, &posts, &m_ms ? &(m_ms.internal.back()) : nullptr, OnOpFunc(), 1);
auto na = m_s.create(myAddress, 0, gasPrice, _gas, init, origin, &suicides, &m_ms ? &(m_ms.internal.back()) : nullptr, OnOpFunc(), 1);
if (!m_ms.internal.back().from)
m_ms.internal.pop_back();
if (!m_s.addresses().count(_receiveAddress))
@ -95,7 +96,7 @@ bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data,
}
m_ms.internal.resize(m_ms.internal.size() + 1);
auto ret = m_s.call(_receiveAddress, Address() ? Address() : _receiveAddress, Address() ? Address() : myAddress, _value, gasPrice, _data, _gas, _out, origin, &suicides, &posts, &(m_ms.internal.back()), OnOpFunc(), 1);
auto ret = m_s.call(_receiveAddress, Address() ? Address() : _receiveAddress, Address() ? Address() : myAddress, _value, gasPrice, _data, _gas, _out, origin, &suicides, &(m_ms.internal.back()), OnOpFunc(), 1);
if (!m_ms.internal.back().from)
m_ms.internal.pop_back();
if (!ret)

Loading…
Cancel
Save