/* 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 . */ /** @file AccountHolder.cpp * @authors: * Christian R * Lefteris Karapetsas * @date 2015 */ #include "AccountHolder.h" #include #include #include #include #include using namespace std; using namespace dev; using namespace dev::eth; vector g_emptyQueue; static std::mt19937 g_randomNumberGenerator(time(0)); static Mutex x_rngMutex; vector
AccountHolder::allAccounts() const { vector
accounts; accounts += realAccounts(); for (auto const& pair: m_proxyAccounts) if (!isRealAccount(pair.first)) accounts.push_back(pair.first); return accounts; } Address const& AccountHolder::defaultTransactAccount() const { auto accounts = realAccounts(); if (accounts.empty()) return ZeroAddress; Address const* bestMatch = &*accounts.begin(); for (auto const& account: accounts) if (m_client()->balanceAt(account) > m_client()->balanceAt(*bestMatch)) bestMatch = &account; return *bestMatch; } int AccountHolder::addProxyAccount(const Address& _account) { Guard g(x_rngMutex); int id = std::uniform_int_distribution(1)(g_randomNumberGenerator); id = int(u256(FixedHash<32>(sha3(bytesConstRef((byte*)(&id), sizeof(int) / sizeof(byte)))))); if (isProxyAccount(_account) || id == 0 || m_transactionQueues.count(id)) return 0; m_proxyAccounts.insert(make_pair(_account, id)); m_transactionQueues[id].first = _account; return id; } bool AccountHolder::removeProxyAccount(unsigned _id) { if (!m_transactionQueues.count(_id)) return false; m_proxyAccounts.erase(m_transactionQueues[_id].first); m_transactionQueues.erase(_id); return true; } void AccountHolder::queueTransaction(TransactionSkeleton const& _transaction) { if (!m_proxyAccounts.count(_transaction.from)) return; int id = m_proxyAccounts[_transaction.from]; m_transactionQueues[id].second.push_back(_transaction); } vector const& AccountHolder::queuedTransactions(int _id) const { if (!m_transactionQueues.count(_id)) return g_emptyQueue; return m_transactionQueues.at(_id).second; } void AccountHolder::clearQueue(int _id) { if (m_transactionQueues.count(_id)) m_transactionQueues.at(_id).second.clear(); } AddressHash SimpleAccountHolder::realAccounts() const { return m_keyManager.accountsHash(); } void SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) { if (isRealAccount(_t.from)) m_client()->submitTransaction(m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); }), _t); else if (isProxyAccount(_t.from)) queueTransaction(_t); } void FixedAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) { if (isRealAccount(_t.from)) m_client()->submitTransaction(m_accounts[_t.from], _t); else if (isProxyAccount(_t.from)) queueTransaction(_t); }