Skip to content

Commit

Permalink
Merge pull request #304 from Fez29/rpc-wallet-staking
Browse files Browse the repository at this point in the history
Adds staking ability to transfer_split RPC, Don't provide RTA-related…
  • Loading branch information
mbg033 authored Jun 20, 2019
2 parents 1e65b61 + e87fa54 commit ff4ed03
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 8 deletions.
16 changes: 8 additions & 8 deletions src/rpc/core_rpc_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,15 @@ namespace cryptonote
END_JSON_RPC_MAP()
// Graft RTA handlers start here
BEGIN_JSON_RPC_MAP("/json_rpc/rta")
MAP_JON_RPC_WE("send_supernode_announce",on_supernode_announce, COMMAND_RPC_SUPERNODE_ANNOUNCE)
MAP_JON_RPC_WE("broadcast", on_broadcast, COMMAND_RPC_BROADCAST)
MAP_JON_RPC_WE("multicast", on_multicast, COMMAND_RPC_MULTICAST)
MAP_JON_RPC_WE("unicast", on_unicast, COMMAND_RPC_UNICAST)
MAP_JON_RPC_WE_IF("send_supernode_announce",on_supernode_announce, COMMAND_RPC_SUPERNODE_ANNOUNCE, !m_restricted)
MAP_JON_RPC_WE_IF("broadcast", on_broadcast, COMMAND_RPC_BROADCAST, !m_restricted)
MAP_JON_RPC_WE_IF("multicast", on_multicast, COMMAND_RPC_MULTICAST, !m_restricted)
MAP_JON_RPC_WE_IF("unicast", on_unicast, COMMAND_RPC_UNICAST, !m_restricted)

MAP_JON_RPC_WE("get_tunnels", on_get_tunnels, COMMAND_RPC_TUNNEL_DATA)
MAP_JON_RPC_WE("send_supernode_stakes", on_supernode_stakes, COMMAND_RPC_SUPERNODE_GET_STAKES)
MAP_JON_RPC_WE("send_supernode_blockchain_based_list", on_supernode_blockchain_based_list, COMMAND_RPC_SUPERNODE_GET_BLOCKCHAIN_BASED_LIST)
MAP_JON_RPC_WE("get_stats", on_get_rta_stats, COMMAND_RPC_RTA_STATS)
MAP_JON_RPC_WE_IF("get_tunnels", on_get_tunnels, COMMAND_RPC_TUNNEL_DATA, !m_restricted)
MAP_JON_RPC_WE_IF("send_supernode_stakes", on_supernode_stakes, COMMAND_RPC_SUPERNODE_GET_STAKES, !m_restricted)
MAP_JON_RPC_WE_IF("send_supernode_blockchain_based_list", on_supernode_blockchain_based_list, COMMAND_RPC_SUPERNODE_GET_BLOCKCHAIN_BASED_LIST, !m_restricted)
MAP_JON_RPC_WE_IF("get_stats", on_get_rta_stats, COMMAND_RPC_RTA_STATS, !m_restricted)
END_JSON_RPC_MAP()
END_URI_MAP2()

Expand Down
68 changes: 68 additions & 0 deletions src/wallet/wallet_rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ using namespace epee;
#include "daemonizer/daemonizer.h"
#include "wallet/wallet_errors.h"
#include "utils/cryptmsg.h"
#include "graft_rta_config.h"

#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "wallet.rpc"
Expand Down Expand Up @@ -1031,6 +1032,73 @@ namespace tools
{
return false;
}

if (req.stake_transfer) {
crypto::signature supernode_signature;
if (!epee::string_tools::hex_to_pod(req.supernode_signature, supernode_signature))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_SIGNATURE;
er.message = "failed to parse supernode signature";
return false;
}

crypto::public_key W;
if (!epee::string_tools::hex_to_pod(req.supernode_public_id, W) || !check_key(W))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_SUPERNODE_KEY;
er.message = "invalid supernode public identifier";
return false;
}
const cryptonote::account_public_address& supernode_public_address = dsts.front().addr;
std::string supernode_public_address_str = cryptonote::get_account_address_as_str(m_wallet->nettype(), dsts.front().is_subaddress, supernode_public_address);
std::string data = supernode_public_address_str + ":" + req.supernode_public_id;
crypto::hash hash;
crypto::cn_fast_hash(data.data(), data.size(), hash);

if (!crypto::check_signature(hash, W, supernode_signature))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_SIGNATURE;
er.message = "invalid supernode signature";
return false;
}

auto current_height = m_wallet->get_blockchain_current_height();
if (req.unlock_time < current_height + config::graft::STAKE_MIN_UNLOCK_TIME_FOR_WALLET)
{
er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR;
er.message = "unlock_time is too low";
return false;
}

if (req.unlock_time > current_height + config::graft::STAKE_MAX_UNLOCK_TIME)
{
er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR;
er.message = "unlock_time is too high";
return false;
}

if (dsts.size() != 1)
{
er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR;
er.message = "stake transfer must go to exactly one recipient";
return false;
}

uint64_t amount = dsts.front().amount;
if (amount < config::graft::TIER1_STAKE_AMOUNT && !req.allow_low_stake)
{
er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR;
er.message = "staked amount is too low";
return false;
}

if (!add_graft_stake_tx_extra_to_extra(extra, req.supernode_public_id, supernode_public_address, supernode_signature))
{
er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR;
er.message = "failed to add stake transaction extra fields";
return false;
}
}

try
{
Expand Down
9 changes: 9 additions & 0 deletions src/wallet/wallet_rpc_server_commands_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,11 @@ namespace wallet_rpc
bool get_tx_hex;
bool get_tx_metadata;

bool stake_transfer;
std::string supernode_public_id;
std::string supernode_signature;
bool allow_low_stake;

BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(destinations)
KV_SERIALIZE(account_index)
Expand All @@ -495,6 +500,10 @@ namespace wallet_rpc
KV_SERIALIZE_OPT(do_not_relay, false)
KV_SERIALIZE_OPT(get_tx_hex, false)
KV_SERIALIZE_OPT(get_tx_metadata, false)
KV_SERIALIZE_OPT(stake_transfer, false)
KV_SERIALIZE(supernode_public_id)
KV_SERIALIZE(supernode_signature)
KV_SERIALIZE_OPT(allow_low_stake, false)
END_KV_SERIALIZE_MAP()
};

Expand Down

0 comments on commit ff4ed03

Please sign in to comment.