Browse Source

Ready for move to log entries in JS API.

cl-refactor
Gav Wood 10 years ago
parent
commit
1d16e1556f
  1. 5
      libdevcore/FixedHash.h
  2. 3
      libdevcrypto/Common.h
  3. 3
      libdevcrypto/SHA3.h
  4. 55
      libethereum/MessageFilter.cpp
  5. 34
      libethereum/MessageFilter.h
  6. 3
      libethereum/State.cpp
  7. 20
      libevm/ExtVMFace.h
  8. 71
      libweb3jsonrpc/WebThreeStubServer.cpp
  9. 4
      libweb3jsonrpc/WebThreeStubServer.h
  10. 7
      libweb3jsonrpc/abstractwebthreestubserver.h
  11. 1
      libweb3jsonrpc/spec.json

5
libdevcore/FixedHash.h

@ -163,6 +163,11 @@ public:
return (*this |= _h.template nbloom<P, N>());
}
template <unsigned P, unsigned M> inline bool containsBloom(FixedHash<M> const& _h)
{
return contains(_h.template nbloom<P, N>());
}
template <unsigned P, unsigned M> inline FixedHash<M> nbloom() const
{
static const unsigned c_bloomBits = M * 8;

3
libdevcrypto/Common.h

@ -50,6 +50,9 @@ using Address = h160;
/// A vector of Ethereum addresses.
using Addresses = h160s;
/// A vector of Ethereum addresses.
using AddressSet = std::set<h160>;
/// A vector of secrets.
using Secrets = h256s;

3
libdevcrypto/SHA3.h

@ -56,6 +56,9 @@ inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef((bytes*)&_inpu
/// Calculate SHA3-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash.
inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); }
/// Calculate SHA3-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash.
template<unsigned N> inline h256 sha3(FixedHash<N> const& _input) { return sha3(_input.ref()); }
extern h256 EmptySHA3;
extern h256 EmptyListSHA3;

55
libethereum/MessageFilter.cpp

@ -149,3 +149,58 @@ bool MessageFilter::matches(Manifest const& _m, vector<unsigned> _p, Address _o,
return ret;
}
void LogFilter::streamRLP(RLPStream& _s) const
{
_s.appendList(6) << m_addresses << m_topics << m_earliest << m_latest << m_max << m_skip;
}
h256 LogFilter::sha3() const
{
RLPStream s;
streamRLP(s);
return dev::sha3(s.out());
}
bool LogFilter::matches(LogBloom _bloom) const
{
if (m_addresses.size())
{
for (auto i: m_addresses)
if (_bloom.containsBloom<3>(dev::sha3(i)))
goto OK1;
return false;
}
OK1:
if (m_topics.size())
{
for (auto i: m_topics)
if (_bloom.containsBloom<3>(dev::sha3(i)))
goto OK2;
return false;
}
OK2:
return true;
}
bool LogFilter::matches(State const& _s, unsigned _i) const
{
return matches(_s.receipt(_i)).size() > 0;
}
LogEntries LogFilter::matches(TransactionReceipt const& _m) const
{
LogEntries ret;
for (LogEntry const& e: _m.log())
{
if (!m_addresses.empty() && !m_addresses.count(e.address))
continue;
for (auto const& t: m_topics)
if (!e.topics.count(t))
continue;
ret.push_back(e);
}
return ret;
}

34
libethereum/MessageFilter.h

@ -25,6 +25,7 @@
#include <libdevcore/RLP.h>
#include <libethcore/CommonEth.h>
#include "PastMessage.h"
#include "TransactionReceipt.h"
namespace dev
{
@ -72,5 +73,38 @@ private:
unsigned m_skip;
};
class LogFilter
{
public:
LogFilter(int _earliest = 0, int _latest = -1, unsigned _max = 10, unsigned _skip = 0): m_earliest(_earliest), m_latest(_latest), m_max(_max), m_skip(_skip) {}
void streamRLP(RLPStream& _s) const;
h256 sha3() const;
int earliest() const { return m_earliest; }
int latest() const { return m_latest; }
unsigned max() const { return m_max; }
unsigned skip() const { return m_skip; }
bool matches(LogBloom _bloom) const;
bool matches(State const& _s, unsigned _i) const;
LogEntries matches(TransactionReceipt const& _r) const;
LogFilter address(Address _a) { m_addresses.insert(_a); return *this; }
LogFilter from(Address _a) { return topic(u256((u160)_a) + 1); }
LogFilter topic(h256 const& _t) { m_topics.insert(_t); return *this; }
LogFilter withMax(unsigned _m) { m_max = _m; return *this; }
LogFilter withSkip(unsigned _m) { m_skip = _m; return *this; }
LogFilter withEarliest(int _e) { m_earliest = _e; return *this; }
LogFilter withLatest(int _e) { m_latest = _e; return *this; }
private:
AddressSet m_addresses;
h256Set m_topics;
int m_earliest = 0;
int m_latest = -1;
unsigned m_max;
unsigned m_skip;
};
}
}

3
libethereum/State.cpp

@ -791,7 +791,8 @@ h256 State::oldBloom() const
LogBloom State::logBloom() const
{
LogBloom ret;
ret.shiftBloom<3>(sha3(m_currentBlock.coinbaseAddress.ref()));
auto sa = sha3(m_currentBlock.coinbaseAddress.ref());
ret.shiftBloom<3>(sa);
for (TransactionReceipt const& i: m_receipts)
ret |= i.bloom();
return ret;

20
libevm/ExtVMFace.h

@ -36,27 +36,35 @@ namespace dev
namespace eth
{
template <class T> inline std::set<T> toSet(std::vector<T> const& _ts)
{
std::set<T> ret;
for (auto const& t: _ts)
ret.insert(t);
return ret;
}
using LogBloom = h512;
struct LogEntry
{
LogEntry() {}
LogEntry(RLP const& _r) { from = (Address)_r[0]; topics = (h256s)_r[1]; data = (bytes)_r[2]; }
LogEntry(Address const& _f, h256s&& _ts, bytes&& _d): from(_f), topics(std::move(_ts)), data(std::move(_d)) {}
LogEntry(RLP const& _r) { address = (Address)_r[0]; topics = (h256Set)_r[1]; data = (bytes)_r[2]; }
LogEntry(Address const& _address, h256s const& _ts, bytes&& _d): address(_address), topics(toSet(_ts)), data(std::move(_d)) {}
void streamRLP(RLPStream& _s) const { _s.appendList(3) << from << topics << data; }
void streamRLP(RLPStream& _s) const { _s.appendList(3) << address << topics << data; }
LogBloom bloom() const
{
LogBloom ret;
ret.shiftBloom<3, 32>(sha3(from.ref()));
ret.shiftBloom<3, 32>(sha3(address.ref()));
for (auto t: topics)
ret.shiftBloom<3, 32>(sha3(t.ref()));
return ret;
}
Address from;
h256s topics;
Address address;
h256Set topics;
bytes data;
};

71
libweb3jsonrpc/WebThreeStubServer.cpp

@ -97,6 +97,24 @@ static Json::Value toJson(dev::eth::Transaction const& _t)
return res;
}
static Json::Value toJson(dev::eth::LogEntry const& _e)
{
Json::Value res;
res["data"] = jsFromBinary(_e.data);
res["address"] = toJS(_e.address);
for (auto const& t: _e.topics)
res["topics"].append(toJS(t));
return res;
}
static Json::Value toJson(dev::eth::LogEntries const& _es)
{
Json::Value res;
for (dev::eth::LogEntry const& e: _es)
res.append(toJson(e));
return res;
}
static dev::eth::MessageFilter toMessageFilter(Json::Value const& _json)
{
dev::eth::MessageFilter filter;
@ -123,9 +141,9 @@ static dev::eth::MessageFilter toMessageFilter(Json::Value const& _json)
{
if (_json["to"].isArray())
for (auto i : _json["to"])
filter.from(jsToAddress(i.asString()));
filter.to(jsToAddress(i.asString()));
else
filter.from(jsToAddress(_json["to"].asString()));
filter.to(jsToAddress(_json["to"].asString()));
}
if (!_json["altered"].empty())
{
@ -143,6 +161,48 @@ static dev::eth::MessageFilter toMessageFilter(Json::Value const& _json)
return filter;
}
static dev::eth::LogFilter toLogFilter(Json::Value const& _json)
{
dev::eth::LogFilter filter;
if (!_json.isObject() || _json.empty())
return filter;
if (!_json["earliest"].empty())
filter.withEarliest(_json["earliest"].asInt());
if (!_json["latest"].empty())
filter.withLatest(_json["lastest"].asInt());
if (!_json["max"].empty())
filter.withMax(_json["max"].asInt());
if (!_json["skip"].empty())
filter.withSkip(_json["skip"].asInt());
if (!_json["from"].empty())
{
if (_json["from"].isArray())
for (auto i : _json["from"])
filter.from(jsToAddress(i.asString()));
else
filter.from(jsToAddress(_json["from"].asString()));
}
if (!_json["address"].empty())
{
if (_json["address"].isArray())
for (auto i : _json["address"])
filter.address(jsToAddress(i.asString()));
else
filter.from(jsToAddress(_json["address"].asString()));
}
if (!_json["topics"].empty())
{
if (_json["topics"].isArray())
for (auto i: _json["topics"])
if (i.isString())
filter.topic(jsToU256(i.asString()));
else if(_json["topics"].isString())
filter.topic(jsToU256(_json["topics"].asString()));
}
return filter;
}
static shh::Message toMessage(Json::Value const& _json)
{
shh::Message ret;
@ -252,13 +312,6 @@ std::shared_ptr<dev::shh::Interface> WebThreeStubServer::face() const
return m_web3.whisper();
}
std::string WebThreeStubServer::account()
{
if (!m_accounts.empty())
return toJS(m_accounts.begin()->first);
return "";
}
Json::Value WebThreeStubServer::accounts()
{
Json::Value ret(Json::arrayValue);

4
libweb3jsonrpc/WebThreeStubServer.h

@ -56,13 +56,14 @@ class Interface;
* @brief JSON-RPC api implementation
* @todo filters should work on unsigned instead of int
* unsigned are not supported in json-rpc-cpp and there are bugs with double in json-rpc-cpp version 0.2.1
* @todo split these up according to subprotocol (eth, shh, db, p2p, web3) and make it /very/ clear about how to add other subprotocols.
* @todo modularise everything so additional subprotocols don't need to change this file.
*/
class WebThreeStubServer: public AbstractWebThreeStubServer
{
public:
WebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector<dev::KeyPair> const& _accounts);
virtual std::string account();
virtual Json::Value accounts();
virtual std::string addToGroup(std::string const& _group, std::string const& _who);
virtual std::string balanceAt(std::string const& _address);
@ -109,6 +110,7 @@ public:
void setAccounts(std::vector<dev::KeyPair> const& _accounts);
void setIdentities(std::vector<dev::KeyPair> const& _ids);
std::map<dev::Public, dev::Secret> const& ids() const { return m_ids; }
private:
dev::eth::Interface* client() const;
std::shared_ptr<dev::shh::Interface> face() const;

7
libweb3jsonrpc/abstractwebthreestubserver.h

@ -13,7 +13,6 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
AbstractWebThreeStubServer(jsonrpc::AbstractServerConnector* conn) :
jsonrpc::AbstractServer<AbstractWebThreeStubServer>(conn)
{
this->bindAndAddMethod(new jsonrpc::Procedure("account", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::accountI);
this->bindAndAddMethod(new jsonrpc::Procedure("accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::accountsI);
this->bindAndAddMethod(new jsonrpc::Procedure("addToGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::addToGroupI);
this->bindAndAddMethod(new jsonrpc::Procedure("balanceAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::balanceAtI);
@ -59,11 +58,6 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
}
inline virtual void accountI(const Json::Value& request, Json::Value& response)
{
response = this->account();
}
inline virtual void accountsI(const Json::Value& request, Json::Value& response)
{
response = this->accounts();
@ -275,7 +269,6 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
}
virtual std::string account() = 0;
virtual Json::Value accounts() = 0;
virtual std::string addToGroup(const std::string& param1, const std::string& param2) = 0;
virtual std::string balanceAt(const std::string& param1) = 0;

1
libweb3jsonrpc/spec.json

@ -6,7 +6,6 @@
{ "method": "mining", "params": [], "order": [], "returns" : false },
{ "method": "setMining", "params": [false], "order" : [], "returns" : true },
{ "method": "gasPrice", "params": [], "order": [], "returns" : "" },
{ "method": "account", "params": [], "order": [], "returns" : "" },
{ "method": "accounts", "params": [], "order": [], "returns" : [] },
{ "method": "peerCount", "params": [], "order": [], "returns" : 0 },
{ "method": "defaultBlock", "params": [], "order": [], "returns" : 0},

Loading…
Cancel
Save