Merge branch 'develop' into feature/libbitcoin-son-final
This commit is contained in:
commit
89ad18a479
9 changed files with 325 additions and 175 deletions
|
|
@ -720,11 +720,11 @@ void database::update_active_sons()
|
|||
}
|
||||
|
||||
assert( _son_count_histogram_buffer.size() > 0 );
|
||||
for( const auto& son_count_histogram_buffer : _son_count_histogram_buffer ){
|
||||
#ifndef NDEBUG
|
||||
for( const auto& son_count_histogram_buffer : _son_count_histogram_buffer ){
|
||||
assert( son_count_histogram_buffer.second.size() > 0 );
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
const flat_map<sidechain_type, share_type> stake_target = [this]{
|
||||
flat_map<sidechain_type, share_type> stake_target;
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@ object_id_type add_sidechain_address_evaluator::do_apply(const sidechain_address
|
|||
|
||||
if (addr_itr != sidechain_addresses_idx.end())
|
||||
{
|
||||
db().modify(*addr_itr, [&](sidechain_address_object &sao) {
|
||||
sao.expires = db().head_block_time();
|
||||
});
|
||||
//db().modify(*addr_itr, [&](sidechain_address_object &sao) {
|
||||
// sao.expires = db().head_block_time();
|
||||
//});
|
||||
db().remove(*addr_itr);
|
||||
}
|
||||
|
||||
const auto& new_sidechain_address_object = db().create<sidechain_address_object>( [&]( sidechain_address_object& obj ){
|
||||
|
|
@ -106,9 +107,10 @@ void_result delete_sidechain_address_evaluator::do_apply(const sidechain_address
|
|||
const auto& idx = db().get_index_type<sidechain_address_index>().indices().get<by_id>();
|
||||
auto sidechain_address = idx.find(op.sidechain_address_id);
|
||||
if(sidechain_address != idx.end()) {
|
||||
db().modify(*sidechain_address, [&](sidechain_address_object &sao) {
|
||||
sao.expires = db().head_block_time();
|
||||
});
|
||||
//db().modify(*sidechain_address, [&](sidechain_address_object &sao) {
|
||||
// sao.expires = db().head_block_time();
|
||||
//});
|
||||
db().remove(*sidechain_address);
|
||||
}
|
||||
return void_result();
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
|
|
|||
|
|
@ -62,47 +62,67 @@ rpc_client::rpc_client(std::string _url, std::string _user, std::string _passwor
|
|||
}
|
||||
|
||||
std::string rpc_client::retrieve_array_value_from_reply(std::string reply_str, std::string array_path, uint32_t idx) {
|
||||
std::stringstream ss(reply_str);
|
||||
boost::property_tree::ptree json;
|
||||
boost::property_tree::read_json(ss, json);
|
||||
if (json.find("result") == json.not_found()) {
|
||||
if (reply_str.empty()) {
|
||||
wlog("RPC call ${function}, empty reply string", ("function", __FUNCTION__));
|
||||
return "";
|
||||
}
|
||||
|
||||
auto json_result = json.get_child_optional("result");
|
||||
if (json_result) {
|
||||
boost::property_tree::ptree array_ptree = json_result.get();
|
||||
if (!array_path.empty()) {
|
||||
array_ptree = json_result.get().get_child(array_path);
|
||||
try {
|
||||
std::stringstream ss(reply_str);
|
||||
boost::property_tree::ptree json;
|
||||
boost::property_tree::read_json(ss, json);
|
||||
if (json.find("result") == json.not_found()) {
|
||||
return "";
|
||||
}
|
||||
uint32_t array_el_idx = -1;
|
||||
for (const auto &array_el : array_ptree) {
|
||||
array_el_idx = array_el_idx + 1;
|
||||
if (array_el_idx == idx) {
|
||||
std::stringstream ss_res;
|
||||
boost::property_tree::json_parser::write_json(ss_res, array_el.second);
|
||||
return ss_res.str();
|
||||
|
||||
auto json_result = json.get_child_optional("result");
|
||||
if (json_result) {
|
||||
boost::property_tree::ptree array_ptree = json_result.get();
|
||||
if (!array_path.empty()) {
|
||||
array_ptree = json_result.get().get_child(array_path);
|
||||
}
|
||||
uint32_t array_el_idx = -1;
|
||||
for (const auto &array_el : array_ptree) {
|
||||
array_el_idx = array_el_idx + 1;
|
||||
if (array_el_idx == idx) {
|
||||
std::stringstream ss_res;
|
||||
boost::property_tree::json_parser::write_json(ss_res, array_el.second);
|
||||
return ss_res.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const boost::property_tree::json_parser::json_parser_error &e) {
|
||||
wlog("RPC call ${function} failed: ${e}", ("function", __FUNCTION__)("e", e.what()));
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string rpc_client::retrieve_value_from_reply(std::string reply_str, std::string value_path) {
|
||||
std::stringstream ss(reply_str);
|
||||
boost::property_tree::ptree json;
|
||||
boost::property_tree::read_json(ss, json);
|
||||
if (json.find("result") == json.not_found()) {
|
||||
if (reply_str.empty()) {
|
||||
wlog("RPC call ${function}, empty reply string", ("function", __FUNCTION__));
|
||||
return "";
|
||||
}
|
||||
|
||||
auto json_result = json.get_child_optional("result");
|
||||
if (json_result) {
|
||||
return json_result.get().get<std::string>(value_path);
|
||||
try {
|
||||
std::stringstream ss(reply_str);
|
||||
boost::property_tree::ptree json;
|
||||
boost::property_tree::read_json(ss, json);
|
||||
if (json.find("result") == json.not_found()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
auto json_result = json.get_child_optional("result");
|
||||
if (json_result) {
|
||||
return json_result.get().get<std::string>(value_path);
|
||||
}
|
||||
|
||||
return json.get<std::string>("result");
|
||||
} catch (const boost::property_tree::json_parser::json_parser_error &e) {
|
||||
wlog("RPC call ${function} failed: ${e}", ("function", __FUNCTION__)("e", e.what()));
|
||||
}
|
||||
|
||||
return json.get<std::string>("result");
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string rpc_client::send_post_request(std::string method, std::string params, bool show_log) {
|
||||
|
|
@ -118,23 +138,27 @@ std::string rpc_client::send_post_request(std::string method, std::string params
|
|||
|
||||
body << " }";
|
||||
|
||||
const auto reply = send_post_request(body.str(), show_log);
|
||||
try {
|
||||
const auto reply = send_post_request(body.str(), show_log);
|
||||
|
||||
if (reply.body.empty()) {
|
||||
wlog("RPC call ${function} failed", ("function", __FUNCTION__));
|
||||
return "";
|
||||
}
|
||||
if (reply.body.empty()) {
|
||||
wlog("RPC call ${function} failed", ("function", __FUNCTION__));
|
||||
return "";
|
||||
}
|
||||
|
||||
std::stringstream ss(std::string(reply.body.begin(), reply.body.end()));
|
||||
boost::property_tree::ptree json;
|
||||
boost::property_tree::read_json(ss, json);
|
||||
std::stringstream ss(std::string(reply.body.begin(), reply.body.end()));
|
||||
boost::property_tree::ptree json;
|
||||
boost::property_tree::read_json(ss, json);
|
||||
|
||||
if (json.count("error") && !json.get_child("error").empty()) {
|
||||
wlog("RPC call ${function} with body ${body} failed with reply '${msg}'", ("function", __FUNCTION__)("body", body.str())("msg", ss.str()));
|
||||
}
|
||||
if (json.count("error") && !json.get_child("error").empty()) {
|
||||
wlog("RPC call ${function} with body ${body} failed with reply '${msg}'", ("function", __FUNCTION__)("body", body.str())("msg", ss.str()));
|
||||
}
|
||||
|
||||
if (reply.status == 200) {
|
||||
return ss.str();
|
||||
if (reply.status == 200) {
|
||||
return ss.str();
|
||||
}
|
||||
} catch (const boost::system::system_error &e) {
|
||||
elog("RPC call ${function} failed: ${e}", ("function", __FUNCTION__)("e", e.what()));
|
||||
}
|
||||
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ bitcoin_rpc_client::bitcoin_rpc_client(std::string _url, std::string _user, std:
|
|||
}
|
||||
|
||||
uint64_t bitcoin_rpc_client::estimatesmartfee(uint16_t conf_target) {
|
||||
std::string params = std::string("[") + std::to_string(conf_target) + std::string("]");
|
||||
std::string str = send_post_request("estimatesmartfee", params, debug_rpc_calls);
|
||||
const std::string params = std::string("[") + std::to_string(conf_target) + std::string("]");
|
||||
const std::string str = send_post_request("estimatesmartfee", params, debug_rpc_calls);
|
||||
|
||||
if (str.length() == 0) {
|
||||
wlog("Bitcoin RPC call ${function} failed", ("function", __FUNCTION__));
|
||||
|
|
@ -157,8 +157,8 @@ btc_tx bitcoin_rpc_client::getrawtransaction(const std::string &txid, const bool
|
|||
}
|
||||
|
||||
std::string bitcoin_rpc_client::getblockchaininfo() {
|
||||
std::string params = std::string("[]");
|
||||
std::string str = send_post_request("getblockchaininfo", params, debug_rpc_calls);
|
||||
static const std::string params = std::string("[]");
|
||||
const std::string str = send_post_request("getblockchaininfo", params, debug_rpc_calls);
|
||||
|
||||
std::string result;
|
||||
|
||||
|
|
@ -215,8 +215,8 @@ void bitcoin_rpc_client::importmulti(const std::vector<multi_params> &address_or
|
|||
|
||||
std::vector<btc_txout> bitcoin_rpc_client::listunspent(const uint32_t minconf, const uint32_t maxconf) {
|
||||
std::vector<btc_txout> result;
|
||||
std::string params = std::string("[") + std::to_string(minconf) + "," + std::to_string(maxconf) + std::string("]");
|
||||
std::string str = send_post_request("listunspent", params, debug_rpc_calls);
|
||||
const std::string params = std::string("[") + std::to_string(minconf) + "," + std::to_string(maxconf) + std::string("]");
|
||||
const std::string str = send_post_request("listunspent", params, debug_rpc_calls);
|
||||
|
||||
if (str.length() == 0) {
|
||||
wlog("Bitcoin RPC call ${function} failed", ("function", __FUNCTION__));
|
||||
|
|
@ -252,7 +252,7 @@ std::vector<btc_txout> bitcoin_rpc_client::listunspent_by_address_and_amount(con
|
|||
params += std::string("} ]");
|
||||
|
||||
std::vector<btc_txout> result;
|
||||
std::string str = send_post_request("listunspent", params, debug_rpc_calls);
|
||||
const std::string str = send_post_request("listunspent", params, debug_rpc_calls);
|
||||
|
||||
if (str.length() == 0) {
|
||||
wlog("Bitcoin RPC call ${function} failed", ("function", __FUNCTION__));
|
||||
|
|
@ -279,16 +279,13 @@ std::vector<btc_txout> bitcoin_rpc_client::listunspent_by_address_and_amount(con
|
|||
}
|
||||
|
||||
std::string bitcoin_rpc_client::loadwallet(const std::string &filename) {
|
||||
|
||||
std::string params = std::string("[\"") + filename + std::string("\"]");
|
||||
std::string str = send_post_request("loadwallet", params, debug_rpc_calls);
|
||||
return str;
|
||||
const std::string params = std::string("[\"") + filename + std::string("\"]");
|
||||
return send_post_request("loadwallet", params, debug_rpc_calls);
|
||||
}
|
||||
|
||||
std::string bitcoin_rpc_client::sendrawtransaction(const std::string &tx_hex) {
|
||||
|
||||
std::string params = std::string("[\"") + tx_hex + std::string("\"]");
|
||||
std::string str = send_post_request("sendrawtransaction", params, debug_rpc_calls);
|
||||
const std::string params = std::string("[\"") + tx_hex + std::string("\"]");
|
||||
const std::string str = send_post_request("sendrawtransaction", params, debug_rpc_calls);
|
||||
|
||||
if (str.length() > 0) {
|
||||
std::stringstream ss(str);
|
||||
|
|
@ -310,8 +307,8 @@ std::string bitcoin_rpc_client::sendrawtransaction(const std::string &tx_hex) {
|
|||
}
|
||||
|
||||
std::string bitcoin_rpc_client::walletlock() {
|
||||
std::string params = std::string("[]");
|
||||
std::string str = send_post_request("walletlock", params, debug_rpc_calls);
|
||||
static const std::string params = std::string("[]");
|
||||
const std::string str = send_post_request("walletlock", params, debug_rpc_calls);
|
||||
|
||||
if (str.length() == 0) {
|
||||
wlog("Bitcoin RPC call ${function} failed", ("function", __FUNCTION__));
|
||||
|
|
@ -328,8 +325,8 @@ std::string bitcoin_rpc_client::walletlock() {
|
|||
}
|
||||
|
||||
bool bitcoin_rpc_client::walletpassphrase(const std::string &passphrase, uint32_t timeout) {
|
||||
std::string params = std::string("[\"") + passphrase + std::string("\",") + std::to_string(timeout) + std::string("]");
|
||||
std::string str = send_post_request("walletpassphrase", params, debug_rpc_calls);
|
||||
const std::string params = std::string("[\"") + passphrase + std::string("\",") + std::to_string(timeout) + std::string("]");
|
||||
const std::string str = send_post_request("walletpassphrase", params, debug_rpc_calls);
|
||||
if (str.length() == 0)
|
||||
return false;
|
||||
else
|
||||
|
|
@ -812,18 +809,22 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
|
|||
tx_address = address;
|
||||
break;
|
||||
}
|
||||
std::string tx_amount_s = input.second.get<std::string>("value");
|
||||
tx_amount_s.erase(std::remove(tx_amount_s.begin(), tx_amount_s.end(), '.'), tx_amount_s.end());
|
||||
tx_amount = std::stoll(tx_amount_s);
|
||||
break;
|
||||
}
|
||||
|
||||
tx_amount = input.tx_amount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
process_ok = (swdo_txid == tx_txid) &&
|
||||
(swdo_address == tx_address) &&
|
||||
(swdo_amount == tx_amount) &&
|
||||
(swdo_vout == tx_vout) &&
|
||||
(gpo.parameters.son_bitcoin_min_tx_confirmations() <= tx_confirmations);
|
||||
process_ok = (swdo_txid == tx_txid) &&
|
||||
(swdo_address == tx_address) &&
|
||||
(swdo_amount == tx_amount) &&
|
||||
(swdo_vout == tx_vout) &&
|
||||
(gpo.parameters.son_bitcoin_min_tx_confirmations() <= tx_confirmations);
|
||||
}
|
||||
}
|
||||
|
||||
object_id_type object_id = op_obj_idx_1.get<sidechain_transaction_create_operation>().object_id;
|
||||
|
|
@ -962,6 +963,10 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() {
|
|||
const auto &active_sw = swi.rbegin();
|
||||
if (active_sw != swi.rend()) {
|
||||
|
||||
const auto &prev_sw = std::next(active_sw);
|
||||
if (prev_sw != swi.rend() && active_sw->sons.at(sidechain) == prev_sw->sons.at(sidechain))
|
||||
return;
|
||||
|
||||
if ((active_sw->addresses.find(sidechain) == active_sw->addresses.end()) ||
|
||||
(active_sw->addresses.at(sidechain).empty())) {
|
||||
|
||||
|
|
@ -998,7 +1003,6 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() {
|
|||
|
||||
proposal_op.proposed_ops.emplace_back(swu_op);
|
||||
|
||||
const auto &prev_sw = std::next(active_sw);
|
||||
if (prev_sw != swi.rend()) {
|
||||
std::string new_pw_address = active_pw_pt.get<std::string>("result.address");
|
||||
std::string tx_str = create_primary_wallet_transaction(*prev_sw, new_pw_address);
|
||||
|
|
@ -1205,7 +1209,7 @@ bool sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain
|
|||
return false;
|
||||
}
|
||||
|
||||
const chain::global_property_object &gpo = database.get_global_properties();
|
||||
const chain::global_property_object &gpo = database.get_global_properties();
|
||||
|
||||
using namespace bitcoin;
|
||||
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkey_weights;
|
||||
|
|
@ -1235,15 +1239,15 @@ bool sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain
|
|||
break;
|
||||
}
|
||||
}
|
||||
settle_amount = asset(tx_amount, database.get_global_properties().parameters.btc_asset());
|
||||
return true;
|
||||
}
|
||||
settle_amount = asset(tx_amount, database.get_global_properties().parameters.btc_asset());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
||||
auto swwo = database.get<son_wallet_withdraw_object>(sto.object_id);
|
||||
settle_amount = asset(swwo.withdraw_amount, database.get_global_properties().parameters.btc_asset());
|
||||
return true;
|
||||
if (sto.object_id.is<son_wallet_withdraw_id_type>()) {
|
||||
auto swwo = database.get<son_wallet_withdraw_object>(sto.object_id);
|
||||
settle_amount = asset(swwo.withdraw_amount, database.get_global_properties().parameters.btc_asset());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
@ -1297,11 +1301,11 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_transaction(con
|
|||
}
|
||||
|
||||
uint64_t fee_rate = bitcoin_client->estimatesmartfee();
|
||||
uint64_t min_fee_rate = 1000;
|
||||
const uint64_t min_fee_rate = 1000;
|
||||
fee_rate = std::max(fee_rate, min_fee_rate);
|
||||
|
||||
uint64_t total_amount = 0.0;
|
||||
std::vector<btc_txout> inputs = bitcoin_client->listunspent_by_address_and_amount(prev_pw_address, 0);
|
||||
const std::vector<btc_txout> inputs = bitcoin_client->listunspent_by_address_and_amount(prev_pw_address, 0);
|
||||
|
||||
if (inputs.size() == 0) {
|
||||
elog("Failed to find UTXOs to spend for ${pw}", ("pw", prev_pw_address));
|
||||
|
|
@ -1344,7 +1348,7 @@ std::string sidechain_net_handler_bitcoin::create_deposit_transaction(const son_
|
|||
std::string nvout = suid.substr(suid.find_last_of("-") + 1);
|
||||
uint64_t deposit_amount = swdo.sidechain_amount.value;
|
||||
uint64_t fee_rate = bitcoin_client->estimatesmartfee();
|
||||
uint64_t min_fee_rate = 1000;
|
||||
const uint64_t min_fee_rate = 1000;
|
||||
fee_rate = std::max(fee_rate, min_fee_rate);
|
||||
|
||||
if (fee_rate >= deposit_amount) {
|
||||
|
|
@ -1387,11 +1391,11 @@ std::string sidechain_net_handler_bitcoin::create_withdrawal_transaction(const s
|
|||
std::string redeem_script = json.get<std::string>("redeemScript");
|
||||
|
||||
int64_t fee_rate = bitcoin_client->estimatesmartfee();
|
||||
int64_t min_fee_rate = 1000;
|
||||
const int64_t min_fee_rate = 1000;
|
||||
fee_rate = std::max(fee_rate, min_fee_rate);
|
||||
|
||||
int64_t total_amount = 0;
|
||||
std::vector<btc_txout> inputs = bitcoin_client->listunspent_by_address_and_amount(pw_address, 0);
|
||||
const std::vector<btc_txout> inputs = bitcoin_client->listunspent_by_address_and_amount(pw_address, 0);
|
||||
|
||||
if (inputs.size() == 0) {
|
||||
elog("Failed to find UTXOs to spend for ${pw}", ("pw", pw_address));
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ std::string ethereum_rpc_client::admin_node_info() {
|
|||
}
|
||||
|
||||
std::string ethereum_rpc_client::eth_get_block_by_number(std::string block_number, bool full_block) {
|
||||
std::string params = "[ \"" + block_number + "\", " + (full_block ? "true" : "false") + "]";
|
||||
const std::string params = "[ \"" + block_number + "\", " + (full_block ? "true" : "false") + "]";
|
||||
return send_post_request("eth_getBlockByNumber", params, debug_rpc_calls);
|
||||
}
|
||||
|
||||
std::string ethereum_rpc_client::eth_get_logs(std::string wallet_contract_address) {
|
||||
std::string params = "[{\"address\": \"" + wallet_contract_address + "\"}]";
|
||||
std::string reply_str = send_post_request("eth_getLogs", params, debug_rpc_calls);
|
||||
const std::string params = "[{\"address\": \"" + wallet_contract_address + "\"}]";
|
||||
const std::string reply_str = send_post_request("eth_getLogs", params, debug_rpc_calls);
|
||||
return retrieve_value_from_reply(reply_str, "");
|
||||
}
|
||||
|
||||
|
|
@ -56,28 +56,32 @@ std::string ethereum_rpc_client::eth_gas_price() {
|
|||
}
|
||||
|
||||
std::string ethereum_rpc_client::get_chain_id() {
|
||||
std::string reply_str = net_version();
|
||||
const std::string reply_str = net_version();
|
||||
return retrieve_value_from_reply(reply_str, "");
|
||||
}
|
||||
|
||||
std::string ethereum_rpc_client::get_network_id() {
|
||||
std::string reply_str = admin_node_info();
|
||||
const std::string reply_str = admin_node_info();
|
||||
return retrieve_value_from_reply(reply_str, "protocols.eth.network");
|
||||
}
|
||||
|
||||
std::string ethereum_rpc_client::get_nonce(const std::string &address) {
|
||||
std::string reply_str = eth_get_transaction_count("[\"" + address + "\", \"latest\"]");
|
||||
const auto nonce_val = ethereum::from_hex<boost::multiprecision::uint256_t>(retrieve_value_from_reply(reply_str, ""));
|
||||
return nonce_val == 0 ? ethereum::add_0x("0") : ethereum::add_0x(ethereum::to_hex(nonce_val));
|
||||
const std::string reply_str = eth_get_transaction_count("[\"" + address + "\", \"latest\"]");
|
||||
const auto nonce_string = retrieve_value_from_reply(reply_str, "");
|
||||
if (!nonce_string.empty()) {
|
||||
const auto nonce_val = ethereum::from_hex<boost::multiprecision::uint256_t>(nonce_string);
|
||||
return nonce_val == 0 ? ethereum::add_0x("0") : ethereum::add_0x(ethereum::to_hex(nonce_val));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string ethereum_rpc_client::get_gas_price() {
|
||||
std::string reply_str = eth_gas_price();
|
||||
const std::string reply_str = eth_gas_price();
|
||||
return retrieve_value_from_reply(reply_str, "");
|
||||
}
|
||||
|
||||
std::string ethereum_rpc_client::get_gas_limit() {
|
||||
std::string reply_str = eth_get_block_by_number("latest", false);
|
||||
const std::string reply_str = eth_get_block_by_number("latest", false);
|
||||
if (!reply_str.empty()) {
|
||||
std::stringstream ss(reply_str);
|
||||
boost::property_tree::ptree json;
|
||||
|
|
@ -138,13 +142,18 @@ sidechain_net_handler_ethereum::sidechain_net_handler_ethereum(peerplays_sidecha
|
|||
|
||||
rpc_client = new ethereum_rpc_client(rpc_url, rpc_user, rpc_password, debug_rpc_calls);
|
||||
|
||||
std::string chain_id_str = rpc_client->get_chain_id();
|
||||
const std::string chain_id_str = rpc_client->get_chain_id();
|
||||
if (chain_id_str.empty()) {
|
||||
elog("No Ethereum node running at ${url}", ("url", rpc_url));
|
||||
FC_ASSERT(false);
|
||||
}
|
||||
chain_id = std::stoll(chain_id_str);
|
||||
std::string network_id_str = rpc_client->get_network_id();
|
||||
|
||||
const std::string network_id_str = rpc_client->get_network_id();
|
||||
if (network_id_str.empty()) {
|
||||
elog("No Ethereum node running at ${url}", ("url", rpc_url));
|
||||
FC_ASSERT(false);
|
||||
}
|
||||
network_id = std::stoll(network_id_str);
|
||||
|
||||
ilog("Running on Ethereum network, chain id ${chain_id_str}, network id ${network_id_str}", ("chain_id_str", chain_id_str)("network_id_str", network_id_str));
|
||||
|
|
@ -399,6 +408,10 @@ void sidechain_net_handler_ethereum::process_primary_wallet() {
|
|||
const auto &active_sw = swi.rbegin();
|
||||
if (active_sw != swi.rend()) {
|
||||
|
||||
const auto &prev_sw = std::next(active_sw);
|
||||
if (prev_sw != swi.rend() && active_sw->sons.at(sidechain) == prev_sw->sons.at(sidechain))
|
||||
return;
|
||||
|
||||
if ((active_sw->addresses.find(sidechain) == active_sw->addresses.end()) ||
|
||||
(active_sw->addresses.at(sidechain).empty())) {
|
||||
|
||||
|
|
@ -423,6 +436,21 @@ void sidechain_net_handler_ethereum::process_primary_wallet() {
|
|||
swu_op.address = wallet_contract_address;
|
||||
proposal_op.proposed_ops.emplace_back(swu_op);
|
||||
|
||||
const auto signers = [this, &prev_sw, &active_sw, &swi] {
|
||||
std::vector<son_info> signers;
|
||||
//! Check if we don't have any previous set of active SONs use the current one
|
||||
if (prev_sw != swi.rend()) {
|
||||
if (!prev_sw->sons.at(sidechain).empty())
|
||||
signers = prev_sw->sons.at(sidechain);
|
||||
else
|
||||
signers = active_sw->sons.at(sidechain);
|
||||
} else {
|
||||
signers = active_sw->sons.at(sidechain);
|
||||
}
|
||||
|
||||
return signers;
|
||||
}();
|
||||
|
||||
std::string tx_str = create_primary_wallet_transaction(gpo.active_sons.at(sidechain), active_sw->id.operator std::string());
|
||||
if (!tx_str.empty()) {
|
||||
sidechain_transaction_create_operation stc_op;
|
||||
|
|
@ -430,7 +458,7 @@ void sidechain_net_handler_ethereum::process_primary_wallet() {
|
|||
stc_op.object_id = active_sw->id;
|
||||
stc_op.sidechain = sidechain;
|
||||
stc_op.transaction = tx_str;
|
||||
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||
stc_op.signers = signers;
|
||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||
}
|
||||
|
||||
|
|
@ -678,7 +706,7 @@ void sidechain_net_handler_ethereum::schedule_ethereum_listener() {
|
|||
void sidechain_net_handler_ethereum::ethereum_listener_loop() {
|
||||
schedule_ethereum_listener();
|
||||
|
||||
std::string reply = rpc_client->eth_get_block_by_number("latest", false);
|
||||
const std::string reply = rpc_client->eth_get_block_by_number("latest", false);
|
||||
//std::string reply = rpc_client->eth_get_logs(wallet_contract_address);
|
||||
if (!reply.empty()) {
|
||||
std::stringstream ss(reply);
|
||||
|
|
@ -697,7 +725,7 @@ void sidechain_net_handler_ethereum::ethereum_listener_loop() {
|
|||
}
|
||||
|
||||
void sidechain_net_handler_ethereum::handle_event(const std::string &event_data) {
|
||||
std::string block = rpc_client->eth_get_block_by_number("latest", true);
|
||||
const std::string block = rpc_client->eth_get_block_by_number("latest", true);
|
||||
if (block != "") {
|
||||
add_to_son_listener_log("BLOCK : " + event_data);
|
||||
std::stringstream ss(block);
|
||||
|
|
|
|||
|
|
@ -35,12 +35,12 @@ hive_rpc_client::hive_rpc_client(const std::string &url, const std::string &user
|
|||
}
|
||||
|
||||
std::string hive_rpc_client::account_history_api_get_transaction(std::string transaction_id) {
|
||||
std::string params = "{ \"id\": \"" + transaction_id + "\" }";
|
||||
const std::string params = "{ \"id\": \"" + transaction_id + "\" }";
|
||||
return send_post_request("account_history_api.get_transaction", params, debug_rpc_calls);
|
||||
}
|
||||
|
||||
std::string hive_rpc_client::block_api_get_block(uint32_t block_number) {
|
||||
std::string params = "{ \"block_num\": " + std::to_string(block_number) + " }";
|
||||
const std::string params = "{ \"block_num\": " + std::to_string(block_number) + " }";
|
||||
return send_post_request("block_api.get_block", params, debug_rpc_calls);
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ std::string hive_rpc_client::condenser_api_get_accounts(std::vector<std::string>
|
|||
}
|
||||
|
||||
std::string hive_rpc_client::condenser_api_get_config() {
|
||||
std::string params = "[]";
|
||||
static const std::string params = "[]";
|
||||
return send_post_request("condenser_api.get_config", params, debug_rpc_calls);
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ std::string hive_rpc_client::database_api_get_version() {
|
|||
}
|
||||
|
||||
std::string hive_rpc_client::network_broadcast_api_broadcast_transaction(std::string htrx) {
|
||||
std::string params = "{ \"trx\": " + htrx + ", \"max_block_age\": -1 }";
|
||||
const std::string params = "{ \"trx\": " + htrx + ", \"max_block_age\": -1 }";
|
||||
return send_post_request("network_broadcast_api.broadcast_transaction", params, debug_rpc_calls);
|
||||
}
|
||||
|
||||
|
|
@ -88,27 +88,27 @@ std::string hive_rpc_client::get_account_memo_key(std::string account) {
|
|||
}
|
||||
|
||||
std::string hive_rpc_client::get_chain_id() {
|
||||
std::string reply_str = database_api_get_version();
|
||||
const std::string reply_str = database_api_get_version();
|
||||
return retrieve_value_from_reply(reply_str, "chain_id");
|
||||
}
|
||||
|
||||
std::string hive_rpc_client::get_head_block_id() {
|
||||
std::string reply_str = database_api_get_dynamic_global_properties();
|
||||
const std::string reply_str = database_api_get_dynamic_global_properties();
|
||||
return retrieve_value_from_reply(reply_str, "head_block_id");
|
||||
}
|
||||
|
||||
std::string hive_rpc_client::get_head_block_time() {
|
||||
std::string reply_str = database_api_get_dynamic_global_properties();
|
||||
const std::string reply_str = database_api_get_dynamic_global_properties();
|
||||
return retrieve_value_from_reply(reply_str, "time");
|
||||
}
|
||||
|
||||
std::string hive_rpc_client::get_is_test_net() {
|
||||
std::string reply_str = condenser_api_get_config();
|
||||
const std::string reply_str = condenser_api_get_config();
|
||||
return retrieve_value_from_reply(reply_str, "IS_TEST_NET");
|
||||
}
|
||||
|
||||
std::string hive_rpc_client::get_last_irreversible_block_num() {
|
||||
std::string reply_str = database_api_get_dynamic_global_properties();
|
||||
const std::string reply_str = database_api_get_dynamic_global_properties();
|
||||
return retrieve_value_from_reply(reply_str, "last_irreversible_block_num");
|
||||
}
|
||||
|
||||
|
|
@ -148,14 +148,14 @@ sidechain_net_handler_hive::sidechain_net_handler_hive(peerplays_sidechain_plugi
|
|||
|
||||
rpc_client = new hive_rpc_client(rpc_url, rpc_user, rpc_password, debug_rpc_calls);
|
||||
|
||||
std::string chain_id_str = rpc_client->get_chain_id();
|
||||
const std::string chain_id_str = rpc_client->get_chain_id();
|
||||
if (chain_id_str.empty()) {
|
||||
elog("No Hive node running at ${url}", ("url", rpc_url));
|
||||
FC_ASSERT(false);
|
||||
}
|
||||
chain_id = chain_id_type(chain_id_str);
|
||||
|
||||
std::string is_test_net = rpc_client->get_is_test_net();
|
||||
const std::string is_test_net = rpc_client->get_is_test_net();
|
||||
network_type = is_test_net.compare("true") == 0 ? hive::network::testnet : hive::network::mainnet;
|
||||
if (network_type == hive::network::mainnet) {
|
||||
ilog("Running on Hive mainnet, chain id ${chain_id_str}", ("chain_id_str", chain_id_str));
|
||||
|
|
@ -254,7 +254,7 @@ bool sidechain_net_handler_hive::process_proposal(const proposal_object &po) {
|
|||
account_auths[wallet_son.public_key] = wallet_son.weight;
|
||||
}
|
||||
|
||||
std::string memo_key = rpc_client->get_account_memo_key(wallet_account_name);
|
||||
const std::string memo_key = rpc_client->get_account_memo_key(wallet_account_name);
|
||||
|
||||
hive::authority active;
|
||||
active.weight_threshold = total_weight * 2 / 3 + 1;
|
||||
|
|
@ -303,7 +303,7 @@ bool sidechain_net_handler_hive::process_proposal(const proposal_object &po) {
|
|||
uint64_t swdo_sidechain_amount = swdo->sidechain_amount.value;
|
||||
uint64_t swdo_op_idx = std::stoll(swdo->sidechain_uid.substr(swdo->sidechain_uid.find_last_of("-")));
|
||||
|
||||
std::string tx_str = rpc_client->account_history_api_get_transaction(swdo_txid);
|
||||
const std::string tx_str = rpc_client->account_history_api_get_transaction(swdo_txid);
|
||||
if (tx_str != "") {
|
||||
|
||||
std::stringstream ss_tx(tx_str);
|
||||
|
|
@ -478,6 +478,10 @@ void sidechain_net_handler_hive::process_primary_wallet() {
|
|||
const auto &active_sw = swi.rbegin();
|
||||
if (active_sw != swi.rend()) {
|
||||
|
||||
const auto &prev_sw = std::next(active_sw);
|
||||
if (prev_sw != swi.rend() && active_sw->sons.at(sidechain) == prev_sw->sons.at(sidechain))
|
||||
return;
|
||||
|
||||
if ((active_sw->addresses.find(sidechain) == active_sw->addresses.end()) ||
|
||||
(active_sw->addresses.at(sidechain).empty())) {
|
||||
|
||||
|
|
@ -495,7 +499,7 @@ void sidechain_net_handler_hive::process_primary_wallet() {
|
|||
account_auths[active_son.public_key] = active_son.weight;
|
||||
}
|
||||
|
||||
std::string memo_key = rpc_client->get_account_memo_key(wallet_account_name);
|
||||
const std::string memo_key = rpc_client->get_account_memo_key(wallet_account_name);
|
||||
|
||||
if (memo_key.empty()) {
|
||||
return;
|
||||
|
|
@ -510,10 +514,10 @@ void sidechain_net_handler_hive::process_primary_wallet() {
|
|||
auo.active = active;
|
||||
auo.memo_key = hive::public_key_type(memo_key);
|
||||
|
||||
std::string block_id_str = rpc_client->get_head_block_id();
|
||||
const std::string block_id_str = rpc_client->get_head_block_id();
|
||||
hive::block_id_type head_block_id(block_id_str);
|
||||
|
||||
std::string head_block_time_str = rpc_client->get_head_block_time();
|
||||
const std::string head_block_time_str = rpc_client->get_head_block_time();
|
||||
time_point head_block_time = fc::time_point_sec::from_iso_string(head_block_time_str);
|
||||
|
||||
hive::signed_transaction htrx;
|
||||
|
|
@ -668,10 +672,10 @@ bool sidechain_net_handler_hive::process_withdrawal(const son_wallet_withdraw_ob
|
|||
t_op.amount.symbol = symbol;
|
||||
t_op.memo = "";
|
||||
|
||||
std::string block_id_str = rpc_client->get_head_block_id();
|
||||
const std::string block_id_str = rpc_client->get_head_block_id();
|
||||
hive::block_id_type head_block_id(block_id_str);
|
||||
|
||||
std::string head_block_time_str = rpc_client->get_head_block_time();
|
||||
const std::string head_block_time_str = rpc_client->get_head_block_time();
|
||||
time_point head_block_time = fc::time_point_sec::from_iso_string(head_block_time_str);
|
||||
|
||||
hive::signed_transaction htrx;
|
||||
|
|
@ -727,7 +731,7 @@ std::string sidechain_net_handler_hive::process_sidechain_transaction(const side
|
|||
hive::signed_transaction htrx;
|
||||
fc::raw::unpack(ss_trx, htrx, 1000);
|
||||
|
||||
std::string chain_id_str = rpc_client->get_chain_id();
|
||||
const std::string chain_id_str = rpc_client->get_chain_id();
|
||||
const hive::chain_id_type chain_id(chain_id_str);
|
||||
|
||||
fc::optional<fc::ecc::private_key> privkey = graphene::utilities::wif_to_key(get_private_key(plugin.get_current_son_object(sidechain).sidechain_public_keys.at(sidechain)));
|
||||
|
|
@ -770,7 +774,7 @@ bool sidechain_net_handler_hive::settle_sidechain_transaction(const sidechain_tr
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string tx_str = rpc_client->account_history_api_get_transaction(sto.sidechain_transaction);
|
||||
const std::string tx_str = rpc_client->account_history_api_get_transaction(sto.sidechain_transaction);
|
||||
if (tx_str != "") {
|
||||
|
||||
std::stringstream ss_tx(tx_str);
|
||||
|
|
@ -781,7 +785,7 @@ bool sidechain_net_handler_hive::settle_sidechain_transaction(const sidechain_tr
|
|||
|
||||
std::string tx_txid = tx_json.get<std::string>("result.transaction_id");
|
||||
uint32_t tx_block_num = tx_json.get<uint32_t>("result.block_num");
|
||||
uint32_t last_irreversible_block = std::stoul(rpc_client->get_last_irreversible_block_num());
|
||||
const uint32_t last_irreversible_block = std::stoul(rpc_client->get_last_irreversible_block_num());
|
||||
|
||||
//std::string tx_address = addr.get_address();
|
||||
//int64_t tx_amount = -1;
|
||||
|
|
@ -817,7 +821,7 @@ void sidechain_net_handler_hive::schedule_hive_listener() {
|
|||
void sidechain_net_handler_hive::hive_listener_loop() {
|
||||
schedule_hive_listener();
|
||||
|
||||
std::string reply = rpc_client->database_api_get_dynamic_global_properties();
|
||||
const std::string reply = rpc_client->database_api_get_dynamic_global_properties();
|
||||
if (!reply.empty()) {
|
||||
std::stringstream ss(reply);
|
||||
boost::property_tree::ptree json;
|
||||
|
|
@ -844,7 +848,7 @@ void sidechain_net_handler_hive::hive_listener_loop() {
|
|||
}
|
||||
|
||||
void sidechain_net_handler_hive::handle_event(const std::string &event_data) {
|
||||
std::string block = rpc_client->block_api_get_block(std::atoll(event_data.c_str()));
|
||||
const std::string block = rpc_client->block_api_get_block(std::atoll(event_data.c_str()));
|
||||
if (block != "") {
|
||||
add_to_son_listener_log("BLOCK : " + event_data);
|
||||
std::stringstream ss(block);
|
||||
|
|
|
|||
|
|
@ -263,12 +263,25 @@ class wallet_api
|
|||
|
||||
fc::ecc::private_key derive_private_key(const std::string& prefix_string, int sequence_number) const;
|
||||
|
||||
/** Returns info about head block, chain_id, maintenance, participation, current active witnesses and
|
||||
* committee members.
|
||||
* @returns runtime info about the blockchain
|
||||
*/
|
||||
variant info();
|
||||
/** Returns info such as client version, git version of graphene/fc, version of boost, openssl.
|
||||
* @returns compile time info and client and dependencies versions
|
||||
*/
|
||||
variant_object about() const;
|
||||
/** Returns info about a specified block.
|
||||
* @param num height of the block to retrieve
|
||||
* @returns info about the block, or null if not found
|
||||
*/
|
||||
optional<signed_block_with_info> get_block( uint32_t num );
|
||||
/** Get signed blocks
|
||||
* @param block_num_from The lowest block number
|
||||
* @param block_num_to The highest block number
|
||||
* @returns A list of signed blocks from block_num_from till block_num_to
|
||||
*/
|
||||
vector<optional<signed_block>> get_blocks(uint32_t block_num_from, uint32_t block_num_to)const;
|
||||
/** Returns the number of accounts registered on the blockchain
|
||||
* @returns the number of registered accounts
|
||||
|
|
@ -351,9 +364,38 @@ class wallet_api
|
|||
|
||||
vector<account_balance_object> list_core_accounts()const;
|
||||
|
||||
/** Get OHLCV data of a trading pair in a time range
|
||||
* @param symbol Asset symbol or ID in a trading pair
|
||||
* @param symbol2 The other asset symbol or ID in the trading pair
|
||||
* @param bucket Length of each time bucket in seconds.
|
||||
* Note: it need to be within result of get_market_history_buckets() API, otherwise no data will be returned
|
||||
* @param start The start of a time range, E.G. "2018-01-01T00:00:00"
|
||||
* @param end The end of the time range
|
||||
* @return A list of OHLCV data, in "least recent first" order.
|
||||
* If there are more than 200 records in the specified time range, the first 200 records will be returned.
|
||||
*/
|
||||
vector<bucket_object> get_market_history(string symbol, string symbol2, uint32_t bucket, fc::time_point_sec start, fc::time_point_sec end)const;
|
||||
|
||||
/** Get limit orders in a given market
|
||||
* @param a symbol or ID of asset being sold
|
||||
* @param b symbol or ID of asset being purchased
|
||||
* @param limit Maximum number of orders to retrieve
|
||||
* @return The limit orders, ordered from least price to greatest
|
||||
*/
|
||||
vector<limit_order_object> get_limit_orders(string a, string b, uint32_t limit)const;
|
||||
|
||||
/** Get call orders (aka margin positions) for a given asset
|
||||
* @param a symbol or ID of the debt asset
|
||||
* @param limit Maximum number of orders to retrieve
|
||||
* @return The call orders, ordered from earliest to be called to latest
|
||||
*/
|
||||
vector<call_order_object> get_call_orders(string a, uint32_t limit)const;
|
||||
|
||||
/** Get forced settlement orders in a given asset
|
||||
* @param a Symbol or ID of asset being settled
|
||||
* @param limit Maximum number of orders to retrieve
|
||||
* @return The settle orders, ordered from earliest settlement date to latest
|
||||
*/
|
||||
vector<force_settlement_object> get_settle_orders(string a, uint32_t limit)const;
|
||||
|
||||
/** Returns the block chain's slowly-changing settings.
|
||||
|
|
@ -732,8 +774,26 @@ class wallet_api
|
|||
*/
|
||||
bool import_key(string account_name_or_id, string wif_key);
|
||||
|
||||
/** Imports accounts from Peerplays 0.x wallet file.
|
||||
* Current wallet file must be unlocked to perform the import.
|
||||
*
|
||||
* @param filename the Peerplays 0.x wallet file to import
|
||||
* @param password the password to encrypt the Peerplays 0.x wallet file
|
||||
* @returns a map containing the accounts found and whether imported
|
||||
*/
|
||||
map<string, bool> import_accounts( string filename, string password );
|
||||
|
||||
/** Imports from a Peerplays 0.x wallet file, find keys that were bound to a given account name on the
|
||||
* Peerplays 0.x chain, rebind them to an account name on the 2.0 chain.
|
||||
* Current wallet file must be unlocked to perform the import.
|
||||
*
|
||||
* @param filename the Peerplays 0.x wallet file to import
|
||||
* @param password the password to encrypt the Peerplays 0.x wallet file
|
||||
* @param src_account_name name of the account on Peerplays 0.x chain
|
||||
* @param dest_account_name name of the account on Peerplays 2.0 chain,
|
||||
* can be same or different to \c src_account_name
|
||||
* @returns whether the import has succeeded
|
||||
*/
|
||||
bool import_account_keys( string filename, string password, string src_account_name, string dest_account_name );
|
||||
|
||||
/**
|
||||
|
|
@ -921,9 +981,17 @@ class wallet_api
|
|||
* @return true if the label was set, otherwise false
|
||||
*/
|
||||
bool set_key_label( public_key_type, string label );
|
||||
|
||||
/** Get label of a public key.
|
||||
* @param key a public key
|
||||
* @return the label if already set by \c set_key_label(), or an empty string if not set
|
||||
*/
|
||||
string get_key_label( public_key_type )const;
|
||||
|
||||
/** @return the public key associated with the given label */
|
||||
/* Get the public key associated with a given label.
|
||||
* @param label a label
|
||||
* @return the public key associated with the given label
|
||||
*/
|
||||
public_key_type get_public_key( string label )const;
|
||||
///@}
|
||||
|
||||
|
|
@ -1620,6 +1688,7 @@ class wallet_api
|
|||
* @param url Same as for create_witness. The empty string makes it remain the same.
|
||||
* @param block_signing_key The new block signing public key. The empty string makes it remain the same.
|
||||
* @param broadcast true if you wish to broadcast the transaction.
|
||||
* @return the signed transaction
|
||||
*/
|
||||
signed_transaction update_witness(string witness_name,
|
||||
string url,
|
||||
|
|
@ -1638,6 +1707,7 @@ class wallet_api
|
|||
* @param url Any text
|
||||
* @param worker_settings {"type" : "burn"|"refund"|"vesting", "pay_vesting_period_days" : x}
|
||||
* @param broadcast true if you wish to broadcast the transaction.
|
||||
* @return the signed transaction
|
||||
*/
|
||||
signed_transaction create_worker(
|
||||
string owner_account,
|
||||
|
|
@ -1656,6 +1726,7 @@ class wallet_api
|
|||
* @param account The account which will pay the fee and update votes.
|
||||
* @param delta {"vote_for" : [...], "vote_against" : [...], "vote_abstain" : [...]}
|
||||
* @param broadcast true if you wish to broadcast the transaction.
|
||||
* @return the signed transaction
|
||||
*/
|
||||
signed_transaction update_worker_votes(
|
||||
string account,
|
||||
|
|
@ -1670,7 +1741,7 @@ class wallet_api
|
|||
* @param asset_symbol the symbol of the asset to vest
|
||||
* @param vesting_type "normal", "gpos" or "son"
|
||||
* @param broadcast true to broadcast the transaction on the network
|
||||
* @returns the signed transaction registering a vesting object
|
||||
* @return the signed transaction registering a vesting object
|
||||
*/
|
||||
signed_transaction create_vesting_balance(string owner_account,
|
||||
string amount,
|
||||
|
|
@ -1682,6 +1753,7 @@ class wallet_api
|
|||
* Get information about a vesting balance object.
|
||||
*
|
||||
* @param account_name An account name, account ID, or vesting balance object ID.
|
||||
* @return a list of vesting balance objects with additional info
|
||||
*/
|
||||
vector< vesting_balance_object_with_info > get_vesting_balances( string account_name );
|
||||
|
||||
|
|
@ -1692,6 +1764,7 @@ class wallet_api
|
|||
* @param amount The amount to withdraw.
|
||||
* @param asset_symbol The symbol of the asset to withdraw.
|
||||
* @param broadcast true if you wish to broadcast the transaction
|
||||
* @return the signed transaction
|
||||
*/
|
||||
signed_transaction withdraw_vesting(
|
||||
string witness_name,
|
||||
|
|
@ -1705,6 +1778,7 @@ class wallet_api
|
|||
* @param amount The amount to withdraw.
|
||||
* @param asset_symbol The symbol of the asset to withdraw.
|
||||
* @param broadcast true if you wish to broadcast the transaction
|
||||
* @return the signed transaction
|
||||
*/
|
||||
signed_transaction withdraw_GPOS_vesting_balance(
|
||||
string account_name,
|
||||
|
|
@ -2064,6 +2138,13 @@ class wallet_api
|
|||
bool broadcast /* = false */
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the order book for the market base:quote.
|
||||
* @param base symbol or ID of the base asset
|
||||
* @param quote symbol or ID of the quote asset
|
||||
* @param limit depth of the order book to retrieve, for bids and asks each, capped at 50
|
||||
* @return Order book of the market
|
||||
*/
|
||||
order_book get_order_book( const string& base, const string& quote, unsigned limit = 50);
|
||||
|
||||
asset get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id);
|
||||
|
|
|
|||
|
|
@ -5706,53 +5706,12 @@ string wallet_api::gethelp(const string& method)const
|
|||
std::stringstream ss;
|
||||
ss << "\n";
|
||||
|
||||
if( method == "import_key" )
|
||||
{
|
||||
ss << "usage: import_key ACCOUNT_NAME_OR_ID WIF_PRIVATE_KEY\n\n";
|
||||
ss << "example: import_key \"1.2.11\" 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\n";
|
||||
ss << "example: import_key \"usera\" 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\n";
|
||||
}
|
||||
else if( method == "transfer" )
|
||||
{
|
||||
ss << "usage: transfer FROM TO AMOUNT SYMBOL \"memo\" BROADCAST\n\n";
|
||||
ss << "example: transfer \"1.2.11\" \"1.2.4\" 1000.03 CORE \"memo\" true\n";
|
||||
ss << "example: transfer \"usera\" \"userb\" 1000.123 CORE \"memo\" true\n";
|
||||
}
|
||||
else if( method == "create_account_with_brain_key" )
|
||||
{
|
||||
ss << "usage: create_account_with_brain_key BRAIN_KEY ACCOUNT_NAME REGISTRAR REFERRER BROADCAST\n\n";
|
||||
ss << "example: create_account_with_brain_key \"my really long brain key\" \"newaccount\" \"1.2.11\" \"1.2.11\" true\n";
|
||||
ss << "example: create_account_with_brain_key \"my really long brain key\" \"newaccount\" \"someaccount\" \"otheraccount\" true\n";
|
||||
ss << "\n";
|
||||
ss << "This method should be used if you would like the wallet to generate new keys derived from the brain key.\n";
|
||||
ss << "The BRAIN_KEY will be used as the owner key, and the active key will be derived from the BRAIN_KEY. Use\n";
|
||||
ss << "register_account if you already know the keys you know the public keys that you would like to register.\n";
|
||||
}
|
||||
else if( method == "register_account" )
|
||||
{
|
||||
ss << "usage: register_account ACCOUNT_NAME OWNER_PUBLIC_KEY ACTIVE_PUBLIC_KEY REGISTRAR REFERRER REFERRER_PERCENT BROADCAST\n\n";
|
||||
ss << "example: register_account \"newaccount\" \"CORE6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\" \"CORE6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\" \"1.3.11\" \"1.3.11\" 50 true\n";
|
||||
ss << "\n";
|
||||
ss << "Use this method to register an account for which you do not know the private keys.";
|
||||
}
|
||||
else if( method == "create_asset" )
|
||||
{
|
||||
ss << "usage: ISSUER SYMBOL PRECISION_DIGITS OPTIONS BITASSET_OPTIONS BROADCAST\n\n";
|
||||
ss << "PRECISION_DIGITS: the number of digits after the decimal point\n\n";
|
||||
ss << "Example value of OPTIONS: \n";
|
||||
ss << fc::json::to_pretty_string( graphene::chain::asset_options() );
|
||||
ss << "\nExample value of BITASSET_OPTIONS: \n";
|
||||
ss << fc::json::to_pretty_string( graphene::chain::bitasset_options() );
|
||||
ss << "\nBITASSET_OPTIONS may be null\n";
|
||||
}
|
||||
std::string doxygenHelpString = my->method_documentation.get_detailed_description(method);
|
||||
if (!doxygenHelpString.empty())
|
||||
ss << doxygenHelpString;
|
||||
else
|
||||
{
|
||||
std::string doxygenHelpString = my->method_documentation.get_detailed_description(method);
|
||||
if (!doxygenHelpString.empty())
|
||||
ss << doxygenHelpString;
|
||||
else
|
||||
ss << "No help defined for method " << method << "\n";
|
||||
}
|
||||
ss << "No help defined for method " << method << "\n";
|
||||
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -266,18 +266,66 @@ BOOST_AUTO_TEST_CASE( sidechain_address_delete_test ) {
|
|||
sign(trx, alice_private_key);
|
||||
PUSH_TX(db, trx, ~0);
|
||||
}
|
||||
time_point_sec now = db.head_block_time();
|
||||
//time_point_sec now = db.head_block_time();
|
||||
generate_block();
|
||||
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Check sidechain_address_delete_operation results");
|
||||
|
||||
const auto& idx = db.get_index_type<sidechain_address_index>().indices().get<by_account_and_sidechain_and_expires>();
|
||||
BOOST_REQUIRE( idx.size() == 1 );
|
||||
auto obj = idx.find( boost::make_tuple( alice_id, sidechain_type::bitcoin, time_point_sec::maximum() ) );
|
||||
BOOST_REQUIRE( obj == idx.end() );
|
||||
auto expired_obj = idx.find( boost::make_tuple( alice_id, sidechain_type::bitcoin, now ) );
|
||||
BOOST_REQUIRE( expired_obj != idx.end() );
|
||||
//BOOST_REQUIRE( idx.size() == 1 );
|
||||
//auto obj = idx.find( boost::make_tuple( alice_id, sidechain_type::bitcoin, time_point_sec::maximum() ) );
|
||||
//BOOST_REQUIRE( obj == idx.end() );
|
||||
//auto expired_obj = idx.find( boost::make_tuple( alice_id, sidechain_type::bitcoin, now ) );
|
||||
//BOOST_REQUIRE( expired_obj != idx.end() );
|
||||
BOOST_REQUIRE( idx.size() == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sidechain_address_delete_create_test) {
|
||||
|
||||
BOOST_TEST_MESSAGE("sidechain_address_delete_create_test");
|
||||
|
||||
INVOKE(sidechain_address_add_test);
|
||||
|
||||
GET_ACTOR(alice);
|
||||
|
||||
const auto &idx = db.get_index_type<sidechain_address_index>().indices().get<by_account_and_sidechain_and_expires>();
|
||||
BOOST_REQUIRE(idx.size() == 1);
|
||||
auto obj = idx.find(boost::make_tuple(alice_id, sidechain_type::bitcoin, time_point_sec::maximum()));
|
||||
BOOST_REQUIRE(obj != idx.end());
|
||||
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Delete and create sidechain address");
|
||||
sidechain_address_delete_operation op_del;
|
||||
op_del.payer = alice_id;
|
||||
op_del.sidechain_address_id = sidechain_address_id_type(0);
|
||||
op_del.sidechain_address_account = alice_id;
|
||||
op_del.sidechain = obj->sidechain;
|
||||
|
||||
sidechain_address_add_operation op_create;
|
||||
op_create.payer = alice_id;
|
||||
op_create.sidechain_address_account = alice_id;
|
||||
op_create.sidechain = sidechain_type::bitcoin;
|
||||
op_create.deposit_public_key = "deposit_public_key";
|
||||
op_create.withdraw_public_key = "withdraw_public_key";
|
||||
op_create.withdraw_address = "withdraw_address";
|
||||
|
||||
trx.operations.push_back(op_del);
|
||||
trx.operations.push_back(op_create);
|
||||
sign(trx, alice_private_key);
|
||||
PUSH_TX(db, trx, ~0);
|
||||
}
|
||||
|
||||
// both transactions should goes in one block (delete + create)
|
||||
generate_block();
|
||||
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Check sidechain_address_delete_add_operation results");
|
||||
const auto &idx = db.get_index_type<sidechain_address_index>().indices().get<by_account_and_sidechain_and_expires>();
|
||||
BOOST_REQUIRE(idx.size() == 1);
|
||||
auto obj = idx.find(boost::make_tuple(alice_id, sidechain_type::bitcoin, time_point_sec::maximum()));
|
||||
BOOST_REQUIRE(obj != idx.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue