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. 6
      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
<< " -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
<< " --master <password> Give the master password for the key store." << endl
<< "Client transacting:" << 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
@ -546,6 +547,9 @@ int main(int argc, char** argv)
string farmURL = "http://127.0.0.1:8080";
unsigned farmRecheckPeriod = 500;
/// Wallet password stuff
string masterPassword;
string configFile = getDataDir() + "/config.rlp";
bytes b = contents(configFile);
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;
remotePort = (short)atoi(argv[++i]);
}
else if (arg == "--master" && i + 1 < argc)
masterPassword = argv[++i];
else if ((arg == "-I" || arg == "--import") && i + 1 < argc)
{
mode = OperationMode::Import;

1
libethereum/Client.h

@ -309,7 +309,6 @@ private:
ActivityReport m_report;
// TODO!!!!!! REPLACE WITH A PROPER X-THREAD ASIO SIGNAL SYSTEM (could just be condition variables)
std::condition_variable m_signalled;
Mutex x_signalled;
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
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;
try
{
State temp = asOf(_blockNumber);
Address a = toAddress(_secret);
u256 n = temp.transactionsFrom(a);
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret);
u256 n = temp.transactionsFrom(_from);
Transaction t(_value, _gasPrice, _gas, _dest, _data, n);
t.forceSender(_from);
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);
}
catch (...)
@ -95,19 +95,19 @@ ExecutionResult ClientBase::call(Secret _secret, u256 _value, Address _dest, byt
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;
try
{
State temp = asOf(_blockNumber);
Address a = toAddress(_secret);
u256 n = temp.transactionsFrom(a);
u256 n = temp.transactionsFrom(_from);
// 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)
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);
}
catch (...)

6
libethereum/ClientBase.h

@ -83,10 +83,12 @@ public:
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.
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.
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::countAt;

12
libethereum/Interface.h

@ -76,13 +76,17 @@ public:
virtual void flushTransactions() = 0;
/// 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;
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); }
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(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.
/// @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;
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); }
virtual ExecutionResult create(Address const& _from, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) = 0;
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.
virtual ImportResult injectTransaction(bytes const& _rlp) = 0;

2
libethereum/KeyManager.h

@ -37,7 +37,7 @@ struct KeyInfo
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: 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); }
/// 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.
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.
explicit Transaction(bytesConstRef _rlp, CheckTransaction _checkSig);
@ -132,6 +132,8 @@ public:
Address const& sender() const;
/// Like sender() but will never throw. @returns a null Address if the signature is invalid.
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.
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();
}

2
libethereumx/Ethereum.h

@ -75,7 +75,7 @@ public:
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);
bytes call(Address const& _from, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
// 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):
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)
{
m_ids.clear();
m_shhIds.clear();
for (auto i: _ids)
m_ids[i.pub()] = i.secret();
m_shhIds[i.pub()] = i.secret();
}
string WebThreeStubServerBase::web3_sha3(string const& _param1)
@ -353,7 +353,7 @@ string WebThreeStubServerBase::eth_gasPrice()
Json::Value WebThreeStubServerBase::eth_accounts()
{
Json::Value ret(Json::arrayValue);
for (auto const& i: m_accounts->getAllAccounts())
for (auto const& i: m_ethAccounts->getAllAccounts())
ret.append(toJS(i));
return ret;
}
@ -499,7 +499,7 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json)
TransactionSkeleton t = toTransaction(_json);
if (!t.from)
t.from = m_accounts->getDefaultTransactAccount();
t.from = m_ethAccounts->getDefaultTransactAccount();
if (t.creation)
ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));;
if (t.gasPrice == UndefinedU256)
@ -507,9 +507,9 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json)
if (t.gas == UndefinedU256)
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);
else if (m_accounts->isProxyAccount(t.from))
else if (m_ethAccounts->isProxyAccount(t.from))
authenticate(t, true);
return ret;
@ -528,7 +528,7 @@ string WebThreeStubServerBase::eth_signTransaction(Json::Value const& _json)
TransactionSkeleton t = toTransaction(_json);
if (!t.from)
t.from = m_accounts->getDefaultTransactAccount();
t.from = m_ethAccounts->getDefaultTransactAccount();
if (t.creation)
ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));;
if (t.gasPrice == UndefinedU256)
@ -536,9 +536,9 @@ string WebThreeStubServerBase::eth_signTransaction(Json::Value const& _json)
if (t.gas == UndefinedU256)
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);
else if (m_accounts->isProxyAccount(t.from))
else if (m_ethAccounts->isProxyAccount(t.from))
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));
@ -579,7 +579,7 @@ string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const&
{
TransactionSkeleton t = toTransaction(_json);
if (!t.from)
t.from = m_accounts->getDefaultTransactAccount();
t.from = m_ethAccounts->getDefaultTransactAccount();
// if (!m_accounts->isRealAccount(t.from))
// return ret;
if (t.gasPrice == UndefinedU256)
@ -587,7 +587,7 @@ string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const&
if (t.gas == UndefinedU256)
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 (...)
{
@ -879,7 +879,7 @@ string WebThreeStubServerBase::eth_register(string const& _address)
{
try
{
return toJS(m_accounts->addProxyAccount(jsToAddress(_address)));
return toJS(m_ethAccounts->addProxyAccount(jsToAddress(_address)));
}
catch (...)
{
@ -891,7 +891,7 @@ bool WebThreeStubServerBase::eth_unregister(string const& _accountId)
{
try
{
return m_accounts->removeProxyAccount(jsToInt(_accountId));
return m_ethAccounts->removeProxyAccount(jsToInt(_accountId));
}
catch (...)
{
@ -906,9 +906,9 @@ Json::Value WebThreeStubServerBase::eth_fetchQueuedTransactions(string const& _a
auto id = jsToInt(_accountId);
Json::Value ret(Json::arrayValue);
// 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));
m_accounts->clearQueue(id);
m_ethAccounts->clearQueue(id);
return ret;
}
catch (...)
@ -934,11 +934,11 @@ bool WebThreeStubServerBase::shh_post(Json::Value const& _json)
{
shh::Message m = toMessage(_json);
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.";
// TODO: insert validification hook here.
from = m_ids[m.from()];
from = m_shhIds[m.from()];
}
face()->inject(toSealed(_json, m, from));
@ -953,7 +953,7 @@ bool WebThreeStubServerBase::shh_post(Json::Value const& _json)
string WebThreeStubServerBase::shh_newIdentity()
{
KeyPair kp = KeyPair::create();
m_ids[kp.pub()] = kp.secret();
m_shhIds[kp.pub()] = kp.secret();
return toJS(kp.pub());
}
@ -961,7 +961,7 @@ bool WebThreeStubServerBase::shh_hasIdentity(string const& _identity)
{
try
{
return m_ids.count(jsToPublic(_identity)) > 0;
return m_shhIds.count(jsToPublic(_identity)) > 0;
}
catch (...)
{
@ -1021,7 +1021,7 @@ Json::Value WebThreeStubServerBase::shh_getFilterChanges(string const& _filterId
int id = jsToInt(_filterId);
auto pub = m_shhWatches[id];
if (!pub || m_ids.count(pub))
if (!pub || m_shhIds.count(pub))
for (h256 const& h: face()->checkWatch(id))
{
auto e = face()->envelope(h);
@ -1029,7 +1029,7 @@ Json::Value WebThreeStubServerBase::shh_getFilterChanges(string const& _filterId
if (pub)
{
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
m = e.open(face()->fullTopic(id));
@ -1054,7 +1054,7 @@ Json::Value WebThreeStubServerBase::shh_getMessages(string const& _filterId)
int id = jsToInt(_filterId);
auto pub = m_shhWatches[id];
if (!pub || m_ids.count(pub))
if (!pub || m_shhIds.count(pub))
for (h256 const& h: face()->watchMessages(id))
{
auto e = face()->envelope(h);
@ -1062,7 +1062,7 @@ Json::Value WebThreeStubServerBase::shh_getMessages(string const& _filterId)
if (pub)
{
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
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)
{
if (_toProxy)
m_accounts->queueTransaction(_t);
m_ethAccounts->queueTransaction(_t);
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
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)
{
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 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:
virtual void authenticate(dev::eth::TransactionSkeleton const& _t, bool _toProxy);
@ -147,9 +147,10 @@ protected:
virtual dev::WebThreeNetworkFace* network() = 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::shared_ptr<dev::AccountHolder> m_accounts;
};
} //namespace dev

48
mix/MixClient.cpp

@ -98,17 +98,20 @@ void MixClient::resetState(std::unordered_map<Address, Account> const& _accounts
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())
return Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce(), _secret);
ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce());
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();
// do debugging run first
@ -219,7 +222,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c
// execute on a state
if (!_call)
{
t = _gasAuto ? replaceGas(_t, _secret, d.gasUsed) : _t;
t = _gasAuto ? replaceGas(_t, d.gasUsed) : _t;
er =_state.execute(lastHashes, t);
if (t.isCreation() && _state.code(d.contractAddress).empty())
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);
u256 n = m_state.transactionsFrom(toAddress(_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)
@ -290,23 +293,23 @@ Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes cons
WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_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())));
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;
Address a = toAddress(_secret);
State temp = asOf(eth::PendingBlock);
u256 n = temp.transactionsFrom(a);
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret);
u256 n = temp.transactionsFrom(_from);
Transaction t(_value, _gasPrice, _gas, _dest, _data, n);
t.forceSender(_from);
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
executeTransaction(t, temp, true, _gasAuto, _secret);
executeTransaction(t, temp, true, _gasAuto);
return lastExecution().result;
}
@ -320,28 +323,27 @@ Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes cons
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;
u256 n;
Address a = toAddress(_secret);
State temp;
{
ReadGuard lr(x_state);
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)
temp.addBalance(a, (u256)(t.gasRequired() * t.gasPrice() + t.value()));
bytes rlp = t.rlp();
temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value()));
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;
}

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;
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 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 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(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);
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 startMining() override;
@ -87,9 +87,9 @@ protected:
virtual void prepareForTransaction() override {}
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);
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_startState;

Loading…
Cancel
Save