RPC ledger, accounts_create, block_create (offline signing), wallet_lock
This commit is contained in:
commit
9a594e6f21
5 changed files with 1453 additions and 161 deletions
|
@ -900,15 +900,15 @@ TEST (rpc, history_count)
|
|||
|
||||
TEST (rpc, process_block)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
rai::system system (24000, 1);
|
||||
rai::keypair key;
|
||||
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));
|
||||
rai::rpc rpc (system.service, node1, rai::rpc_config (true));
|
||||
rai::rpc rpc (system.service, node1, rai::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "process");
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "process");
|
||||
std::string json;
|
||||
send.serialize_json (json);
|
||||
request.put ("block", json);
|
||||
|
@ -917,8 +917,10 @@ TEST (rpc, process_block)
|
|||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response.status);
|
||||
ASSERT_EQ (200, response.status);
|
||||
ASSERT_EQ (send.hash (), system.nodes [0]->latest (rai::test_genesis_key.pub));
|
||||
std::string send_hash (response.json.get <std::string> ("hash"));
|
||||
ASSERT_EQ (send.hash ().to_string (), send_hash);
|
||||
}
|
||||
|
||||
TEST (rpc, process_block_no_work)
|
||||
|
@ -1286,6 +1288,27 @@ TEST (rpc, pending)
|
|||
ASSERT_EQ (200, response1.status);
|
||||
blocks_node = response1.json.get_child ("blocks");
|
||||
ASSERT_EQ (0, blocks_node.size ());
|
||||
request.put ("threshold", "0");
|
||||
request.put ("source", "true");
|
||||
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");
|
||||
ASSERT_EQ (1, blocks_node.size ());
|
||||
std::unordered_map <rai::block_hash, rai::uint128_union> amounts;
|
||||
std::unordered_map <rai::block_hash, rai::account> sources;
|
||||
for (auto i (blocks_node.begin ()), j (blocks_node.end ()); i != j; ++i)
|
||||
{
|
||||
rai::block_hash hash;
|
||||
hash.decode_hex (i->first);
|
||||
amounts[hash].decode_dec (i->second.get <std::string> ("amount"));
|
||||
sources[hash].decode_account (i->second.get <std::string> ("source"));
|
||||
}
|
||||
ASSERT_EQ (amounts[block1->hash ()], 100);
|
||||
ASSERT_EQ (sources[block1->hash ()], rai::test_genesis_key.pub);
|
||||
}
|
||||
|
||||
TEST (rpc_config, serialization)
|
||||
|
@ -1790,18 +1813,18 @@ TEST (rpc, account_remove)
|
|||
|
||||
TEST (rpc, representatives)
|
||||
{
|
||||
rai::system system0 (24000, 1);
|
||||
rai::rpc rpc (system0.service, *system0.nodes [0], rai::rpc_config (true));
|
||||
rai::system system0 (24000, 1);
|
||||
rai::rpc rpc (system0.service, *system0.nodes [0], rai::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
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"));
|
||||
ASSERT_EQ (200, response.status);
|
||||
auto & representatives_node (response.json.get_child ("representatives"));
|
||||
std::vector <rai::account> representatives;
|
||||
for (auto i (representatives_node.begin ()), n (representatives_node.end ()); i != n; ++i)
|
||||
{
|
||||
|
@ -1959,7 +1982,7 @@ TEST (rpc, bootstrap_any)
|
|||
ASSERT_TRUE (success.empty());
|
||||
}
|
||||
|
||||
TEST (rpc, DISABLED_republish)
|
||||
TEST (rpc, republish)
|
||||
{
|
||||
rai::system system (24000, 2);
|
||||
rai::keypair key;
|
||||
|
@ -2164,11 +2187,11 @@ TEST (rpc, accounts_pending)
|
|||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response1.status);
|
||||
std::unordered_map <rai::block_hash, rai::uint128_union> blocks;
|
||||
for (auto & pending : response1.json.get_child("blocks"))
|
||||
{
|
||||
std::string account_text (pending.first);
|
||||
ASSERT_EQ (key1.pub.to_account (), account_text);
|
||||
std::unordered_map <rai::block_hash, rai::uint128_union> blocks;
|
||||
for (auto i (pending.second.begin ()), j (pending.second.end ()); i != j; ++i)
|
||||
{
|
||||
rai::block_hash hash;
|
||||
|
@ -2177,8 +2200,31 @@ TEST (rpc, accounts_pending)
|
|||
amount.decode_dec (i->second.get <std::string> (""));
|
||||
blocks [hash] = amount;
|
||||
}
|
||||
ASSERT_EQ (blocks[block1->hash ()], 100);
|
||||
}
|
||||
ASSERT_EQ (blocks[block1->hash ()], 100);
|
||||
request.put ("source", "true");
|
||||
test_response response2 (request, rpc, system.service);
|
||||
while (response2.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response2.status);
|
||||
std::unordered_map <rai::block_hash, rai::uint128_union> amounts;
|
||||
std::unordered_map <rai::block_hash, rai::account> sources;
|
||||
for (auto & pending : response2.json.get_child("blocks"))
|
||||
{
|
||||
std::string account_text (pending.first);
|
||||
ASSERT_EQ (key1.pub.to_account (), account_text);
|
||||
for (auto i (pending.second.begin ()), j (pending.second.end ()); i != j; ++i)
|
||||
{
|
||||
rai::block_hash hash;
|
||||
hash.decode_hex (i->first);
|
||||
amounts[hash].decode_dec (i->second.get <std::string> ("amount"));
|
||||
sources[hash].decode_account (i->second.get <std::string> ("source"));
|
||||
}
|
||||
}
|
||||
ASSERT_EQ (amounts[block1->hash ()], 100);
|
||||
ASSERT_EQ (sources[block1->hash ()], rai::test_genesis_key.pub);
|
||||
}
|
||||
|
||||
TEST (rpc, blocks)
|
||||
|
@ -2256,6 +2302,25 @@ TEST (rpc, wallet_balances)
|
|||
std::string pending_text (balances.second.get <std::string> ("pending"));
|
||||
ASSERT_EQ ("0", pending_text);
|
||||
}
|
||||
rai::keypair key;
|
||||
system0.wallet (0)->insert_adhoc (key.prv);
|
||||
auto send (system0.wallet (0)->send_action (rai::test_genesis_key.pub, key.pub, 1));
|
||||
request.put ("threshold", "2");
|
||||
test_response response1 (request, rpc, system0.service);
|
||||
while (response1.status == 0)
|
||||
{
|
||||
system0.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response1.status);
|
||||
for (auto & balances : response1.json.get_child("balances"))
|
||||
{
|
||||
std::string account_text (balances.first);
|
||||
ASSERT_EQ (rai::test_genesis_key.pub.to_account (), account_text);
|
||||
std::string balance_text (balances.second.get <std::string> ("balance"));
|
||||
ASSERT_EQ ("340282366920938463463374607431768211454", balance_text);
|
||||
std::string pending_text (balances.second.get <std::string> ("pending"));
|
||||
ASSERT_EQ ("0", pending_text);
|
||||
}
|
||||
}
|
||||
|
||||
TEST (rpc, pending_exists)
|
||||
|
@ -2294,6 +2359,7 @@ TEST (rpc, wallet_pending)
|
|||
rai::system system0 (24000, 1);
|
||||
rai::keypair key1;
|
||||
system0.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
|
||||
system0.wallet (0)->insert_adhoc (key1.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 ();
|
||||
|
@ -2310,10 +2376,8 @@ TEST (rpc, wallet_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);
|
||||
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 <std::string> (""));
|
||||
ASSERT_EQ (key1.pub.to_account (), account_text);
|
||||
rai::block_hash hash1 (pending.second.begin ()->second.get <std::string> (""));
|
||||
ASSERT_EQ (block1->hash (), hash1);
|
||||
}
|
||||
request.put ("threshold", "100"); // Threshold test
|
||||
|
@ -2323,11 +2387,11 @@ TEST (rpc, wallet_pending)
|
|||
system0.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response0.status);
|
||||
std::unordered_map <rai::block_hash, rai::uint128_union> blocks;
|
||||
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);
|
||||
std::unordered_map <rai::block_hash, rai::uint128_union> blocks;
|
||||
ASSERT_EQ (key1.pub.to_account (), account_text);
|
||||
for (auto i (pending.second.begin ()), j (pending.second.end ()); i != j; ++i)
|
||||
{
|
||||
rai::block_hash hash;
|
||||
|
@ -2336,8 +2400,8 @@ TEST (rpc, wallet_pending)
|
|||
amount.decode_dec (i->second.get <std::string> (""));
|
||||
blocks [hash] = amount;
|
||||
}
|
||||
ASSERT_EQ (blocks[block1->hash ()], 100);
|
||||
}
|
||||
ASSERT_EQ (blocks[block1->hash ()], 100);
|
||||
request.put ("threshold", "101");
|
||||
test_response response1 (request, rpc, system0.service);
|
||||
while (response1.status == 0)
|
||||
|
@ -2347,6 +2411,30 @@ TEST (rpc, wallet_pending)
|
|||
ASSERT_EQ (200, response1.status);
|
||||
auto & pending1 (response1.json.get_child ("blocks"));
|
||||
ASSERT_EQ (0, pending1.size ());
|
||||
request.put ("threshold", "0");
|
||||
request.put ("source", "true");
|
||||
test_response response2 (request, rpc, system0.service);
|
||||
while (response2.status == 0)
|
||||
{
|
||||
system0.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response2.status);
|
||||
std::unordered_map <rai::block_hash, rai::uint128_union> amounts;
|
||||
std::unordered_map <rai::block_hash, rai::account> sources;
|
||||
for (auto & pending : response2.json.get_child("blocks"))
|
||||
{
|
||||
std::string account_text (pending.first);
|
||||
ASSERT_EQ (key1.pub.to_account (), account_text);
|
||||
for (auto i (pending.second.begin ()), j (pending.second.end ()); i != j; ++i)
|
||||
{
|
||||
rai::block_hash hash;
|
||||
hash.decode_hex (i->first);
|
||||
amounts[hash].decode_dec (i->second.get <std::string> ("amount"));
|
||||
sources[hash].decode_account (i->second.get <std::string> ("source"));
|
||||
}
|
||||
}
|
||||
ASSERT_EQ (amounts[block1->hash ()], 100);
|
||||
ASSERT_EQ (sources[block1->hash ()], rai::test_genesis_key.pub);
|
||||
}
|
||||
|
||||
TEST (rpc, receive_minimum)
|
||||
|
@ -2487,7 +2575,7 @@ TEST (rpc, search_pending_all)
|
|||
}
|
||||
}
|
||||
|
||||
TEST (rpc, DISABLED_wallet_republish)
|
||||
TEST (rpc, wallet_republish)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
rai::genesis genesis;
|
||||
|
@ -2713,3 +2801,267 @@ TEST (rpc, work_peers_all)
|
|||
peers_node = response3.json.get_child ("work_peers");
|
||||
ASSERT_EQ (0, peers_node.size ());
|
||||
}
|
||||
|
||||
TEST (rpc, block_count_type)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
|
||||
auto send (system.wallet (0)->send_action (rai::test_genesis_key.pub, rai::test_genesis_key.pub, system.nodes [0]->config.receive_minimum.number ()));
|
||||
ASSERT_NE (nullptr, send);
|
||||
auto receive (system.wallet (0)->receive_action (static_cast <rai::send_block &>(*send), rai::test_genesis_key.pub, system.nodes [0]->config.receive_minimum.number ()));
|
||||
ASSERT_NE (nullptr, receive);
|
||||
rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "block_count_type");
|
||||
test_response response (request, rpc, system.service);
|
||||
while (response.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response.status);
|
||||
std::string send_count (response.json.get <std::string> ("send"));
|
||||
ASSERT_EQ ("1", send_count);
|
||||
std::string receive_count (response.json.get <std::string> ("receive"));
|
||||
ASSERT_EQ ("1", receive_count);
|
||||
std::string open_count (response.json.get <std::string> ("open"));
|
||||
ASSERT_EQ ("1", open_count);
|
||||
std::string change_count (response.json.get <std::string> ("change"));
|
||||
ASSERT_EQ ("0", change_count);
|
||||
}
|
||||
|
||||
TEST (rpc, ledger)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
rai::keypair key;
|
||||
rai::genesis genesis;
|
||||
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 (), rai::test_genesis_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);
|
||||
auto time (std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
|
||||
rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "ledger");
|
||||
request.put ("sorting", "1");
|
||||
request.put ("count", "1");
|
||||
test_response response (request, rpc, system.service);
|
||||
while (response.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
for (auto & accounts : response.json.get_child("accounts"))
|
||||
{
|
||||
std::string account_text (accounts.first);
|
||||
ASSERT_EQ (key.pub.to_account (), account_text);
|
||||
std::string frontier (accounts.second.get <std::string> ("frontier"));
|
||||
ASSERT_EQ (open.hash ().to_string (), frontier);
|
||||
std::string open_block (accounts.second.get <std::string> ("open_block"));
|
||||
ASSERT_EQ (open.hash ().to_string (), open_block);
|
||||
std::string representative_block (accounts.second.get <std::string> ("representative_block"));
|
||||
ASSERT_EQ (open.hash ().to_string (), representative_block);
|
||||
std::string balance_text (accounts.second.get <std::string> ("balance"));
|
||||
ASSERT_EQ ("340282366920938463463374607431768211355", balance_text);
|
||||
std::string modified_timestamp (accounts.second.get <std::string> ("modified_timestamp"));
|
||||
ASSERT_EQ (std::to_string (time), modified_timestamp);
|
||||
std::string block_count (accounts.second.get <std::string> ("block_count"));
|
||||
ASSERT_EQ ("1", block_count);
|
||||
}
|
||||
}
|
||||
|
||||
TEST (rpc, accounts_create)
|
||||
{
|
||||
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", "accounts_create");
|
||||
request.put ("wallet", system.nodes [0]->wallets.items.begin ()->first.to_string ());
|
||||
request.put ("count", "8");
|
||||
test_response response (request, rpc, system.service);
|
||||
while (response.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response.status);
|
||||
auto & accounts (response.json.get_child ("accounts"));
|
||||
for (auto i (accounts.begin ()), n (accounts.end ()); i != n; ++i)
|
||||
{
|
||||
std::string account_text (i->second.get <std::string> (""));
|
||||
rai::uint256_union account;
|
||||
ASSERT_FALSE (account.decode_account (account_text));
|
||||
ASSERT_TRUE (system.wallet (0)->exists (account));
|
||||
}
|
||||
ASSERT_EQ (8, accounts.size ());
|
||||
}
|
||||
|
||||
TEST (rpc, block_create)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
rai::keypair key;
|
||||
rai::genesis genesis;
|
||||
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));
|
||||
auto send_work = node1.generate_work (latest);
|
||||
rai::send_block send (latest, key.pub, 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, send_work);
|
||||
auto open_work = node1.generate_work (key.pub);
|
||||
rai::open_block open (send.hash (), rai::test_genesis_key.pub, key.pub, key.prv, key.pub, open_work);
|
||||
rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "block_create");
|
||||
request.put ("type", "send");
|
||||
request.put ("wallet", system.nodes [0]->wallets.items.begin ()->first.to_string ());
|
||||
request.put ("account", rai::test_genesis_key.pub.to_account ());
|
||||
request.put ("previous", latest.to_string ());
|
||||
request.put ("amount", "340282366920938463463374607431768211355");
|
||||
request.put ("destination", key.pub.to_account ());
|
||||
request.put ("work", rai::to_string_hex (send_work));
|
||||
test_response response (request, rpc, system.service);
|
||||
while (response.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response.status);
|
||||
std::string send_hash (response.json.get <std::string> ("hash"));
|
||||
ASSERT_EQ (send.hash ().to_string (), send_hash);
|
||||
auto send_text (response.json.get <std::string> ("block"));
|
||||
boost::property_tree::ptree block_l;
|
||||
std::stringstream block_stream (send_text);
|
||||
boost::property_tree::read_json (block_stream, block_l);
|
||||
auto send_block (rai::deserialize_block_json (block_l));
|
||||
ASSERT_EQ (send.hash (), send_block->hash ());
|
||||
system.nodes [0]->process (send);
|
||||
boost::property_tree::ptree request1;
|
||||
request1.put ("action", "block_create");
|
||||
request1.put ("type", "open");
|
||||
std::string key_text;
|
||||
key.prv.data.encode_hex (key_text);
|
||||
request1.put ("key", key_text);
|
||||
request1.put ("representative", rai::test_genesis_key.pub.to_account ());
|
||||
request1.put ("source", send.hash ().to_string ());
|
||||
request1.put ("work", rai::to_string_hex (open_work));
|
||||
test_response response1 (request1, rpc, system.service);
|
||||
while (response1.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response1.status);
|
||||
std::string open_hash (response1.json.get <std::string> ("hash"));
|
||||
ASSERT_EQ (open.hash ().to_string (), open_hash);
|
||||
auto open_text (response1.json.get <std::string> ("block"));
|
||||
std::stringstream block_stream1 (open_text);
|
||||
boost::property_tree::read_json (block_stream1, block_l);
|
||||
auto open_block (rai::deserialize_block_json (block_l));
|
||||
ASSERT_EQ (open.hash (), open_block->hash ());
|
||||
ASSERT_EQ (rai::process_result::progress, system.nodes [0]->process (open).code);
|
||||
request1.put ("representative", key.pub.to_account ());
|
||||
test_response response2 (request1, rpc, system.service);
|
||||
while (response2.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response2.status);
|
||||
std::string open2_hash (response2.json.get <std::string> ("hash"));
|
||||
ASSERT_NE (open.hash ().to_string (), open2_hash); // different blocks with wrong representative
|
||||
auto change_work = node1.generate_work (open.hash ());
|
||||
rai::change_block change (open.hash (), key.pub, key.prv, key.pub, change_work);
|
||||
request1.put ("type", "change");
|
||||
request1.put ("work", rai::to_string_hex (change_work));
|
||||
test_response response3 (request1, rpc, system.service);
|
||||
while (response3.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response3.status);
|
||||
ASSERT_FALSE (response3.json.get <std::string> ("error").empty ()); // error with missing previous block
|
||||
request1.put ("previous", open.hash ().to_string ());
|
||||
test_response response4 (request1, rpc, system.service);
|
||||
while (response4.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response4.status);
|
||||
std::string change_hash (response4.json.get <std::string> ("hash"));
|
||||
ASSERT_EQ (change.hash ().to_string (), change_hash);
|
||||
auto change_text (response4.json.get <std::string> ("block"));
|
||||
std::stringstream block_stream4 (change_text);
|
||||
boost::property_tree::read_json (block_stream4, block_l);
|
||||
auto change_block (rai::deserialize_block_json (block_l));
|
||||
ASSERT_EQ (change.hash (), change_block->hash ());
|
||||
ASSERT_EQ (rai::process_result::progress, node1.process (change).code);
|
||||
rai::send_block send2 (send.hash (), key.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, node1.generate_work (send.hash ()));
|
||||
ASSERT_EQ (rai::process_result::progress, system.nodes [0]->process (send2).code);
|
||||
boost::property_tree::ptree request2;
|
||||
request2.put ("action", "block_create");
|
||||
request2.put ("type", "receive");
|
||||
request2.put ("wallet", system.nodes [0]->wallets.items.begin ()->first.to_string ());
|
||||
request2.put ("account", key.pub.to_account ());
|
||||
request2.put ("source", send2.hash ().to_string ());
|
||||
request2.put ("previous", change.hash ().to_string ());
|
||||
request2.put ("work", rai::to_string_hex (node1.generate_work (change.hash ())));
|
||||
test_response response5 (request2, rpc, system.service);
|
||||
while (response5.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response5.status);
|
||||
std::string receive_hash (response4.json.get <std::string> ("hash"));
|
||||
auto receive_text (response5.json.get <std::string> ("block"));
|
||||
std::stringstream block_stream5 (change_text);
|
||||
boost::property_tree::read_json (block_stream5, block_l);
|
||||
auto receive_block (rai::deserialize_block_json (block_l));
|
||||
ASSERT_EQ (receive_hash, receive_block->hash ().to_string ());
|
||||
system.nodes [0]->process_active (std::move (receive_block));
|
||||
latest = system.nodes [0]->latest (key.pub);
|
||||
ASSERT_EQ (receive_hash, latest.to_string ());
|
||||
}
|
||||
|
||||
TEST (rpc, wallet_lock)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
std::string wallet;
|
||||
system.nodes [0]->wallets.items.begin ()->first.encode_hex (wallet);
|
||||
ASSERT_TRUE (system.wallet (0)->valid_password ());
|
||||
request.put ("wallet", wallet);
|
||||
request.put ("action", "wallet_lock");
|
||||
test_response response (request, rpc, system.service);
|
||||
while (response.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response.status);
|
||||
std::string account_text1 (response.json.get <std::string> ("locked"));
|
||||
ASSERT_EQ (account_text1, "1");
|
||||
ASSERT_FALSE (system.wallet (0)->valid_password ());
|
||||
}
|
||||
|
||||
TEST (rpc, wallet_locked)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
rai::rpc rpc (system.service, *system.nodes [0], rai::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
std::string wallet;
|
||||
system.nodes [0]->wallets.items.begin ()->first.encode_hex (wallet);
|
||||
request.put ("wallet", wallet);
|
||||
request.put ("action", "wallet_locked");
|
||||
test_response response (request, rpc, system.service);
|
||||
while (response.status == 0)
|
||||
{
|
||||
system.poll ();
|
||||
}
|
||||
ASSERT_EQ (200, response.status);
|
||||
std::string account_text1 (response.json.get <std::string> ("locked"));
|
||||
ASSERT_EQ (account_text1, "0");
|
||||
}
|
||||
|
|
1046
rai/node/rpc.cpp
1046
rai/node/rpc.cpp
File diff suppressed because it is too large
Load diff
|
@ -104,6 +104,7 @@ public:
|
|||
void account_representative_set ();
|
||||
void account_weight ();
|
||||
void accounts_balances ();
|
||||
void accounts_create ();
|
||||
void accounts_frontiers ();
|
||||
void accounts_pending ();
|
||||
void available_supply ();
|
||||
|
@ -113,6 +114,7 @@ public:
|
|||
void block_account ();
|
||||
void block_count ();
|
||||
void block_count_type ();
|
||||
void block_create ();
|
||||
void bootstrap ();
|
||||
void bootstrap_any ();
|
||||
void chain ();
|
||||
|
@ -127,11 +129,12 @@ public:
|
|||
void key_expand ();
|
||||
void krai_to_raw ();
|
||||
void krai_from_raw ();
|
||||
void ledger ();
|
||||
void mrai_to_raw ();
|
||||
void mrai_from_raw ();
|
||||
void password_change ();
|
||||
void password_enter ();
|
||||
void password_valid ();
|
||||
void password_valid (bool wallet_locked);
|
||||
void payment_begin ();
|
||||
void payment_init ();
|
||||
void payment_end ();
|
||||
|
@ -168,6 +171,7 @@ public:
|
|||
void wallet_export ();
|
||||
void wallet_frontiers ();
|
||||
void wallet_key_valid ();
|
||||
void wallet_lock ();
|
||||
void wallet_pending ();
|
||||
void wallet_representative ();
|
||||
void wallet_representative_set ();
|
||||
|
|
|
@ -908,38 +908,68 @@ bool rai::wallet::enter_password (std::string const & password_a)
|
|||
}
|
||||
|
||||
rai::public_key rai::wallet::deterministic_insert (MDB_txn * transaction_a)
|
||||
{
|
||||
auto result (deterministic_insert(transaction_a, true));
|
||||
return result;
|
||||
}
|
||||
|
||||
rai::public_key rai::wallet::deterministic_insert (MDB_txn * transaction_a, bool const & generate_work_a)
|
||||
{
|
||||
rai::public_key key (0);
|
||||
if (store.valid_password (transaction_a))
|
||||
{
|
||||
key = store.deterministic_insert (transaction_a);
|
||||
work_ensure (transaction_a, key);
|
||||
if (generate_work_a)
|
||||
{
|
||||
work_ensure (transaction_a, key);
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
rai::public_key rai::wallet::deterministic_insert ()
|
||||
{
|
||||
auto result (deterministic_insert (true));
|
||||
return result;
|
||||
}
|
||||
|
||||
rai::public_key rai::wallet::deterministic_insert (bool const & generate_work_a)
|
||||
{
|
||||
rai::transaction transaction (store.environment, nullptr, true);
|
||||
auto result (deterministic_insert (transaction));
|
||||
auto result (deterministic_insert (transaction, generate_work_a));
|
||||
return result;
|
||||
}
|
||||
|
||||
rai::public_key rai::wallet::insert_adhoc (MDB_txn * transaction_a, rai::raw_key const & key_a)
|
||||
{
|
||||
auto result (insert_adhoc (transaction_a, key_a, true));
|
||||
return result;
|
||||
}
|
||||
|
||||
rai::public_key rai::wallet::insert_adhoc (MDB_txn * transaction_a, rai::raw_key const & key_a, bool const & generate_work_a)
|
||||
{
|
||||
rai::public_key key (0);
|
||||
if (store.valid_password (transaction_a))
|
||||
{
|
||||
key = store.insert_adhoc (transaction_a, key_a);
|
||||
work_ensure (transaction_a, key);
|
||||
if (generate_work_a)
|
||||
{
|
||||
work_ensure (transaction_a, key);
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
rai::public_key rai::wallet::insert_adhoc (rai::raw_key const & account_a)
|
||||
{
|
||||
auto result (insert_adhoc (account_a, true));
|
||||
return result;
|
||||
}
|
||||
|
||||
rai::public_key rai::wallet::insert_adhoc (rai::raw_key const & account_a, bool const & generate_work_a)
|
||||
{
|
||||
rai::transaction transaction (store.environment, nullptr, true);
|
||||
auto result (insert_adhoc (transaction, account_a));
|
||||
auto result (insert_adhoc (transaction, account_a, generate_work_a));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -994,6 +1024,11 @@ bool check_ownership (rai::wallets & wallets_a, rai::account const & account_a)
|
|||
}
|
||||
|
||||
std::shared_ptr <rai::block> rai::wallet::receive_action (rai::send_block const & send_a, rai::account const & representative_a, rai::uint128_union const & amount_a)
|
||||
{
|
||||
return receive_action (send_a, representative_a, amount_a, true);
|
||||
}
|
||||
|
||||
std::shared_ptr <rai::block> rai::wallet::receive_action (rai::send_block const & send_a, rai::account const & representative_a, rai::uint128_union const & amount_a, bool const & generate_work_a)
|
||||
{
|
||||
auto hash (send_a.hash ());
|
||||
std::shared_ptr <rai::block> block;
|
||||
|
@ -1037,17 +1072,30 @@ std::shared_ptr <rai::block> rai::wallet::receive_action (rai::send_block const
|
|||
assert (block != nullptr);
|
||||
node.process_active (block);
|
||||
auto hash (block->hash ());
|
||||
auto this_l (shared_from_this ());
|
||||
auto source (send_a.hashables.destination);
|
||||
node.wallets.queue_wallet_action (source, rai::wallets::generate_priority, [this_l, source, hash]
|
||||
if (generate_work_a)
|
||||
{
|
||||
this_l->work_generate (source, hash);
|
||||
});
|
||||
auto this_l (shared_from_this ());
|
||||
node.wallets.queue_wallet_action (source, rai::wallets::generate_priority, [this_l, source, hash]
|
||||
{
|
||||
this_l->work_generate (source, hash);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
rai::transaction transaction (store.environment, nullptr, true);
|
||||
work_update (transaction, source, hash, 0);
|
||||
}
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
std::shared_ptr <rai::block> rai::wallet::change_action (rai::account const & source_a, rai::account const & representative_a)
|
||||
{
|
||||
return change_action (source_a, representative_a, true);
|
||||
}
|
||||
|
||||
std::shared_ptr <rai::block> rai::wallet::change_action (rai::account const & source_a, rai::account const & representative_a, bool const & generate_work_a)
|
||||
{
|
||||
std::shared_ptr <rai::block> block;
|
||||
{
|
||||
|
@ -1075,16 +1123,29 @@ std::shared_ptr <rai::block> rai::wallet::change_action (rai::account const & so
|
|||
assert (block != nullptr);
|
||||
node.process_active (block);
|
||||
auto hash (block->hash ());
|
||||
auto this_l (shared_from_this ());
|
||||
node.wallets.queue_wallet_action (source_a, rai::wallets::generate_priority, [this_l, source_a, hash]
|
||||
if (generate_work_a)
|
||||
{
|
||||
this_l->work_generate (source_a, hash);
|
||||
});
|
||||
auto this_l (shared_from_this ());
|
||||
node.wallets.queue_wallet_action (source_a, rai::wallets::generate_priority, [this_l, source_a, hash]
|
||||
{
|
||||
this_l->work_generate (source_a, hash);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
rai::transaction transaction (store.environment, nullptr, true);
|
||||
work_update (transaction, source_a, hash, 0);
|
||||
}
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
std::shared_ptr <rai::block> rai::wallet::send_action (rai::account const & source_a, rai::account const & account_a, rai::uint128_t const & amount_a)
|
||||
{
|
||||
return send_action (source_a, account_a, amount_a, true);
|
||||
}
|
||||
|
||||
std::shared_ptr <rai::block> rai::wallet::send_action (rai::account const & source_a, rai::account const & account_a, rai::uint128_t const & amount_a, bool const & generate_work_a)
|
||||
{
|
||||
std::shared_ptr <rai::block> block;
|
||||
{
|
||||
|
@ -1116,11 +1177,19 @@ std::shared_ptr <rai::block> rai::wallet::send_action (rai::account const & sour
|
|||
assert (block != nullptr);
|
||||
node.process_active (block);
|
||||
auto hash (block->hash ());
|
||||
auto this_l (shared_from_this ());
|
||||
node.wallets.queue_wallet_action (source_a, rai::wallets::generate_priority, [this_l, source_a, hash]
|
||||
if (generate_work_a)
|
||||
{
|
||||
this_l->work_generate (source_a, hash);
|
||||
});
|
||||
auto this_l (shared_from_this ());
|
||||
node.wallets.queue_wallet_action (source_a, rai::wallets::generate_priority, [this_l, source_a, hash]
|
||||
{
|
||||
this_l->work_generate (source_a, hash);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
rai::transaction transaction (store.environment, nullptr, true);
|
||||
work_update (transaction, source_a, hash, 0);
|
||||
}
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
@ -1137,10 +1206,15 @@ bool rai::wallet::change_sync (rai::account const & source_a, rai::account const
|
|||
|
||||
void rai::wallet::change_async (rai::account const & source_a, rai::account const & representative_a, std::function <void (std::shared_ptr <rai::block>)> const & action_a)
|
||||
{
|
||||
node.wallets.queue_wallet_action (source_a, rai::wallets::high_priority, [this, source_a, representative_a, action_a] ()
|
||||
change_async (source_a, representative_a, action_a, true);
|
||||
}
|
||||
|
||||
void rai::wallet::change_async (rai::account const & source_a, rai::account const & representative_a, std::function <void (std::shared_ptr <rai::block>)> const & action_a, bool const & generate_work_a)
|
||||
{
|
||||
node.wallets.queue_wallet_action (source_a, rai::wallets::high_priority, [this, source_a, representative_a, action_a, generate_work_a] ()
|
||||
{
|
||||
assert (!check_ownership (node.wallets, source_a));
|
||||
auto block (change_action (source_a, representative_a));
|
||||
auto block (change_action (source_a, representative_a, generate_work_a));
|
||||
action_a (block);
|
||||
});
|
||||
}
|
||||
|
@ -1156,12 +1230,17 @@ bool rai::wallet::receive_sync (std::shared_ptr <rai::block> block_a, rai::accou
|
|||
}
|
||||
|
||||
void rai::wallet::receive_async (std::shared_ptr <rai::block> block_a, rai::account const & representative_a, rai::uint128_t const & amount_a, std::function <void (std::shared_ptr <rai::block>)> const & action_a)
|
||||
{
|
||||
receive_async (block_a, representative_a, amount_a, action_a, true);
|
||||
}
|
||||
|
||||
void rai::wallet::receive_async (std::shared_ptr <rai::block> block_a, rai::account const & representative_a, rai::uint128_t const & amount_a, std::function <void (std::shared_ptr <rai::block>)> const & action_a, bool const & generate_work_a)
|
||||
{
|
||||
assert (dynamic_cast <rai::send_block *> (block_a.get ()) != nullptr);
|
||||
node.wallets.queue_wallet_action (static_cast <rai::send_block *> (block_a.get ())->hashables.destination, amount_a, [this, block_a, representative_a, amount_a, action_a] ()
|
||||
node.wallets.queue_wallet_action (static_cast <rai::send_block *> (block_a.get ())->hashables.destination, amount_a, [this, block_a, representative_a, amount_a, action_a, generate_work_a] ()
|
||||
{
|
||||
assert (!check_ownership (node.wallets, static_cast <rai::send_block *> (block_a.get ())->hashables.destination));
|
||||
auto block (receive_action (*static_cast <rai::send_block *> (block_a.get ()), representative_a, amount_a));
|
||||
auto block (receive_action (*static_cast <rai::send_block *> (block_a.get ()), representative_a, amount_a, generate_work_a));
|
||||
action_a (block);
|
||||
});
|
||||
}
|
||||
|
@ -1178,12 +1257,17 @@ rai::block_hash rai::wallet::send_sync (rai::account const & source_a, rai::acco
|
|||
|
||||
void rai::wallet::send_async (rai::account const & source_a, rai::account const & account_a, rai::uint128_t const & amount_a, std::function <void (std::shared_ptr <rai::block>)> const & action_a)
|
||||
{
|
||||
node.background ([this, source_a, account_a, amount_a, action_a] ()
|
||||
send_async (source_a, account_a, amount_a, action_a, true);
|
||||
}
|
||||
|
||||
void rai::wallet::send_async (rai::account const & source_a, rai::account const & account_a, rai::uint128_t const & amount_a, std::function <void (std::shared_ptr <rai::block>)> const & action_a, bool const & generate_work_a)
|
||||
{
|
||||
node.background ([this, source_a, account_a, amount_a, action_a, generate_work_a] ()
|
||||
{
|
||||
this->node.wallets.queue_wallet_action (source_a, rai::wallets::high_priority, [this, source_a, account_a, amount_a, action_a] ()
|
||||
this->node.wallets.queue_wallet_action (source_a, rai::wallets::high_priority, [this, source_a, account_a, amount_a, action_a, generate_work_a] ()
|
||||
{
|
||||
assert (!check_ownership (node.wallets, source_a));
|
||||
auto block (send_action (source_a, account_a, amount_a));
|
||||
auto block (send_action (source_a, account_a, amount_a, generate_work_a));
|
||||
action_a (block);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -149,36 +149,46 @@ class wallet : public std::enable_shared_from_this <rai::wallet>
|
|||
{
|
||||
public:
|
||||
std::shared_ptr <rai::block> change_action (rai::account const &, rai::account const &);
|
||||
std::shared_ptr <rai::block> receive_action (rai::send_block const &, rai::account const &, rai::uint128_union const &);
|
||||
std::shared_ptr <rai::block> change_action (rai::account const &, rai::account const &, bool const &);
|
||||
std::shared_ptr <rai::block> receive_action (rai::send_block const &, rai::account const &, rai::uint128_union const &);
|
||||
std::shared_ptr <rai::block> receive_action (rai::send_block const &, rai::account const &, rai::uint128_union const &, bool const &);
|
||||
std::shared_ptr <rai::block> send_action (rai::account const &, rai::account const &, rai::uint128_t const &);
|
||||
wallet (bool &, rai::transaction &, rai::node &, std::string const &);
|
||||
wallet (bool &, rai::transaction &, rai::node &, std::string const &, std::string const &);
|
||||
std::shared_ptr <rai::block> send_action (rai::account const &, rai::account const &, rai::uint128_t const &, bool const &);
|
||||
wallet (bool &, rai::transaction &, rai::node &, std::string const &);
|
||||
wallet (bool &, rai::transaction &, rai::node &, std::string const &, std::string const &);
|
||||
void enter_initial_password ();
|
||||
bool valid_password ();
|
||||
bool enter_password (std::string const &);
|
||||
bool valid_password ();
|
||||
bool enter_password (std::string const &);
|
||||
rai::public_key insert_adhoc (rai::raw_key const &);
|
||||
rai::public_key insert_adhoc (rai::raw_key const &, bool const &);
|
||||
rai::public_key insert_adhoc (MDB_txn *, rai::raw_key const &);
|
||||
rai::public_key insert_adhoc (MDB_txn *, rai::raw_key const &, bool const &);
|
||||
rai::public_key deterministic_insert (MDB_txn *);
|
||||
rai::public_key deterministic_insert (MDB_txn *, bool const &);
|
||||
rai::public_key deterministic_insert ();
|
||||
bool exists (rai::public_key const &);
|
||||
rai::public_key deterministic_insert (bool const &);
|
||||
bool exists (rai::public_key const &);
|
||||
bool import (std::string const &, std::string const &);
|
||||
void serialize (std::string &);
|
||||
bool change_sync (rai::account const &, rai::account const &);
|
||||
void change_async (rai::account const &, rai::account const &, std::function <void (std::shared_ptr <rai::block>)> const &);
|
||||
bool receive_sync (std::shared_ptr <rai::block>, rai::account const &, rai::uint128_t const &);
|
||||
void change_async (rai::account const &, rai::account const &, std::function <void (std::shared_ptr <rai::block>)> const &, bool const &);
|
||||
bool receive_sync (std::shared_ptr <rai::block>, rai::account const &, rai::uint128_t const &);
|
||||
void receive_async (std::shared_ptr <rai::block>, rai::account const &, rai::uint128_t const &, std::function <void (std::shared_ptr <rai::block>)> const &);
|
||||
void receive_async (std::shared_ptr <rai::block>, rai::account const &, rai::uint128_t const &, std::function <void (std::shared_ptr <rai::block>)> const &, bool const &);
|
||||
rai::block_hash send_sync (rai::account const &, rai::account const &, rai::uint128_t const &);
|
||||
void send_async (rai::account const &, rai::account const &, rai::uint128_t const &, std::function <void (std::shared_ptr <rai::block>)> const &);
|
||||
void work_generate (rai::account const &, rai::block_hash const &);
|
||||
void work_update (MDB_txn *, rai::account const &, rai::block_hash const &, uint64_t);
|
||||
uint64_t work_fetch (MDB_txn *, rai::account const &, rai::block_hash const &);
|
||||
void send_async (rai::account const &, rai::account const &, rai::uint128_t const &, std::function <void (std::shared_ptr <rai::block>)> const &, bool const &);
|
||||
void work_generate (rai::account const &, rai::block_hash const &);
|
||||
void work_update (MDB_txn *, rai::account const &, rai::block_hash const &, uint64_t);
|
||||
uint64_t work_fetch (MDB_txn *, rai::account const &, rai::block_hash const &);
|
||||
void work_ensure (MDB_txn *, rai::account const &);
|
||||
bool search_pending ();
|
||||
void init_free_accounts (MDB_txn *);
|
||||
std::unordered_set <rai::account> free_accounts;
|
||||
std::function <void (bool, bool)> lock_observer;
|
||||
rai::wallet_store store;
|
||||
rai::node & node;
|
||||
rai::wallet_store store;
|
||||
rai::node & node;
|
||||
};
|
||||
// The wallets set is all the wallets a node controls. A node may contain multiple wallets independently encrypted and operated.
|
||||
class wallets
|
||||
|
@ -187,8 +197,8 @@ public:
|
|||
wallets (bool &, rai::node &);
|
||||
std::shared_ptr <rai::wallet> open (rai::uint256_union const &);
|
||||
std::shared_ptr <rai::wallet> create (rai::uint256_union const &);
|
||||
bool search_pending (rai::uint256_union const &);
|
||||
void search_pending_all ();
|
||||
bool search_pending (rai::uint256_union const &);
|
||||
void search_pending_all ();
|
||||
void destroy (rai::uint256_union const &);
|
||||
void do_wallet_actions (rai::account const &);
|
||||
void queue_wallet_action (rai::account const &, rai::uint128_t const &, std::function <void ()> const &);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue