Improve RPC JSON depth handling (#1072)
This commit is contained in:
commit
62a8e677b3
5 changed files with 597 additions and 480 deletions
|
@ -96,7 +96,7 @@ TEST (wallet, one_item_iteration)
|
|||
rai::raw_key password;
|
||||
wallet.wallet_key (password, transaction);
|
||||
rai::raw_key key;
|
||||
key.decrypt (rai::wallet_value (i->second).key, password, wallet.salt (transaction).owords[0]);
|
||||
key.decrypt (rai::wallet_value (i->second).key, password, i->first.uint256 ().owords[0]);
|
||||
ASSERT_EQ (key1.prv, key);
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ TEST (wallet, two_item_iteration)
|
|||
rai::raw_key password;
|
||||
wallet.wallet_key (password, transaction);
|
||||
rai::raw_key key;
|
||||
key.decrypt (rai::wallet_value (i->second).key, password, wallet.salt (transaction).owords[0]);
|
||||
key.decrypt (rai::wallet_value (i->second).key, password, i->first.uint256 ().owords[0]);
|
||||
prvs.insert (key.data);
|
||||
}
|
||||
}
|
||||
|
@ -658,7 +658,7 @@ TEST (wallet, insert_locked)
|
|||
ASSERT_TRUE (wallet->insert_adhoc (rai::keypair ().prv).is_zero ());
|
||||
}
|
||||
|
||||
TEST (wallet, version_1_2_upgrade)
|
||||
TEST (wallet, version_1_upgrade)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
auto wallet (system.wallet (0));
|
||||
|
@ -683,7 +683,7 @@ TEST (wallet, version_1_2_upgrade)
|
|||
|
||||
wallet->enter_password ("1");
|
||||
ASSERT_TRUE (wallet->valid_password ());
|
||||
ASSERT_EQ (2, wallet->store.version (rai::transaction (wallet->store.environment, nullptr, false)));
|
||||
ASSERT_EQ (wallet->store.version_current, wallet->store.version (rai::transaction (wallet->store.environment, nullptr, false)));
|
||||
rai::raw_key prv;
|
||||
ASSERT_FALSE (wallet->store.fetch (rai::transaction (wallet->store.environment, nullptr, false), key.pub, prv));
|
||||
ASSERT_EQ (key.prv, prv);
|
||||
|
@ -702,7 +702,7 @@ TEST (wallet, version_1_2_upgrade)
|
|||
}
|
||||
wallet->enter_password ("1");
|
||||
ASSERT_TRUE (wallet->valid_password ());
|
||||
ASSERT_EQ (2, wallet->store.version (rai::transaction (wallet->store.environment, nullptr, false)));
|
||||
ASSERT_EQ (wallet->store.version_current, wallet->store.version (rai::transaction (wallet->store.environment, nullptr, false)));
|
||||
rai::raw_key prv2;
|
||||
ASSERT_FALSE (wallet->store.fetch (rai::transaction (wallet->store.environment, nullptr, false), key.pub, prv2));
|
||||
ASSERT_EQ (key.prv, prv2);
|
||||
|
@ -798,7 +798,7 @@ TEST (wallet, insert_deterministic_locked)
|
|||
ASSERT_TRUE (wallet->deterministic_insert ().is_zero ());
|
||||
}
|
||||
|
||||
TEST (wallet, version_2_3_upgrade)
|
||||
TEST (wallet, version_2_upgrade)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
auto wallet (system.wallet (0));
|
||||
|
@ -818,12 +818,53 @@ TEST (wallet, version_2_3_upgrade)
|
|||
wallet->store.attempt_password (transaction, "1");
|
||||
}
|
||||
rai::transaction transaction (wallet->store.environment, nullptr, false);
|
||||
ASSERT_EQ (3, wallet->store.version (transaction));
|
||||
ASSERT_EQ (wallet->store.version_current, wallet->store.version (transaction));
|
||||
ASSERT_TRUE (wallet->store.exists (transaction, rai::wallet_store::deterministic_index_special));
|
||||
ASSERT_TRUE (wallet->store.exists (transaction, rai::wallet_store::seed_special));
|
||||
ASSERT_FALSE (wallet->deterministic_insert ().is_zero ());
|
||||
}
|
||||
|
||||
TEST (wallet, version_3_upgrade)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
auto wallet (system.wallet (0));
|
||||
wallet->store.rekey (rai::transaction (wallet->store.environment, nullptr, true), "1");
|
||||
wallet->enter_password ("1");
|
||||
ASSERT_TRUE (wallet->valid_password ());
|
||||
ASSERT_EQ (wallet->store.version_current, wallet->store.version (rai::transaction (wallet->store.environment, nullptr, false)));
|
||||
rai::keypair key;
|
||||
rai::raw_key seed;
|
||||
rai::uint256_union seed_ciphertext;
|
||||
rai::random_pool.GenerateBlock (seed.data.bytes.data (), seed.data.bytes.size ());
|
||||
{
|
||||
rai::transaction transaction (wallet->store.environment, nullptr, true);
|
||||
rai::raw_key password_l;
|
||||
rai::wallet_value value (wallet->store.entry_get_raw (transaction, rai::wallet_store::wallet_key_special));
|
||||
rai::raw_key kdf;
|
||||
wallet->store.derive_key (kdf, transaction, "1");
|
||||
password_l.decrypt (value.key, kdf, wallet->store.salt (transaction).owords[0]);
|
||||
rai::uint256_union ciphertext;
|
||||
ciphertext.encrypt (key.prv, password_l, wallet->store.salt (transaction).owords[0]);
|
||||
wallet->store.entry_put_raw (transaction, key.pub, rai::wallet_value (ciphertext, 0));
|
||||
seed_ciphertext.encrypt (seed, password_l, wallet->store.salt (transaction).owords[0]);
|
||||
wallet->store.entry_put_raw (transaction, rai::wallet_store::seed_special, rai::wallet_value (seed_ciphertext, 0));
|
||||
wallet->store.version_put (transaction, 3);
|
||||
}
|
||||
wallet->enter_password ("1");
|
||||
ASSERT_TRUE (wallet->valid_password ());
|
||||
ASSERT_EQ (wallet->store.version_current, wallet->store.version (rai::transaction (wallet->store.environment, nullptr, false)));
|
||||
rai::raw_key prv;
|
||||
ASSERT_FALSE (wallet->store.fetch (rai::transaction (wallet->store.environment, nullptr, false), key.pub, prv));
|
||||
ASSERT_EQ (key.prv, prv);
|
||||
{
|
||||
rai::transaction transaction (wallet->store.environment, nullptr, false);
|
||||
rai::raw_key seed_compare;
|
||||
wallet->store.seed (seed_compare, transaction);
|
||||
ASSERT_EQ (seed, seed_compare);
|
||||
ASSERT_NE (seed_ciphertext, wallet->store.entry_get_raw (transaction, rai::wallet_store::seed_special).key);
|
||||
}
|
||||
}
|
||||
|
||||
TEST (wallet, no_work)
|
||||
{
|
||||
rai::system system (24000, 1);
|
||||
|
|
931
rai/node/rpc.cpp
931
rai/node/rpc.cpp
|
@ -53,7 +53,8 @@ address (boost::asio::ip::address_v6::loopback ()),
|
|||
port (rai::rpc::rpc_port),
|
||||
enable_control (false),
|
||||
frontier_request_limit (16384),
|
||||
chain_request_limit (16384)
|
||||
chain_request_limit (16384),
|
||||
max_json_depth (20)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -62,7 +63,8 @@ address (boost::asio::ip::address_v6::loopback ()),
|
|||
port (rai::rpc::rpc_port),
|
||||
enable_control (enable_control_a),
|
||||
frontier_request_limit (16384),
|
||||
chain_request_limit (16384)
|
||||
chain_request_limit (16384),
|
||||
max_json_depth (20)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -73,6 +75,7 @@ void rai::rpc_config::serialize_json (boost::property_tree::ptree & tree_a) cons
|
|||
tree_a.put ("enable_control", enable_control);
|
||||
tree_a.put ("frontier_request_limit", frontier_request_limit);
|
||||
tree_a.put ("chain_request_limit", chain_request_limit);
|
||||
tree_a.put ("max_json_depth", max_json_depth);
|
||||
}
|
||||
|
||||
bool rai::rpc_config::deserialize_json (boost::property_tree::ptree const & tree_a)
|
||||
|
@ -93,6 +96,7 @@ bool rai::rpc_config::deserialize_json (boost::property_tree::ptree const & tree
|
|||
enable_control = tree_a.get<bool> ("enable_control");
|
||||
auto frontier_request_limit_l (tree_a.get<std::string> ("frontier_request_limit"));
|
||||
auto chain_request_limit_l (tree_a.get<std::string> ("chain_request_limit"));
|
||||
max_json_depth = tree_a.get<uint8_t> ("max_json_depth", max_json_depth);
|
||||
try
|
||||
{
|
||||
port = std::stoul (port_l);
|
||||
|
@ -3522,460 +3526,481 @@ void rai::rpc_handler::process_request ()
|
|||
{
|
||||
try
|
||||
{
|
||||
std::stringstream istream (body);
|
||||
boost::property_tree::read_json (istream, request);
|
||||
std::string action (request.get<std::string> ("action"));
|
||||
if (action == "password_enter")
|
||||
{
|
||||
password_enter ();
|
||||
request.erase ("password");
|
||||
reprocess_body (body, request);
|
||||
}
|
||||
else if (action == "password_change")
|
||||
{
|
||||
password_change ();
|
||||
request.erase ("password");
|
||||
reprocess_body (body, request);
|
||||
}
|
||||
else if (action == "wallet_unlock")
|
||||
{
|
||||
password_enter ();
|
||||
request.erase ("password");
|
||||
reprocess_body (body, request);
|
||||
}
|
||||
if (node.config.logging.log_rpc ())
|
||||
{
|
||||
BOOST_LOG (node.log) << boost::str (boost::format ("%1% ") % request_id) << body;
|
||||
}
|
||||
if (action == "account_balance")
|
||||
{
|
||||
account_balance ();
|
||||
}
|
||||
else if (action == "account_block_count")
|
||||
{
|
||||
account_block_count ();
|
||||
}
|
||||
else if (action == "account_count")
|
||||
{
|
||||
account_count ();
|
||||
}
|
||||
else if (action == "account_create")
|
||||
{
|
||||
account_create ();
|
||||
}
|
||||
else if (action == "account_get")
|
||||
{
|
||||
account_get ();
|
||||
}
|
||||
else if (action == "account_history")
|
||||
{
|
||||
account_history ();
|
||||
}
|
||||
else if (action == "account_info")
|
||||
{
|
||||
account_info ();
|
||||
}
|
||||
else if (action == "account_key")
|
||||
{
|
||||
account_key ();
|
||||
}
|
||||
else if (action == "account_list")
|
||||
{
|
||||
account_list ();
|
||||
}
|
||||
else if (action == "account_move")
|
||||
{
|
||||
account_move ();
|
||||
}
|
||||
else if (action == "account_remove")
|
||||
{
|
||||
account_remove ();
|
||||
}
|
||||
else if (action == "account_representative")
|
||||
{
|
||||
account_representative ();
|
||||
}
|
||||
else if (action == "account_representative_set")
|
||||
{
|
||||
account_representative_set ();
|
||||
}
|
||||
else if (action == "account_weight")
|
||||
{
|
||||
account_weight ();
|
||||
}
|
||||
else if (action == "accounts_balances")
|
||||
{
|
||||
accounts_balances ();
|
||||
}
|
||||
else if (action == "accounts_create")
|
||||
{
|
||||
accounts_create ();
|
||||
}
|
||||
else if (action == "accounts_frontiers")
|
||||
{
|
||||
accounts_frontiers ();
|
||||
}
|
||||
else if (action == "accounts_pending")
|
||||
{
|
||||
accounts_pending ();
|
||||
}
|
||||
else if (action == "available_supply")
|
||||
{
|
||||
available_supply ();
|
||||
}
|
||||
else if (action == "block")
|
||||
{
|
||||
block ();
|
||||
}
|
||||
else if (action == "block_confirm")
|
||||
{
|
||||
block_confirm ();
|
||||
}
|
||||
else if (action == "blocks")
|
||||
{
|
||||
blocks ();
|
||||
}
|
||||
else if (action == "blocks_info")
|
||||
{
|
||||
blocks_info ();
|
||||
}
|
||||
else if (action == "block_account")
|
||||
{
|
||||
block_account ();
|
||||
}
|
||||
else if (action == "block_count")
|
||||
{
|
||||
block_count ();
|
||||
}
|
||||
else if (action == "block_count_type")
|
||||
{
|
||||
block_count_type ();
|
||||
}
|
||||
else if (action == "block_create")
|
||||
{
|
||||
block_create ();
|
||||
}
|
||||
else if (action == "block_hash")
|
||||
{
|
||||
block_hash ();
|
||||
}
|
||||
else if (action == "successors")
|
||||
{
|
||||
chain (true);
|
||||
}
|
||||
else if (action == "bootstrap")
|
||||
{
|
||||
bootstrap ();
|
||||
}
|
||||
else if (action == "bootstrap_any")
|
||||
{
|
||||
bootstrap_any ();
|
||||
}
|
||||
else if (action == "chain")
|
||||
{
|
||||
chain ();
|
||||
}
|
||||
else if (action == "delegators")
|
||||
{
|
||||
delegators ();
|
||||
}
|
||||
else if (action == "delegators_count")
|
||||
{
|
||||
delegators_count ();
|
||||
}
|
||||
else if (action == "deterministic_key")
|
||||
{
|
||||
deterministic_key ();
|
||||
}
|
||||
else if (action == "confirmation_history")
|
||||
{
|
||||
confirmation_history ();
|
||||
}
|
||||
else if (action == "frontiers")
|
||||
{
|
||||
frontiers ();
|
||||
}
|
||||
else if (action == "frontier_count")
|
||||
{
|
||||
account_count ();
|
||||
}
|
||||
else if (action == "history")
|
||||
{
|
||||
request.put ("head", request.get<std::string> ("hash"));
|
||||
account_history ();
|
||||
}
|
||||
else if (action == "keepalive")
|
||||
{
|
||||
keepalive ();
|
||||
}
|
||||
else if (action == "key_create")
|
||||
{
|
||||
key_create ();
|
||||
}
|
||||
else if (action == "key_expand")
|
||||
{
|
||||
key_expand ();
|
||||
}
|
||||
else if (action == "krai_from_raw")
|
||||
{
|
||||
mrai_from_raw (rai::kxrb_ratio);
|
||||
}
|
||||
else if (action == "krai_to_raw")
|
||||
{
|
||||
mrai_to_raw (rai::kxrb_ratio);
|
||||
}
|
||||
else if (action == "ledger")
|
||||
{
|
||||
ledger ();
|
||||
}
|
||||
else if (action == "mrai_from_raw")
|
||||
{
|
||||
mrai_from_raw ();
|
||||
}
|
||||
else if (action == "mrai_to_raw")
|
||||
{
|
||||
mrai_to_raw ();
|
||||
}
|
||||
else if (action == "password_change")
|
||||
{
|
||||
// Processed before logging
|
||||
}
|
||||
else if (action == "password_enter")
|
||||
{
|
||||
// Processed before logging
|
||||
}
|
||||
else if (action == "password_valid")
|
||||
{
|
||||
password_valid ();
|
||||
}
|
||||
else if (action == "payment_begin")
|
||||
{
|
||||
payment_begin ();
|
||||
}
|
||||
else if (action == "payment_init")
|
||||
{
|
||||
payment_init ();
|
||||
}
|
||||
else if (action == "payment_end")
|
||||
{
|
||||
payment_end ();
|
||||
}
|
||||
else if (action == "payment_wait")
|
||||
{
|
||||
payment_wait ();
|
||||
}
|
||||
else if (action == "peers")
|
||||
{
|
||||
peers ();
|
||||
}
|
||||
else if (action == "pending")
|
||||
{
|
||||
pending ();
|
||||
}
|
||||
else if (action == "pending_exists")
|
||||
{
|
||||
pending_exists ();
|
||||
}
|
||||
else if (action == "process")
|
||||
{
|
||||
process ();
|
||||
}
|
||||
else if (action == "rai_from_raw")
|
||||
{
|
||||
mrai_from_raw (rai::xrb_ratio);
|
||||
}
|
||||
else if (action == "rai_to_raw")
|
||||
{
|
||||
mrai_to_raw (rai::xrb_ratio);
|
||||
}
|
||||
else if (action == "receive")
|
||||
{
|
||||
receive ();
|
||||
}
|
||||
else if (action == "receive_minimum")
|
||||
{
|
||||
receive_minimum ();
|
||||
}
|
||||
else if (action == "receive_minimum_set")
|
||||
{
|
||||
receive_minimum_set ();
|
||||
}
|
||||
else if (action == "representatives")
|
||||
{
|
||||
representatives ();
|
||||
}
|
||||
else if (action == "representatives_online")
|
||||
{
|
||||
representatives_online ();
|
||||
}
|
||||
else if (action == "republish")
|
||||
{
|
||||
republish ();
|
||||
}
|
||||
else if (action == "search_pending")
|
||||
{
|
||||
search_pending ();
|
||||
}
|
||||
else if (action == "search_pending_all")
|
||||
{
|
||||
search_pending_all ();
|
||||
}
|
||||
else if (action == "send")
|
||||
{
|
||||
send ();
|
||||
}
|
||||
else if (action == "stats")
|
||||
{
|
||||
stats ();
|
||||
}
|
||||
else if (action == "stop")
|
||||
{
|
||||
stop ();
|
||||
}
|
||||
else if (action == "unchecked")
|
||||
{
|
||||
unchecked ();
|
||||
}
|
||||
else if (action == "unchecked_clear")
|
||||
{
|
||||
unchecked_clear ();
|
||||
}
|
||||
else if (action == "unchecked_get")
|
||||
{
|
||||
unchecked_get ();
|
||||
}
|
||||
else if (action == "unchecked_keys")
|
||||
{
|
||||
unchecked_keys ();
|
||||
}
|
||||
else if (action == "validate_account_number")
|
||||
{
|
||||
validate_account_number ();
|
||||
}
|
||||
else if (action == "version")
|
||||
{
|
||||
version ();
|
||||
}
|
||||
else if (action == "wallet_add")
|
||||
{
|
||||
wallet_add ();
|
||||
}
|
||||
else if (action == "wallet_add_watch")
|
||||
{
|
||||
wallet_add_watch ();
|
||||
}
|
||||
// Obsolete
|
||||
else if (action == "wallet_balance_total")
|
||||
{
|
||||
wallet_info ();
|
||||
}
|
||||
else if (action == "wallet_balances")
|
||||
{
|
||||
wallet_balances ();
|
||||
}
|
||||
else if (action == "wallet_change_seed")
|
||||
{
|
||||
wallet_change_seed ();
|
||||
}
|
||||
else if (action == "wallet_contains")
|
||||
{
|
||||
wallet_contains ();
|
||||
}
|
||||
else if (action == "wallet_create")
|
||||
{
|
||||
wallet_create ();
|
||||
}
|
||||
else if (action == "wallet_destroy")
|
||||
{
|
||||
wallet_destroy ();
|
||||
}
|
||||
else if (action == "wallet_export")
|
||||
{
|
||||
wallet_export ();
|
||||
}
|
||||
else if (action == "wallet_frontiers")
|
||||
{
|
||||
wallet_frontiers ();
|
||||
}
|
||||
else if (action == "wallet_info")
|
||||
{
|
||||
wallet_info ();
|
||||
}
|
||||
else if (action == "wallet_key_valid")
|
||||
{
|
||||
wallet_key_valid ();
|
||||
}
|
||||
else if (action == "wallet_ledger")
|
||||
{
|
||||
wallet_ledger ();
|
||||
}
|
||||
else if (action == "wallet_lock")
|
||||
{
|
||||
wallet_lock ();
|
||||
}
|
||||
else if (action == "wallet_locked")
|
||||
{
|
||||
password_valid (true);
|
||||
}
|
||||
else if (action == "wallet_pending")
|
||||
{
|
||||
wallet_pending ();
|
||||
}
|
||||
else if (action == "wallet_representative")
|
||||
{
|
||||
wallet_representative ();
|
||||
}
|
||||
else if (action == "wallet_representative_set")
|
||||
{
|
||||
wallet_representative_set ();
|
||||
}
|
||||
else if (action == "wallet_republish")
|
||||
{
|
||||
wallet_republish ();
|
||||
}
|
||||
else if (action == "wallet_unlock")
|
||||
{
|
||||
// Processed before logging
|
||||
}
|
||||
else if (action == "wallet_work_get")
|
||||
{
|
||||
wallet_work_get ();
|
||||
}
|
||||
else if (action == "work_generate")
|
||||
{
|
||||
work_generate ();
|
||||
}
|
||||
else if (action == "work_cancel")
|
||||
{
|
||||
work_cancel ();
|
||||
}
|
||||
else if (action == "work_get")
|
||||
{
|
||||
work_get ();
|
||||
}
|
||||
else if (action == "work_set")
|
||||
{
|
||||
work_set ();
|
||||
}
|
||||
else if (action == "work_validate")
|
||||
{
|
||||
work_validate ();
|
||||
}
|
||||
else if (action == "work_peer_add")
|
||||
{
|
||||
work_peer_add ();
|
||||
}
|
||||
else if (action == "work_peers")
|
||||
{
|
||||
work_peers ();
|
||||
}
|
||||
else if (action == "work_peers_clear")
|
||||
{
|
||||
work_peers_clear ();
|
||||
auto max_depth_exceeded (false);
|
||||
auto max_depth_possible (0);
|
||||
for (auto ch : body)
|
||||
{
|
||||
if (ch == '[' || ch == '{')
|
||||
{
|
||||
if (max_depth_possible >= rpc.config.max_json_depth)
|
||||
{
|
||||
max_depth_exceeded = true;
|
||||
break;
|
||||
}
|
||||
++max_depth_possible;
|
||||
}
|
||||
}
|
||||
if (max_depth_exceeded)
|
||||
{
|
||||
error_response (response, "Max JSON depth exceeded");
|
||||
}
|
||||
else
|
||||
{
|
||||
error_response (response, "Unknown command");
|
||||
std::stringstream istream (body);
|
||||
boost::property_tree::read_json (istream, request);
|
||||
std::string action (request.get<std::string> ("action"));
|
||||
if (action == "password_enter")
|
||||
{
|
||||
password_enter ();
|
||||
request.erase ("password");
|
||||
reprocess_body (body, request);
|
||||
}
|
||||
else if (action == "password_change")
|
||||
{
|
||||
password_change ();
|
||||
request.erase ("password");
|
||||
reprocess_body (body, request);
|
||||
}
|
||||
else if (action == "wallet_unlock")
|
||||
{
|
||||
password_enter ();
|
||||
request.erase ("password");
|
||||
reprocess_body (body, request);
|
||||
}
|
||||
if (node.config.logging.log_rpc ())
|
||||
{
|
||||
BOOST_LOG (node.log) << boost::str (boost::format ("%1% ") % request_id) << body;
|
||||
}
|
||||
if (action == "account_balance")
|
||||
{
|
||||
account_balance ();
|
||||
}
|
||||
else if (action == "account_block_count")
|
||||
{
|
||||
account_block_count ();
|
||||
}
|
||||
else if (action == "account_count")
|
||||
{
|
||||
account_count ();
|
||||
}
|
||||
else if (action == "account_create")
|
||||
{
|
||||
account_create ();
|
||||
}
|
||||
else if (action == "account_get")
|
||||
{
|
||||
account_get ();
|
||||
}
|
||||
else if (action == "account_history")
|
||||
{
|
||||
account_history ();
|
||||
}
|
||||
else if (action == "account_info")
|
||||
{
|
||||
account_info ();
|
||||
}
|
||||
else if (action == "account_key")
|
||||
{
|
||||
account_key ();
|
||||
}
|
||||
else if (action == "account_list")
|
||||
{
|
||||
account_list ();
|
||||
}
|
||||
else if (action == "account_move")
|
||||
{
|
||||
account_move ();
|
||||
}
|
||||
else if (action == "account_remove")
|
||||
{
|
||||
account_remove ();
|
||||
}
|
||||
else if (action == "account_representative")
|
||||
{
|
||||
account_representative ();
|
||||
}
|
||||
else if (action == "account_representative_set")
|
||||
{
|
||||
account_representative_set ();
|
||||
}
|
||||
else if (action == "account_weight")
|
||||
{
|
||||
account_weight ();
|
||||
}
|
||||
else if (action == "accounts_balances")
|
||||
{
|
||||
accounts_balances ();
|
||||
}
|
||||
else if (action == "accounts_create")
|
||||
{
|
||||
accounts_create ();
|
||||
}
|
||||
else if (action == "accounts_frontiers")
|
||||
{
|
||||
accounts_frontiers ();
|
||||
}
|
||||
else if (action == "accounts_pending")
|
||||
{
|
||||
accounts_pending ();
|
||||
}
|
||||
else if (action == "available_supply")
|
||||
{
|
||||
available_supply ();
|
||||
}
|
||||
else if (action == "block")
|
||||
{
|
||||
block ();
|
||||
}
|
||||
else if (action == "block_confirm")
|
||||
{
|
||||
block_confirm ();
|
||||
}
|
||||
else if (action == "blocks")
|
||||
{
|
||||
blocks ();
|
||||
}
|
||||
else if (action == "blocks_info")
|
||||
{
|
||||
blocks_info ();
|
||||
}
|
||||
else if (action == "block_account")
|
||||
{
|
||||
block_account ();
|
||||
}
|
||||
else if (action == "block_count")
|
||||
{
|
||||
block_count ();
|
||||
}
|
||||
else if (action == "block_count_type")
|
||||
{
|
||||
block_count_type ();
|
||||
}
|
||||
else if (action == "block_create")
|
||||
{
|
||||
block_create ();
|
||||
}
|
||||
else if (action == "block_hash")
|
||||
{
|
||||
block_hash ();
|
||||
}
|
||||
else if (action == "successors")
|
||||
{
|
||||
chain (true);
|
||||
}
|
||||
else if (action == "bootstrap")
|
||||
{
|
||||
bootstrap ();
|
||||
}
|
||||
else if (action == "bootstrap_any")
|
||||
{
|
||||
bootstrap_any ();
|
||||
}
|
||||
else if (action == "chain")
|
||||
{
|
||||
chain ();
|
||||
}
|
||||
else if (action == "delegators")
|
||||
{
|
||||
delegators ();
|
||||
}
|
||||
else if (action == "delegators_count")
|
||||
{
|
||||
delegators_count ();
|
||||
}
|
||||
else if (action == "deterministic_key")
|
||||
{
|
||||
deterministic_key ();
|
||||
}
|
||||
else if (action == "confirmation_history")
|
||||
{
|
||||
confirmation_history ();
|
||||
}
|
||||
else if (action == "frontiers")
|
||||
{
|
||||
frontiers ();
|
||||
}
|
||||
else if (action == "frontier_count")
|
||||
{
|
||||
account_count ();
|
||||
}
|
||||
else if (action == "history")
|
||||
{
|
||||
request.put ("head", request.get<std::string> ("hash"));
|
||||
account_history ();
|
||||
}
|
||||
else if (action == "keepalive")
|
||||
{
|
||||
keepalive ();
|
||||
}
|
||||
else if (action == "key_create")
|
||||
{
|
||||
key_create ();
|
||||
}
|
||||
else if (action == "key_expand")
|
||||
{
|
||||
key_expand ();
|
||||
}
|
||||
else if (action == "krai_from_raw")
|
||||
{
|
||||
mrai_from_raw (rai::kxrb_ratio);
|
||||
}
|
||||
else if (action == "krai_to_raw")
|
||||
{
|
||||
mrai_to_raw (rai::kxrb_ratio);
|
||||
}
|
||||
else if (action == "ledger")
|
||||
{
|
||||
ledger ();
|
||||
}
|
||||
else if (action == "mrai_from_raw")
|
||||
{
|
||||
mrai_from_raw ();
|
||||
}
|
||||
else if (action == "mrai_to_raw")
|
||||
{
|
||||
mrai_to_raw ();
|
||||
}
|
||||
else if (action == "password_change")
|
||||
{
|
||||
// Processed before logging
|
||||
}
|
||||
else if (action == "password_enter")
|
||||
{
|
||||
// Processed before logging
|
||||
}
|
||||
else if (action == "password_valid")
|
||||
{
|
||||
password_valid ();
|
||||
}
|
||||
else if (action == "payment_begin")
|
||||
{
|
||||
payment_begin ();
|
||||
}
|
||||
else if (action == "payment_init")
|
||||
{
|
||||
payment_init ();
|
||||
}
|
||||
else if (action == "payment_end")
|
||||
{
|
||||
payment_end ();
|
||||
}
|
||||
else if (action == "payment_wait")
|
||||
{
|
||||
payment_wait ();
|
||||
}
|
||||
else if (action == "peers")
|
||||
{
|
||||
peers ();
|
||||
}
|
||||
else if (action == "pending")
|
||||
{
|
||||
pending ();
|
||||
}
|
||||
else if (action == "pending_exists")
|
||||
{
|
||||
pending_exists ();
|
||||
}
|
||||
else if (action == "process")
|
||||
{
|
||||
process ();
|
||||
}
|
||||
else if (action == "rai_from_raw")
|
||||
{
|
||||
mrai_from_raw (rai::xrb_ratio);
|
||||
}
|
||||
else if (action == "rai_to_raw")
|
||||
{
|
||||
mrai_to_raw (rai::xrb_ratio);
|
||||
}
|
||||
else if (action == "receive")
|
||||
{
|
||||
receive ();
|
||||
}
|
||||
else if (action == "receive_minimum")
|
||||
{
|
||||
receive_minimum ();
|
||||
}
|
||||
else if (action == "receive_minimum_set")
|
||||
{
|
||||
receive_minimum_set ();
|
||||
}
|
||||
else if (action == "representatives")
|
||||
{
|
||||
representatives ();
|
||||
}
|
||||
else if (action == "representatives_online")
|
||||
{
|
||||
representatives_online ();
|
||||
}
|
||||
else if (action == "republish")
|
||||
{
|
||||
republish ();
|
||||
}
|
||||
else if (action == "search_pending")
|
||||
{
|
||||
search_pending ();
|
||||
}
|
||||
else if (action == "search_pending_all")
|
||||
{
|
||||
search_pending_all ();
|
||||
}
|
||||
else if (action == "send")
|
||||
{
|
||||
send ();
|
||||
}
|
||||
else if (action == "stats")
|
||||
{
|
||||
stats ();
|
||||
}
|
||||
else if (action == "stop")
|
||||
{
|
||||
stop ();
|
||||
}
|
||||
else if (action == "unchecked")
|
||||
{
|
||||
unchecked ();
|
||||
}
|
||||
else if (action == "unchecked_clear")
|
||||
{
|
||||
unchecked_clear ();
|
||||
}
|
||||
else if (action == "unchecked_get")
|
||||
{
|
||||
unchecked_get ();
|
||||
}
|
||||
else if (action == "unchecked_keys")
|
||||
{
|
||||
unchecked_keys ();
|
||||
}
|
||||
else if (action == "validate_account_number")
|
||||
{
|
||||
validate_account_number ();
|
||||
}
|
||||
else if (action == "version")
|
||||
{
|
||||
version ();
|
||||
}
|
||||
else if (action == "wallet_add")
|
||||
{
|
||||
wallet_add ();
|
||||
}
|
||||
else if (action == "wallet_add_watch")
|
||||
{
|
||||
wallet_add_watch ();
|
||||
}
|
||||
// Obsolete
|
||||
else if (action == "wallet_balance_total")
|
||||
{
|
||||
wallet_info ();
|
||||
}
|
||||
else if (action == "wallet_balances")
|
||||
{
|
||||
wallet_balances ();
|
||||
}
|
||||
else if (action == "wallet_change_seed")
|
||||
{
|
||||
wallet_change_seed ();
|
||||
}
|
||||
else if (action == "wallet_contains")
|
||||
{
|
||||
wallet_contains ();
|
||||
}
|
||||
else if (action == "wallet_create")
|
||||
{
|
||||
wallet_create ();
|
||||
}
|
||||
else if (action == "wallet_destroy")
|
||||
{
|
||||
wallet_destroy ();
|
||||
}
|
||||
else if (action == "wallet_export")
|
||||
{
|
||||
wallet_export ();
|
||||
}
|
||||
else if (action == "wallet_frontiers")
|
||||
{
|
||||
wallet_frontiers ();
|
||||
}
|
||||
else if (action == "wallet_info")
|
||||
{
|
||||
wallet_info ();
|
||||
}
|
||||
else if (action == "wallet_key_valid")
|
||||
{
|
||||
wallet_key_valid ();
|
||||
}
|
||||
else if (action == "wallet_ledger")
|
||||
{
|
||||
wallet_ledger ();
|
||||
}
|
||||
else if (action == "wallet_lock")
|
||||
{
|
||||
wallet_lock ();
|
||||
}
|
||||
else if (action == "wallet_locked")
|
||||
{
|
||||
password_valid (true);
|
||||
}
|
||||
else if (action == "wallet_pending")
|
||||
{
|
||||
wallet_pending ();
|
||||
}
|
||||
else if (action == "wallet_representative")
|
||||
{
|
||||
wallet_representative ();
|
||||
}
|
||||
else if (action == "wallet_representative_set")
|
||||
{
|
||||
wallet_representative_set ();
|
||||
}
|
||||
else if (action == "wallet_republish")
|
||||
{
|
||||
wallet_republish ();
|
||||
}
|
||||
else if (action == "wallet_unlock")
|
||||
{
|
||||
// Processed before logging
|
||||
}
|
||||
else if (action == "wallet_work_get")
|
||||
{
|
||||
wallet_work_get ();
|
||||
}
|
||||
else if (action == "work_generate")
|
||||
{
|
||||
work_generate ();
|
||||
}
|
||||
else if (action == "work_cancel")
|
||||
{
|
||||
work_cancel ();
|
||||
}
|
||||
else if (action == "work_get")
|
||||
{
|
||||
work_get ();
|
||||
}
|
||||
else if (action == "work_set")
|
||||
{
|
||||
work_set ();
|
||||
}
|
||||
else if (action == "work_validate")
|
||||
{
|
||||
work_validate ();
|
||||
}
|
||||
else if (action == "work_peer_add")
|
||||
{
|
||||
work_peer_add ();
|
||||
}
|
||||
else if (action == "work_peers")
|
||||
{
|
||||
work_peers ();
|
||||
}
|
||||
else if (action == "work_peers_clear")
|
||||
{
|
||||
work_peers_clear ();
|
||||
}
|
||||
else
|
||||
{
|
||||
error_response (response, "Unknown command");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error const & err)
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
uint64_t frontier_request_limit;
|
||||
uint64_t chain_request_limit;
|
||||
rpc_secure_config secure;
|
||||
uint8_t max_json_depth;
|
||||
};
|
||||
enum class payment_status
|
||||
{
|
||||
|
|
|
@ -40,7 +40,7 @@ void rai::wallet_store::seed (rai::raw_key & prv_a, MDB_txn * transaction_a)
|
|||
rai::wallet_value value (entry_get_raw (transaction_a, rai::wallet_store::seed_special));
|
||||
rai::raw_key password_l;
|
||||
wallet_key (password_l, transaction_a);
|
||||
prv_a.decrypt (value.key, password_l, salt (transaction_a).owords[0]);
|
||||
prv_a.decrypt (value.key, password_l, salt (transaction_a).owords[seed_iv_index]);
|
||||
}
|
||||
|
||||
void rai::wallet_store::seed_set (MDB_txn * transaction_a, rai::raw_key const & prv_a)
|
||||
|
@ -48,7 +48,7 @@ void rai::wallet_store::seed_set (MDB_txn * transaction_a, rai::raw_key const &
|
|||
rai::raw_key password_l;
|
||||
wallet_key (password_l, transaction_a);
|
||||
rai::uint256_union ciphertext;
|
||||
ciphertext.encrypt (prv_a, password_l, salt (transaction_a).owords[0]);
|
||||
ciphertext.encrypt (prv_a, password_l, salt (transaction_a).owords[seed_iv_index]);
|
||||
entry_put_raw (transaction_a, rai::wallet_store::seed_special, rai::wallet_value (ciphertext, 0));
|
||||
deterministic_clear (transaction_a);
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ bool rai::wallet_store::valid_password (MDB_txn * transaction_a)
|
|||
rai::raw_key wallet_key_l;
|
||||
wallet_key (wallet_key_l, transaction_a);
|
||||
rai::uint256_union check_l;
|
||||
check_l.encrypt (zero, wallet_key_l, salt (transaction_a).owords[0]);
|
||||
check_l.encrypt (zero, wallet_key_l, salt (transaction_a).owords[check_iv_index]);
|
||||
bool ok = check (transaction_a) == check_l;
|
||||
return ok;
|
||||
}
|
||||
|
@ -143,13 +143,18 @@ bool rai::wallet_store::attempt_password (MDB_txn * transaction_a, std::string c
|
|||
}
|
||||
if (!result)
|
||||
{
|
||||
if (version (transaction_a) == version_1)
|
||||
switch (version (transaction_a))
|
||||
{
|
||||
upgrade_v1_v2 ();
|
||||
}
|
||||
if (version (transaction_a) == version_2)
|
||||
{
|
||||
upgrade_v2_v3 ();
|
||||
case version_1:
|
||||
upgrade_v1_v2 ();
|
||||
case version_2:
|
||||
upgrade_v2_v3 ();
|
||||
case version_3:
|
||||
upgrade_v3_v4 ();
|
||||
case version_4:
|
||||
break;
|
||||
default:
|
||||
assert (false);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -245,10 +250,6 @@ rai::mdb_val rai::wallet_value::val () const
|
|||
return rai::mdb_val (sizeof (*this), const_cast<rai::wallet_value *> (this));
|
||||
}
|
||||
|
||||
unsigned const rai::wallet_store::version_1 (1);
|
||||
unsigned const rai::wallet_store::version_2 (2);
|
||||
unsigned const rai::wallet_store::version_3 (3);
|
||||
unsigned const rai::wallet_store::version_current (version_3);
|
||||
// Wallet version number
|
||||
rai::uint256_union const rai::wallet_store::version_special (0);
|
||||
// Random number used to salt private key encryption
|
||||
|
@ -264,6 +265,8 @@ rai::uint256_union const rai::wallet_store::seed_special (5);
|
|||
// Current key index for deterministic keys
|
||||
rai::uint256_union const rai::wallet_store::deterministic_index_special (6);
|
||||
int const rai::wallet_store::special_count (7);
|
||||
size_t const rai::wallet_store::check_iv_index (0);
|
||||
size_t const rai::wallet_store::seed_iv_index (1);
|
||||
|
||||
rai::wallet_store::wallet_store (bool & init_a, rai::kdf & kdf_a, rai::transaction & transaction_a, rai::account representative_a, unsigned fanout_a, std::string const & wallet_a, std::string const & json_a) :
|
||||
password (0, fanout_a),
|
||||
|
@ -357,7 +360,7 @@ environment (transaction_a.environment)
|
|||
wallet_key_enc.data = encrypted;
|
||||
wallet_key_mem.value_set (wallet_key_enc);
|
||||
rai::uint256_union check;
|
||||
check.encrypt (zero, wallet_key, salt_l.owords[0]);
|
||||
check.encrypt (zero, wallet_key, salt_l.owords[check_iv_index]);
|
||||
entry_put_raw (transaction_a, rai::wallet_store::check_special, rai::wallet_value (check, 0));
|
||||
entry_put_raw (transaction_a, rai::wallet_store::representative_special, rai::wallet_value (representative_a, 0));
|
||||
rai::raw_key seed;
|
||||
|
@ -413,7 +416,7 @@ rai::public_key rai::wallet_store::insert_adhoc (MDB_txn * transaction_a, rai::r
|
|||
rai::raw_key password_l;
|
||||
wallet_key (password_l, transaction_a);
|
||||
rai::uint256_union ciphertext;
|
||||
ciphertext.encrypt (prv, password_l, salt (transaction_a).owords[0]);
|
||||
ciphertext.encrypt (prv, password_l, pub.owords[0].number ());
|
||||
entry_put_raw (transaction_a, pub, rai::wallet_value (ciphertext, 0));
|
||||
return pub;
|
||||
}
|
||||
|
@ -498,7 +501,7 @@ bool rai::wallet_store::fetch (MDB_txn * transaction_a, rai::public_key const &
|
|||
// Ad-hoc keys
|
||||
rai::raw_key password_l;
|
||||
wallet_key (password_l, transaction_a);
|
||||
prv.decrypt (value.key, password_l, salt (transaction_a).owords[0]);
|
||||
prv.decrypt (value.key, password_l, pub.owords[0].number ());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -691,6 +694,49 @@ void rai::wallet_store::upgrade_v2_v3 ()
|
|||
version_put (transaction, 3);
|
||||
}
|
||||
|
||||
void rai::wallet_store::upgrade_v3_v4 ()
|
||||
{
|
||||
rai::transaction transaction (environment, nullptr, true);
|
||||
assert (version (transaction) == 3);
|
||||
version_put (transaction, 4);
|
||||
assert (valid_password (transaction));
|
||||
rai::raw_key seed;
|
||||
rai::wallet_value value (entry_get_raw (transaction, rai::wallet_store::seed_special));
|
||||
rai::raw_key password_l;
|
||||
wallet_key (password_l, transaction);
|
||||
seed.decrypt (value.key, password_l, salt (transaction).owords[0]);
|
||||
rai::uint256_union ciphertext;
|
||||
ciphertext.encrypt (seed, password_l, salt (transaction).owords[seed_iv_index]);
|
||||
entry_put_raw (transaction, rai::wallet_store::seed_special, rai::wallet_value (ciphertext, 0));
|
||||
for (auto i (begin (transaction)), n (end ()); i != n; ++i)
|
||||
{
|
||||
rai::wallet_value value (i->second);
|
||||
if (!value.key.is_zero ())
|
||||
{
|
||||
switch (key_type (i->second))
|
||||
{
|
||||
case rai::key_type::adhoc:
|
||||
{
|
||||
rai::raw_key key;
|
||||
if (fetch (transaction, i->first.uint256 (), key))
|
||||
{
|
||||
// Key failed to decrypt despite valid password
|
||||
key.decrypt (value.key, password_l, salt (transaction).owords[0]);
|
||||
rai::uint256_union new_key_ciphertext;
|
||||
new_key_ciphertext.encrypt (key, password_l, i->first.uint256 ().owords[0].number ());
|
||||
rai::wallet_value new_value (new_key_ciphertext, value.work);
|
||||
mdb_cursor_put (i.cursor, i->first, new_value.val (), MDB_CURRENT);
|
||||
}
|
||||
}
|
||||
case rai::key_type::deterministic:
|
||||
break;
|
||||
default:
|
||||
assert (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rai::kdf::phs (rai::raw_key & result_a, std::string const & password_a, rai::uint256_union const & salt_a)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
|
|
|
@ -96,12 +96,14 @@ public:
|
|||
void version_put (MDB_txn *, unsigned);
|
||||
void upgrade_v1_v2 ();
|
||||
void upgrade_v2_v3 ();
|
||||
void upgrade_v3_v4 ();
|
||||
rai::fan password;
|
||||
rai::fan wallet_key_mem;
|
||||
static unsigned const version_1;
|
||||
static unsigned const version_2;
|
||||
static unsigned const version_3;
|
||||
static unsigned const version_current;
|
||||
static unsigned const version_1 = 1;
|
||||
static unsigned const version_2 = 2;
|
||||
static unsigned const version_3 = 3;
|
||||
static unsigned const version_4 = 4;
|
||||
unsigned const version_current = version_4;
|
||||
static rai::uint256_union const version_special;
|
||||
static rai::uint256_union const wallet_key_special;
|
||||
static rai::uint256_union const salt_special;
|
||||
|
@ -109,6 +111,8 @@ public:
|
|||
static rai::uint256_union const representative_special;
|
||||
static rai::uint256_union const seed_special;
|
||||
static rai::uint256_union const deterministic_index_special;
|
||||
static size_t const check_iv_index;
|
||||
static size_t const seed_iv_index;
|
||||
static int const special_count;
|
||||
static unsigned const kdf_full_work = 64 * 1024;
|
||||
static unsigned const kdf_test_work = 8;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue