Browse Source

Refactored account management out of WebThreeStubServerBase.

cl-refactor
Christian 10 years ago
parent
commit
73d5ff677e
  1. 2
      libdevcrypto/Common.cpp
  2. 3
      libdevcrypto/Common.h
  3. 66
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  4. 33
      libweb3jsonrpc/WebThreeStubServerBase.h

2
libdevcrypto/Common.cpp

@ -44,6 +44,8 @@ bool dev::SignatureStruct::isValid() const
return true; return true;
} }
Address dev::ZeroAddress = Address();
Public dev::toPublic(Secret const& _secret) Public dev::toPublic(Secret const& _secret)
{ {
Public p; Public p;

3
libdevcrypto/Common.h

@ -62,6 +62,9 @@ struct SignatureStruct
/// @NOTE This is not endian-specific; it's just a bunch of bytes. /// @NOTE This is not endian-specific; it's just a bunch of bytes.
using Address = h160; using Address = h160;
/// The zero address.
extern Address ZeroAddress;
/// A vector of Ethereum addresses. /// A vector of Ethereum addresses.
using Addresses = h160s; using Addresses = h160s;

66
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -211,22 +211,33 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message
return res; return res;
} }
WebThreeStubServerBase::WebThreeStubServerBase(jsonrpc::AbstractServerConnector& _conn, std::vector<dev::KeyPair> const& _accounts): void AccountHolder::setAccounts(std::vector<dev::KeyPair> const& _accounts)
AbstractWebThreeStubServer(_conn)
{
setAccounts(_accounts);
}
void WebThreeStubServerBase::setAccounts(std::vector<dev::KeyPair> const& _accounts)
{ {
m_accounts.clear(); m_accounts.clear();
for (auto const& i: _accounts) for (auto const& keyPair: _accounts)
{ {
m_accounts.push_back(i.address()); m_accounts.push_back(keyPair.address());
m_accountsLookup[i.address()] = i; m_keyPairs[keyPair.address()] = keyPair;
} }
} }
Address const& AccountHolder::getDefaultCallAccount() const
{
if (m_accounts.empty())
return ZeroAddress;
Address const* bestMatch = &m_accounts.front();
for (auto const& account: m_accounts)
if (m_client()->balanceAt(account) > m_client()->balanceAt(*bestMatch))
bestMatch = &account;
return *bestMatch;
}
WebThreeStubServerBase::WebThreeStubServerBase(jsonrpc::AbstractServerConnector& _conn, std::vector<dev::KeyPair> const& _accounts):
AbstractWebThreeStubServer(_conn), m_accounts(std::bind(&WebThreeStubServerBase::client, this))
{
m_accounts.setAccounts(_accounts);
}
void WebThreeStubServerBase::setIdentities(std::vector<dev::KeyPair> const& _ids) void WebThreeStubServerBase::setIdentities(std::vector<dev::KeyPair> const& _ids)
{ {
m_ids.clear(); m_ids.clear();
@ -242,7 +253,7 @@ std::string WebThreeStubServerBase::web3_sha3(std::string const& _param1)
Json::Value WebThreeStubServerBase::eth_accounts() Json::Value WebThreeStubServerBase::eth_accounts()
{ {
Json::Value ret(Json::arrayValue); Json::Value ret(Json::arrayValue);
for (auto const& i: m_accounts) for (auto const& i: m_accounts.getAllAccounts())
ret.append(toJS(i)); ret.append(toJS(i));
return ret; return ret;
} }
@ -326,21 +337,15 @@ std::string WebThreeStubServerBase::eth_call(Json::Value const& _json)
{ {
std::string ret; std::string ret;
TransactionSkeleton t = toTransaction(_json); TransactionSkeleton t = toTransaction(_json);
if (!t.from && m_accounts.size()) if (!t.from)
{ t.from = m_accounts.getDefaultCallAccount();
auto b = m_accounts.front(); if (!m_accounts.isRealAccount(t.from))
for (auto const& a: m_accounts)
if (client()->balanceAt(a) > client()->balanceAt(b))
b = a;
t.from = b;
}
if (!m_accountsLookup.count(t.from))
return ret; return ret;
if (!t.gasPrice) if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo; t.gasPrice = 10 * dev::eth::szabo;
if (!t.gas) if (!t.gas)
t.gas = min<u256>(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice); t.gas = min<u256>(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice);
ret = toJS(client()->call(m_accountsLookup[t.from].secret(), t.value, t.to, t.data, t.gas, t.gasPrice)); ret = toJS(client()->call(m_accounts.secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice));
return ret; return ret;
} }
@ -684,16 +689,14 @@ std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json)
{ {
std::string ret; std::string ret;
TransactionSkeleton t = toTransaction(_json); TransactionSkeleton t = toTransaction(_json);
if (!t.from && m_accounts.size()) if (!t.from)
t.from = m_accounts.getDefaultCallAccount();
if (!m_accounts.isRealAccount(t.from))
{ {
auto b = m_accounts.front(); // if (m_accounts.isProxyAccount(t.from))
for (auto const& a: m_accounts) // m_accounts.storeTransaction(t);
if (client()->balanceAt(a) > client()->balanceAt(b))
b = a;
t.from = b;
}
if (!m_accountsLookup.count(t.from))
return ret; return ret;
}
if (!t.gasPrice) if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo; t.gasPrice = 10 * dev::eth::szabo;
if (!t.gas) if (!t.gas)
@ -702,9 +705,9 @@ std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json)
{ {
if (t.to) if (t.to)
// TODO: from qethereum, insert validification hook here. // TODO: from qethereum, insert validification hook here.
client()->transact(m_accountsLookup[t.from].secret(), t.value, t.to, t.data, t.gas, t.gasPrice); client()->transact(m_accounts.secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice);
else else
ret = toJS(client()->transact(m_accountsLookup[t.from].secret(), t.value, t.data, t.gas, t.gasPrice)); ret = toJS(client()->transact(m_accounts.secretKey(t.from), t.value, t.data, t.gas, t.gasPrice));
client()->flushTransactions(); client()->flushTransactions();
} }
return ret; return ret;
@ -741,4 +744,3 @@ bool WebThreeStubServerBase::eth_uninstallFilter(int _id)
client()->uninstallWatch(_id); client()->uninstallWatch(_id);
return true; return true;
} }

33
libweb3jsonrpc/WebThreeStubServerBase.h

@ -24,6 +24,7 @@
#pragma once #pragma once
#include <iostream> #include <iostream>
#include <functional>
#include <jsonrpccpp/server.h> #include <jsonrpccpp/server.h>
#include <libdevcrypto/Common.h> #include <libdevcrypto/Common.h>
#pragma GCC diagnostic push #pragma GCC diagnostic push
@ -53,6 +54,32 @@ public:
virtual void put(std::string const& _name, std::string const& _key, std::string const& _value) = 0; virtual void put(std::string const& _name, std::string const& _key, std::string const& _value) = 0;
}; };
/**
* Manages real accounts (where we know the secret key) and proxy accounts (where transactions
* to be sent from these accounts are forwarded to a proxy on the other side).
*/
class AccountHolder
{
public:
explicit AccountHolder(std::function<dev::eth::Interface*()> const& _client): m_client(_client) {}
/// Sets or resets the list of real accounts.
void setAccounts(std::vector<dev::KeyPair> const& _accounts);
std::vector<dev::Address> const& getRealAccounts() const { return m_accounts; }
bool isRealAccount(dev::Address const& _account) const { return m_keyPairs.count(_account) > 0; }
Secret const& secretKey(dev::Address const& _account) const { return m_keyPairs.at(_account).secret(); }
std::vector<dev::Address> const& getAllAccounts() const { return m_accounts; /*todo */}
dev::Address const& getDefaultCallAccount() const;
private:
std::map<dev::Address, dev::KeyPair> m_keyPairs;
std::vector<dev::Address> m_accounts;
std::function<dev::eth::Interface*()> m_client;
};
/** /**
* @brief JSON-RPC api implementation * @brief JSON-RPC api implementation
* @todo filters should work on unsigned instead of int * @todo filters should work on unsigned instead of int
@ -125,7 +152,7 @@ public:
virtual bool shh_post(Json::Value const& _json); virtual bool shh_post(Json::Value const& _json);
virtual bool shh_uninstallFilter(int _id); virtual bool shh_uninstallFilter(int _id);
void setAccounts(std::vector<dev::KeyPair> const& _accounts); void setAccounts(std::vector<dev::KeyPair> const& _accounts) { m_accounts.setAccounts(_accounts); }
void setIdentities(std::vector<dev::KeyPair> const& _ids); void setIdentities(std::vector<dev::KeyPair> const& _ids);
std::map<dev::Public, dev::Secret> const& ids() const { return m_ids; } std::map<dev::Public, dev::Secret> const& ids() const { return m_ids; }
@ -138,11 +165,9 @@ protected:
virtual dev::WebThreeNetworkFace* network() = 0; virtual dev::WebThreeNetworkFace* network() = 0;
virtual dev::WebThreeStubDatabaseFace* db() = 0; virtual dev::WebThreeStubDatabaseFace* db() = 0;
std::map<dev::Address, dev::KeyPair> m_accountsLookup;
std::vector<dev::Address> m_accounts;
std::map<dev::Public, dev::Secret> m_ids; std::map<dev::Public, dev::Secret> m_ids;
std::map<unsigned, dev::Public> m_shhWatches; std::map<unsigned, dev::Public> m_shhWatches;
AccountHolder m_accounts;
}; };
} //namespace dev } //namespace dev

Loading…
Cancel
Save