Skip to content

Commit

Permalink
Merge pull request Beldex-Coin#127 from victor-tucci/coin-burn
Browse files Browse the repository at this point in the history
burn process by amount/transaction_id
  • Loading branch information
sanada08 authored Nov 14, 2023
2 parents ec797f5 + 91a035c commit 1b634ee
Show file tree
Hide file tree
Showing 18 changed files with 551 additions and 22 deletions.
3 changes: 2 additions & 1 deletion contrib/epee/include/epee/misc_log_ex.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ enum console_colors
console_color_blue,
console_color_cyan,
console_color_magenta,
console_color_yellow
console_color_yellow,
console_color_orange
};

bool is_stdout_a_tty();
Expand Down
14 changes: 13 additions & 1 deletion contrib/epee/src/mlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,19 @@ void set_console_color(int color, bool bright)
#endif
}
break;

case console_color_orange:
{
#ifdef WIN32
HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | (bright ? FOREGROUND_INTENSITY : 0));
#else
if (bright)
std::cout << "\033[1;38;5;208m"; // Use ANSI escape code for bright orange (38;5;208).
else
std::cout << "\033[0;38;5;166m"; // Use ANSI escape code for normal orange (38;5;166).
#endif
}
break;
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/cryptonote_basic/cryptonote_basic.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ namespace cryptonote
txversion version;
txtype type;

bool is_transfer() const { return type == txtype::standard || type == txtype::stake || type == txtype::beldex_name_system; }
bool is_transfer() const { return type == txtype::standard || type == txtype::stake || type == txtype::beldex_name_system || type == txtype::coin_burn; }

// not used after version 2, but remains for compatibility
uint64_t unlock_time; //number of block (or time), used as a limitation like: spend this tx not early then block/time
Expand Down Expand Up @@ -529,10 +529,11 @@ namespace cryptonote
constexpr txtype transaction_prefix::get_max_type_for_hf(uint8_t hf_version)
{
txtype result = txtype::standard;
if (hf_version >= network_version_16) result = txtype::beldex_name_system;
if (hf_version >= network_version_18_bns) result = txtype::coin_burn;
else if (hf_version >= network_version_16) result = txtype::beldex_name_system;
else if (hf_version >= network_version_15_flash) result = txtype::stake;
else if (hf_version >= network_version_11_infinite_staking) result = txtype::key_image_unlock;
else if (hf_version >= network_version_9_master_nodes) result = txtype::state_change;
else if (hf_version >= network_version_9_master_nodes) result = txtype::state_change;

return result;
}
Expand All @@ -557,7 +558,8 @@ namespace cryptonote
case txtype::state_change: return "state_change";
case txtype::key_image_unlock: return "key_image_unlock";
case txtype::stake: return "stake";
case txtype::beldex_name_system: return "beldex_name_system";
case txtype::beldex_name_system: return "beldex_name_system";
case txtype::coin_burn: return "coin_burn";
default: assert(false); return "xx_unhandled_type";
}
}
Expand Down
1 change: 1 addition & 0 deletions src/cryptonote_basic/txtypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum class txversion : uint16_t {
key_image_unlock,
stake,
beldex_name_system,
coin_burn,
_count
};

Expand Down
13 changes: 12 additions & 1 deletion src/cryptonote_core/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3267,7 +3267,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,

if (tx.is_transfer())
{
if (tx.type != txtype::beldex_name_system && hf_version >= HF_VERSION_MIN_2_OUTPUTS && tx.vout.size() < 2)
if (tx.type != txtype::beldex_name_system && tx.type != txtype::coin_burn && hf_version >= HF_VERSION_MIN_2_OUTPUTS && tx.vout.size() < 2)
{
MERROR_VER("Tx " << get_transaction_hash(tx) << " has fewer than two outputs, which is not allowed as of hardfork " << +HF_VERSION_MIN_2_OUTPUTS);
tvc.m_too_few_outputs = true;
Expand Down Expand Up @@ -3557,6 +3557,17 @@ if (tx.version >= cryptonote::txversion::v2_ringct)
return false;
}
}
else if (tx.type == txtype::coin_burn)
{
uint64_t burn = cryptonote::get_burned_amount_from_tx_extra(tx.extra);
if (burn == 0)
{
std::string fail_reason = "Burn amount must not equals to zero";
MERROR_VER("Failed to validate Burn TX reason: " << fail_reason);
tvc.m_verbose_error = std::move(fail_reason);
return false;
}
}
}
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/cryptonote_core/tx_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ namespace cryptonote
}
else
{
if (tx.type != txtype::standard && tx.type != txtype::stake)
if (tx.type != txtype::standard && tx.type != txtype::stake && tx.type != txtype::coin_burn)
{
// NOTE(beldex): This is a developer error. If we come across this in production, be conservative and just reject
MERROR("Unrecognised transaction type: " << tx.type << " for tx: " << get_transaction_hash(tx));
Expand Down
128 changes: 126 additions & 2 deletions src/simplewallet/simplewallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ namespace
const char* USAGE_BNS_MAKE_UPDATE_MAPPING_SIGNATURE("bns_make_update_mapping_signature [owner=<value>] [backup_owner=<value>] <name>");
const char* USAGE_BNS_BY_OWNER("bns_by_owner [<owner> ...]");
const char* USAGE_BNS_LOOKUP("bns_lookup <name> [<name> ...]");

const char* USAGE_COIN_BURN("coin_burn [index=<N1>[,<N2>,...]] [<priority>] <burn=amount | txid>");


#if defined (BELDEX_ENABLE_INTEGRATION_TEST_HOOKS)
std::string input_line(const std::string &prompt, bool yesno = false)
Expand Down Expand Up @@ -3117,6 +3120,11 @@ Pending or Failed: "failed"|"pending", "out", Lock, Checkpointed, Time, Amount*
[this](const auto& x) { return bns_make_update_mapping_signature(x); },
tr(USAGE_BNS_MAKE_UPDATE_MAPPING_SIGNATURE),
tr(tools::wallet_rpc::BNS_MAKE_UPDATE_SIGNATURE::description));

m_cmd_binder.set_handler("coin_burn",
[this](const auto& x) { return coin_burn(x); },
tr(USAGE_COIN_BURN),
tr(tools::wallet_rpc::COIN_BURN::description));
}

simple_wallet::~simple_wallet()
Expand Down Expand Up @@ -7203,6 +7211,119 @@ bool simple_wallet::bns_by_owner(const std::vector<std::string>& args)
return true;
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::coin_burn(std::vector<std::string> args)
{
if (!try_connect_to_daemon())
return false;

size_t outputs = 1;
// priority and subaddress fetch
uint32_t priority = 0;
std::set<uint32_t> subaddr_indices = {};
if (!parse_subaddr_indices_and_priority(*m_wallet, args, subaddr_indices, priority, m_current_subaddress_account)) return false;

// get the burn amount from the argument
static constexpr auto BURN_PREFIX = "burn="sv;
uint64_t burn_amount = 0;
crypto::hash txid;
std::string burn_amount_str = eat_named_argument(args, BURN_PREFIX);

if (!burn_amount_str.empty() && !cryptonote::parse_amount(burn_amount, burn_amount_str)) {
if (!tools::hex_to_type(burn_amount_str, txid))
{
fail_msg_writer() << tr("failed to parse transactio ID or Invalid amount");
return true;
}
}

if(args.size() != 0){
PRINT_USAGE(USAGE_COIN_BURN);
return false;
}
if(!txid && burn_amount == 0){
fail_msg_writer() << tr("Burn amount equals to zero/not given.");
PRINT_USAGE(USAGE_COIN_BURN);
return false;
}
// unlock the wallet for getting the keys
SCOPED_WALLET_UNLOCK();
// create_transaction2 try for burning
try
{
std::vector<uint8_t> extra;
std::vector<tools::wallet2::pending_tx> ptx_vector;
std::optional<uint8_t> hf_version = m_wallet->get_hard_fork_version();
if (!hf_version)
{
fail_msg_writer() << tools::ERR_MSG_NETWORK_VERSION_QUERY_FAILED;
return false;
}
// parms are constructed
beldex_construct_tx_params tx_params = tools::wallet2::construct_params(*hf_version, txtype::coin_burn, priority, burn_amount);
// transaction process called
if(burn_amount){
ptx_vector = m_wallet->create_transactions_2({}, CRYPTONOTE_DEFAULT_TX_MIXIN, 0, priority, extra, m_current_subaddress_account, subaddr_indices, tx_params);
}else{
tools::wallet2::transfer_container transfers;
bool available = false;
std::vector<crypto::key_image> ki;
m_wallet->get_transfers(transfers);

for (const auto& td : transfers)
{
if(td.m_txid == txid)
{
available = true;
if(!td.m_spent)
{
ki.push_back(td.m_key_image) ;
}
}
}
if(available && ki.size() == 0)
{
fail_msg_writer() << tr("The txid already spent.");
return false;
}
if(!available)
{
fail_msg_writer() << tr("No incoming available transfers");
return false;
}

ptx_vector = m_wallet->create_transactions_burn(ki, outputs, CRYPTONOTE_DEFAULT_TX_MIXIN, 0, priority, extra);
}

if (ptx_vector.empty())
{
fail_msg_writer() << tr("No outputs found, or daemon is not ready");
return false;
}

std::vector<cryptonote::address_parse_info> dsts;
cryptonote::address_parse_info info = {};
info.address = m_wallet->get_subaddress({m_current_subaddress_account, 0});
info.is_subaddress = m_current_subaddress_account != 0;
dsts.push_back(info);

if (!confirm_and_send_tx(dsts, ptx_vector, priority == tools::tx_priority_flash))
return false;
}
catch (const std::exception &e)
{
handle_transfer_exception(std::current_exception(), m_wallet->is_trusted_daemon());
return true;
}
catch (...)
{
LOG_ERROR("unknown error");
fail_msg_writer() << tr("unknown error");
return true;
}

return true;
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
{
if (!try_connect_to_daemon())
Expand Down Expand Up @@ -8624,8 +8745,9 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
case wallet::pay_type::governance: color = epee::console_color_cyan; break;
case wallet::pay_type::stake: color = epee::console_color_blue; break;
case wallet::pay_type::bns: color = epee::console_color_blue; break;
case wallet::pay_type::master_node: color = epee::console_color_cyan; break;
default: color = epee::console_color_magenta; break;
case wallet::pay_type::coin_burn: color = epee::console_color_orange; break;
case wallet::pay_type::master_node: color = epee::console_color_cyan; break;
default: color = epee::console_color_magenta; break;
}
}

Expand All @@ -8647,6 +8769,8 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
transfer.pay_type == wallet::pay_type::bns ||
transfer.pay_type == wallet::pay_type::miner)
destinations += output.address.substr(0, 6);
else if (transfer.pay_type == wallet::pay_type::coin_burn){
destinations = "-"; continue;}
else
destinations += output.address;

Expand Down
2 changes: 2 additions & 0 deletions src/simplewallet/simplewallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ namespace cryptonote
bool bns_by_owner(const std::vector<std::string> &args);
bool bns_lookup(std::vector<std::string> args);

bool coin_burn(std::vector<std::string> args);

enum class sweep_type_t { stake, register_stake, all_or_below, single };
bool sweep_main_internal(sweep_type_t sweep_type, std::vector<tools::wallet2::pending_tx> &ptx_vector, cryptonote::address_parse_info const &dest, bool flash);
bool sweep_main(uint32_t account, uint64_t below, Transfer transfer_type, const std::vector<std::string> &args);
Expand Down
6 changes: 5 additions & 1 deletion src/wallet/api/transaction_history.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ void TransactionHistoryImpl::refresh()
ti->m_hash = tools::type_to_hex(pd.m_tx_hash);
ti->m_blockheight = pd.m_block_height;
ti->m_is_stake = pd.m_type == wallet::pay_type::stake;
ti->m_is_bns = pd.m_type == wallet::pay_type::bns;
ti->m_is_bns = pd.m_type == wallet::pay_type::bns;
ti->m_is_coin_burn = pd.m_type == wallet::pay_type::coin_burn;
ti->m_subaddrIndex = { pd.m_subaddr_index.minor };
ti->m_subaddrAccount = pd.m_subaddr_index.major;
ti->m_label = w->get_subaddress_label(pd.m_subaddr_index);
Expand Down Expand Up @@ -192,6 +193,7 @@ void TransactionHistoryImpl::refresh()
ti->m_blockheight = pd.m_block_height;
ti->m_is_stake = pd.m_pay_type == wallet::pay_type::stake;
ti->m_is_bns = pd.m_pay_type == wallet::pay_type::bns;
ti->m_is_coin_burn = pd.m_pay_type == wallet::pay_type::coin_burn;
ti->m_subaddrIndex = pd.m_subaddr_indices;
ti->m_subaddrAccount = pd.m_subaddr_account;
ti->m_label = pd.m_subaddr_indices.size() == 1 ? w->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "";
Expand Down Expand Up @@ -225,6 +227,7 @@ void TransactionHistoryImpl::refresh()
ti->m_direction = TransactionInfo::Direction_Out;
ti->m_is_stake = pd.m_pay_type == wallet::pay_type::stake;
ti->m_is_bns = pd.m_pay_type == wallet::pay_type::bns;
ti->m_is_coin_burn = pd.m_pay_type == wallet::pay_type::coin_burn;
ti->m_failed = is_failed;
ti->m_pending = true;
ti->m_hash = tools::type_to_hex(hash);
Expand Down Expand Up @@ -253,6 +256,7 @@ void TransactionHistoryImpl::refresh()
ti->m_blockheight = pd.m_block_height;
ti->m_is_stake = pd.m_type == wallet::pay_type::stake;
ti->m_is_bns = pd.m_type == wallet::pay_type::bns;
ti->m_is_coin_burn = pd.m_type == wallet::pay_type::coin_burn;
ti->m_pending = true;
ti->m_subaddrIndex = { pd.m_subaddr_index.minor };
ti->m_subaddrAccount = pd.m_subaddr_index.major;
Expand Down
1 change: 1 addition & 0 deletions src/wallet/api/transaction_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ TransactionInfoImpl::TransactionInfoImpl()
: m_direction(Direction_Out)
, m_is_stake(false)
, m_is_bns(false)
, m_is_coin_burn(false)
, m_pending(false)
, m_failed(false)
, m_reward_type(reward_type::unspecified)
Expand Down
1 change: 1 addition & 0 deletions src/wallet/api/transaction_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class TransactionInfoImpl : public TransactionInfo
int m_direction;
bool m_is_stake;
bool m_is_bns;
bool m_is_coin_burn;
bool m_pending;
bool m_failed;
reward_type m_reward_type; // may have a value rather than `unspecified` after hf 10
Expand Down
5 changes: 4 additions & 1 deletion src/wallet/transfer_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ enum struct pay_type
miner,
master_node,
governance,
bns
bns,
coin_burn
};

inline const char *pay_type_string(pay_type type)
Expand All @@ -62,6 +63,7 @@ inline const char *pay_type_string(pay_type type)
case pay_type::bns: return "bns";
case pay_type::master_node: return "mnode";
case pay_type::governance: return "gov";
case pay_type::coin_burn: return "burn";
default: assert(false); return "xxxxx";
}
}
Expand All @@ -72,6 +74,7 @@ inline pay_type pay_type_from_tx(const cryptonote::transaction tx)
{
case cryptonote::txtype::stake: return wallet::pay_type::stake;
case cryptonote::txtype::beldex_name_system: return wallet::pay_type::bns;
case cryptonote::txtype::coin_burn: return wallet::pay_type::coin_burn;
default: return wallet::pay_type::out;
}
}
Expand Down
Loading

0 comments on commit 1b634ee

Please sign in to comment.