mirror of https://github.com/oxen-io/oxen-core.git
simplewallet: add sanity check to staking commands (#123)
This commit is contained in:
parent
591fda78f0
commit
79406a28a0
|
@ -50,7 +50,6 @@
|
|||
#include "common/int-util.h"
|
||||
#include "common/threadpool.h"
|
||||
#include "common/boost_serialization_helper.h"
|
||||
#include "common/exp2.h"
|
||||
#include "warnings.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "cryptonote_core.h"
|
||||
|
@ -851,20 +850,6 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
|
|||
m_difficulty_for_next_block = diff;
|
||||
return diff;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
uint64_t Blockchain::get_staking_requirement(uint64_t height) const
|
||||
{
|
||||
if (m_nettype == TESTNET)
|
||||
return COIN * 100;
|
||||
uint64_t height_adjusted = height-129600;
|
||||
uint64_t base = 10000 * COIN;
|
||||
uint64_t variable = (35000.0 * COIN) / loki_exp2(height_adjusted/129600.0);
|
||||
uint64_t linear_up = 5 * COIN * height / 2592;
|
||||
uint64_t flat = 15000 * COIN;
|
||||
return std::min(30000 * COIN,
|
||||
std::max(base + variable, height < 3628800 ? linear_up : flat));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// This function removes blocks from the blockchain until it gets to the
|
||||
// position where the blockchain switch started and then re-adds the blocks
|
||||
|
|
|
@ -320,13 +320,6 @@ namespace cryptonote
|
|||
*/
|
||||
difficulty_type get_difficulty_for_next_block();
|
||||
|
||||
/**
|
||||
* @brief returns the staking requirement for the block at height
|
||||
*
|
||||
* @return the target
|
||||
*/
|
||||
uint64_t get_staking_requirement(uint64_t height) const;
|
||||
|
||||
/**
|
||||
* @brief adds a block to the blockchain
|
||||
*
|
||||
|
@ -781,6 +774,12 @@ namespace cryptonote
|
|||
*/
|
||||
void safesyncmode(const bool onoff);
|
||||
|
||||
/**
|
||||
* @brief Get the nettype
|
||||
* @return the nettype
|
||||
*/
|
||||
network_type nettype() const { return m_nettype; }
|
||||
|
||||
/**
|
||||
* @brief set whether or not to show/print time statistics
|
||||
*
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "common/scoped_message_writer.h"
|
||||
#include "common/i18n.h"
|
||||
#include "quorum_cop.h"
|
||||
#include "common/exp2.h"
|
||||
|
||||
#include "service_node_list.h"
|
||||
|
||||
|
@ -298,7 +299,7 @@ namespace service_nodes
|
|||
|
||||
// check the initial contribution exists
|
||||
|
||||
info.staking_requirement = m_blockchain.get_staking_requirement(block_height);
|
||||
info.staking_requirement = get_staking_requirement(m_blockchain.nettype(), block_height);
|
||||
|
||||
cryptonote::account_public_address address;
|
||||
uint64_t transferred = 0;
|
||||
|
@ -1087,6 +1088,16 @@ namespace service_nodes
|
|||
cmd = stream.str();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t get_staking_requirement(cryptonote::network_type m_nettype, uint64_t height)
|
||||
{
|
||||
if (m_nettype == cryptonote::TESTNET)
|
||||
return COIN * 100;
|
||||
uint64_t height_adjusted = height-129600;
|
||||
uint64_t base = 10000 * COIN;
|
||||
uint64_t variable = (35000.0 * COIN) / loki_exp2(height_adjusted/129600.0);
|
||||
uint64_t linear_up = 5 * COIN * height / 2592;
|
||||
uint64_t flat = 15000 * COIN;
|
||||
return std::min(30000 * COIN, std::max(base + variable, height < 3628800 ? linear_up : flat));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -258,6 +258,8 @@ namespace service_nodes
|
|||
bool make_registration_cmd(cryptonote::network_type nettype, const std::vector<std::string> args, const crypto::public_key& service_node_pubkey,
|
||||
const crypto::secret_key service_node_key, std::string &cmd, bool make_friendly);
|
||||
|
||||
uint64_t get_staking_requirement(cryptonote::network_type nettype, uint64_t height);
|
||||
|
||||
const static cryptonote::account_public_address null_address{ crypto::null_pkey, crypto::null_pkey };
|
||||
}
|
||||
|
||||
|
|
|
@ -4712,17 +4712,29 @@ bool simple_wallet::register_service_node(const std::vector<std::string> &args_)
|
|||
|
||||
size_t mixins = DEFAULT_MIX;
|
||||
|
||||
uint64_t unlock_block = 0;
|
||||
uint64_t locked_blocks = STAKING_REQUIREMENT_LOCK_BLOCKS + STAKING_REQUIREMENT_LOCK_BLOCKS_EXCESS;
|
||||
|
||||
std::string err;
|
||||
uint64_t bc_height = get_daemon_blockchain_height(err);
|
||||
if (!err.empty())
|
||||
uint64_t bc_height = m_wallet->get_daemon_blockchain_height(err);
|
||||
|
||||
if (!m_wallet->is_synced() || !err.empty() || bc_height < 10)
|
||||
{
|
||||
fail_msg_writer() << tr("failed to get blockchain height: ") << err;
|
||||
return true;
|
||||
if (!m_wallet->is_synced())
|
||||
err = tr("daemon not finished syncing");
|
||||
fail_msg_writer() << tr("unable to get network blockchain height from daemon: ") << err;
|
||||
std::string height = input_line(tr("Please enter the current network block height: "));
|
||||
try
|
||||
{
|
||||
bc_height = boost::lexical_cast<uint64_t>(height);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
fail_msg_writer() << tr("Invalid block height");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unlock_block = bc_height + locked_blocks;
|
||||
|
||||
uint64_t unlock_block = bc_height + locked_blocks;
|
||||
|
||||
if (local_args.size() < 4)
|
||||
{
|
||||
|
@ -4793,6 +4805,19 @@ bool simple_wallet::register_service_node(const std::vector<std::string> &args_)
|
|||
return true;
|
||||
}
|
||||
|
||||
uint64_t expected_staking_requirement = std::max(
|
||||
service_nodes::get_staking_requirement(m_wallet->nettype(), bc_height),
|
||||
service_nodes::get_staking_requirement(m_wallet->nettype(), bc_height+STAKING_REQUIREMENT_LOCK_BLOCKS_EXCESS)
|
||||
);
|
||||
|
||||
if (amount < expected_staking_requirement / MAX_NUMBER_OF_CONTRIBUTORS)
|
||||
{
|
||||
fail_msg_writer() << tr("This staking amount is not enough and cannot be used for a registration");
|
||||
fail_msg_writer() << tr("If it looks correct, please send a little bit extra to ensure that it is still correct when it makes it into a block");
|
||||
fail_msg_writer() << tr("Please send at least: ") << print_money(expected_staking_requirement / MAX_NUMBER_OF_CONTRIBUTORS);
|
||||
return true;
|
||||
}
|
||||
|
||||
LOCK_IDLE_SCOPE();
|
||||
|
||||
cryptonote::account_public_address address = addresses[0];
|
||||
|
@ -4946,17 +4971,29 @@ bool simple_wallet::stake(const std::vector<std::string> &args_)
|
|||
|
||||
size_t mixins = DEFAULT_MIX;
|
||||
|
||||
uint64_t unlock_block = 0;
|
||||
uint64_t locked_blocks = STAKING_REQUIREMENT_LOCK_BLOCKS + STAKING_REQUIREMENT_LOCK_BLOCKS_EXCESS;
|
||||
|
||||
std::string err;
|
||||
uint64_t bc_height = get_daemon_blockchain_height(err);
|
||||
if (!err.empty())
|
||||
uint64_t bc_height = m_wallet->get_daemon_blockchain_height(err);
|
||||
|
||||
if (!m_wallet->is_synced() || !err.empty() || bc_height < 10)
|
||||
{
|
||||
fail_msg_writer() << tr("failed to get blockchain height: ") << err;
|
||||
return true;
|
||||
if (!m_wallet->is_synced())
|
||||
err = tr("daemon not finished syncing");
|
||||
fail_msg_writer() << tr("unable to get network blockchain height from daemon: ") << err;
|
||||
std::string height = input_line(tr("Please enter the current network block height: "));
|
||||
try
|
||||
{
|
||||
bc_height = boost::lexical_cast<uint64_t>(height);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
fail_msg_writer() << tr("Invalid block height");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unlock_block = bc_height + locked_blocks;
|
||||
|
||||
uint64_t unlock_block = bc_height + locked_blocks;
|
||||
|
||||
if (local_args.size() < 2)
|
||||
{
|
||||
|
@ -4979,6 +5016,33 @@ bool simple_wallet::stake(const std::vector<std::string> &args_)
|
|||
return true;
|
||||
}
|
||||
|
||||
uint64_t expected_staking_requirement = std::max(
|
||||
service_nodes::get_staking_requirement(m_wallet->nettype(), bc_height),
|
||||
service_nodes::get_staking_requirement(m_wallet->nettype(), bc_height+STAKING_REQUIREMENT_LOCK_BLOCKS_EXCESS)
|
||||
);
|
||||
|
||||
if (amount < expected_staking_requirement / MAX_NUMBER_OF_CONTRIBUTORS)
|
||||
{
|
||||
std::stringstream prompt;
|
||||
prompt << tr("This staking amount is not enough and cannot be used to stake") << '\n';
|
||||
prompt << tr("If it looks correct, please send a little bit extra to ensure that it is still correct when it makes it into a block") << '\n';
|
||||
prompt << tr("This warning was triggered because you sent less than: ") << print_money(expected_staking_requirement / MAX_NUMBER_OF_CONTRIBUTORS) << tr(" loki\n");
|
||||
prompt << tr("") << '\n';
|
||||
prompt << tr("If this is not the first time you are making a contribution to this service node") << '\n';
|
||||
prompt << tr("then it should be okay to top-up the amount you are contributing. This is also true") << '\n';
|
||||
prompt << tr("if this address was specified in the service node registration.") << '\n';
|
||||
prompt << tr("") << '\n';
|
||||
prompt << tr("Most likely this is not the right amount to send. Only continue if you know what you are doing.") << '\n';
|
||||
prompt << tr("\nDo you want to continue?");
|
||||
std::string accepted = input_line(prompt.str());
|
||||
if (std::cin.eof())
|
||||
return true;
|
||||
if (!command_line::is_yes(accepted))
|
||||
{
|
||||
fail_msg_writer() << tr("transaction cancelled.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
std::vector<uint8_t> extra;
|
||||
|
||||
add_service_node_pubkey_to_tx_extra(extra, service_node_key);
|
||||
|
|
Loading…
Reference in New Issue