Browse Source

Refactor call/create so they don't need a Secret in preparation for

integration of the KeyManager.
cl-refactor
Gav Wood 10 years ago
parent
commit
456872daec
  1. 6
      eth/main.cpp
  2. 1
      libethereum/Client.h
  3. 20
      libethereum/ClientBase.cpp
  4. 8
      libethereum/ClientBase.h
  5. 12
      libethereum/Interface.h
  6. 2
      libethereum/KeyManager.h
  7. 6
      libethereum/Transaction.h
  8. 2
      libethereumx/Ethereum.cpp
  9. 2
      libethereumx/Ethereum.h
  10. 58
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  11. 7
      libweb3jsonrpc/WebThreeStubServerBase.h
  12. 48
      mix/MixClient.cpp
  13. 10
      mix/MixClient.h

6
eth/main.cpp

@ -124,6 +124,7 @@ void help()
<< " -R,--rebuild Rebuild the blockchain from the existing database." << endl << " -R,--rebuild Rebuild the blockchain from the existing database." << endl
<< " -s,--secret <secretkeyhex> Set the secret key for use with send command (default: auto)." << endl << " -s,--secret <secretkeyhex> Set the secret key for use with send command (default: auto)." << endl
<< " -S,--session-secret <secretkeyhex> Set the secret key for use with send command, for this session only." << endl << " -S,--session-secret <secretkeyhex> Set the secret key for use with send command, for this session only." << endl
<< " --master <password> Give the master password for the key store." << endl
<< "Client transacting:" << endl << "Client transacting:" << endl
<< " -B,--block-fees <n> Set the block fee profit in the reference unit e.g. ¢ (default: 15)." << endl << " -B,--block-fees <n> Set the block fee profit in the reference unit e.g. ¢ (default: 15)." << endl
<< " -e,--ether-price <n> Set the ether price in the reference unit e.g. ¢ (default: 30.679)." << endl << " -e,--ether-price <n> Set the ether price in the reference unit e.g. ¢ (default: 30.679)." << endl
@ -546,6 +547,9 @@ int main(int argc, char** argv)
string farmURL = "http://127.0.0.1:8080"; string farmURL = "http://127.0.0.1:8080";
unsigned farmRecheckPeriod = 500; unsigned farmRecheckPeriod = 500;
/// Wallet password stuff
string masterPassword;
string configFile = getDataDir() + "/config.rlp"; string configFile = getDataDir() + "/config.rlp";
bytes b = contents(configFile); bytes b = contents(configFile);
if (b.size()) if (b.size())
@ -580,6 +584,8 @@ int main(int argc, char** argv)
cerr << "-p is DEPRECATED. It will be removed for the Frontier. Use --port instead (or place directly as host:port)." << endl; cerr << "-p is DEPRECATED. It will be removed for the Frontier. Use --port instead (or place directly as host:port)." << endl;
remotePort = (short)atoi(argv[++i]); remotePort = (short)atoi(argv[++i]);
} }
else if (arg == "--master" && i + 1 < argc)
masterPassword = argv[++i];
else if ((arg == "-I" || arg == "--import") && i + 1 < argc) else if ((arg == "-I" || arg == "--import") && i + 1 < argc)
{ {
mode = OperationMode::Import; mode = OperationMode::Import;

1
libethereum/Client.h

@ -309,7 +309,6 @@ private:
ActivityReport m_report; ActivityReport m_report;
// TODO!!!!!! REPLACE WITH A PROPER X-THREAD ASIO SIGNAL SYSTEM (could just be condition variables)
std::condition_variable m_signalled; std::condition_variable m_signalled;
Mutex x_signalled; Mutex x_signalled;
std::atomic<bool> m_syncTransactionQueue = {false}; std::atomic<bool> m_syncTransactionQueue = {false};

20
libethereum/ClientBase.cpp

@ -75,17 +75,17 @@ Address ClientBase::submitTransaction(Secret _secret, u256 _endowment, bytes con
} }
// TODO: remove try/catch, allow exceptions // TODO: remove try/catch, allow exceptions
ExecutionResult ClientBase::call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff) ExecutionResult ClientBase::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff)
{ {
ExecutionResult ret; ExecutionResult ret;
try try
{ {
State temp = asOf(_blockNumber); State temp = asOf(_blockNumber);
Address a = toAddress(_secret); u256 n = temp.transactionsFrom(_from);
u256 n = temp.transactionsFrom(a); Transaction t(_value, _gasPrice, _gas, _dest, _data, n);
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); t.forceSender(_from);
if (_ff == FudgeFactor::Lenient) if (_ff == FudgeFactor::Lenient)
temp.addBalance(a, (u256)(t.gas() * t.gasPrice() + t.value())); temp.addBalance(_from, (u256)(t.gas() * t.gasPrice() + t.value()));
ret = temp.execute(bc().lastHashes(), t, Permanence::Reverted); ret = temp.execute(bc().lastHashes(), t, Permanence::Reverted);
} }
catch (...) catch (...)
@ -95,19 +95,19 @@ ExecutionResult ClientBase::call(Secret _secret, u256 _value, Address _dest, byt
return ret; return ret;
} }
ExecutionResult ClientBase::create(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff) ExecutionResult ClientBase::create(Address const& _from, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff)
{ {
ExecutionResult ret; ExecutionResult ret;
try try
{ {
State temp = asOf(_blockNumber); State temp = asOf(_blockNumber);
Address a = toAddress(_secret); u256 n = temp.transactionsFrom(_from);
u256 n = temp.transactionsFrom(a);
// cdebug << "Nonce at " << toAddress(_secret) << " pre:" << m_preMine.transactionsFrom(toAddress(_secret)) << " post:" << m_postMine.transactionsFrom(toAddress(_secret)); // cdebug << "Nonce at " << toAddress(_secret) << " pre:" << m_preMine.transactionsFrom(toAddress(_secret)) << " post:" << m_postMine.transactionsFrom(toAddress(_secret));
Transaction t(_value, _gasPrice, _gas, _data, n, _secret); Transaction t(_value, _gasPrice, _gas, _data, n);
t.forceSender(_from);
if (_ff == FudgeFactor::Lenient) if (_ff == FudgeFactor::Lenient)
temp.addBalance(a, (u256)(t.gasRequired() * t.gasPrice() + t.value())); temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value()));
ret = temp.execute(bc().lastHashes(), t, Permanence::Reverted); ret = temp.execute(bc().lastHashes(), t, Permanence::Reverted);
} }
catch (...) catch (...)

8
libethereum/ClientBase.h

@ -83,11 +83,13 @@ public:
virtual Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = 10 * szabo) override; virtual Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = 10 * szabo) override;
/// Makes the given call. Nothing is recorded into the state. /// Makes the given call. Nothing is recorded into the state.
virtual ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock, FudgeFactor _ff = FudgeFactor::Strict) override; virtual ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock, FudgeFactor _ff = FudgeFactor::Strict) override;
using Interface::call;
/// Makes the given create. Nothing is recorded into the state. /// Makes the given create. Nothing is recorded into the state.
virtual ExecutionResult create(Secret _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock, FudgeFactor _ff = FudgeFactor::Strict) override; virtual ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock, FudgeFactor _ff = FudgeFactor::Strict) override;
using Interface::create;
using Interface::balanceAt; using Interface::balanceAt;
using Interface::countAt; using Interface::countAt;
using Interface::stateAt; using Interface::stateAt;

12
libethereum/Interface.h

@ -76,13 +76,17 @@ public:
virtual void flushTransactions() = 0; virtual void flushTransactions() = 0;
/// Makes the given call. Nothing is recorded into the state. /// Makes the given call. Nothing is recorded into the state.
virtual ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) = 0; virtual ExecutionResult call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) = 0;
ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, FudgeFactor _ff = FudgeFactor::Strict) { return call(_secret, _value, _dest, _data, _gas, _gasPrice, m_default, _ff); } ExecutionResult call(Address const& _from, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, FudgeFactor _ff = FudgeFactor::Strict) { return call(_from, _value, _dest, _data, _gas, _gasPrice, m_default, _ff); }
ExecutionResult call(Secret const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) { return call(toAddress(_secret), _value, _dest, _data, _gas, _gasPrice, _blockNumber, _ff); }
ExecutionResult call(Secret const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return call(toAddress(_secret), _value, _dest, _data, _gas, _gasPrice, _ff); }
/// Does the given creation. Nothing is recorded into the state. /// Does the given creation. Nothing is recorded into the state.
/// @returns the pair of the Address of the created contract together with its code. /// @returns the pair of the Address of the created contract together with its code.
virtual ExecutionResult create(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) = 0; virtual ExecutionResult create(Address const& _from, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) = 0;
ExecutionResult create(Secret _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, FudgeFactor _ff = FudgeFactor::Strict) { return create(_secret, _value, _data, _gas, _gasPrice, m_default, _ff); } ExecutionResult create(Address const& _from, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, FudgeFactor _ff = FudgeFactor::Strict) { return create(_from, _value, _data, _gas, _gasPrice, m_default, _ff); }
ExecutionResult create(Secret const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) { return create(toAddress(_secret), _value, _data, _gas, _gasPrice, _blockNumber, _ff); }
ExecutionResult create(Secret const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return create(toAddress(_secret), _value, _data, _gas, _gasPrice, _ff); }
/// Injects the RLP-encoded transaction given by the _rlp into the transaction queue directly. /// Injects the RLP-encoded transaction given by the _rlp into the transaction queue directly.
virtual ImportResult injectTransaction(bytes const& _rlp) = 0; virtual ImportResult injectTransaction(bytes const& _rlp) = 0;

2
libethereum/KeyManager.h

@ -37,7 +37,7 @@ struct KeyInfo
std::string info; std::string info;
}; };
static const auto DontKnowThrow = [](){ BOOST_THROW_EXCEPTION(UnknownPassword()); return std::string(); }; static const auto DontKnowThrow = [](){ throw UnknownPassword(); return std::string(); };
// TODO: This one is specifically for Ethereum, but we can make it generic in due course. // TODO: This one is specifically for Ethereum, but we can make it generic in due course.
// TODO: hidden-partition style key-store. // TODO: hidden-partition style key-store.

6
libethereum/Transaction.h

@ -111,10 +111,10 @@ public:
Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); } Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); }
/// Constructs an unsigned message-call transaction. /// Constructs an unsigned message-call transaction.
Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data): m_type(MessageCall), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce = 0): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
/// Constructs an unsigned contract-creation transaction. /// Constructs an unsigned contract-creation transaction.
Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data): m_type(ContractCreation), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce = 0): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
/// Constructs a transaction from the given RLP. /// Constructs a transaction from the given RLP.
explicit Transaction(bytesConstRef _rlp, CheckTransaction _checkSig); explicit Transaction(bytesConstRef _rlp, CheckTransaction _checkSig);
@ -132,6 +132,8 @@ public:
Address const& sender() const; Address const& sender() const;
/// Like sender() but will never throw. @returns a null Address if the signature is invalid. /// Like sender() but will never throw. @returns a null Address if the signature is invalid.
Address const& safeSender() const noexcept; Address const& safeSender() const noexcept;
/// Force the sender to a particular value. This will result in an invalid transaction RLP.
void forceSender(Address const& _a) { m_sender = _a; }
/// @returns true if transaction is non-null. /// @returns true if transaction is non-null.
explicit operator bool() const { return m_type != NullTransaction; } explicit operator bool() const { return m_type != NullTransaction; }

2
libethereumx/Ethereum.cpp

@ -87,7 +87,7 @@ void Ethereum::submitTransaction(Secret _secret, u256 _value, Address _dest, byt
{ {
} }
bytes Ethereum::call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) bytes Ethereum::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice)
{ {
return bytes(); return bytes();
} }

2
libethereumx/Ethereum.h

@ -75,7 +75,7 @@ public:
void flushTransactions(); void flushTransactions();
/// Makes the given call. Nothing is recorded into the state. /// 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); bytes call(Address const& _from, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
// Informational stuff // Informational stuff

58
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -298,16 +298,16 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message
} }
WebThreeStubServerBase::WebThreeStubServerBase(AbstractServerConnector& _conn, vector<dev::KeyPair> const& _accounts): WebThreeStubServerBase::WebThreeStubServerBase(AbstractServerConnector& _conn, vector<dev::KeyPair> const& _accounts):
AbstractWebThreeStubServer(_conn), m_accounts(make_shared<AccountHolder>(bind(&WebThreeStubServerBase::client, this))) AbstractWebThreeStubServer(_conn), m_ethAccounts(make_shared<AccountHolder>(bind(&WebThreeStubServerBase::client, this)))
{ {
m_accounts->setAccounts(_accounts); m_ethAccounts->setAccounts(_accounts);
} }
void WebThreeStubServerBase::setIdentities(vector<dev::KeyPair> const& _ids) void WebThreeStubServerBase::setIdentities(vector<dev::KeyPair> const& _ids)
{ {
m_ids.clear(); m_shhIds.clear();
for (auto i: _ids) for (auto i: _ids)
m_ids[i.pub()] = i.secret(); m_shhIds[i.pub()] = i.secret();
} }
string WebThreeStubServerBase::web3_sha3(string const& _param1) string WebThreeStubServerBase::web3_sha3(string const& _param1)
@ -353,7 +353,7 @@ string WebThreeStubServerBase::eth_gasPrice()
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->getAllAccounts()) for (auto const& i: m_ethAccounts->getAllAccounts())
ret.append(toJS(i)); ret.append(toJS(i));
return ret; return ret;
} }
@ -499,7 +499,7 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json)
TransactionSkeleton t = toTransaction(_json); TransactionSkeleton t = toTransaction(_json);
if (!t.from) if (!t.from)
t.from = m_accounts->getDefaultTransactAccount(); t.from = m_ethAccounts->getDefaultTransactAccount();
if (t.creation) if (t.creation)
ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));; ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));;
if (t.gasPrice == UndefinedU256) if (t.gasPrice == UndefinedU256)
@ -507,9 +507,9 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json)
if (t.gas == UndefinedU256) if (t.gas == UndefinedU256)
t.gas = min<u256>(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice); t.gas = min<u256>(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice);
if (m_accounts->isRealAccount(t.from)) if (m_ethAccounts->isRealAccount(t.from))
authenticate(t, false); authenticate(t, false);
else if (m_accounts->isProxyAccount(t.from)) else if (m_ethAccounts->isProxyAccount(t.from))
authenticate(t, true); authenticate(t, true);
return ret; return ret;
@ -528,7 +528,7 @@ string WebThreeStubServerBase::eth_signTransaction(Json::Value const& _json)
TransactionSkeleton t = toTransaction(_json); TransactionSkeleton t = toTransaction(_json);
if (!t.from) if (!t.from)
t.from = m_accounts->getDefaultTransactAccount(); t.from = m_ethAccounts->getDefaultTransactAccount();
if (t.creation) if (t.creation)
ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));; ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));;
if (t.gasPrice == UndefinedU256) if (t.gasPrice == UndefinedU256)
@ -536,9 +536,9 @@ string WebThreeStubServerBase::eth_signTransaction(Json::Value const& _json)
if (t.gas == UndefinedU256) if (t.gas == UndefinedU256)
t.gas = min<u256>(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice); t.gas = min<u256>(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice);
if (m_accounts->isRealAccount(t.from)) if (m_ethAccounts->isRealAccount(t.from))
authenticate(t, false); authenticate(t, false);
else if (m_accounts->isProxyAccount(t.from)) else if (m_ethAccounts->isProxyAccount(t.from))
authenticate(t, true); authenticate(t, true);
return toJS((t.creation ? Transaction(t.value, t.gasPrice, t.gas, t.data) : Transaction(t.value, t.gasPrice, t.gas, t.to, t.data)).sha3(WithoutSignature)); return toJS((t.creation ? Transaction(t.value, t.gasPrice, t.gas, t.data) : Transaction(t.value, t.gasPrice, t.gas, t.to, t.data)).sha3(WithoutSignature));
@ -579,7 +579,7 @@ string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const&
{ {
TransactionSkeleton t = toTransaction(_json); TransactionSkeleton t = toTransaction(_json);
if (!t.from) if (!t.from)
t.from = m_accounts->getDefaultTransactAccount(); t.from = m_ethAccounts->getDefaultTransactAccount();
// if (!m_accounts->isRealAccount(t.from)) // if (!m_accounts->isRealAccount(t.from))
// return ret; // return ret;
if (t.gasPrice == UndefinedU256) if (t.gasPrice == UndefinedU256)
@ -587,7 +587,7 @@ string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const&
if (t.gas == UndefinedU256) if (t.gas == UndefinedU256)
t.gas = client()->gasLimitRemaining(); t.gas = client()->gasLimitRemaining();
return toJS(client()->call(m_accounts->secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice, jsToBlockNumber(_blockNumber), FudgeFactor::Lenient).output); return toJS(client()->call(m_ethAccounts->secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice, jsToBlockNumber(_blockNumber), FudgeFactor::Lenient).output);
} }
catch (...) catch (...)
{ {
@ -879,7 +879,7 @@ string WebThreeStubServerBase::eth_register(string const& _address)
{ {
try try
{ {
return toJS(m_accounts->addProxyAccount(jsToAddress(_address))); return toJS(m_ethAccounts->addProxyAccount(jsToAddress(_address)));
} }
catch (...) catch (...)
{ {
@ -891,7 +891,7 @@ bool WebThreeStubServerBase::eth_unregister(string const& _accountId)
{ {
try try
{ {
return m_accounts->removeProxyAccount(jsToInt(_accountId)); return m_ethAccounts->removeProxyAccount(jsToInt(_accountId));
} }
catch (...) catch (...)
{ {
@ -906,9 +906,9 @@ Json::Value WebThreeStubServerBase::eth_fetchQueuedTransactions(string const& _a
auto id = jsToInt(_accountId); auto id = jsToInt(_accountId);
Json::Value ret(Json::arrayValue); Json::Value ret(Json::arrayValue);
// TODO: throw an error on no account with given id // TODO: throw an error on no account with given id
for (TransactionSkeleton const& t: m_accounts->getQueuedTransactions(id)) for (TransactionSkeleton const& t: m_ethAccounts->getQueuedTransactions(id))
ret.append(toJson(t)); ret.append(toJson(t));
m_accounts->clearQueue(id); m_ethAccounts->clearQueue(id);
return ret; return ret;
} }
catch (...) catch (...)
@ -934,11 +934,11 @@ bool WebThreeStubServerBase::shh_post(Json::Value const& _json)
{ {
shh::Message m = toMessage(_json); shh::Message m = toMessage(_json);
Secret from; Secret from;
if (m.from() && m_ids.count(m.from())) if (m.from() && m_shhIds.count(m.from()))
{ {
cwarn << "Silently signing message from identity" << m.from() << ": User validation hook goes here."; cwarn << "Silently signing message from identity" << m.from() << ": User validation hook goes here.";
// TODO: insert validification hook here. // TODO: insert validification hook here.
from = m_ids[m.from()]; from = m_shhIds[m.from()];
} }
face()->inject(toSealed(_json, m, from)); face()->inject(toSealed(_json, m, from));
@ -953,7 +953,7 @@ bool WebThreeStubServerBase::shh_post(Json::Value const& _json)
string WebThreeStubServerBase::shh_newIdentity() string WebThreeStubServerBase::shh_newIdentity()
{ {
KeyPair kp = KeyPair::create(); KeyPair kp = KeyPair::create();
m_ids[kp.pub()] = kp.secret(); m_shhIds[kp.pub()] = kp.secret();
return toJS(kp.pub()); return toJS(kp.pub());
} }
@ -961,7 +961,7 @@ bool WebThreeStubServerBase::shh_hasIdentity(string const& _identity)
{ {
try try
{ {
return m_ids.count(jsToPublic(_identity)) > 0; return m_shhIds.count(jsToPublic(_identity)) > 0;
} }
catch (...) catch (...)
{ {
@ -1021,7 +1021,7 @@ Json::Value WebThreeStubServerBase::shh_getFilterChanges(string const& _filterId
int id = jsToInt(_filterId); int id = jsToInt(_filterId);
auto pub = m_shhWatches[id]; auto pub = m_shhWatches[id];
if (!pub || m_ids.count(pub)) if (!pub || m_shhIds.count(pub))
for (h256 const& h: face()->checkWatch(id)) for (h256 const& h: face()->checkWatch(id))
{ {
auto e = face()->envelope(h); auto e = face()->envelope(h);
@ -1029,7 +1029,7 @@ Json::Value WebThreeStubServerBase::shh_getFilterChanges(string const& _filterId
if (pub) if (pub)
{ {
cwarn << "Silently decrypting message from identity" << pub << ": User validation hook goes here."; cwarn << "Silently decrypting message from identity" << pub << ": User validation hook goes here.";
m = e.open(face()->fullTopic(id), m_ids[pub]); m = e.open(face()->fullTopic(id), m_shhIds[pub]);
} }
else else
m = e.open(face()->fullTopic(id)); m = e.open(face()->fullTopic(id));
@ -1054,7 +1054,7 @@ Json::Value WebThreeStubServerBase::shh_getMessages(string const& _filterId)
int id = jsToInt(_filterId); int id = jsToInt(_filterId);
auto pub = m_shhWatches[id]; auto pub = m_shhWatches[id];
if (!pub || m_ids.count(pub)) if (!pub || m_shhIds.count(pub))
for (h256 const& h: face()->watchMessages(id)) for (h256 const& h: face()->watchMessages(id))
{ {
auto e = face()->envelope(h); auto e = face()->envelope(h);
@ -1062,7 +1062,7 @@ Json::Value WebThreeStubServerBase::shh_getMessages(string const& _filterId)
if (pub) if (pub)
{ {
cwarn << "Silently decrypting message from identity" << pub << ": User validation hook goes here."; cwarn << "Silently decrypting message from identity" << pub << ": User validation hook goes here.";
m = e.open(face()->fullTopic(id), m_ids[pub]); m = e.open(face()->fullTopic(id), m_shhIds[pub]);
} }
else else
m = e.open(face()->fullTopic(id)); m = e.open(face()->fullTopic(id));
@ -1081,14 +1081,14 @@ Json::Value WebThreeStubServerBase::shh_getMessages(string const& _filterId)
void WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t, bool _toProxy) void WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t, bool _toProxy)
{ {
if (_toProxy) if (_toProxy)
m_accounts->queueTransaction(_t); m_ethAccounts->queueTransaction(_t);
else if (_t.to) else if (_t.to)
client()->submitTransaction(m_accounts->secretKey(_t.from), _t.value, _t.to, _t.data, _t.gas, _t.gasPrice); client()->submitTransaction(m_ethAccounts->secretKey(_t.from), _t.value, _t.to, _t.data, _t.gas, _t.gasPrice);
else else
client()->submitTransaction(m_accounts->secretKey(_t.from), _t.value, _t.data, _t.gas, _t.gasPrice); client()->submitTransaction(m_ethAccounts->secretKey(_t.from), _t.value, _t.data, _t.gas, _t.gasPrice);
} }
void WebThreeStubServerBase::setAccounts(const vector<KeyPair>& _accounts) void WebThreeStubServerBase::setAccounts(const vector<KeyPair>& _accounts)
{ {
m_accounts->setAccounts(_accounts); m_ethAccounts->setAccounts(_accounts);
} }

7
libweb3jsonrpc/WebThreeStubServerBase.h

@ -136,7 +136,7 @@ public:
void setAccounts(std::vector<dev::KeyPair> const& _accounts); void setAccounts(std::vector<dev::KeyPair> const& _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_shhIds; }
protected: protected:
virtual void authenticate(dev::eth::TransactionSkeleton const& _t, bool _toProxy); virtual void authenticate(dev::eth::TransactionSkeleton const& _t, bool _toProxy);
@ -147,9 +147,10 @@ protected:
virtual dev::WebThreeNetworkFace* network() = 0; virtual dev::WebThreeNetworkFace* network() = 0;
virtual dev::WebThreeStubDatabaseFace* db() = 0; virtual dev::WebThreeStubDatabaseFace* db() = 0;
std::map<dev::Public, dev::Secret> m_ids; std::shared_ptr<dev::AccountHolder> m_ethAccounts;
std::map<dev::Public, dev::Secret> m_shhIds;
std::map<unsigned, dev::Public> m_shhWatches; std::map<unsigned, dev::Public> m_shhWatches;
std::shared_ptr<dev::AccountHolder> m_accounts;
}; };
} //namespace dev } //namespace dev

48
mix/MixClient.cpp

@ -98,17 +98,20 @@ void MixClient::resetState(std::unordered_map<Address, Account> const& _accounts
m_executions.clear(); m_executions.clear();
} }
Transaction MixClient::replaceGas(Transaction const& _t, Secret const& _secret, u256 const& _gas) Transaction MixClient::replaceGas(Transaction const& _t, u256 const& _gas)
{ {
Transaction ret;
if (_t.isCreation()) if (_t.isCreation())
return Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce(), _secret); ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce());
else else
return Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce(), _secret); ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce());
ret.forceSender(_t.safeSender());
return ret;
} }
void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _call, bool _gasAuto, Secret const& _secret) void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _call, bool _gasAuto)
{ {
Transaction t = _gasAuto ? replaceGas(_t, _secret, m_state.gasLimitRemaining()) : _t; Transaction t = _gasAuto ? replaceGas(_t, m_state.gasLimitRemaining()) : _t;
bytes rlp = t.rlp(); bytes rlp = t.rlp();
// do debugging run first // do debugging run first
@ -219,7 +222,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c
// execute on a state // execute on a state
if (!_call) if (!_call)
{ {
t = _gasAuto ? replaceGas(_t, _secret, d.gasUsed) : _t; t = _gasAuto ? replaceGas(_t, d.gasUsed) : _t;
er =_state.execute(lastHashes, t); er =_state.execute(lastHashes, t);
if (t.isCreation() && _state.code(d.contractAddress).empty()) if (t.isCreation() && _state.code(d.contractAddress).empty())
BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment")); BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment"));
@ -282,7 +285,7 @@ void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, by
WriteGuard l(x_state); WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_secret)); u256 n = m_state.transactionsFrom(toAddress(_secret));
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret);
executeTransaction(t, m_state, false, _gasAuto, _secret); executeTransaction(t, m_state, false, _gasAuto);
} }
Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto) Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto)
@ -290,23 +293,23 @@ Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes cons
WriteGuard l(x_state); WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_secret)); u256 n = m_state.transactionsFrom(toAddress(_secret));
eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret);
executeTransaction(t, m_state, false, _gasAuto, _secret); executeTransaction(t, m_state, false, _gasAuto);
Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); Address address = right160(sha3(rlpList(t.sender(), t.nonce())));
return address; return address;
} }
dev::eth::ExecutionResult MixClient::call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, bool _gasAuto, FudgeFactor _ff) dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, bool _gasAuto, FudgeFactor _ff)
{ {
(void)_blockNumber; (void)_blockNumber;
Address a = toAddress(_secret);
State temp = asOf(eth::PendingBlock); State temp = asOf(eth::PendingBlock);
u256 n = temp.transactionsFrom(a); u256 n = temp.transactionsFrom(_from);
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); Transaction t(_value, _gasPrice, _gas, _dest, _data, n);
t.forceSender(_from);
if (_ff == FudgeFactor::Lenient) if (_ff == FudgeFactor::Lenient)
temp.addBalance(a, (u256)(t.gasRequired() * t.gasPrice() + t.value())); temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value()));
bytes rlp = t.rlp(); bytes rlp = t.rlp();
WriteGuard lw(x_state); //TODO: lock is required only for last execution state WriteGuard lw(x_state); //TODO: lock is required only for last execution state
executeTransaction(t, temp, true, _gasAuto, _secret); executeTransaction(t, temp, true, _gasAuto);
return lastExecution().result; return lastExecution().result;
} }
@ -320,28 +323,27 @@ Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes cons
return submitTransaction(_secret, _endowment, _init, _gas, _gasPrice, false); return submitTransaction(_secret, _endowment, _init, _gas, _gasPrice, false);
} }
dev::eth::ExecutionResult MixClient::call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff) dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff)
{ {
return call(_secret, _value, _dest, _data, _gas, _gasPrice, _blockNumber, false, _ff); return call(_from, _value, _dest, _data, _gas, _gasPrice, _blockNumber, false, _ff);
} }
dev::eth::ExecutionResult MixClient::create(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff) dev::eth::ExecutionResult MixClient::create(Address const& _from, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff)
{ {
(void)_blockNumber; (void)_blockNumber;
u256 n; u256 n;
Address a = toAddress(_secret);
State temp; State temp;
{ {
ReadGuard lr(x_state); ReadGuard lr(x_state);
temp = asOf(eth::PendingBlock); temp = asOf(eth::PendingBlock);
n = temp.transactionsFrom(a); n = temp.transactionsFrom(_from);
} }
Transaction t(_value, _gasPrice, _gas, _data, n, _secret); Transaction t(_value, _gasPrice, _gas, _data, n);
t.forceSender(_from);
if (_ff == FudgeFactor::Lenient) if (_ff == FudgeFactor::Lenient)
temp.addBalance(a, (u256)(t.gasRequired() * t.gasPrice() + t.value())); temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value()));
bytes rlp = t.rlp();
WriteGuard lw(x_state); //TODO: lock is required only for last execution state WriteGuard lw(x_state); //TODO: lock is required only for last execution state
executeTransaction(t, temp, true, false, _secret); executeTransaction(t, temp, true, false);
return lastExecution().result; return lastExecution().result;
} }

10
mix/MixClient.h

@ -55,12 +55,12 @@ public:
void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) override; void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) override;
Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice) override; Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice) override;
dev::eth::ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber = eth::PendingBlock, eth::FudgeFactor _ff = eth::FudgeFactor::Strict) override; dev::eth::ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber = eth::PendingBlock, eth::FudgeFactor _ff = eth::FudgeFactor::Strict) override;
dev::eth::ExecutionResult create(Secret _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * eth::szabo, eth::BlockNumber _blockNumber = eth::PendingBlock, eth::FudgeFactor _ff = eth::FudgeFactor::Strict) override; dev::eth::ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * eth::szabo, eth::BlockNumber _blockNumber = eth::PendingBlock, eth::FudgeFactor _ff = eth::FudgeFactor::Strict) override;
void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, bool _gasAuto); void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, bool _gasAuto);
Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto); Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto);
dev::eth::ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber, bool _gasAuto, eth::FudgeFactor _ff = eth::FudgeFactor::Strict); dev::eth::ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber, bool _gasAuto, eth::FudgeFactor _ff = eth::FudgeFactor::Strict);
void setAddress(Address _us) override; void setAddress(Address _us) override;
void startMining() override; void startMining() override;
@ -87,9 +87,9 @@ protected:
virtual void prepareForTransaction() override {} virtual void prepareForTransaction() override {}
private: private:
void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call, bool _gasAuto, dev::Secret const& _secret); void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call, bool _gasAuto);
void noteChanged(h256Set const& _filters); void noteChanged(h256Set const& _filters);
dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::Secret const& _secret, dev::u256 const& _gas); dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::u256 const& _gas);
eth::State m_state; eth::State m_state;
eth::State m_startState; eth::State m_startState;

Loading…
Cancel
Save