From f4846c0f70ea86bf31d34c8ce84d7d3a6409a886 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Mon, 10 Apr 2017 11:15:48 +0300 Subject: [PATCH 1/3] Porting RPC from CLI part 2 & extended RPC frontier_list account_remove, representatives, wallet_change_seed & frontier_list --- rai/node/rpc.cpp | 186 +++++++++++++++++++++++++++++++++++++++++++++++ rai/node/rpc.hpp | 4 + 2 files changed, 190 insertions(+) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 9cc6e898..4722859f 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -349,6 +349,74 @@ void rai::rpc_handler::account_move () } } +void rai::rpc_handler::account_remove () +{ + if (rpc.config.enable_control) + { + std::string wallet_text (request.get ("wallet")); + std::string account_text (request.get ("account")); + rai::uint256_union wallet; + auto error (wallet.decode_hex (wallet_text)); + if (!error) + { + auto existing (node.wallets.items.find (wallet)); + if (existing != node.wallets.items.end ()) + { + auto wallet (existing->second); + rai::transaction transaction (node.store.environment, nullptr, true); + if (existing->second->store.valid_password (transaction)) + { + rai::account account_id; + auto error (account_id.decode_account (account_text)); + if (!error) + { + auto account (wallet->store.find (transaction, account_id)); + if (account != wallet->store.end ()) + { + wallet->store.erase (transaction, account_id); + auto removed (wallet->store.find (transaction, account_id)); + boost::property_tree::ptree response_l; + if (removed != wallet->store.end ()) + { + response_l.put ("removed", "0"); + } + else + { + response_l.put ("removed", "1"); + } + response (response_l); + } + else + { + error_response (response, "Account not found in wallet"); + } + } + else + { + error_response (response, "Bad account number"); + } + } + else + { + error_response (response, "Wallet locked"); + } + } + else + { + error_response (response, "Wallet not found"); + } + } + else + { + error_response (response, "Bad wallet number"); + } + } + else + { + error_response (response, "RPC control is disabled"); + } +} + void rai::rpc_handler::account_representative () { std::string account_text (request.get ("account")); @@ -628,6 +696,42 @@ void rai::rpc_handler::frontier_count () response (response_l); } +void rai::rpc_handler::frontier_list () +{ + std::string wallet_text (request.get ("wallet")); + rai::uint256_union wallet; + auto error (wallet.decode_hex (wallet_text)); + if (!error) + { + auto existing (node.wallets.items.find (wallet)); + if (existing != node.wallets.items.end ()) + { + boost::property_tree::ptree response_l; + boost::property_tree::ptree frontiers; + rai::transaction transaction (node.store.environment, nullptr, false); + for (auto i (existing->second->store.begin (transaction)), j (existing->second->store.end ()); i != j; ++i) + { + rai::account account(i->first); + auto latest (node.ledger.latest (transaction, account)); + if (!latest.is_zero ()) + { + frontiers.put (account.to_account (), latest.to_string ()); + } + } + response_l.add_child ("frontiers", frontiers); + response (response_l); + } + else + { + error_response (response, "Wallet not found"); + } + } + else + { + error_response (response, "Bad wallet number"); + } +} + namespace { class history_visitor : public rai::block_visitor @@ -1261,6 +1365,21 @@ void rai::rpc_handler::rai_to_raw () } } +void rai::rpc_handler::representatives () +{ + boost::property_tree::ptree response_l; + boost::property_tree::ptree representatives; + rai::transaction transaction (node.store.environment, nullptr, false); + for (auto i(node.store.representation_begin(transaction)), n(node.store.representation_end()); i != n; ++i) + { + rai::account account(i->first); + auto amount (node.store.representation_get(transaction, account)); + representatives.put (account.to_account (), amount.convert_to ()); + } + response_l.add_child ("representatives", representatives); + response (response_l); +} + void rai::rpc_handler::search_pending () { if (rpc.config.enable_control) @@ -1444,6 +1563,57 @@ void rai::rpc_handler::wallet_add () } } +void rai::rpc_handler::wallet_change_seed () +{ + if (rpc.config.enable_control) + { + std::string seed_text (request.get ("seed")); + std::string wallet_text (request.get ("wallet")); + rai::raw_key seed; + auto error (seed.data.decode_hex (seed_text)); + if (!error) + { + rai::uint256_union wallet; + auto error (wallet.decode_hex (wallet_text)); + if (!error) + { + auto existing (node.wallets.items.find (wallet)); + if (existing != node.wallets.items.end ()) + { + rai::transaction transaction (node.store.environment, nullptr, true); + if (existing->second->store.valid_password (transaction)) + { + existing->second->store.seed_set (transaction, seed); + boost::property_tree::ptree response_l; + response_l.put ("success", ""); + response (response_l); + } + else + { + error_response (response, "Wallet locked"); + } + } + else + { + error_response (response, "Wallet not found"); + } + } + else + { + error_response (response, "Bad wallet number"); + } + } + else + { + error_response (response, "Bad seed"); + } + } + else + { + error_response (response, "RPC control is disabled"); + } +} + void rai::rpc_handler::wallet_contains () { std::string account_text (request.get ("account")); @@ -1814,6 +1984,10 @@ void rai::rpc_handler::process_request () { account_move (); } + else if (action == "account_remove") + { + account_remove (); + } else if (action == "account_representative") { account_representative (); @@ -1858,6 +2032,10 @@ void rai::rpc_handler::process_request () { frontier_count (); } + else if (action == "frontier_list") + { + frontier_list (); + } else if (action == "history") { history (); @@ -1938,6 +2116,10 @@ void rai::rpc_handler::process_request () { rai_to_raw (); } + else if (action == "representatives") + { + representatives (); + } else if (action == "search_pending") { search_pending (); @@ -1962,6 +2144,10 @@ void rai::rpc_handler::process_request () { wallet_add (); } + else if (action == "wallet_change_seed") + { + wallet_change_seed (); + } else if (action == "wallet_contains") { wallet_contains (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index e3cf2a45..55b2d9fc 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -94,6 +94,7 @@ public: void account_key (); void account_list (); void account_move (); + void account_remove (); void account_representative (); void account_representative_set (); void account_weight (); @@ -105,6 +106,7 @@ public: void chain (); void frontiers (); void frontier_count (); + void frontier_list (); void history (); void keepalive (); void key_create (); @@ -125,12 +127,14 @@ public: void process (); void rai_to_raw (); void rai_from_raw (); + void representatives (); void search_pending (); void send (); void stop (); void validate_account_number (); void version (); void wallet_add (); + void wallet_change_seed (); void wallet_contains (); void wallet_create (); void wallet_destroy (); From 64cb6fdb2083dd8d01f9d00de42b7115ac1fc953 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Tue, 11 Apr 2017 22:07:45 +0300 Subject: [PATCH 2/3] Simplifying account_remove --- rai/node/rpc.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 4722859f..032797b7 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -374,16 +374,8 @@ void rai::rpc_handler::account_remove () if (account != wallet->store.end ()) { wallet->store.erase (transaction, account_id); - auto removed (wallet->store.find (transaction, account_id)); boost::property_tree::ptree response_l; - if (removed != wallet->store.end ()) - { - response_l.put ("removed", "0"); - } - else - { - response_l.put ("removed", "1"); - } + response_l.put ("removed", "1"); response (response_l); } else From 068b96626bf14818da7ea70f8e0c6b4f003dbe1c Mon Sep 17 00:00:00 2001 From: clemahieu Date: Sun, 16 Apr 2017 12:08:29 -0500 Subject: [PATCH 3/3] Adding tests for new RPCs and renaming frontiers_list to wallet_frontiers to better indicate what it's doing. --- rai/core_test/rpc.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++ rai/node/rpc.cpp | 86 ++++++++++++++++++------------------- rai/node/rpc.hpp | 2 +- rai/secure.cpp | 2 +- 4 files changed, 144 insertions(+), 45 deletions(-) diff --git a/rai/core_test/rpc.cpp b/rai/core_test/rpc.cpp index 9784e748..d8cd5cf2 100644 --- a/rai/core_test/rpc.cpp +++ b/rai/core_test/rpc.cpp @@ -1741,3 +1741,102 @@ TEST (rpc, bootstrap) ASSERT_GT (200, iterations); } } + +TEST (rpc, account_remove) +{ + rai::system system0 (24000, 1); + auto key1 (system0.wallet (0)->deterministic_insert ()); + ASSERT_TRUE (system0.wallet (0)->exists (key1)); + rai::rpc rpc (system0.service, *system0.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "account_remove"); + request.put ("wallet", system0.nodes [0]->wallets.items.begin ()->first.to_string ()); + request.put ("account", key1.to_account ()); + test_response response (request, rpc, system0.service); + while (response.status == 0) + { + system0.poll (); + } + ASSERT_FALSE (system0.wallet (0)->exists (key1)); +} + +TEST (rpc, representatives) +{ + rai::system system0 (24000, 1); + rai::rpc rpc (system0.service, *system0.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "representatives"); + test_response response (request, rpc, system0.service); + while (response.status == 0) + { + system0.poll (); + } + ASSERT_EQ (200, response.status); + auto & representatives_node (response.json.get_child ("representatives")); + std::vector representatives; + for (auto i (representatives_node.begin ()), n (representatives_node.end ()); i != n; ++i) + { + rai::account account; + ASSERT_FALSE (account.decode_account (i->first)); + representatives.push_back (account); + } + ASSERT_EQ (1, representatives.size ()); + ASSERT_EQ (rai::genesis_account, representatives [0]); +} + +TEST (rpc, wallet_change_seed) +{ + rai::system system0 (24000, 1); + rai::keypair seed; + { + rai::transaction transaction (system0.nodes [0]->store.environment, nullptr, false); + rai::raw_key seed0; + system0.wallet (0)->store.seed (seed0, transaction); + ASSERT_NE (seed.pub, seed0.data); + } + rai::rpc rpc (system0.service, *system0.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "wallet_change_seed"); + request.put ("wallet", system0.nodes [0]->wallets.items.begin ()->first.to_string ()); + request.put ("seed", seed.pub.to_string ()); + test_response response (request, rpc, system0.service); + while (response.status == 0) + { + system0.poll (); + } + ASSERT_EQ (200, response.status); + { + rai::transaction transaction (system0.nodes [0]->store.environment, nullptr, false); + rai::raw_key seed0; + system0.wallet (0)->store.seed (seed0, transaction); + ASSERT_EQ (seed.pub, seed0.data); + } +} + +TEST (rpc, wallet_frontiers) +{ + rai::system system0 (24000, 1); + system0.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + rai::rpc rpc (system0.service, *system0.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "wallet_frontiers"); + request.put ("wallet", system0.nodes [0]->wallets.items.begin ()->first.to_string ()); + test_response response (request, rpc, system0.service); + while (response.status == 0) + { + system0.poll (); + } + ASSERT_EQ (200, response.status); + auto & frontiers_node (response.json.get_child ("frontiers")); + std::vector frontiers; + for (auto i (frontiers_node.begin ()), n (frontiers_node.end ()); i != n; ++i) + { + frontiers.push_back (rai::block_hash (i->second.get (""))); + } + ASSERT_EQ (1, frontiers.size ()); + ASSERT_EQ (system0.nodes [0]->latest (rai::genesis_account), frontiers [0]); +} diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 2450deca..17abfa2c 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -391,7 +391,7 @@ void rai::rpc_handler::account_remove () auto wallet (existing->second); rai::transaction transaction (node.store.environment, nullptr, true); if (existing->second->store.valid_password (transaction)) - { + { rai::account account_id; auto error (account_id.decode_account (account_text)); if (!error) @@ -714,42 +714,6 @@ void rai::rpc_handler::frontier_count () response (response_l); } -void rai::rpc_handler::frontier_list () -{ - std::string wallet_text (request.get ("wallet")); - rai::uint256_union wallet; - auto error (wallet.decode_hex (wallet_text)); - if (!error) - { - auto existing (node.wallets.items.find (wallet)); - if (existing != node.wallets.items.end ()) - { - boost::property_tree::ptree response_l; - boost::property_tree::ptree frontiers; - rai::transaction transaction (node.store.environment, nullptr, false); - for (auto i (existing->second->store.begin (transaction)), j (existing->second->store.end ()); i != j; ++i) - { - rai::account account(i->first); - auto latest (node.ledger.latest (transaction, account)); - if (!latest.is_zero ()) - { - frontiers.put (account.to_account (), latest.to_string ()); - } - } - response_l.add_child ("frontiers", frontiers); - response (response_l); - } - else - { - error_response (response, "Wallet not found"); - } - } - else - { - error_response (response, "Bad wallet number"); - } -} - namespace { class history_visitor : public rai::block_visitor @@ -1388,10 +1352,10 @@ void rai::rpc_handler::representatives () boost::property_tree::ptree response_l; boost::property_tree::ptree representatives; rai::transaction transaction (node.store.environment, nullptr, false); - for (auto i(node.store.representation_begin(transaction)), n(node.store.representation_end()); i != n; ++i) + for (auto i (node.store.representation_begin (transaction)), n (node.store.representation_end ()); i != n; ++i) { rai::account account(i->first); - auto amount (node.store.representation_get(transaction, account)); + auto amount (node.store.representation_get (transaction, account)); representatives.put (account.to_account (), amount.convert_to ()); } response_l.add_child ("representatives", representatives); @@ -1745,6 +1709,42 @@ void rai::rpc_handler::wallet_export () } } +void rai::rpc_handler::wallet_frontiers () +{ + std::string wallet_text (request.get ("wallet")); + rai::uint256_union wallet; + auto error (wallet.decode_hex (wallet_text)); + if (!error) + { + auto existing (node.wallets.items.find (wallet)); + if (existing != node.wallets.items.end ()) + { + boost::property_tree::ptree response_l; + boost::property_tree::ptree frontiers; + rai::transaction transaction (node.store.environment, nullptr, false); + for (auto i (existing->second->store.begin (transaction)), n (existing->second->store.end ()); i != n; ++i) + { + rai::account account(i->first); + auto latest (node.ledger.latest (transaction, account)); + if (!latest.is_zero ()) + { + frontiers.put (account.to_account (), latest.to_string ()); + } + } + response_l.add_child ("frontiers", frontiers); + response (response_l); + } + else + { + error_response (response, "Wallet not found"); + } + } + else + { + error_response (response, "Bad wallet number"); + } +} + void rai::rpc_handler::wallet_key_valid () { std::string wallet_text (request.get ("wallet")); @@ -2054,10 +2054,6 @@ void rai::rpc_handler::process_request () { frontier_count (); } - else if (action == "frontier_list") - { - frontier_list (); - } else if (action == "history") { history (); @@ -2186,6 +2182,10 @@ void rai::rpc_handler::process_request () { wallet_export (); } + else if (action == "wallet_frontiers") + { + wallet_frontiers (); + } else if (action == "wallet_key_valid") { wallet_key_valid (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index cb38e36c..b8a2c23f 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -107,7 +107,6 @@ public: void chain (); void frontiers (); void frontier_count (); - void frontier_list (); void history (); void keepalive (); void key_create (); @@ -140,6 +139,7 @@ public: void wallet_create (); void wallet_destroy (); void wallet_export (); + void wallet_frontiers (); void wallet_key_valid (); void wallet_representative (); void wallet_representative_set (); diff --git a/rai/secure.cpp b/rai/secure.cpp index f350d7cd..7d7a7207 100644 --- a/rai/secure.cpp +++ b/rai/secure.cpp @@ -2299,7 +2299,7 @@ void rai::block_store::representation_put (MDB_txn * transaction_a, rai::account rai::store_iterator rai::block_store::representation_begin (MDB_txn * transaction_a) { - rai::store_iterator result(transaction_a, representation); + rai::store_iterator result (transaction_a, representation); return result; }