From 776a328f2f1545016efc1b11bc08704c4b5d3d58 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Mon, 17 Jul 2017 17:45:36 +0300 Subject: [PATCH 01/19] RPC pending_threshold & accounts_pending_threshold --- rai/node/rpc.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ rai/node/rpc.hpp | 2 + 2 files changed, 99 insertions(+) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 7c30735c..bf233c36 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -626,6 +626,50 @@ void rai::rpc_handler::accounts_pending () } } +void rai::rpc_handler::accounts_pending_threshold () +{ + std::string threshold_text (request.get ("threshold")); + rai::uint128_union threshold; + if (!threshold.decode_dec (threshold_text)) + { + boost::property_tree::ptree response_l; + boost::property_tree::ptree pending; + rai::transaction transaction (node.store.environment, nullptr, false); + for (auto &accounts : request.get_child("accounts")) + { + std::string account_text = accounts.second.data (); + rai::uint256_union account; + if (!account.decode_account (account_text)) + { + boost::property_tree::ptree peers_l; + rai::account end (account.number () + 1); + for (auto i (node.store.pending_begin (transaction, rai::pending_key (account, 0))), n (node.store.pending_begin (transaction, rai::pending_key (end, 0))); i != n; ++i) + { + rai::pending_key key (i->first); + rai::pending_info info (i->second); + if (info.amount.number () >= threshold.number ()) + { + boost::property_tree::ptree entry; + entry.put (key.hash.to_string (), info.amount.number ().convert_to ()); + peers_l.push_back (std::make_pair ("", entry)); + } + } + pending.add_child (account.to_account (), peers_l); + } + else + { + error_response (response, "Bad account number"); + } + } + response_l.add_child ("blocks", pending); + response (response_l); + } + else + { + error_response (response, "Bad threshold number"); + } +} + void rai::rpc_handler::available_supply () { auto genesis_balance (node.balance (rai::genesis_account)); // Cold storage genesis @@ -1337,6 +1381,51 @@ void rai::rpc_handler::pending () response_l.add_child ("blocks", peers_l); response (response_l); } + else + { + error_response (response, "Invalid count"); + } + } + else + { + error_response (response, "Bad account number"); + } +} + +void rai::rpc_handler::pending_threshold () +{ + std::string account_text (request.get ("account")); + rai::account account; + if (!account.decode_account(account_text)) + { + std::string threshold_text (request.get ("threshold")); + rai::uint128_union threshold; + if (!threshold.decode_dec (threshold_text)) + { + boost::property_tree::ptree response_l; + boost::property_tree::ptree peers_l; + { + rai::transaction transaction (node.store.environment, nullptr, false); + rai::account end (account.number () + 1); + for (auto i (node.store.pending_begin (transaction, rai::pending_key (account, 0))), n (node.store.pending_begin (transaction, rai::pending_key (end, 0))); i != n; ++i) + { + rai::pending_key key (i->first); + rai::pending_info info (i->second); + if (info.amount.number () >= threshold.number ()) + { + boost::property_tree::ptree entry; + entry.put (key.hash.to_string (), info.amount.number ().convert_to ()); + peers_l.push_back (std::make_pair ("", entry)); + } + } + } + response_l.add_child ("blocks", peers_l); + response (response_l); + } + else + { + error_response (response, "Bad threshold number"); + } } else { @@ -2522,6 +2611,10 @@ void rai::rpc_handler::process_request () { accounts_pending (); } + else if (action == "accounts_pending_threshold") + { + accounts_pending_threshold (); + } else if (action == "available_supply") { available_supply (); @@ -2638,6 +2731,10 @@ void rai::rpc_handler::process_request () { pending (); } + else if (action == "pending_threshold") + { + pending_threshold (); + } else if (action == "process") { process (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index 7cc8d98d..c03eef68 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -104,6 +104,7 @@ public: void accounts_balances (); void accounts_frontiers (); void accounts_pending (); + void accounts_pending_threshold (); void available_supply (); void block (); void blocks (); @@ -132,6 +133,7 @@ public: void payment_wait (); void peers (); void pending (); + void pending_threshold (); void process (); void rai_to_raw (); void rai_from_raw (); From f0559da2330a15c5e0c39175c10d4f8388e20272 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Mon, 17 Jul 2017 19:34:11 +0300 Subject: [PATCH 02/19] RPC wallet_pending & wallet_pending_threshold --- rai/node/rpc.cpp | 118 +++++++++++++++++++++++++++++++++++++++++++++++ rai/node/rpc.hpp | 2 + 2 files changed, 120 insertions(+) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index bf233c36..54f08387 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -2309,6 +2309,116 @@ void rai::rpc_handler::wallet_key_valid () } } +void rai::rpc_handler::wallet_pending () +{ + 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 ()) + { + std::string count_text (request.get ("count")); + uint64_t count; + if (!decode_unsigned (count_text, count)) + { + boost::property_tree::ptree response_l; + boost::property_tree::ptree pending; + 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); + boost::property_tree::ptree peers_l; + rai::account end (account.number () + 1); + for (auto ii (node.store.pending_begin (transaction, rai::pending_key (account, 0))), nn (node.store.pending_begin (transaction, rai::pending_key (end, 0))); ii != nn && peers_l.size ()< count; ++ii) + { + rai::pending_key key (ii->first); + boost::property_tree::ptree entry; + entry.put ("", key.hash.to_string ()); + peers_l.push_back (std::make_pair ("", entry)); + } + if (!peers_l.empty ()) + { + pending.add_child (account.to_account (), peers_l); + } + } + response_l.add_child ("pending", pending); + response (response_l); + } + else + { + error_response (response, "Invalid count"); + } + } + else + { + error_response (response, "Wallet not found"); + } + } + else + { + error_response (response, "Bad wallet number"); + } +} + +void rai::rpc_handler::wallet_pending_threshold () +{ + 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 ()) + { + std::string threshold_text (request.get ("threshold")); + rai::uint128_union threshold; + if (!threshold.decode_dec (threshold_text)) + { + boost::property_tree::ptree response_l; + boost::property_tree::ptree pending; + 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); + boost::property_tree::ptree peers_l; + rai::account end (account.number () + 1); + for (auto ii (node.store.pending_begin (transaction, rai::pending_key (account, 0))), nn (node.store.pending_begin (transaction, rai::pending_key (end, 0))); ii != nn; ++ii) + { + rai::pending_key key (ii->first); + rai::pending_info info (ii->second); + if (info.amount.number () >= threshold.number ()) + { + boost::property_tree::ptree entry; + entry.put (key.hash.to_string (), info.amount.number ().convert_to ()); + peers_l.push_back (std::make_pair ("", entry)); + } + } + if (!peers_l.empty ()) + { + pending.add_child (account.to_account (), peers_l); + } + } + response_l.add_child ("pending", pending); + response (response_l); + } + else + { + error_response (response, "Bad threshold number"); + } + } + else + { + error_response (response, "Wallet not found"); + } + } + else + { + error_response (response, "Bad wallet number"); + } +} + void rai::rpc_handler::wallet_representative () { std::string wallet_text (request.get ("wallet")); @@ -2819,6 +2929,14 @@ void rai::rpc_handler::process_request () { wallet_key_valid (); } + else if (action == "wallet_pending") + { + wallet_pending (); + } + else if (action == "wallet_pending_threshold") + { + wallet_pending_threshold (); + } else if (action == "wallet_representative") { wallet_representative (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index c03eef68..ef09781b 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -156,6 +156,8 @@ public: void wallet_export (); void wallet_frontiers (); void wallet_key_valid (); + void wallet_pending (); + void wallet_pending_threshold (); void wallet_representative (); void wallet_representative_set (); void work_generate (); From 6034fbc14b5d1e4e6a638474a2deae229f404b81 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Mon, 17 Jul 2017 19:47:05 +0300 Subject: [PATCH 03/19] RPC receive_minimum & receive_minimum_set --- rai/node/rpc.cpp | 39 +++++++++++++++++++++++++++++++++++++++ rai/node/rpc.hpp | 2 ++ 2 files changed, 41 insertions(+) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 54f08387..57fc5289 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -1780,6 +1780,37 @@ void rai::rpc_handler::receive () } } +void rai::rpc_handler::receive_minimum () +{ + boost::property_tree::ptree response_l; + response_l.put ("amount", node.config.receive_minimum.to_string_dec ()); + response (response_l); +} + +void rai::rpc_handler::receive_minimum_set () +{ + if (rpc.config.enable_control) + { + std::string amount_text (request.get ("amount")); + rai::uint128_union amount; + if (!amount.decode_dec (amount_text)) + { + node.config.receive_minimum = amount; + boost::property_tree::ptree response_l; + response_l.put ("success", ""); + response (response_l); + } + else + { + error_response (response, "Bad amount number"); + } + } + else + { + error_response (response, "RPC control is disabled"); + } +} + void rai::rpc_handler::representatives () { boost::property_tree::ptree response_l; @@ -2861,6 +2892,14 @@ void rai::rpc_handler::process_request () { receive (); } + else if (action == "receive_minimum") + { + receive_minimum (); + } + else if (action == "receive_minimum_set") + { + receive_minimum_set (); + } else if (action == "representatives") { representatives (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index ef09781b..8f7ee457 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -138,6 +138,8 @@ public: void rai_to_raw (); void rai_from_raw (); void receive (); + void receive_minimum (); + void receive_minimum_set (); void representatives (); void republish (); void search_pending (); From aa523c7fe050e8f5e9caaa45554bd18b010e714a Mon Sep 17 00:00:00 2001 From: SergiySW Date: Tue, 18 Jul 2017 10:50:02 +0300 Subject: [PATCH 04/19] RPC pending_exists --- rai/node/rpc.cpp | 33 +++++++++++++++++++++++++++++++++ rai/node/rpc.hpp | 1 + 2 files changed, 34 insertions(+) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 57fc5289..773031f5 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -1392,6 +1392,35 @@ void rai::rpc_handler::pending () } } +void rai::rpc_handler::pending_exists () +{ + std::string hash_text (request.get ("hash")); + rai::uint256_union hash; + auto error (hash.decode_hex (hash_text)); + if (!error) + { + rai::transaction transaction (node.store.environment, nullptr, false); + auto block (node.store.block_get (transaction, hash)); + if (block != nullptr) + { + auto block_l (static_cast (block.release ())); + auto account (block_l->hashables.destination); + boost::property_tree::ptree response_l; + auto exists (node.store.pending_exists (transaction, rai::pending_key (account, hash))); + response_l.put ("exists", exists ? "1" : "0"); + response (response_l); + } + else + { + error_response (response, "Block not found"); + } + } + else + { + error_response (response, "Bad hash number"); + } +} + void rai::rpc_handler::pending_threshold () { std::string account_text (request.get ("account")); @@ -2872,6 +2901,10 @@ void rai::rpc_handler::process_request () { pending (); } + else if (action == "pending_exists") + { + pending_exists (); + } else if (action == "pending_threshold") { pending_threshold (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index 8f7ee457..6f0baa98 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -133,6 +133,7 @@ public: void payment_wait (); void peers (); void pending (); + void pending_exists (); void pending_threshold (); void process (); void rai_to_raw (); From d1df852f7f6c119794191fd852f1181dfcb05c36 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Tue, 18 Jul 2017 13:18:52 +0300 Subject: [PATCH 05/19] Tests for new RPC pending_threshold, accounts_pending_threshold, pending_exists, wallet_pending, wallet_pending_threshold, receive_minimum, receive_minimum_set --- rai/core_test/rpc.cpp | 201 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 200 insertions(+), 1 deletion(-) diff --git a/rai/core_test/rpc.cpp b/rai/core_test/rpc.cpp index fb3d2ce0..c4739971 100644 --- a/rai/core_test/rpc.cpp +++ b/rai/core_test/rpc.cpp @@ -2151,7 +2151,6 @@ TEST (rpc, wallet_balances) system0.poll (); } ASSERT_EQ (200, response.status); - std::vector balances; for (auto & balances : response.json.get_child("balances")) { std::string account_text (balances.first); @@ -2162,3 +2161,203 @@ TEST (rpc, wallet_balances) ASSERT_EQ ("0", pending_text); } } + +TEST (rpc, pending_threshold) +{ + rai::system system (24000, 1); + rai::keypair key1; + system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + auto block1 (system.wallet (0)->send_action (rai::test_genesis_key.pub, key1.pub, 100)); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "pending_threshold"); + request.put ("account", key1.pub.to_account ()); + request.put ("threshold", "100"); + test_response response0 (request, rpc, system.service); + while (response0.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response0.status); + auto & blocks_node (response0.json.get_child ("blocks")); + ASSERT_EQ (1, blocks_node.size ()); + auto amount (blocks_node.begin ()->second.get (block1->hash ().to_string ())); + ASSERT_EQ ("100", amount); + request.put ("threshold", "101"); + test_response response1 (request, rpc, system.service); + while (response1.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response1.status); + auto & blocks_node1 (response1.json.get_child ("blocks")); + ASSERT_EQ (0, blocks_node1.size ()); +} + +TEST (rpc, accounts_pending_threshold) +{ + rai::system system (24000, 1); + rai::keypair key1; + system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + auto block1 (system.wallet (0)->send_action (rai::test_genesis_key.pub, key1.pub, 100)); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "accounts_pending_threshold"); + boost::property_tree::ptree entry; + boost::property_tree::ptree peers_l; + entry.put ("", key1.pub.to_account ()); + peers_l.push_back (std::make_pair ("", entry)); + request.add_child ("accounts", peers_l); + request.put ("threshold", "100"); + test_response response (request, rpc, system.service); + while (response.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response.status); + for (auto & blocks : response.json.get_child("blocks")) + { + std::string account_text (blocks.first); + ASSERT_EQ (key1.pub.to_account (), account_text); + auto amount (blocks.second.begin ()->second.get (block1->hash ().to_string ())); + ASSERT_EQ ("100", amount); + } +} + +TEST (rpc, pending_exists) +{ + rai::system system (24000, 1); + rai::keypair key1; + system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + auto hash0 (system.nodes [0]->latest (rai::genesis_account)); + auto block1 (system.wallet (0)->send_action (rai::test_genesis_key.pub, key1.pub, 100)); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "pending_exists"); + request.put ("hash", hash0.to_string ()); + test_response response0 (request, rpc, system.service); + while (response0.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response0.status); + std::string exists_text (response0.json.get ("exists")); + ASSERT_EQ ("0", exists_text); + request.put ("hash", block1->hash ().to_string ()); + test_response response1 (request, rpc, system.service); + while (response1.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response1.status); + std::string exists_text1 (response1.json.get ("exists")); + ASSERT_EQ ("1", exists_text1); +} + +TEST (rpc, wallet_pending) +{ + rai::system system0 (24000, 1); + rai::keypair key1; + system0.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + auto block1 (system0.wallet (0)->send_action (rai::test_genesis_key.pub, key1.pub, 100)); + rai::rpc rpc (system0.service, *system0.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "wallet_pending"); + request.put ("wallet", system0.nodes [0]->wallets.items.begin ()->first.to_string ()); + request.put ("count", "100"); + test_response response (request, rpc, system0.service); + while (response.status == 0) + { + system0.poll (); + } + ASSERT_EQ (200, response.status); + for (auto & pending : response.json.get_child("pending")) + { + std::string account_text (pending.first); + ASSERT_EQ (rai::test_genesis_key.pub.to_account (), account_text); + auto & blocks_node (pending.second.get_child (rai::test_genesis_key.pub.to_account ())); + ASSERT_EQ (1, blocks_node.size ()); + rai::block_hash hash1 (blocks_node.begin ()->second.get ("")); + ASSERT_EQ (block1->hash (), hash1); + } +} + +TEST (rpc, wallet_pending_threshold) +{ + rai::system system0 (24000, 1); + rai::keypair key1; + system0.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + auto block1 (system0.wallet (0)->send_action (rai::test_genesis_key.pub, key1.pub, 100)); + rai::rpc rpc (system0.service, *system0.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "wallet_pending_threshold"); + request.put ("wallet", system0.nodes [0]->wallets.items.begin ()->first.to_string ()); + request.put ("threshold", "100"); + test_response response0 (request, rpc, system0.service); + while (response0.status == 0) + { + system0.poll (); + } + ASSERT_EQ (200, response0.status); + for (auto & pending : response0.json.get_child("pending")) + { + std::string account_text (pending.first); + ASSERT_EQ (rai::test_genesis_key.pub.to_account (), account_text); + auto & blocks_node (pending.second.get_child (rai::test_genesis_key.pub.to_account ())); + ASSERT_EQ (1, blocks_node.size ()); + rai::block_hash hash1 (blocks_node.begin ()->second.get ("")); + ASSERT_EQ (block1->hash (), hash1); + } + request.put ("threshold", "101"); + test_response response1 (request, rpc, system0.service); + while (response1.status == 0) + { + system0.poll (); + } + ASSERT_EQ (200, response1.status); + auto & pending1 (response1.json.get_child ("pending")); + ASSERT_EQ (0, pending1.size ()); +} + + +TEST (rpc, receive_minimum) +{ + rai::system system (24000, 1); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "receive_minimum"); + test_response response (request, rpc, system.service); + while (response.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response.status); + std::string amount (response.json.get ("amount")); + ASSERT_EQ (system.nodes [0]->config.receive_minimum.to_string_dec (), amount); +} + +TEST (rpc, receive_minimum_set) +{ + rai::system system (24000, 1); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "receive_minimum_set"); + request.put ("amount", "100"); + ASSERT_NE (system.nodes [0]->config.receive_minimum.to_string_dec (), "100"); + test_response response (request, rpc, system.service); + while (response.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response.status); + std::string success (response.json.get ("success")); + ASSERT_TRUE (success.empty()); + ASSERT_EQ (system.nodes [0]->config.receive_minimum.to_string_dec (), "100"); +} From 2c6159e30b1a4e89af3f0b1dd4f25093870e997f Mon Sep 17 00:00:00 2001 From: SergiySW Date: Tue, 18 Jul 2017 16:56:49 +0300 Subject: [PATCH 06/19] RPC search_pending_all --- rai/node/rpc.cpp | 19 +++++++++++++++++++ rai/node/rpc.hpp | 1 + 2 files changed, 20 insertions(+) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 773031f5..1897f765 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -1916,6 +1916,21 @@ void rai::rpc_handler::search_pending () } } +void rai::rpc_handler::search_pending_all () +{ + if (rpc.config.enable_control) + { + node.wallets.search_pending_all (); + boost::property_tree::ptree response_l; + response_l.put ("success", ""); + response (response_l); + } + else + { + error_response (response, "RPC control is disabled"); + } +} + void rai::rpc_handler::send () { if (rpc.config.enable_control) @@ -2945,6 +2960,10 @@ void rai::rpc_handler::process_request () { search_pending (); } + else if (action == "search_pending_all") + { + search_pending_all (); + } else if (action == "send") { send (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index 6f0baa98..ed3c81d0 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -144,6 +144,7 @@ public: void representatives (); void republish (); void search_pending (); + void search_pending_all (); void send (); void stop (); void successors (); From 27dedd70f0801fb64ae8863edb44feaaa915cba0 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Tue, 18 Jul 2017 17:37:36 +0300 Subject: [PATCH 07/19] RPC work_get & work_set --- rai/node/rpc.cpp | 123 +++++++++++++++++++++++++++++++++++++++++++++++ rai/node/rpc.hpp | 2 + 2 files changed, 125 insertions(+) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 1897f765..db296f7c 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -2623,6 +2623,121 @@ void rai::rpc_handler::work_cancel () } } +void rai::rpc_handler::work_get () +{ + if (rpc.config.enable_control) + { + 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 ()) + { + std::string account_text (request.get ("account")); + rai::account account; + auto error (account.decode_account (account_text)); + if (!error) + { + rai::transaction transaction (node.store.environment, nullptr, false); + auto account_check (existing->second->store.find (transaction, account)); + if (account_check != existing->second->store.end ()) + { + uint64_t work (0); + auto error (existing->second->store.work_get (transaction, account, work)); + boost::property_tree::ptree response_l; + response_l.put ("work", rai::to_string_hex (work)); + response (response_l); + } + else + { + error_response (response, "Account not found in wallet"); + } + } + else + { + error_response (response, "Bad account number"); + } + } + 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::work_set () +{ + if (rpc.config.enable_control) + { + 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 ()) + { + std::string account_text (request.get ("account")); + rai::account account; + auto error (account.decode_account (account_text)); + if (!error) + { + rai::transaction transaction (node.store.environment, nullptr, true); + auto account_check (existing->second->store.find (transaction, account)); + if (account_check != existing->second->store.end ()) + { + std::string work_text (request.get ("work")); + uint64_t work; + auto work_error (rai::from_string_hex (work_text, work)); + if (!work_error) + { + existing->second->store.work_put (transaction, account, work); + boost::property_tree::ptree response_l; + response_l.put ("success", ""); + response (response_l); + } + else + { + error_response (response, "Bad work"); + } + } + else + { + error_response (response, "Account not found in wallet"); + } + } + else + { + error_response (response, "Bad account number"); + } + } + 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::work_validate () { std::string hash_text (request.get ("hash")); @@ -3044,6 +3159,14 @@ void rai::rpc_handler::process_request () { work_cancel (); } + else if (action == "work_get") + { + work_get (); + } + else if (action == "work_set") + { + work_set (); + } else if (action == "work_validate") { work_validate (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index ed3c81d0..cce2a1d8 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -166,6 +166,8 @@ public: void wallet_representative_set (); void work_generate (); void work_cancel (); + void work_get (); + void work_set (); void work_validate (); std::string body; rai::node & node; From 73ebd5a8cba497037e2cc9158283164fd9146868 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Tue, 18 Jul 2017 19:37:56 +0300 Subject: [PATCH 08/19] RPC wallet_work_get --- rai/node/rpc.cpp | 40 +++++++++++++++++++++++++++++++++++++++- rai/node/rpc.hpp | 1 + 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index db296f7c..df9f4d67 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -2564,6 +2564,40 @@ void rai::rpc_handler::wallet_representative_set () } } +void rai::rpc_handler::wallet_work_get () +{ + 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 works; + 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); + uint64_t work (0); + auto error_work (existing->second->store.work_get (transaction, account, work)); + works.put (account.to_account (), rai::to_string_hex (work)); + } + response_l.add_child ("works", works); + response (response_l); + } + else + { + error_response (response, "Wallet not found"); + } + } + else + { + error_response (response, "Bad wallet number"); + } +} + void rai::rpc_handler::work_generate () { if (rpc.config.enable_control) @@ -2645,7 +2679,7 @@ void rai::rpc_handler::work_get () if (account_check != existing->second->store.end ()) { uint64_t work (0); - auto error (existing->second->store.work_get (transaction, account, work)); + auto error_work (existing->second->store.work_get (transaction, account, work)); boost::property_tree::ptree response_l; response_l.put ("work", rai::to_string_hex (work)); response (response_l); @@ -3151,6 +3185,10 @@ void rai::rpc_handler::process_request () { wallet_representative_set (); } + else if (action == "wallet_work_get") + { + wallet_work_get (); + } else if (action == "work_generate") { work_generate (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index cce2a1d8..ce62e3fb 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -164,6 +164,7 @@ public: void wallet_pending_threshold (); void wallet_representative (); void wallet_representative_set (); + void wallet_work_get (); void work_generate (); void work_cancel (); void work_get (); From 0b8d09db7138b9c8fa31c93406b520c699d8431d Mon Sep 17 00:00:00 2001 From: SergiySW Date: Tue, 18 Jul 2017 21:02:12 +0300 Subject: [PATCH 09/19] RPC: merge pending_threshold with pending --- rai/core_test/rpc.cpp | 6 +- rai/node/rpc.cpp | 345 +++++++++++++++++------------------------- rai/node/rpc.hpp | 3 - 3 files changed, 145 insertions(+), 209 deletions(-) diff --git a/rai/core_test/rpc.cpp b/rai/core_test/rpc.cpp index c4739971..60c6d92c 100644 --- a/rai/core_test/rpc.cpp +++ b/rai/core_test/rpc.cpp @@ -2171,7 +2171,7 @@ TEST (rpc, pending_threshold) rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); rpc.start (); boost::property_tree::ptree request; - request.put ("action", "pending_threshold"); + request.put ("action", "pending"); request.put ("account", key1.pub.to_account ()); request.put ("threshold", "100"); test_response response0 (request, rpc, system.service); @@ -2204,7 +2204,7 @@ TEST (rpc, accounts_pending_threshold) rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); rpc.start (); boost::property_tree::ptree request; - request.put ("action", "accounts_pending_threshold"); + request.put ("action", "accounts_pending"); boost::property_tree::ptree entry; boost::property_tree::ptree peers_l; entry.put ("", key1.pub.to_account ()); @@ -2295,7 +2295,7 @@ TEST (rpc, wallet_pending_threshold) rai::rpc rpc (system0.service, *system0.nodes [0], rai::rpc_config (true)); rpc.start (); boost::property_tree::ptree request; - request.put ("action", "wallet_pending_threshold"); + request.put ("action", "wallet_pending"); request.put ("wallet", system0.nodes [0]->wallets.items.begin ()->first.to_string ()); request.put ("threshold", "100"); test_response response0 (request, rpc, system0.service); diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index df9f4d67..f384ff9f 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -588,86 +588,73 @@ void rai::rpc_handler::accounts_frontiers () void rai::rpc_handler::accounts_pending () { - std::string count_text (request.get ("count")); - uint64_t count; - if (!decode_unsigned (count_text, count)) + uint64_t count (18446744073709551615U); + rai::uint128_union threshold (0); + try { - boost::property_tree::ptree response_l; - boost::property_tree::ptree pending; - rai::transaction transaction (node.store.environment, nullptr, false); - for (auto &accounts : request.get_child("accounts")) + std::string count_text (request.get ("count")); + auto error (decode_unsigned (count_text, count)); + if (error) { - std::string account_text = accounts.second.data (); - rai::uint256_union account; - if (!account.decode_account (account_text)) + error_response (response, "Invalid count"); + } + } + catch (std::runtime_error &) + { + // If there is no "count" in request + } + try + { + std::string threshold_text (request.get ("threshold")); + auto error_threshold (threshold.decode_dec (threshold_text)); + if (error_threshold) + { + error_response (response, "Bad threshold number"); + } + } + catch (std::runtime_error &) + { + // If there is no "threshold" in request + } + boost::property_tree::ptree response_l; + boost::property_tree::ptree pending; + rai::transaction transaction (node.store.environment, nullptr, false); + for (auto &accounts : request.get_child("accounts")) + { + std::string account_text = accounts.second.data (); + rai::uint256_union account; + if (!account.decode_account (account_text)) + { + boost::property_tree::ptree peers_l; + rai::account end (account.number () + 1); + for (auto i (node.store.pending_begin (transaction, rai::pending_key (account, 0))), n (node.store.pending_begin (transaction, rai::pending_key (end, 0))); i != n && peers_l.size () < count; ++i) { - boost::property_tree::ptree peers_l; - rai::account end (account.number () + 1); - for (auto i (node.store.pending_begin (transaction, rai::pending_key (account, 0))), n (node.store.pending_begin (transaction, rai::pending_key (end, 0))); i != n && peers_l.size () < count; ++i) + rai::pending_key key (i->first); + boost::property_tree::ptree entry; + if (threshold.is_zero ()) { - rai::pending_key key (i->first); - boost::property_tree::ptree entry; entry.put ("", key.hash.to_string ()); peers_l.push_back (std::make_pair ("", entry)); } - pending.add_child (account.to_account (), peers_l); - } - else - { - error_response (response, "Bad account number"); - } - } - response_l.add_child ("blocks", pending); - response (response_l); - } - else - { - error_response (response, "Invalid count"); - } -} - -void rai::rpc_handler::accounts_pending_threshold () -{ - std::string threshold_text (request.get ("threshold")); - rai::uint128_union threshold; - if (!threshold.decode_dec (threshold_text)) - { - boost::property_tree::ptree response_l; - boost::property_tree::ptree pending; - rai::transaction transaction (node.store.environment, nullptr, false); - for (auto &accounts : request.get_child("accounts")) - { - std::string account_text = accounts.second.data (); - rai::uint256_union account; - if (!account.decode_account (account_text)) - { - boost::property_tree::ptree peers_l; - rai::account end (account.number () + 1); - for (auto i (node.store.pending_begin (transaction, rai::pending_key (account, 0))), n (node.store.pending_begin (transaction, rai::pending_key (end, 0))); i != n; ++i) + else { - rai::pending_key key (i->first); rai::pending_info info (i->second); if (info.amount.number () >= threshold.number ()) { - boost::property_tree::ptree entry; entry.put (key.hash.to_string (), info.amount.number ().convert_to ()); peers_l.push_back (std::make_pair ("", entry)); } } - pending.add_child (account.to_account (), peers_l); - } - else - { - error_response (response, "Bad account number"); } + pending.add_child (account.to_account (), peers_l); + } + else + { + error_response (response, "Bad account number"); } - response_l.add_child ("blocks", pending); - response (response_l); - } - else - { - error_response (response, "Bad threshold number"); } + response_l.add_child ("blocks", pending); + response (response_l); } void rai::rpc_handler::available_supply () @@ -1361,30 +1348,61 @@ void rai::rpc_handler::pending () rai::account account; if (!account.decode_account(account_text)) { - std::string count_text (request.get ("count")); - uint64_t count; - if (!decode_unsigned (count_text, count)) + uint64_t count (18446744073709551615U); + rai::uint128_union threshold (0); + try { - boost::property_tree::ptree response_l; - boost::property_tree::ptree peers_l; + std::string count_text (request.get ("count")); + auto error (decode_unsigned (count_text, count)); + if (error) { - rai::transaction transaction (node.store.environment, nullptr, false); - rai::account end (account.number () + 1); - for (auto i (node.store.pending_begin (transaction, rai::pending_key (account, 0))), n (node.store.pending_begin (transaction, rai::pending_key (end, 0))); i != n && peers_l.size ()< count; ++i) + error_response (response, "Invalid count"); + } + } + catch (std::runtime_error &) + { + // If there is no "count" in request + } + try + { + std::string threshold_text (request.get ("threshold")); + auto error_threshold (threshold.decode_dec (threshold_text)); + if (error_threshold) + { + error_response (response, "Bad threshold number"); + } + } + catch (std::runtime_error &) + { + // If there is no "threshold" in request + } + boost::property_tree::ptree response_l; + boost::property_tree::ptree peers_l; + { + rai::transaction transaction (node.store.environment, nullptr, false); + rai::account end (account.number () + 1); + for (auto i (node.store.pending_begin (transaction, rai::pending_key (account, 0))), n (node.store.pending_begin (transaction, rai::pending_key (end, 0))); i != n && peers_l.size ()< count; ++i) + { + rai::pending_key key (i->first); + boost::property_tree::ptree entry; + if (threshold.is_zero ()) { - rai::pending_key key (i->first); - boost::property_tree::ptree entry; entry.put ("", key.hash.to_string ()); peers_l.push_back (std::make_pair ("", entry)); } + else + { + rai::pending_info info (i->second); + if (info.amount.number () >= threshold.number ()) + { + entry.put (key.hash.to_string (), info.amount.number ().convert_to ()); + peers_l.push_back (std::make_pair ("", entry)); + } + } } - response_l.add_child ("blocks", peers_l); - response (response_l); - } - else - { - error_response (response, "Invalid count"); } + response_l.add_child ("blocks", peers_l); + response (response_l); } else { @@ -1421,47 +1439,6 @@ void rai::rpc_handler::pending_exists () } } -void rai::rpc_handler::pending_threshold () -{ - std::string account_text (request.get ("account")); - rai::account account; - if (!account.decode_account(account_text)) - { - std::string threshold_text (request.get ("threshold")); - rai::uint128_union threshold; - if (!threshold.decode_dec (threshold_text)) - { - boost::property_tree::ptree response_l; - boost::property_tree::ptree peers_l; - { - rai::transaction transaction (node.store.environment, nullptr, false); - rai::account end (account.number () + 1); - for (auto i (node.store.pending_begin (transaction, rai::pending_key (account, 0))), n (node.store.pending_begin (transaction, rai::pending_key (end, 0))); i != n; ++i) - { - rai::pending_key key (i->first); - rai::pending_info info (i->second); - if (info.amount.number () >= threshold.number ()) - { - boost::property_tree::ptree entry; - entry.put (key.hash.to_string (), info.amount.number ().convert_to ()); - peers_l.push_back (std::make_pair ("", entry)); - } - } - } - response_l.add_child ("blocks", peers_l); - response (response_l); - } - else - { - error_response (response, "Bad threshold number"); - } - } - else - { - error_response (response, "Bad account number"); - } -} - void rai::rpc_handler::payment_begin () { std::string id_text (request.get ("wallet")); @@ -2394,94 +2371,68 @@ void rai::rpc_handler::wallet_pending () auto existing (node.wallets.items.find (wallet)); if (existing != node.wallets.items.end ()) { - std::string count_text (request.get ("count")); - uint64_t count; - if (!decode_unsigned (count_text, count)) + uint64_t count (18446744073709551615U); + rai::uint128_union threshold (0); + try { - boost::property_tree::ptree response_l; - boost::property_tree::ptree pending; - rai::transaction transaction (node.store.environment, nullptr, false); - for (auto i (existing->second->store.begin (transaction)), n (existing->second->store.end ()); i != n; ++i) + std::string count_text (request.get ("count")); + auto error_count (decode_unsigned (count_text, count)); + if (error_count) { - rai::account account(i->first); - boost::property_tree::ptree peers_l; - rai::account end (account.number () + 1); - for (auto ii (node.store.pending_begin (transaction, rai::pending_key (account, 0))), nn (node.store.pending_begin (transaction, rai::pending_key (end, 0))); ii != nn && peers_l.size ()< count; ++ii) + error_response (response, "Invalid count"); + } + } + catch (std::runtime_error &) + { + // If there is no "count" in request + } + try + { + std::string threshold_text (request.get ("threshold")); + auto error_threshold (threshold.decode_dec (threshold_text)); + if (error_threshold) + { + error_response (response, "Bad threshold number"); + } + } + catch (std::runtime_error &) + { + // If there is no "threshold" in request + } + boost::property_tree::ptree response_l; + boost::property_tree::ptree pending; + 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); + boost::property_tree::ptree peers_l; + rai::account end (account.number () + 1); + for (auto ii (node.store.pending_begin (transaction, rai::pending_key (account, 0))), nn (node.store.pending_begin (transaction, rai::pending_key (end, 0))); ii != nn && peers_l.size ()< count; ++ii) + { + rai::pending_key key (ii->first); + boost::property_tree::ptree entry; + if (threshold.is_zero ()) { - rai::pending_key key (ii->first); - boost::property_tree::ptree entry; entry.put ("", key.hash.to_string ()); peers_l.push_back (std::make_pair ("", entry)); } - if (!peers_l.empty ()) + else { - pending.add_child (account.to_account (), peers_l); - } - } - response_l.add_child ("pending", pending); - response (response_l); - } - else - { - error_response (response, "Invalid count"); - } - } - else - { - error_response (response, "Wallet not found"); - } - } - else - { - error_response (response, "Bad wallet number"); - } -} - -void rai::rpc_handler::wallet_pending_threshold () -{ - 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 ()) - { - std::string threshold_text (request.get ("threshold")); - rai::uint128_union threshold; - if (!threshold.decode_dec (threshold_text)) - { - boost::property_tree::ptree response_l; - boost::property_tree::ptree pending; - 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); - boost::property_tree::ptree peers_l; - rai::account end (account.number () + 1); - for (auto ii (node.store.pending_begin (transaction, rai::pending_key (account, 0))), nn (node.store.pending_begin (transaction, rai::pending_key (end, 0))); ii != nn; ++ii) - { - rai::pending_key key (ii->first); rai::pending_info info (ii->second); if (info.amount.number () >= threshold.number ()) { - boost::property_tree::ptree entry; entry.put (key.hash.to_string (), info.amount.number ().convert_to ()); peers_l.push_back (std::make_pair ("", entry)); } } - if (!peers_l.empty ()) - { - pending.add_child (account.to_account (), peers_l); - } } - response_l.add_child ("pending", pending); - response (response_l); - } - else - { - error_response (response, "Bad threshold number"); + if (!peers_l.empty ()) + { + pending.add_child (account.to_account (), peers_l); + } } + response_l.add_child ("pending", pending); + response (response_l); } else { @@ -2945,10 +2896,6 @@ void rai::rpc_handler::process_request () { accounts_pending (); } - else if (action == "accounts_pending_threshold") - { - accounts_pending_threshold (); - } else if (action == "available_supply") { available_supply (); @@ -3069,10 +3016,6 @@ void rai::rpc_handler::process_request () { pending_exists (); } - else if (action == "pending_threshold") - { - pending_threshold (); - } else if (action == "process") { process (); @@ -3173,10 +3116,6 @@ void rai::rpc_handler::process_request () { wallet_pending (); } - else if (action == "wallet_pending_threshold") - { - wallet_pending_threshold (); - } else if (action == "wallet_representative") { wallet_representative (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index ce62e3fb..a3b3d139 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -104,7 +104,6 @@ public: void accounts_balances (); void accounts_frontiers (); void accounts_pending (); - void accounts_pending_threshold (); void available_supply (); void block (); void blocks (); @@ -134,7 +133,6 @@ public: void peers (); void pending (); void pending_exists (); - void pending_threshold (); void process (); void rai_to_raw (); void rai_from_raw (); @@ -161,7 +159,6 @@ public: void wallet_frontiers (); void wallet_key_valid (); void wallet_pending (); - void wallet_pending_threshold (); void wallet_representative (); void wallet_representative_set (); void wallet_work_get (); From 28df04a3a7e281ec67a1970030052c7efabb709a Mon Sep 17 00:00:00 2001 From: SergiySW Date: Tue, 18 Jul 2017 21:49:53 +0300 Subject: [PATCH 10/19] RPC tests for work_get, wallet_work_get, work_set & search_pending_all --- rai/core_test/rpc.cpp | 103 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/rai/core_test/rpc.cpp b/rai/core_test/rpc.cpp index 60c6d92c..1a291590 100644 --- a/rai/core_test/rpc.cpp +++ b/rai/core_test/rpc.cpp @@ -2324,7 +2324,6 @@ TEST (rpc, wallet_pending_threshold) ASSERT_EQ (0, pending1.size ()); } - TEST (rpc, receive_minimum) { rai::system system (24000, 1); @@ -2361,3 +2360,105 @@ TEST (rpc, receive_minimum_set) ASSERT_TRUE (success.empty()); ASSERT_EQ (system.nodes [0]->config.receive_minimum.to_string_dec (), "100"); } + +TEST (rpc, work_get) +{ + rai::system system (24000, 1); + system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "work_get"); + request.put ("wallet", system.nodes [0]->wallets.items.begin ()->first.to_string ()); + request.put ("account", rai::test_genesis_key.pub.to_account ()); + test_response response (request, rpc, system.service); + while (response.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response.status); + std::string work_text (response.json.get ("work")); + uint64_t work (1); + rai::transaction transaction (system.nodes [0]->store.environment, nullptr, false); + system.nodes [0]->wallets.items.begin ()->second->store.work_get (transaction, rai::genesis_account, work); + ASSERT_EQ (rai::to_string_hex (work), work_text); +} + +TEST (rpc, wallet_work_get) +{ + rai::system system (24000, 1); + system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "wallet_work_get"); + request.put ("wallet", system.nodes [0]->wallets.items.begin ()->first.to_string ()); + test_response response (request, rpc, system.service); + while (response.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response.status); + rai::transaction transaction (system.nodes [0]->store.environment, nullptr, false); + for (auto & works : response.json.get_child("works")) + { + std::string account_text (works.first); + ASSERT_EQ (rai::test_genesis_key.pub.to_account (), account_text); + std::string work_text (works.second.get ("")); + uint64_t work (1); + system.nodes [0]->wallets.items.begin ()->second->store.work_get (transaction, rai::genesis_account, work); + ASSERT_EQ (rai::to_string_hex (work), work_text); + } +} + +TEST (rpc, work_set) +{ + rai::system system (24000, 1); + system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + uint64_t work0 (100); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "work_set"); + request.put ("wallet", system.nodes [0]->wallets.items.begin ()->first.to_string ()); + request.put ("account", rai::test_genesis_key.pub.to_account ()); + request.put ("work", rai::to_string_hex (work0)); + test_response response (request, rpc, system.service); + while (response.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response.status); + std::string success (response.json.get ("success")); + ASSERT_TRUE (success.empty()); + uint64_t work1 (1); + rai::transaction transaction (system.nodes [0]->store.environment, nullptr, false); + system.nodes [0]->wallets.items.begin ()->second->store.work_get (transaction, rai::genesis_account, work1); + ASSERT_EQ (work1, work0); +} + +TEST (rpc, search_pending_all) +{ + rai::system system (24000, 1); + system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + auto wallet (system.nodes [0]->wallets.items.begin ()->first.to_string ()); + rai::send_block block (system.nodes [0]->latest (rai::test_genesis_key.pub), rai::test_genesis_key.pub, rai::genesis_amount - system.nodes [0]->config.receive_minimum.number (), rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0); + ASSERT_EQ (rai::process_result::progress, system.nodes [0]->ledger.process (rai::transaction (system.nodes [0]->store.environment, nullptr, true), block).code); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "search_pending_all"); + test_response response (request, rpc, system.service); + while (response.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response.status); + auto iterations (0); + while (system.nodes [0]->balance (rai::test_genesis_key.pub) != rai::genesis_amount) + { + system.poll (); + ++iterations; + ASSERT_LT (iterations, 200); + } +} From fcbf51eca675b361a950c50b265618d5e365a76b Mon Sep 17 00:00:00 2001 From: SergiySW Date: Tue, 18 Jul 2017 22:09:52 +0300 Subject: [PATCH 11/19] RPC receive_minimum & wallet_work_get require enabled control --- rai/node/rpc.cpp | 56 ++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index f384ff9f..8eed8c97 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -1788,9 +1788,16 @@ void rai::rpc_handler::receive () void rai::rpc_handler::receive_minimum () { - boost::property_tree::ptree response_l; - response_l.put ("amount", node.config.receive_minimum.to_string_dec ()); - response (response_l); + if (rpc.config.enable_control) + { + boost::property_tree::ptree response_l; + response_l.put ("amount", node.config.receive_minimum.to_string_dec ()); + response (response_l); + } + else + { + error_response (response, "RPC control is disabled"); + } } void rai::rpc_handler::receive_minimum_set () @@ -2517,35 +2524,42 @@ void rai::rpc_handler::wallet_representative_set () void rai::rpc_handler::wallet_work_get () { - std::string wallet_text (request.get ("wallet")); - rai::uint256_union wallet; - auto error (wallet.decode_hex (wallet_text)); - if (!error) + if (rpc.config.enable_control) { - auto existing (node.wallets.items.find (wallet)); - if (existing != node.wallets.items.end ()) + std::string wallet_text (request.get ("wallet")); + rai::uint256_union wallet; + auto error (wallet.decode_hex (wallet_text)); + if (!error) { - boost::property_tree::ptree response_l; - boost::property_tree::ptree works; - rai::transaction transaction (node.store.environment, nullptr, false); - for (auto i (existing->second->store.begin (transaction)), n (existing->second->store.end ()); i != n; ++i) + auto existing (node.wallets.items.find (wallet)); + if (existing != node.wallets.items.end ()) { - rai::account account(i->first); - uint64_t work (0); - auto error_work (existing->second->store.work_get (transaction, account, work)); - works.put (account.to_account (), rai::to_string_hex (work)); + boost::property_tree::ptree response_l; + boost::property_tree::ptree works; + 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); + uint64_t work (0); + auto error_work (existing->second->store.work_get (transaction, account, work)); + works.put (account.to_account (), rai::to_string_hex (work)); + } + response_l.add_child ("works", works); + response (response_l); + } + else + { + error_response (response, "Wallet not found"); } - response_l.add_child ("works", works); - response (response_l); } else { - error_response (response, "Wallet not found"); + error_response (response, "Bad wallet number"); } } else { - error_response (response, "Bad wallet number"); + error_response (response, "RPC control is disabled"); } } From 8674bab86d0af047bc28ebbc1726f79113fec70a Mon Sep 17 00:00:00 2001 From: SergiySW Date: Wed, 19 Jul 2017 10:25:03 +0300 Subject: [PATCH 12/19] RPC wallet_republish --- rai/node/rpc.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ rai/node/rpc.hpp | 1 + 2 files changed, 72 insertions(+) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 8eed8c97..3147d8ee 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -2522,6 +2522,73 @@ void rai::rpc_handler::wallet_representative_set () } } + +void rai::rpc_handler::wallet_republish () +{ + if (rpc.config.enable_control) + { + 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 ()) + { + uint64_t count; + std::string count_text (request.get ("count")); + auto error (decode_unsigned (count_text, count)); + if (!error) + { + rai::transaction transaction (node.store.environment, nullptr, false); + boost::property_tree::ptree response_l; + boost::property_tree::ptree blocks; + 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)); + std::unique_ptr block; + std::vector hashes; + while (!latest.is_zero () && hashes.size () < count) + { + hashes.push_back (latest); + block = node.store.block_get (transaction, latest); + latest = block->previous (); + } + std::reverse (hashes.begin (), hashes.end ()); + for (auto & hash : hashes) + { + block = node.store.block_get (transaction, hash); + node.network.republish_block (*block); + boost::property_tree::ptree entry; + entry.put ("", hash.to_string ()); + blocks.push_back (std::make_pair ("", entry)); + } + } + response_l.add_child ("blocks", blocks); + response (response_l); + } + else + { + error_response (response, "Invalid count"); + } + } + 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::wallet_work_get () { if (rpc.config.enable_control) @@ -3138,6 +3205,10 @@ void rai::rpc_handler::process_request () { wallet_representative_set (); } + else if (action == "wallet_republish") + { + wallet_republish (); + } else if (action == "wallet_work_get") { wallet_work_get (); diff --git a/rai/node/rpc.hpp b/rai/node/rpc.hpp index a3b3d139..24b85d42 100644 --- a/rai/node/rpc.hpp +++ b/rai/node/rpc.hpp @@ -161,6 +161,7 @@ public: void wallet_pending (); void wallet_representative (); void wallet_representative_set (); + void wallet_republish (); void wallet_work_get (); void work_generate (); void work_cancel (); From 7077b830158fd053c462c8ae4686c36fe6764b31 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Wed, 19 Jul 2017 10:31:02 +0300 Subject: [PATCH 13/19] RPC republish should return list of rebroadcasted blocks --- rai/node/rpc.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 3147d8ee..564f3141 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -1846,6 +1846,8 @@ void rai::rpc_handler::republish () auto error (hash.decode_hex (hash_text)); if (!error) { + boost::property_tree::ptree response_l; + boost::property_tree::ptree blocks; rai::transaction transaction (node.store.environment, nullptr, false); auto block (node.store.block_get (transaction, hash)); if (block != nullptr) @@ -1854,10 +1856,13 @@ void rai::rpc_handler::republish () { block = node.store.block_get (transaction, hash); node.network.republish_block (*block); + boost::property_tree::ptree entry; + entry.put ("", hash.to_string ()); + blocks.push_back (std::make_pair ("", entry)); hash = node.store.block_successor (transaction, hash); } - boost::property_tree::ptree response_l; - response_l.put ("success", ""); + response_l.put ("success", ""); // obsolete + response_l.add_child ("blocks", blocks); response (response_l); } else @@ -2522,7 +2527,6 @@ void rai::rpc_handler::wallet_representative_set () } } - void rai::rpc_handler::wallet_republish () { if (rpc.config.enable_control) @@ -2540,9 +2544,9 @@ void rai::rpc_handler::wallet_republish () auto error (decode_unsigned (count_text, count)); if (!error) { - rai::transaction transaction (node.store.environment, nullptr, false); boost::property_tree::ptree response_l; boost::property_tree::ptree blocks; + 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); From 3b9739cff9a7738d072097de3f23b0d74887d3ab Mon Sep 17 00:00:00 2001 From: SergiySW Date: Wed, 19 Jul 2017 16:24:02 +0300 Subject: [PATCH 14/19] RPC republish sources depth & count --- rai/node/rpc.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 564f3141..baa3af35 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -1841,6 +1841,34 @@ void rai::rpc_handler::representatives () void rai::rpc_handler::republish () { + uint64_t count (2048U); + uint64_t sources (0); + try + { + std::string count_text (request.get ("count")); + auto error (decode_unsigned (count_text, count)); + if (error) + { + error_response (response, "Invalid count"); + } + } + catch (std::runtime_error &) + { + // If there is no "count" in request + } + try + { + std::string sources_text (request.get ("sources")); + auto error (decode_unsigned (sources_text, sources)); + if (error) + { + error_response (response, "Invalid sources number"); + } + } + catch (std::runtime_error &) + { + // If there is no "sources" in request + } std::string hash_text (request.get ("hash")); rai::uint256_union hash; auto error (hash.decode_hex (hash_text)); @@ -1852,10 +1880,31 @@ void rai::rpc_handler::republish () auto block (node.store.block_get (transaction, hash)); if (block != nullptr) { - while (!hash.is_zero ()) + for (auto i (0); !hash.is_zero () && i < count; ++i) { block = node.store.block_get (transaction, hash); - node.network.republish_block (*block); + if (sources != 0) // Republish source chain + { + std::unique_ptr block_a; + rai::block_hash source (block->source ()); + std::vector hashes; + while (!source.is_zero () && hashes.size () < sources) + { + hashes.push_back (source); + block_a = node.store.block_get (transaction, source); + source = block_a->previous (); + } + std::reverse (hashes.begin (), hashes.end ()); + for (auto & hash_l : hashes) + { + block_a = node.store.block_get (transaction, hash_l); + node.network.republish_block (*block_a); + boost::property_tree::ptree entry_l; + entry_l.put ("", hash_l.to_string ()); + blocks.push_back (std::make_pair ("", entry_l)); + } + } + node.network.republish_block (*block); // Republish block boost::property_tree::ptree entry; entry.put ("", hash.to_string ()); blocks.push_back (std::make_pair ("", entry)); From 41d8e962e1a3327bab14c127b775c202bc3131e5 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Wed, 19 Jul 2017 23:18:53 +0300 Subject: [PATCH 15/19] Tests for RPC wallet_republish & republish --- rai/core_test/rpc.cpp | 100 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 6 deletions(-) diff --git a/rai/core_test/rpc.cpp b/rai/core_test/rpc.cpp index 1a291590..2d9092fc 100644 --- a/rai/core_test/rpc.cpp +++ b/rai/core_test/rpc.cpp @@ -1934,23 +1934,26 @@ TEST (rpc, bootstrap_any) TEST (rpc, republish) { - rai::system system (24000, 2); + rai::system system (24000, 2); rai::keypair key; + rai::genesis genesis; auto latest (system.nodes [0]->latest (rai::test_genesis_key.pub)); auto & node1 (*system.nodes [0]); rai::send_block send (latest, key.pub, 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, node1.generate_work (latest)); system.nodes [0]->process (send); - rai::rpc rpc (system.service, node1, rai::rpc_config (true)); + rai::open_block open (send.hash (), key.pub, key.pub, key.prv, key.pub, node1.generate_work (key.pub)); + ASSERT_EQ (rai::process_result::progress, system.nodes [0]->process (open).code); + rai::rpc rpc (system.service, node1, rai::rpc_config (true)); rpc.start (); - boost::property_tree::ptree request; - request.put ("action", "republish"); + boost::property_tree::ptree request; + request.put ("action", "republish"); request.put ("hash", send.hash ().to_string ()); test_response response (request, rpc, system.service); while (response.status == 0) { system.poll (); } - ASSERT_EQ (200, response.status); + ASSERT_EQ (200, response.status); auto iterations (0); while (system.nodes[1]->balance (rai::test_genesis_key.pub) == rai::genesis_amount) { @@ -1958,6 +1961,50 @@ TEST (rpc, republish) ++iterations; ASSERT_GT (200, iterations); } + auto & blocks_node (response.json.get_child ("blocks")); + std::vector blocks; + for (auto i (blocks_node.begin ()), n (blocks_node.end ()); i != n; ++i) + { + blocks.push_back (rai::block_hash (i->second.get (""))); + } + ASSERT_EQ (1, blocks.size ()); + ASSERT_EQ (send.hash (), blocks [0]); + + request.put ("hash", genesis.hash ().to_string ()); + request.put ("count", 1); + test_response response1 (request, rpc, system.service); + while (response1.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response1.status); + blocks_node = response1.json.get_child ("blocks"); + blocks.clear(); + for (auto i (blocks_node.begin ()), n (blocks_node.end ()); i != n; ++i) + { + blocks.push_back (rai::block_hash (i->second.get (""))); + } + ASSERT_EQ (1, blocks.size ()); + ASSERT_EQ (genesis.hash (), blocks [0]); + + request.put ("hash", open.hash ().to_string ()); + request.put ("sources", 2); + test_response response2 (request, rpc, system.service); + while (response2.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response2.status); + blocks_node = response2.json.get_child ("blocks"); + blocks.clear(); + for (auto i (blocks_node.begin ()), n (blocks_node.end ()); i != n; ++i) + { + blocks.push_back (rai::block_hash (i->second.get (""))); + } + ASSERT_EQ (3, blocks.size ()); + ASSERT_EQ (genesis.hash (), blocks [0]); + ASSERT_EQ (send.hash (), blocks [1]); + ASSERT_EQ (open.hash (), blocks [2]); } TEST (rpc, deterministic_key) @@ -2441,7 +2488,6 @@ TEST (rpc, search_pending_all) { rai::system system (24000, 1); system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); - auto wallet (system.nodes [0]->wallets.items.begin ()->first.to_string ()); rai::send_block block (system.nodes [0]->latest (rai::test_genesis_key.pub), rai::test_genesis_key.pub, rai::genesis_amount - system.nodes [0]->config.receive_minimum.number (), rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0); ASSERT_EQ (rai::process_result::progress, system.nodes [0]->ledger.process (rai::transaction (system.nodes [0]->store.environment, nullptr, true), block).code); rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); @@ -2462,3 +2508,45 @@ TEST (rpc, search_pending_all) ASSERT_LT (iterations, 200); } } + +TEST (rpc, wallet_republish) +{ + rai::system system (24000, 1); + rai::genesis genesis; + rai::keypair key; + while (key.pub < rai::test_genesis_key.pub) + { + rai::keypair key1; + key.pub = key1.pub; + key.prv.data = key1.prv.data; + } + system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); + system.wallet (0)->insert_adhoc (key.prv); + auto & node1 (*system.nodes [0]); + auto latest (system.nodes [0]->latest (rai::test_genesis_key.pub)); + rai::send_block send (latest, key.pub, 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, node1.generate_work (latest)); + system.nodes [0]->process (send); + rai::open_block open (send.hash (), key.pub, key.pub, key.prv, key.pub, node1.generate_work (key.pub)); + ASSERT_EQ (rai::process_result::progress, system.nodes [0]->process (open).code); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rpc.start (); + boost::property_tree::ptree request; + request.put ("action", "wallet_republish"); + request.put ("wallet", system.nodes [0]->wallets.items.begin ()->first.to_string ()); + request.put ("count", 1); + test_response response (request, rpc, system.service); + while (response.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response.status); + auto & blocks_node (response.json.get_child ("blocks")); + std::vector blocks; + for (auto i (blocks_node.begin ()), n (blocks_node.end ()); i != n; ++i) + { + blocks.push_back (rai::block_hash (i->second.get (""))); + } + ASSERT_EQ (2, blocks.size ()); + ASSERT_EQ (send.hash (), blocks [0]); + ASSERT_EQ (open.hash (), blocks [1]); +} From 48dce009b1c341f7173627d1f336003e7290eba0 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Thu, 20 Jul 2017 11:43:27 +0300 Subject: [PATCH 16/19] Merge changes from clemahieu/master --- rai/node/rpc.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index baa3af35..d311e3a6 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -488,7 +488,7 @@ void rai::rpc_handler::account_representative_set () if (!error) { auto response_a (response); - wallet->change_async (account, representative, [response_a] (std::unique_ptr block) + wallet->change_async (account, representative, [response_a] (std::shared_ptr block) { rai::block_hash hash (0); if (block != nullptr) @@ -1733,7 +1733,7 @@ void rai::rpc_handler::receive () if (node.store.pending_exists (transaction, rai::pending_key (account, hash))) { auto response_a (response); - existing->second->receive_async (static_cast (*block), account, rai::genesis_amount, [response_a] (std::unique_ptr block_a) + existing->second->receive_async (std::move (block), account, rai::genesis_amount, [response_a] (std::shared_ptr block_a) { rai::uint256_union hash_a (0); if (block_a != nullptr) @@ -1883,6 +1883,8 @@ void rai::rpc_handler::republish () for (auto i (0); !hash.is_zero () && i < count; ++i) { block = node.store.block_get (transaction, hash); + node.network.republish_block (std::move (block)); + hash = node.store.block_successor (transaction, hash); if (sources != 0) // Republish source chain { std::unique_ptr block_a; @@ -1898,17 +1900,16 @@ void rai::rpc_handler::republish () for (auto & hash_l : hashes) { block_a = node.store.block_get (transaction, hash_l); - node.network.republish_block (*block_a); + node.network.republish_block (std::move (block_a)); boost::property_tree::ptree entry_l; entry_l.put ("", hash_l.to_string ()); blocks.push_back (std::make_pair ("", entry_l)); } } - node.network.republish_block (*block); // Republish block + // Republish block boost::property_tree::ptree entry; entry.put ("", hash.to_string ()); blocks.push_back (std::make_pair ("", entry)); - hash = node.store.block_successor (transaction, hash); } response_l.put ("success", ""); // obsolete response_l.add_child ("blocks", blocks); @@ -1998,7 +1999,7 @@ void rai::rpc_handler::send () { auto rpc_l (shared_from_this ()); auto response_a (response); - existing->second->send_async (source, destination, amount.number (), [response_a] (std::unique_ptr block_a) + existing->second->send_async (source, destination, amount.number (), [response_a] (std::shared_ptr block_a) { rai::uint256_union hash (0); if (block_a != nullptr) @@ -2612,7 +2613,7 @@ void rai::rpc_handler::wallet_republish () for (auto & hash : hashes) { block = node.store.block_get (transaction, hash); - node.network.republish_block (*block); + node.network.republish_block (std::move (block));; boost::property_tree::ptree entry; entry.put ("", hash.to_string ()); blocks.push_back (std::make_pair ("", entry)); From a0577bf480b69fa8fc01a95d368b2246f06328a6 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Sat, 22 Jul 2017 00:49:47 +0300 Subject: [PATCH 17/19] Merge pending_threshold tests with pending --- rai/core_test/rpc.cpp | 125 ++++++++++++++---------------------------- rai/node/rpc.cpp | 5 +- 2 files changed, 43 insertions(+), 87 deletions(-) diff --git a/rai/core_test/rpc.cpp b/rai/core_test/rpc.cpp index 2d9092fc..0b404e60 100644 --- a/rai/core_test/rpc.cpp +++ b/rai/core_test/rpc.cpp @@ -1238,14 +1238,14 @@ TEST (rpc, peers) TEST (rpc, pending) { - rai::system system (24000, 1); + rai::system system (24000, 1); rai::keypair key1; system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); auto block1 (system.wallet (0)->send_action (rai::test_genesis_key.pub, key1.pub, 100)); - rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); + rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); rpc.start (); - boost::property_tree::ptree request; - request.put ("action", "pending"); + boost::property_tree::ptree request; + request.put ("action", "pending"); request.put ("account", key1.pub.to_account ()); request.put ("count", "100"); test_response response (request, rpc, system.service); @@ -1253,11 +1253,31 @@ TEST (rpc, pending) { system.poll (); } - ASSERT_EQ (200, response.status); - auto & blocks_node (response.json.get_child ("blocks")); + ASSERT_EQ (200, response.status); + auto & blocks_node (response.json.get_child ("blocks")); ASSERT_EQ (1, blocks_node.size ()); rai::block_hash hash1 (blocks_node.begin ()->second.get ("")); ASSERT_EQ (block1->hash (), hash1); + request.put ("threshold", "100"); // Threshold test + test_response response0 (request, rpc, system.service); + while (response0.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response0.status); + blocks_node = response0.json.get_child ("blocks"); + ASSERT_EQ (1, blocks_node.size ()); + auto amount (blocks_node.begin ()->second.get (block1->hash ().to_string ())); + ASSERT_EQ ("100", amount); + request.put ("threshold", "101"); + test_response response1 (request, rpc, system.service); + while (response1.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response1.status); + blocks_node = response1.json.get_child ("blocks"); + ASSERT_EQ (0, blocks_node.size ()); } TEST (rpc_config, serialization) @@ -2130,6 +2150,20 @@ TEST (rpc, accounts_pending) rai::block_hash hash1 (blocks.second.begin ()->second.get ("")); ASSERT_EQ (block1->hash (), hash1); } + request.put ("threshold", "100"); // Threshold test + test_response response1 (request, rpc, system.service); + while (response1.status == 0) + { + system.poll (); + } + ASSERT_EQ (200, response1.status); + for (auto & blocks : response1.json.get_child("blocks")) + { + std::string account_text (blocks.first); + ASSERT_EQ (key1.pub.to_account (), account_text); + auto amount (blocks.second.begin ()->second.get (block1->hash ().to_string ())); + ASSERT_EQ ("100", amount); + } } TEST (rpc, blocks) @@ -2209,70 +2243,6 @@ TEST (rpc, wallet_balances) } } -TEST (rpc, pending_threshold) -{ - rai::system system (24000, 1); - rai::keypair key1; - system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); - auto block1 (system.wallet (0)->send_action (rai::test_genesis_key.pub, key1.pub, 100)); - rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); - rpc.start (); - boost::property_tree::ptree request; - request.put ("action", "pending"); - request.put ("account", key1.pub.to_account ()); - request.put ("threshold", "100"); - test_response response0 (request, rpc, system.service); - while (response0.status == 0) - { - system.poll (); - } - ASSERT_EQ (200, response0.status); - auto & blocks_node (response0.json.get_child ("blocks")); - ASSERT_EQ (1, blocks_node.size ()); - auto amount (blocks_node.begin ()->second.get (block1->hash ().to_string ())); - ASSERT_EQ ("100", amount); - request.put ("threshold", "101"); - test_response response1 (request, rpc, system.service); - while (response1.status == 0) - { - system.poll (); - } - ASSERT_EQ (200, response1.status); - auto & blocks_node1 (response1.json.get_child ("blocks")); - ASSERT_EQ (0, blocks_node1.size ()); -} - -TEST (rpc, accounts_pending_threshold) -{ - rai::system system (24000, 1); - rai::keypair key1; - system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); - auto block1 (system.wallet (0)->send_action (rai::test_genesis_key.pub, key1.pub, 100)); - rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true)); - rpc.start (); - boost::property_tree::ptree request; - request.put ("action", "accounts_pending"); - boost::property_tree::ptree entry; - boost::property_tree::ptree peers_l; - entry.put ("", key1.pub.to_account ()); - peers_l.push_back (std::make_pair ("", entry)); - request.add_child ("accounts", peers_l); - request.put ("threshold", "100"); - test_response response (request, rpc, system.service); - while (response.status == 0) - { - system.poll (); - } - ASSERT_EQ (200, response.status); - for (auto & blocks : response.json.get_child("blocks")) - { - std::string account_text (blocks.first); - ASSERT_EQ (key1.pub.to_account (), account_text); - auto amount (blocks.second.begin ()->second.get (block1->hash ().to_string ())); - ASSERT_EQ ("100", amount); - } -} - TEST (rpc, pending_exists) { rai::system system (24000, 1); @@ -2331,20 +2301,7 @@ TEST (rpc, wallet_pending) rai::block_hash hash1 (blocks_node.begin ()->second.get ("")); ASSERT_EQ (block1->hash (), hash1); } -} - -TEST (rpc, wallet_pending_threshold) -{ - rai::system system0 (24000, 1); - rai::keypair key1; - system0.wallet (0)->insert_adhoc (rai::test_genesis_key.prv); - auto block1 (system0.wallet (0)->send_action (rai::test_genesis_key.pub, key1.pub, 100)); - rai::rpc rpc (system0.service, *system0.nodes [0], rai::rpc_config (true)); - rpc.start (); - boost::property_tree::ptree request; - request.put ("action", "wallet_pending"); - request.put ("wallet", system0.nodes [0]->wallets.items.begin ()->first.to_string ()); - request.put ("threshold", "100"); + request.put ("threshold", "100"); // Threshold test test_response response0 (request, rpc, system0.service); while (response0.status == 0) { diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index d311e3a6..b077e50e 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -1883,8 +1883,6 @@ void rai::rpc_handler::republish () for (auto i (0); !hash.is_zero () && i < count; ++i) { block = node.store.block_get (transaction, hash); - node.network.republish_block (std::move (block)); - hash = node.store.block_successor (transaction, hash); if (sources != 0) // Republish source chain { std::unique_ptr block_a; @@ -1906,10 +1904,11 @@ void rai::rpc_handler::republish () blocks.push_back (std::make_pair ("", entry_l)); } } - // Republish block + node.network.republish_block (std::move (block)); // Republish block boost::property_tree::ptree entry; entry.put ("", hash.to_string ()); blocks.push_back (std::make_pair ("", entry)); + hash = node.store.block_successor (transaction, hash); } response_l.put ("success", ""); // obsolete response_l.add_child ("blocks", blocks); From a8f7c3828ca4dbcd78c91847d85b9adda0d054cd Mon Sep 17 00:00:00 2001 From: SergiySW Date: Tue, 25 Jul 2017 19:48:12 +0300 Subject: [PATCH 18/19] RPC pending with threshold as array --- rai/core_test/rpc.cpp | 48 +++++++++++++++++++++++++++++++------------ rai/node/rpc.cpp | 17 +++++++-------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/rai/core_test/rpc.cpp b/rai/core_test/rpc.cpp index 0b404e60..dba52c8e 100644 --- a/rai/core_test/rpc.cpp +++ b/rai/core_test/rpc.cpp @@ -1267,8 +1267,16 @@ TEST (rpc, pending) ASSERT_EQ (200, response0.status); blocks_node = response0.json.get_child ("blocks"); ASSERT_EQ (1, blocks_node.size ()); - auto amount (blocks_node.begin ()->second.get (block1->hash ().to_string ())); - ASSERT_EQ ("100", amount); + std::unordered_map blocks; + for (auto i (blocks_node.begin ()), j (blocks_node.end ()); i != j; ++i) + { + rai::block_hash hash; + hash.decode_hex (i->first); + rai::uint128_union amount; + amount.decode_dec (i->second.get ("")); + blocks [hash] = amount; + } + ASSERT_EQ (blocks[block1->hash ()], 100); request.put ("threshold", "101"); test_response response1 (request, rpc, system.service); while (response1.status == 0) @@ -2157,12 +2165,20 @@ TEST (rpc, accounts_pending) system.poll (); } ASSERT_EQ (200, response1.status); - for (auto & blocks : response1.json.get_child("blocks")) + for (auto & pending : response1.json.get_child("blocks")) { - std::string account_text (blocks.first); + std::string account_text (pending.first); ASSERT_EQ (key1.pub.to_account (), account_text); - auto amount (blocks.second.begin ()->second.get (block1->hash ().to_string ())); - ASSERT_EQ ("100", amount); + std::unordered_map blocks; + for (auto i (pending.second.begin ()), j (pending.second.end ()); i != j; ++i) + { + rai::block_hash hash; + hash.decode_hex (i->first); + rai::uint128_union amount; + amount.decode_dec (i->second.get ("")); + blocks [hash] = amount; + } + ASSERT_EQ (blocks[block1->hash ()], 100); } } @@ -2292,7 +2308,7 @@ TEST (rpc, wallet_pending) system0.poll (); } ASSERT_EQ (200, response.status); - for (auto & pending : response.json.get_child("pending")) + for (auto & pending : response.json.get_child("blocks")) { std::string account_text (pending.first); ASSERT_EQ (rai::test_genesis_key.pub.to_account (), account_text); @@ -2308,14 +2324,20 @@ TEST (rpc, wallet_pending) system0.poll (); } ASSERT_EQ (200, response0.status); - for (auto & pending : response0.json.get_child("pending")) + for (auto & pending : response0.json.get_child("blocks")) { std::string account_text (pending.first); ASSERT_EQ (rai::test_genesis_key.pub.to_account (), account_text); - auto & blocks_node (pending.second.get_child (rai::test_genesis_key.pub.to_account ())); - ASSERT_EQ (1, blocks_node.size ()); - rai::block_hash hash1 (blocks_node.begin ()->second.get ("")); - ASSERT_EQ (block1->hash (), hash1); + std::unordered_map blocks; + for (auto i (pending.second.begin ()), j (pending.second.end ()); i != j; ++i) + { + rai::block_hash hash; + hash.decode_hex (i->first); + rai::uint128_union amount; + amount.decode_dec (i->second.get ("")); + blocks [hash] = amount; + } + ASSERT_EQ (blocks[block1->hash ()], 100); } request.put ("threshold", "101"); test_response response1 (request, rpc, system0.service); @@ -2324,7 +2346,7 @@ TEST (rpc, wallet_pending) system0.poll (); } ASSERT_EQ (200, response1.status); - auto & pending1 (response1.json.get_child ("pending")); + auto & pending1 (response1.json.get_child ("blocks")); ASSERT_EQ (0, pending1.size ()); } diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index b077e50e..8aca2380 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -630,9 +630,9 @@ void rai::rpc_handler::accounts_pending () for (auto i (node.store.pending_begin (transaction, rai::pending_key (account, 0))), n (node.store.pending_begin (transaction, rai::pending_key (end, 0))); i != n && peers_l.size () < count; ++i) { rai::pending_key key (i->first); - boost::property_tree::ptree entry; if (threshold.is_zero ()) { + boost::property_tree::ptree entry; entry.put ("", key.hash.to_string ()); peers_l.push_back (std::make_pair ("", entry)); } @@ -641,8 +641,7 @@ void rai::rpc_handler::accounts_pending () rai::pending_info info (i->second); if (info.amount.number () >= threshold.number ()) { - entry.put (key.hash.to_string (), info.amount.number ().convert_to ()); - peers_l.push_back (std::make_pair ("", entry)); + peers_l.put (key.hash.to_string (), info.amount.number ().convert_to ()); } } } @@ -1384,9 +1383,9 @@ void rai::rpc_handler::pending () for (auto i (node.store.pending_begin (transaction, rai::pending_key (account, 0))), n (node.store.pending_begin (transaction, rai::pending_key (end, 0))); i != n && peers_l.size ()< count; ++i) { rai::pending_key key (i->first); - boost::property_tree::ptree entry; if (threshold.is_zero ()) { + boost::property_tree::ptree entry; entry.put ("", key.hash.to_string ()); peers_l.push_back (std::make_pair ("", entry)); } @@ -1395,8 +1394,7 @@ void rai::rpc_handler::pending () rai::pending_info info (i->second); if (info.amount.number () >= threshold.number ()) { - entry.put (key.hash.to_string (), info.amount.number ().convert_to ()); - peers_l.push_back (std::make_pair ("", entry)); + peers_l.put (key.hash.to_string (), info.amount.number ().convert_to ()); } } } @@ -2471,9 +2469,9 @@ void rai::rpc_handler::wallet_pending () for (auto ii (node.store.pending_begin (transaction, rai::pending_key (account, 0))), nn (node.store.pending_begin (transaction, rai::pending_key (end, 0))); ii != nn && peers_l.size ()< count; ++ii) { rai::pending_key key (ii->first); - boost::property_tree::ptree entry; if (threshold.is_zero ()) { + boost::property_tree::ptree entry; entry.put ("", key.hash.to_string ()); peers_l.push_back (std::make_pair ("", entry)); } @@ -2482,8 +2480,7 @@ void rai::rpc_handler::wallet_pending () rai::pending_info info (ii->second); if (info.amount.number () >= threshold.number ()) { - entry.put (key.hash.to_string (), info.amount.number ().convert_to ()); - peers_l.push_back (std::make_pair ("", entry)); + peers_l.put (key.hash.to_string (), info.amount.number ().convert_to ()); } } } @@ -2492,7 +2489,7 @@ void rai::rpc_handler::wallet_pending () pending.add_child (account.to_account (), peers_l); } } - response_l.add_child ("pending", pending); + response_l.add_child ("blocks", pending); response (response_l); } else From ef7fc179d3fb29db976b3632d1a18ec5cd993d4e Mon Sep 17 00:00:00 2001 From: SergiySW Date: Thu, 27 Jul 2017 16:32:34 +0300 Subject: [PATCH 19/19] uint64_t count numeric_limits --- rai/node/rpc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rai/node/rpc.cpp b/rai/node/rpc.cpp index 8aca2380..3155848d 100755 --- a/rai/node/rpc.cpp +++ b/rai/node/rpc.cpp @@ -588,7 +588,7 @@ void rai::rpc_handler::accounts_frontiers () void rai::rpc_handler::accounts_pending () { - uint64_t count (18446744073709551615U); + uint64_t count (std::numeric_limits ::max ()); rai::uint128_union threshold (0); try { @@ -1347,7 +1347,7 @@ void rai::rpc_handler::pending () rai::account account; if (!account.decode_account(account_text)) { - uint64_t count (18446744073709551615U); + uint64_t count (std::numeric_limits ::max ()); rai::uint128_union threshold (0); try { @@ -2430,7 +2430,7 @@ void rai::rpc_handler::wallet_pending () auto existing (node.wallets.items.find (wallet)); if (existing != node.wallets.items.end ()) { - uint64_t count (18446744073709551615U); + uint64_t count (std::numeric_limits ::max ()); rai::uint128_union threshold (0); try {