Skip to content

Commit

Permalink
Adds staking ability to transfer_split RPC
Browse files Browse the repository at this point in the history
Added parameters are:

    stake_transfer - must be true to do a staking transfer
    supernode_public_id - the SN pubkey
    supernode_signature - a SN signature value
    allow_low_stake - set to true to allow staking less than a T1 (for
                      example, to submit an "upgrade" stake amount).

The transfer must also be sent to a single address (which has to match
the one configured in the SN for the signature to be valid).
  • Loading branch information
jagerman committed Mar 30, 2019
1 parent 3c22f47 commit 374d76f
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/wallet/wallet_rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ using namespace epee;
#include "rpc/rpc_args.h"
#include "rpc/core_rpc_server_commands_defs.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 @@ -679,6 +680,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->testnet(), 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
{
uint64_t mixin = adjust_mixin(req.mixin);
Expand Down
10 changes: 10 additions & 0 deletions src/wallet/wallet_rpc_server_commands_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ namespace wallet_rpc
bool do_not_relay;
bool get_tx_hex;

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(priority)
Expand All @@ -174,6 +179,11 @@ namespace wallet_rpc
KV_SERIALIZE(get_tx_keys)
KV_SERIALIZE_OPT(do_not_relay, false)
KV_SERIALIZE_OPT(get_tx_hex, 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 374d76f

Please sign in to comment.