AccountHolder.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file AccountHolder.h
  15. * @authors:
  16. * Christian R <c@ethdev.com>
  17. * Lefteris Karapetsas <lefteris@ethdev.com>
  18. * @date 2015
  19. */
  20. #pragma once
  21. #include <functional>
  22. #include <algorithm>
  23. #include <vector>
  24. #include <map>
  25. #include <chrono>
  26. #include <libdevcrypto/Common.h>
  27. #include <libethcore/CommonJS.h>
  28. #include <libethereum/Transaction.h>
  29. namespace dev
  30. {
  31. namespace eth
  32. {
  33. class KeyManager;
  34. class Interface;
  35. enum class TransactionRepercussion
  36. {
  37. Unknown,
  38. UnknownAccount,
  39. Locked,
  40. Refused,
  41. ProxySuccess,
  42. Success
  43. };
  44. struct TransactionNotification
  45. {
  46. TransactionRepercussion r;
  47. h256 hash;
  48. Address created;
  49. };
  50. /**
  51. * Manages real accounts (where we know the secret key) and proxy accounts (where transactions
  52. * to be sent from these accounts are forwarded to a proxy on the other side).
  53. */
  54. class AccountHolder
  55. {
  56. public:
  57. explicit AccountHolder(std::function<Interface*()> const& _client): m_client(_client) {}
  58. virtual AddressHash realAccounts() const = 0;
  59. // use m_web3's submitTransaction
  60. // or use AccountHolder::queueTransaction(_t) to accept
  61. virtual TransactionNotification authenticate(dev::eth::TransactionSkeleton const& _t) = 0;
  62. Addresses allAccounts() const;
  63. bool isRealAccount(Address const& _account) const { return realAccounts().count(_account) > 0; }
  64. bool isProxyAccount(Address const& _account) const { return m_proxyAccounts.count(_account) > 0; }
  65. Address const& defaultTransactAccount() const;
  66. /// Automatically authenticate all transactions for the given account for the next @a _duration
  67. /// seconds. Decrypt the key with @a _password if needed. @returns true on success.
  68. /// Only works for direct accounts.
  69. virtual bool unlockAccount(
  70. Address const& /*_account*/,
  71. std::string const& /*_password*/,
  72. unsigned /*_duration*/
  73. )
  74. {
  75. return false;
  76. }
  77. int addProxyAccount(Address const& _account);
  78. bool removeProxyAccount(unsigned _id);
  79. void queueTransaction(eth::TransactionSkeleton const& _transaction);
  80. std::vector<eth::TransactionSkeleton> const& queuedTransactions(int _id) const;
  81. void clearQueue(int _id);
  82. protected:
  83. std::function<Interface*()> m_client;
  84. private:
  85. using TransactionQueue = std::vector<eth::TransactionSkeleton>;
  86. std::unordered_map<Address, int> m_proxyAccounts;
  87. std::unordered_map<int, std::pair<Address, TransactionQueue>> m_transactionQueues;
  88. };
  89. class SimpleAccountHolder: public AccountHolder
  90. {
  91. public:
  92. SimpleAccountHolder(std::function<Interface*()> const& _client, std::function<std::string(Address)> const& _getPassword, KeyManager& _keyman, std::function<bool(TransactionSkeleton const&, bool)> _getAuthorisation = std::function<bool(TransactionSkeleton const&, bool)>()):
  93. AccountHolder(_client),
  94. m_getPassword(_getPassword),
  95. m_getAuthorisation(_getAuthorisation),
  96. m_keyManager(_keyman)
  97. {}
  98. AddressHash realAccounts() const override;
  99. TransactionNotification authenticate(dev::eth::TransactionSkeleton const& _t) override;
  100. virtual bool unlockAccount(Address const& _account, std::string const& _password, unsigned _duration) override;
  101. private:
  102. std::function<std::string(Address)> m_getPassword;
  103. std::function<bool(TransactionSkeleton const&, bool)> m_getAuthorisation;
  104. KeyManager& m_keyManager;
  105. std::map<Address, std::pair<std::chrono::steady_clock::time_point, unsigned>> m_unlockedAccounts;
  106. };
  107. class FixedAccountHolder: public AccountHolder
  108. {
  109. public:
  110. FixedAccountHolder(std::function<Interface*()> const& _client, std::vector<dev::KeyPair> const& _accounts):
  111. AccountHolder(_client)
  112. {
  113. setAccounts(_accounts);
  114. }
  115. void setAccounts(std::vector<dev::KeyPair> const& _accounts)
  116. {
  117. for (auto const& i: _accounts)
  118. m_accounts[i.address()] = i.secret();
  119. }
  120. dev::AddressHash realAccounts() const override
  121. {
  122. dev::AddressHash ret;
  123. for (auto const& i: m_accounts)
  124. ret.insert(i.first);
  125. return ret;
  126. }
  127. // use m_web3's submitTransaction
  128. // or use AccountHolder::queueTransaction(_t) to accept
  129. TransactionNotification authenticate(dev::eth::TransactionSkeleton const& _t) override;
  130. private:
  131. std::unordered_map<dev::Address, dev::Secret> m_accounts;
  132. };
  133. }
  134. }