Browse Source

JSON-RPC now interprets ICAP addresses and throws when hex addresses are bad.

ICAP accepts 35-character "invalid IBAN" addresses.
Console quits with quit.
Many UI tweaks in eth.
cl-refactor
Gav Wood 10 years ago
parent
commit
a8982ade28
  1. 2
      alethzero/MainWin.cpp
  2. 112
      eth/main.cpp
  3. 2
      ethkey/KeyAux.h
  4. 21
      libethcore/CommonJS.cpp
  5. 5
      libethcore/CommonJS.h
  6. 17
      libethcore/ICAP.cpp
  7. 5
      libethcore/ICAP.h
  8. 6
      libjsconsole/JSConsole.h
  9. 6
      libp2p/Common.h
  10. 1
      libweb3jsonrpc/JsonHelper.cpp
  11. 6
      libweb3jsonrpc/JsonHelper.h
  12. 3
      libweb3jsonrpc/WebThreeStubServer.cpp

2
alethzero/MainWin.cpp

@ -183,7 +183,7 @@ Main::Main(QWidget* _parent):
QMessageBox::warning(nullptr, "Try again", "You entered two different passwords - please enter the same password twice.", QMessageBox::Ok);
}
m_keyManager.create(password.toStdString());
m_keyManager.import(Secret::random(), "Default identity");
m_keyManager.import(ICAP::createDirect(), "Default identity");
}
#if ETH_DEBUG

112
eth/main.cpp

@ -38,7 +38,7 @@
#include <libethereum/All.h>
#include <libethereum/BlockChainSync.h>
#include <libethcore/KeyManager.h>
#include <libethcore/ICAP.h>
#include <libwebthree/WebThree.h>
#if ETH_JSCONSOLE || !ETH_TRUE
#include <libjsconsole/JSLocalConsole.h>
@ -68,58 +68,17 @@ using dev::eth::Instruction;
static std::atomic<bool> g_silence = {false};
void interactiveHelp()
{
cout
<< "Commands:" << endl
<< " netstart <port> Starts the network subsystem on a specific port." << endl
<< " netstop Stops the network subsystem." << endl
<< " connect <addr> <port> Connects to a specific peer." << endl
<< " verbosity (<level>) Gets or sets verbosity level." << endl
<< " minestart Starts mining." << endl
<< " minestop Stops mining." << endl
<< " mineforce <enable> Forces mining, even when there are no transactions." << endl
<< " block Gives the current block height." << endl
<< " blockhashfromnumber <number> Gives the block hash with the givne number." << endl
<< " numberfromblockhash <hash> Gives the block number with the given hash." << endl
<< " blockqueue Gives the current block queue status." << endl
<< " findblock <hash> Searches for the block in the blockchain and blockqueue." << endl
<< " firstunknown Gives the first unknown block from the blockqueue." << endl
<< " retryunknown retries to import all unknown blocks from the blockqueue." << endl
<< " accounts Gives information on all owned accounts (balances, mining beneficiary and default signer)." << endl
<< " newaccount <name> Creates a new account with the given name." << endl
<< " transact Execute a given transaction." << endl
<< " transactnonce Execute a given transaction with a specified nonce." << endl
<< " txcreate Execute a given contract creation transaction." << endl
<< " send Execute a given transaction with current secret." << endl
<< " contract Create a new contract with current secret." << endl
<< " peers List the peers that are connected" << endl
#if ETH_FATDB || !ETH_TRUE
<< " listaccounts List the accounts on the network." << endl
<< " listcontracts List the contracts on the network." << endl
<< " balanceat <address> Gives the balance of the given account." << endl
<< " balanceatblock <address> <blocknumber> Gives the balance of the given account." << endl
<< " storageat <address> Gives the storage of the given account." << endl
<< " storageatblock <address> <blocknumber> Gives the storahe of the given account at a given blocknumber." << endl
<< " codeat <address> Gives the code of the given account." << endl
#endif
<< " setsigningkey <addr> Set the address with which to sign transactions." << endl
<< " setaddress <addr> Set the coinbase (mining payout) address." << endl
<< " exportconfig <path> Export the config (.RLP) to the path provided." << endl
<< " importconfig <path> Import the config (.RLP) from the path provided." << endl
<< " inspect <contract> Dumps a contract to <APPDATA>/<contract>.evm." << endl
<< " reprocess <block> Reprocess a given block." << endl
<< " dumptrace <block> <index> <filename> <format> Dumps a transaction trace" << endl << "to <filename>. <format> should be one of pretty, standard, standard+." << endl
<< " dumpreceipt <block> <index> Dumps a transation receipt." << endl
<< " hashrate Print the current hashrate in hashes per second if the client is mining." << endl
<< " exit Exits the application." << endl;
}
void help()
{
cout
<< "Usage eth [OPTIONS]" << endl
<< "Options:" << endl << endl
<< "Operating mode (default is non-interactive node):" << endl
#if ETH_JSCONSOLE || !ETH_TRUE
<< " console Enter interactive console mode (default: non-interactive)." << endl
<< " import <file> Import file as a concatenated series of blocks." << endl
<< " export <file> Export file as a concatenated series of blocks." << endl
#endif
<< "Client mode (default):" << endl
<< " --olympic Use the Olympic (0.9) protocol." << endl
<< " --frontier Use the Frontier (1.0) protocol." << endl
@ -127,9 +86,6 @@ void help()
<< " --genesis-json <file> Import the genesis block information from the given json file." << endl
<< endl
<< " -o,--mode <full/peer> Start a full node or a peer node (default: full)." << endl
#if ETH_JSCONSOLE || !ETH_TRUE
<< " -i,--interactive Enter interactive mode (default: non-interactive)." << endl
#endif
<< endl
#if ETH_JSONRPC || !ETH_TRUE
<< " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl
@ -169,7 +125,8 @@ void help()
<< endl
<< "Client networking:" << endl
<< " --client-name <name> Add a name to your client's version string (default: blank)." << endl
<< " -b,--bootstrap Connect to the default Ethereum peerserver." << endl
<< " --bootstrap Connect to the default Ethereum peerservers (default unless --no-discovery used)." << endl
<< " --no-bootstrap Do not connect to the default Ethereum peerservers (default only when --no-discovery is used)." << endl
<< " -x,--peers <number> Attempt to connect to given number of peers (default: 11)." << endl
<< " --peer-stretch <number> Accepted connection multiplier (default: 7)." << endl
@ -187,7 +144,7 @@ void help()
// << " trusted Keep connected at all times." << endl
// << " --trust-peers <filename> Text list of publickeys." << endl
<< " --no-discovery Disable Node discovery." << endl
<< " --no-discovery Disable Node discovery, implies --no-bootstrap." << endl
<< " --pin Only accept or connect to trusted peers." << endl
<< " --hermit Equivalent to --no-discovery --pin." << endl
<< " --sociable Forces discovery and no pinning." << endl
@ -198,9 +155,8 @@ void help()
<< " --structured-logging Enable structured logging (default output to stdout)." << endl
<< " --structured-logging-format <format> Set the structured logging time format." << endl
<< " --structured-logging-url <URL> Set the structured logging destination (currently only file:// supported)." << endl
<< endl
<< "Import/export modes:" << endl
<< " -I,--import <file> Import file as a concatenated series of blocks and exit." << endl
<< " -E,--export <file> Export file as a concatenated series of blocks and exit." << endl
<< " --from <n> Export only from block n; n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl
<< " --to <n> Export only to block n (inclusive); n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl
<< " --only <n> Equivalent to --export-from n --export-to n." << endl
@ -310,13 +266,17 @@ void stopMiningAfterXBlocks(eth::Client* _c, unsigned _start, unsigned& io_minin
this_thread::sleep_for(chrono::milliseconds(100));
}
void interactiveMode(eth::Client*, std::shared_ptr<eth::TrivialGasPricer>, WebThreeDirect&, KeyManager&, string&, string&, function<string(string const&)>, function<string(Address const&)>, NetworkPreferences, Address, Address, TransactionPriority) {}
int main(int argc, char** argv)
{
// Init defaults
Defaults::get();
#if ETH_DEBUG
g_logVerbosity = 4;
#else
g_logVerbosity = 1;
#endif
/// Operating mode.
OperationMode mode = OperationMode::Node;
string dbPath;
@ -359,7 +319,7 @@ int main(int argc, char** argv)
HostPeerPreferences hprefs;
unsigned peers = hprefs.idealPeerCount;
unsigned peerStretch = hprefs.stretchPeerCount;
bool bootstrap = false;
bool bootstrap = true;
bool disableDiscovery = false;
bool pinning = false;
bool enableDiscovery = false;
@ -444,14 +404,14 @@ int main(int argc, char** argv)
passwordsToNote.push_back(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" || arg == "import") && i + 1 < argc)
{
mode = OperationMode::Import;
filename = argv[++i];
}
else if (arg == "--dont-check")
safeImport = true;
else if ((arg == "-E" || arg == "--export") && i + 1 < argc)
else if ((arg == "-E" || arg == "--export" || arg == "export") && i + 1 < argc)
{
mode = OperationMode::Export;
filename = argv[++i];
@ -685,8 +645,13 @@ int main(int argc, char** argv)
}
else if (arg == "-b" || arg == "--bootstrap")
bootstrap = true;
else if (arg == "--no-bootstrap")
bootstrap = false;
else if (arg == "--no-discovery")
{
disableDiscovery = true;
bootstrap = false;
}
else if (arg == "--pin")
pinning = true;
else if (arg == "--hermit")
@ -708,7 +673,7 @@ int main(int argc, char** argv)
jsonAdmin = argv[++i];
#endif
#if ETH_JSCONSOLE || !ETH_TRUE
else if (arg == "-i" || arg == "--interactive" || arg == "--console")
else if (arg == "-i" || arg == "--interactive" || arg == "--console" || arg == "console")
useConsole = true;
#endif
else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc)
@ -777,7 +742,7 @@ int main(int argc, char** argv)
if (c_network == eth::Network::Olympic)
cout << "Welcome to Olympic!" << endl;
else if (c_network == eth::Network::Frontier)
cout << "Welcome to the " EthMaroonBold "Frontier" EthReset "!" << endl;
cout << "Beware. You're entering the " EthMaroonBold "Frontier" EthReset "!" << endl;
}
m.execute();
@ -993,7 +958,7 @@ int main(int argc, char** argv)
if (keyManager.accounts().empty())
{
h128 uuid = keyManager.import(Secret::random(), "Default key");
h128 uuid = keyManager.import(ICAP::createDirect(), "Default key");
if (!beneficiary)
beneficiary = keyManager.address(uuid);
if (!signingKey)
@ -1019,8 +984,14 @@ int main(int argc, char** argv)
c->setNetworkId(networkId);
}
cout << "Transaction Signer: " << signingKey << endl;
cout << "Mining Benefactor: " << beneficiary << endl;
auto renderFullAddress = [&](Address const& _a) -> std::string
{
return ICAP(_a).encoded() + " (" + toUUID(keyManager.uuid(_a)) + " - " + toHex(_a.ref().cropped(0, 4)) + ")";
};
cout << "Transaction Signer: " << renderFullAddress(signingKey) << endl;
cout << "Mining Beneficiary: " << renderFullAddress(beneficiary) << endl;
cout << "Foundation: " << renderFullAddress(Address("de0b295669a9fd93d5f28d9ec85e40f4cb697bae")) << endl;
if (bootstrap || !remoteHost.empty() || disableDiscovery)
{
@ -1028,7 +999,7 @@ int main(int argc, char** argv)
cout << "Node ID: " << web3.enode() << endl;
}
else
cout << "Networking disabled. To start, use netstart or pass -b or a remote host." << endl;
cout << "Networking disabled. To start, use netstart or pass --bootstrap or a remote host." << endl;
if (useConsole && jsonRPCURL == -1)
jsonRPCURL = SensibleHttpPort;
@ -1061,9 +1032,7 @@ int main(int argc, char** argv)
signal(SIGTERM, &sighandler);
signal(SIGINT, &sighandler);
if (interactive)
interactiveMode(c, gasPricer, web3, keyManager, logbuf, additional, getPassword, getAccountPassword, netPrefs, beneficiary, signingKey, priority);
else if (c)
if (c)
{
unsigned n = c->blockChain().details().number;
if (mining)
@ -1075,11 +1044,8 @@ int main(int argc, char** argv)
shared_ptr<dev::WebThreeStubServer> rpcServer = make_shared<dev::WebThreeStubServer>(*console.connector(), web3, make_shared<SimpleAccountHolder>([&](){ return web3.ethereum(); }, getAccountPassword, keyManager), vector<KeyPair>(), keyManager, *gasPricer);
string sessionKey = rpcServer->newSession(SessionPermissions{{Privilege::Admin}});
console.eval("web3.admin.setSessionKey('" + sessionKey + "')");
while (!g_exit)
{
console.readExpression();
while (console.readExpression())
stopMiningAfterXBlocks(c, n, mining);
}
rpcServer->StopListening();
#endif
}

2
ethkey/KeyAux.h

@ -505,7 +505,7 @@ public:
if (Address a = wallet.address(u))
{
cout << toUUID(u) << " " << a.abridged();
cout << " (Not ICAP) ";
cout << " " << ICAP(a).encoded();
cout << " " << wallet.accountName(a) << endl;
}
for (auto const& u: bare)

21
libethcore/CommonJS.cpp

@ -22,16 +22,27 @@
*/
#include "CommonJS.h"
#include "ICAP.h"
namespace dev
{
Address toAddress(std::string const& _sn)
Address jsToAddress(std::string const& _s)
{
if (_sn.size() == 40)
return Address(fromHex(_sn));
else
return Address();
try
{
eth::ICAP i = eth::ICAP::decoded(_s);
return i.direct();
}
catch (eth::InvalidICAP&) {}
try
{
auto b = fromHex(_s.substr(0, 2) == "0x" ? _s.substr(2) : _s, WhenError::Throw);
if (b.size() == 20)
return Address(b);
}
catch (BadHexCharacter&) {}
BOOST_THROW_EXCEPTION(InvalidAddress());
}
std::string prettyU256(u256 _n, bool _abridged)

5
libethcore/CommonJS.h

@ -33,8 +33,7 @@
namespace dev
{
/// Strictly convert unprefixed hex string string to Address (h160). @returns empty address if (_a.size != 40).
Address toAddress(std::string const& _a);
DEV_SIMPLE_EXCEPTION(InvalidAddress);
/// Leniently convert string to Public (h512). Accepts integers, "0x" prefixing, non-exact length.
inline Public jsToPublic(std::string const& _s) { return jsToFixed<sizeof(dev::Public)>(_s); }
@ -43,7 +42,7 @@ inline Public jsToPublic(std::string const& _s) { return jsToFixed<sizeof(dev::P
inline Secret jsToSecret(std::string const& _s) { h256 d = jsToFixed<sizeof(dev::Secret)>(_s); Secret ret(d); d.ref().cleanse(); return ret; }
/// Leniently convert string to Address (h160). Accepts integers, "0x" prefixing, non-exact length.
inline Address jsToAddress(std::string const& _s) { return jsToFixed<sizeof(dev::Address)>(_s); }
Address jsToAddress(std::string const& _s);
/// Convert u256 into user-readable string. Returns int/hex value of 64 bits int, hex of 160 bits FixedHash. As a fallback try to handle input as h256.
std::string prettyU256(u256 _n, bool _abridged = true);

17
libethcore/ICAP.cpp

@ -64,6 +64,17 @@ std::pair<string, string> ICAP::fromIBAN(std::string _iban)
return make_pair(c, d);
}
Secret ICAP::createDirect()
{
Secret ret;
while (true)
{
ret = Secret::random();
if (!toAddress(ret)[0])
return ret;
}
}
ICAP ICAP::decoded(std::string const& _encoded)
{
ICAP ret;
@ -72,7 +83,7 @@ ICAP ICAP::decoded(std::string const& _encoded)
std::tie(country, data) = fromIBAN(_encoded);
if (country != "XE")
BOOST_THROW_EXCEPTION(InvalidICAP());
if (data.size() == 30)
if (data.size() == 30 || data.size() == 31)
{
ret.m_type = Direct;
// Direct ICAP
@ -100,10 +111,8 @@ std::string ICAP::encoded() const
{
if (m_type == Direct)
{
if (!!m_direct[0])
BOOST_THROW_EXCEPTION(InvalidICAP());
std::string d = toBase36<Address::size>(m_direct);
while (d.size() < 30)
while (d.size() < 30) // always 34, sometimes 35.
d = "0" + d;
return iban("XE", d);
}

5
libethcore/ICAP.h

@ -36,7 +36,7 @@ namespace dev
namespace eth
{
struct InvalidICAP: virtual public dev::Exception {};
DEV_SIMPLE_EXCEPTION(InvalidICAP);
/**
* @brief Encapsulation of an ICAP address.
@ -62,6 +62,9 @@ public:
Indirect
};
/// Create a direct address for ICAP.
static Secret createDirect();
/// @returns IBAN encoding of client and data.
static std::string iban(std::string _c, std::string _d);
/// @returns Client and data from given IBAN address.

6
libjsconsole/JSConsole.h

@ -41,7 +41,7 @@ public:
JSConsole(): m_engine(Engine()), m_printer(Printer(m_engine)) {}
~JSConsole() {}
void readExpression() const
bool readExpression() const
{
std::string cmd = "";
g_logPost = [](std::string const& a, char const*)
@ -83,6 +83,9 @@ public:
}
} while (openBrackets > 0);
if (cmd == "quit")
return false;
if (!isEmpty)
{
#if ETH_READLINE
@ -92,6 +95,7 @@ public:
std::string result = m_printer.prettyPrint(value).cstr();
std::cout << result << std::endl;
}
return true;
}
void eval(std::string const& _expression) { m_engine.eval(_expression.c_str()); }

6
libp2p/Common.h

@ -78,9 +78,9 @@ struct InvalidPublicIPAddress: virtual dev::Exception {};
struct InvalidHostIPAddress: virtual dev::Exception {};
struct NetWarn: public LogChannel { static const char* name(); static const int verbosity = 0; };
struct NetNote: public LogChannel { static const char* name(); static const int verbosity = 1; };
struct NetImpolite: public LogChannel { static const char* name(); static const int verbosity = 2; };
struct NetMessageSummary: public LogChannel { static const char* name(); static const int verbosity = 3; };
struct NetNote: public LogChannel { static const char* name(); static const int verbosity = 2; };
struct NetImpolite: public LogChannel { static const char* name(); static const int verbosity = 3; };
struct NetMessageSummary: public LogChannel { static const char* name(); static const int verbosity = 4; };
struct NetConnect: public LogChannel { static const char* name(); static const int verbosity = 10; };
struct NetMessageDetail: public LogChannel { static const char* name(); static const int verbosity = 5; };
struct NetTriviaSummary: public LogChannel { static const char* name(); static const int verbosity = 10; };

1
libweb3jsonrpc/JsonHelper.cpp

@ -27,6 +27,7 @@
#include <libethereum/Client.h>
#include <libwebthree/WebThree.h>
#include <libethcore/CommonJS.h>
#include <libethcore/ICAP.h>
#include <libwhisper/Message.h>
#include <libwhisper/WhisperHost.h>
using namespace std;

6
libweb3jsonrpc/JsonHelper.h

@ -69,6 +69,12 @@ TransactionSkeleton toTransactionSkeleton(Json::Value const& _json);
LogFilter toLogFilter(Json::Value const& _json);
LogFilter toLogFilter(Json::Value const& _json, Interface const& _client); // commented to avoid warning. Uncomment once in use @ PoC-7.
class AddressResolver
{
public:
static Address fromJS(std::string const& _address);
};
template <class BlockInfoSub>
Json::Value toJson(BlockHeaderPolished<BlockInfoSub> const& _bh)
{

3
libweb3jsonrpc/WebThreeStubServer.cpp

@ -28,6 +28,7 @@
#include <libdevcore/FileSystem.h>
#include <libdevcore/CommonJS.h>
#include <libethcore/KeyManager.h>
#include <libethcore/ICAP.h>
#include <libethereum/Executive.h>
#include <libethereum/Block.h>
#include <libwebthree/WebThree.h>
@ -189,7 +190,7 @@ Json::Value WebThreeStubServer::admin_eth_newAccount(Json::Value const& _info, s
if (!_info.isMember("name"))
throw jsonrpc::JsonRpcException("No member found: name");
string name = _info["name"].asString();
auto s = Secret::random();
auto s = ICAP::createDirect();
h128 uuid;
if (_info.isMember("password"))
{

Loading…
Cancel
Save