From aefeb0f83a3a6ba5c421951048d410e5d842ac90 Mon Sep 17 00:00:00 2001 From: Some Random Crypto Guy Date: Fri, 27 Oct 2023 06:14:59 +0100 Subject: [PATCH] so this commit contains a new GENESIS TX with the revised TX format - no pricing_record_height etc. Lots of reworking of tests because of changes to function prototypes, etc --- src/blockchain_db/lmdb/db_lmdb.cpp | 6 +- .../blockchain_ancestry.cpp | 2 +- .../blockchain_blackball.cpp | 2 +- src/blockchain_utilities/blockchain_depth.cpp | 2 +- .../blockchain_export.cpp | 2 +- .../blockchain_import.cpp | 2 +- src/blockchain_utilities/blockchain_prune.cpp | 2 +- .../blockchain_prune_known_spent_data.cpp | 2 +- src/blockchain_utilities/blockchain_stats.cpp | 4 +- src/blockchain_utilities/blockchain_usage.cpp | 2 +- src/common/dns_utils.h | 2 +- src/common/updates.cpp | 2 +- src/cryptonote_basic/cryptonote_basic.h | 57 +++++++- .../cryptonote_boost_serialization.h | 4 +- .../cryptonote_format_utils.cpp | 8 +- src/cryptonote_config.h | 3 +- src/cryptonote_core/blockchain.cpp | 22 +-- src/cryptonote_core/blockchain.h | 24 ++-- src/cryptonote_core/cryptonote_tx_utils.cpp | 88 ++++++++++-- src/cryptonote_core/cryptonote_tx_utils.h | 6 +- src/cryptonote_core/tx_verification_utils.cpp | 11 +- src/cryptonote_core/tx_verification_utils.h | 3 +- src/daemon/command_server.cpp | 2 +- src/daemon/executor.cpp | 4 +- src/daemonizer/windows_daemonizer.inl | 2 +- src/debug_utilities/cn_deserialize.cpp | 2 +- src/debug_utilities/dns_checks.cpp | 2 +- src/gen_ssl_cert/gen_ssl_cert.cpp | 4 +- src/ringct/rctSigs.cpp | 37 ++++- src/ringct/rctSigs.h | 37 ++++- src/simplewallet/simplewallet.cpp | 124 ++++++++-------- src/simplewallet/simplewallet.h | 4 +- src/wallet/wallet2.cpp | 132 ++++++++++-------- src/wallet/wallet_args.cpp | 6 +- tests/core_tests/block_validation.cpp | 4 +- tests/core_tests/bulletproof_plus.cpp | 4 +- tests/core_tests/bulletproofs.cpp | 4 +- tests/core_tests/chaingen.cpp | 4 +- tests/core_tests/double_spend.inl | 2 +- tests/core_tests/integer_overflow.cpp | 4 +- tests/core_tests/rct.cpp | 8 +- tests/core_tests/rct2.cpp | 4 +- tests/core_tests/transaction_tests.cpp | 2 +- tests/core_tests/v2_tests.cpp | 2 +- tests/core_tests/wallet_tools.cpp | 4 +- tests/performance_tests/check_tx_signature.h | 11 +- tests/performance_tests/construct_tx.h | 4 +- .../performance_tests/ge_frombytes_vartime.h | 2 +- tests/performance_tests/ge_tobytes.h | 2 +- tests/unit_tests/address_from_url.cpp | 2 +- tests/unit_tests/bulletproofs.cpp | 7 +- tests/unit_tests/json_serialization.cpp | 4 +- tests/unit_tests/ringct.cpp | 36 ++++- tests/unit_tests/serialization.cpp | 9 +- .../ver_rct_non_semantics_simple_cached.cpp | 10 +- 55 files changed, 514 insertions(+), 227 deletions(-) diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 0767fd5..e37b40c 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -338,7 +338,7 @@ typedef struct outassettype { typedef struct circ_supply { crypto::hash tx_hash; - uint64_t pricing_record_height; + //uint64_t pricing_record_height; uint64_t source_currency_type; uint64_t dest_currency_type; uint64_t amount_burnt; @@ -1051,7 +1051,7 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons // Conversion TX - update our records circ_supply cs; cs.tx_hash = tx_hash; - cs.pricing_record_height = tx.pricing_record_height; + //cs.pricing_record_height = tx.pricing_record_height; cs.source_currency_type = std::find(oracle::ASSET_TYPES.begin(), oracle::ASSET_TYPES.end(), strSource) - oracle::ASSET_TYPES.begin(); cs.dest_currency_type = std::find(oracle::ASSET_TYPES.begin(), oracle::ASSET_TYPES.end(), strDest) - oracle::ASSET_TYPES.begin(); cs.amount_burnt = tx.amount_burnt; @@ -1162,7 +1162,7 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const // Get the current tally value for the source currency type circ_supply cs; cs.tx_hash = tx_hash; - cs.pricing_record_height = tx.pricing_record_height; + //cs.pricing_record_height = tx.pricing_record_height; cs.amount_burnt = tx.amount_burnt; cs.amount_minted = tx.amount_minted; cs.source_currency_type = std::find(oracle::ASSET_TYPES.begin(), oracle::ASSET_TYPES.end(), strSource) - oracle::ASSET_TYPES.begin(); diff --git a/src/blockchain_utilities/blockchain_ancestry.cpp b/src/blockchain_utilities/blockchain_ancestry.cpp index b0964e4..ed33a0f 100644 --- a/src/blockchain_utilities/blockchain_ancestry.cpp +++ b/src/blockchain_utilities/blockchain_ancestry.cpp @@ -386,7 +386,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } diff --git a/src/blockchain_utilities/blockchain_blackball.cpp b/src/blockchain_utilities/blockchain_blackball.cpp index dee0f7f..7bea444 100644 --- a/src/blockchain_utilities/blockchain_blackball.cpp +++ b/src/blockchain_utilities/blockchain_blackball.cpp @@ -1219,7 +1219,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } diff --git a/src/blockchain_utilities/blockchain_depth.cpp b/src/blockchain_utilities/blockchain_depth.cpp index b98a1f8..66cae6e 100644 --- a/src/blockchain_utilities/blockchain_depth.cpp +++ b/src/blockchain_utilities/blockchain_depth.cpp @@ -88,7 +88,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp index 82fe524..45d6446 100644 --- a/src/blockchain_utilities/blockchain_export.cpp +++ b/src/blockchain_utilities/blockchain_export.cpp @@ -90,7 +90,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index f8cca63..51ba888 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -637,7 +637,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } diff --git a/src/blockchain_utilities/blockchain_prune.cpp b/src/blockchain_utilities/blockchain_prune.cpp index 4a91cf7..8aee529 100644 --- a/src/blockchain_utilities/blockchain_prune.cpp +++ b/src/blockchain_utilities/blockchain_prune.cpp @@ -483,7 +483,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } diff --git a/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp b/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp index 05aaf42..ba0fc92 100644 --- a/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp +++ b/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp @@ -137,7 +137,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } diff --git a/src/blockchain_utilities/blockchain_stats.cpp b/src/blockchain_utilities/blockchain_stats.cpp index 21040a1..09fd8f7 100644 --- a/src/blockchain_utilities/blockchain_stats.cpp +++ b/src/blockchain_utilities/blockchain_stats.cpp @@ -175,7 +175,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } @@ -242,7 +242,7 @@ int main(int argc, char* argv[]) /* * The default output can be plotted with GnuPlot using these commands: set key autotitle columnhead -set title "Monero Blockchain Growth" +set title "Fulmo Blockchain Growth" set timefmt "%Y-%m-%d" set xdata time set xrange ["2014-04-17":*] diff --git a/src/blockchain_utilities/blockchain_usage.cpp b/src/blockchain_utilities/blockchain_usage.cpp index 129a9be..c429a56 100644 --- a/src/blockchain_utilities/blockchain_usage.cpp +++ b/src/blockchain_utilities/blockchain_usage.cpp @@ -120,7 +120,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } diff --git a/src/common/dns_utils.h b/src/common/dns_utils.h index 81079ba..3f4c03f 100644 --- a/src/common/dns_utils.h +++ b/src/common/dns_utils.h @@ -122,7 +122,7 @@ public: * @brief Gets a DNS address from OpenAlias format * * If the address looks good, but contains one @ symbol, replace that with a . - * e.g. donate@getmonero.org becomes donate.getmonero.org + * e.g. donate@fulmo.network becomes donate.fulmo.network * * @param oa_addr OpenAlias address * diff --git a/src/common/updates.cpp b/src/common/updates.cpp index 654ad06..1b1d9a1 100644 --- a/src/common/updates.cpp +++ b/src/common/updates.cpp @@ -102,7 +102,7 @@ namespace tools std::string get_update_url(const std::string &software, const std::string &subdir, const std::string &buildtag, const std::string &version, bool user) { - const char *base = user ? "https://downloads.getmonero.org/" : "https://updates.getmonero.org/"; + const char *base = user ? "https://downloads.fulmo.network/" : "https://updates.fulmo.network/"; #ifdef _WIN32 static const char *extension = strncmp(buildtag.c_str(), "source", 6) ? (strncmp(buildtag.c_str(), "install-", 8) ? ".zip" : ".exe") : ".tar.bz2"; #elif defined(__APPLE__) diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 66c0f27..849c99b 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -197,7 +197,7 @@ namespace cryptonote //extra std::vector extra; // Block height of PR to use - uint64_t pricing_record_height; + //uint64_t pricing_record_height; // Circulating supply information uint64_t amount_burnt; uint64_t amount_minted; @@ -211,7 +211,7 @@ namespace cryptonote FIELD(vin) FIELD(vout) FIELD(extra) - VARINT_FIELD(pricing_record_height) + //VARINT_FIELD(pricing_record_height) VARINT_FIELD(amount_burnt) VARINT_FIELD(amount_minted) VARINT_FIELD(amount_slippage) @@ -226,7 +226,7 @@ namespace cryptonote vin.clear(); vout.clear(); extra.clear(); - pricing_record_height = 0; + //pricing_record_height = 0; amount_burnt = 0; amount_minted = 0; amount_slippage = 0; @@ -520,6 +520,57 @@ namespace cryptonote void set_hash(const crypto::hash &h) const { hash = h; set_hash_valid(true); } transaction miner_tx; + /** + * Ok, the "protocol_tx" is a large part of what makes Fulmo unique, and requires a bit of explaining... + * + * In Haven, and therefore Zephyr also, conversions take place "in-transaction". That is to say, + * amounts of coin A are burnt, and amounts of coin B are minted, and the conversion rate is known, + * and therefore verifiable all in the same TX. All very neat and tidy. + * + * But to implement slippage and yield, it isn't quite as easy to put a nice neat bow around it all. + * Solving slippage in particular requires an approach that means it isn't POSSIBLE to know how much + * you are going to receive ahead of the transaction being included in a mined block. The reason for + * this is simple enough to explain... so here goes. + * + * There are an indeterminate number of conversion TXs that may be included in any given block. Each + * of these conversion TXs may improve the relative pool ratio for each other conversion TX, or it + * may worsen it. For example, an "offshore" (to borrow the Haven definition for the sake of expediency) + * increases the stablecoin pool size and reduces the volatile coin pool size. This means that, for + * other "offshore" TXs in the same block, the pool ratios are potentially worsened. Conversely, any + * "onshore" TXs in the same block would experience a balancing effect from the "offshore" TXs in terms + * of the source -> dest asset pool MCAP ratios. + * + * Now, the slippage for a given conversion TX is determined by the following factors: + * + * change in source asset pool MCAP + * change in destination asset pool MCAP + * the source -> dest asset pool ratios + * the amounts that are being burnt / minted + * + * Therefore, it follows that slippage can only accurately be assessed when we know ALL of the changes + * to the above parameters that will occur at a given point in time (specifically, when the block is + * mined). There is a fundamental interdependence between each conversion TX in a given block. This + * means that, in Fulmo, you can't tell in advance precisely how much you will get minted by a given + * conversion TX until the block is mined. Instead, when creating a conversion TX, the user is asked + * to specify a minimum amount they will accept - if the transaction can satisfy that criterion when + * it is mined, the conversion will be processed and the minted amount will be sent to the user. If + * the transaction cannot satisfy the minimum minted requirement, the user will be refunded their + * money, minus a nominal transaction fee. + * + * Welcome to Fulmo, and the protocol_tx. + * -------------------------------------- + * The protocol_tx is a per-block TX (much like the miner_tx, where the block reward gets paid out). + * It is created at the time of populating the block template to be sent to the miner. Specifically, + * the code takes a snapshot of the circulating supply for each asset type, and then applies the + * "amount burnt" for each of the conversion TXs being included in the block. With this updated + * supply tally information, the slippage for each transaction can be calculated and can be tested + * against the "minimum minted" parameter supplied by the user. Transactions that cannot be satisfied + * are refunded using an RCT output in the protocol_tx for the "amount burnt" minus the nominal TX fee. + * The remainder of the conversion TXs will then have an RCT output created in the protocol_tx for the + * converted amount minus the slippage. + * + * The protocol_tx is also used to pay out "yield" amounts to the yield stakeholders. + */ transaction protocol_tx; std::vector tx_hashes; diff --git a/src/cryptonote_basic/cryptonote_boost_serialization.h b/src/cryptonote_basic/cryptonote_boost_serialization.h index 70a41b1..a32d425 100644 --- a/src/cryptonote_basic/cryptonote_boost_serialization.h +++ b/src/cryptonote_basic/cryptonote_boost_serialization.h @@ -166,7 +166,7 @@ namespace boost a & x.vin; a & x.vout; a & x.extra; - a & x.pricing_record_height; + //a & x.pricing_record_height; a & x.amount_burnt; a & x.amount_minted; a & x.amount_slippage; @@ -180,7 +180,7 @@ namespace boost a & x.vin; a & x.vout; a & x.extra; - a & x.pricing_record_height; + //a & x.pricing_record_height; a & x.amount_burnt; a & x.amount_minted; a & x.amount_slippage; diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index b7c84b8..ef6b987 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -1003,9 +1003,11 @@ namespace cryptonote LOG_ERROR("Source Asset type " << source << " is not supported! Rejecting.."); return false; } - if (std::find(oracle::ASSET_TYPES.begin(), oracle::ASSET_TYPES.end(), destination) == oracle::ASSET_TYPES.end()) { - LOG_ERROR("Destination Asset type " << destination << " is not supported! Rejecting.."); - return false; + if (destination != "BURN") { + if (std::find(oracle::ASSET_TYPES.begin(), oracle::ASSET_TYPES.end(), destination) == oracle::ASSET_TYPES.end()) { + LOG_ERROR("Destination Asset type " << destination << " is not supported! Rejecting.."); + return false; + } } return true; diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index fb6ea21..ee75477 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -256,8 +256,7 @@ namespace config 0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10 } }; // Bender's nightmare - //std::string const GENESIS_TX = ""; - std::string const GENESIS_TX = "023c01ff000180c09e90acbb140217879f01687e9646a08a258638cec94c8e1d0f289aedc9251efde1cca81abd5a0446554c4d3c00000000000000210144bd6165a65653df0f98d438e552becb51b81118396ba6173affdb85105375ba0000000000"; + std::string const GENESIS_TX = "023c01ff000180c09e90acbb1402721d160620a58d7a9fe0a55b4a665284b94d40efffa4e5ff3326e8ea5cd26e8d0446554c4d3c0000000000000021012488e4fc617688fad2304293f2be80032b6deac2f1cd8cb49a578c34387ddafc00000000"; uint32_t const GENESIS_NONCE = 10000; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 2304420..0fddcd5 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -229,7 +229,7 @@ bool Blockchain::scan_outputkeys_for_indexes(size_t tx_version, const txin_to_ke output_index = m_db->get_output_key(tx_in_to_key.amount, i); // call to the passed boost visitor to grab the public key for the output - if (!vis.handle_output(output_index.unlock_time, output_index.pubkey, output_index.commitment)) + if (!vis.handle_output(output_index.unlock_time, tx_in_to_key.asset_type, output_index.pubkey, output_index.commitment)) { MERROR_VER("Failed to handle_output for output no = " << count << ", with absolute offset " << i); return false; @@ -3249,7 +3249,7 @@ bool Blockchain::have_tx_keyimges_as_spent(const transaction &tx) const } return false; } -bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector> &pubkeys) +bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector> &pubkeys, const uint8_t &hf_version) { PERF_TIMER(expand_transaction_2); CHECK_AND_ASSERT_MES(tx.version == 2, false, "Transaction version is not 2"); @@ -3602,7 +3602,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, case rct::RCTTypeCLSAG: case rct::RCTTypeBulletproofPlus: { - if (!ver_rct_non_semantics_simple_cached(tx, pubkeys, m_rct_ver_cache, RCT_CACHE_TYPE)) + if (!ver_rct_non_semantics_simple_cached(tx, pubkeys, m_rct_ver_cache, RCT_CACHE_TYPE, hf_version)) { MERROR_VER("Failed to check ringct signatures!"); return false; @@ -3611,7 +3611,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, } case rct::RCTTypeFull: { - if (!expand_transaction_2(tx, tx_prefix_hash, pubkeys)) + if (!expand_transaction_2(tx, tx_prefix_hash, pubkeys, hf_version)) { MERROR_VER("Failed to expand rct signatures!"); return false; @@ -3911,12 +3911,13 @@ bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, cons { std::vector& m_output_keys; const Blockchain& m_bch; + const std::string& m_asset_type; const uint8_t hf_version; - outputs_visitor(std::vector& output_keys, const Blockchain& bch, uint8_t hf_version) : - m_output_keys(output_keys), m_bch(bch), hf_version(hf_version) + outputs_visitor(std::vector& output_keys, const Blockchain& bch, const std::string& asset_type, uint8_t hf_version) : + m_output_keys(output_keys), m_asset_type(asset_type), m_bch(bch), hf_version(hf_version) { } - bool handle_output(uint64_t unlock_time, const crypto::public_key &pubkey, const rct::key &commitment) + bool handle_output(uint64_t unlock_time, const std::string& asset_type, const crypto::public_key &pubkey, const rct::key &commitment) { //check tx unlock time if (!m_bch.is_tx_spendtime_unlocked(unlock_time, hf_version)) @@ -3925,6 +3926,11 @@ bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, cons return false; } + if (asset_type != m_asset_type) { + MERROR_VER("One of outputs for one of inputs has wrong asset type. Expected = " << asset_type << " Got = " << m_asset_type); + return false; + } + // The original code includes a check for the output corresponding to this input // to be a txout_to_key. This is removed, as the database does not store this info. // Only txout_to_key (and since HF_VERSION_VIEW_TAGS, txout_to_tagged_key) @@ -3940,7 +3946,7 @@ bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, cons output_keys.clear(); // collect output keys - outputs_visitor vi(output_keys, *this, hf_version); + outputs_visitor vi(output_keys, *this, txin.asset_type, hf_version); if (!scan_outputkeys_for_indexes(tx_version, txin, vi, tx_prefix_hash, pmax_related_block_height)) { MERROR_VER("Failed to get output keys for tx with amount = " << print_money(txin.amount) << " and count indexes " << txin.key_offsets.size()); diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 2e2824d..3a51e2d 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -263,6 +263,21 @@ namespace cryptonote */ bool cleanup_handle_incoming_blocks(bool force_sync = false); + /** + * @brief gets the pricing record for the specified timestamp + * + * @return false if method failed to obtain pricing record from oracle, otherwise true + */ + bool get_pricing_record(oracle::pricing_record& pr, uint64_t timestamp); + + /** + * @brief gets the latest pricing record that was in the last 10 block. + * If no pricing record found in the past 10 block, fails. + * + * @return false if method failed to obtain pricing, otherwise true + */ + bool get_latest_acceptable_pr(oracle::pricing_record& pr) const; + /** * @brief search the blockchain for a transaction by hash * @@ -604,7 +619,7 @@ namespace cryptonote * can be reconstituted by the receiver. This function expands * that implicit data. */ - static bool expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector> &pubkeys); + static bool expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector> &pubkeys, const uint8_t &hf_version); /** * @brief validates a transaction's inputs @@ -731,13 +746,6 @@ namespace cryptonote */ uint64_t get_current_cumulative_block_weight_median() const; - /** - * @brief gets the pricing record for the specified timestamp - * - * @return false if method failed to obtain pricing record from oracle, otherwise true - */ - bool get_pricing_record(oracle::pricing_record& pr, uint64_t timestamp); - /** * @brief gets the difficulty of the block with a given height * diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 7a8d4a1..9723de7 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -208,15 +208,18 @@ namespace cryptonote LOG_ERROR("Source Asset type " << source << " is not supported! Rejecting.."); return false; } - if (std::find(oracle::ASSET_TYPES.begin(), oracle::ASSET_TYPES.end(), destination) == oracle::ASSET_TYPES.end()) { - LOG_ERROR("Destination Asset type " << destination << " is not supported! Rejecting.."); - return false; + // Allow an empty destination for BURN commands only + if (destination != "BURN") { + if (std::find(oracle::ASSET_TYPES.begin(), oracle::ASSET_TYPES.end(), destination) == oracle::ASSET_TYPES.end()) { + LOG_ERROR("Destination Asset type " << destination << " is not supported! Rejecting.."); + return false; + } } // Find the tx type if (source == destination) { type = transaction_type::TRANSFER; - } else if (destination == "") { + } else if (destination == "BURN") { type = transaction_type::BURN; } else { type = transaction_type::CONVERT; @@ -226,7 +229,25 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const uint8_t hf_version, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool shuffle_outs, bool use_view_tags) + bool construct_tx_with_tx_key( + const account_keys& sender_account_keys, + const std::unordered_map& subaddresses, + std::vector& sources, + std::vector& destinations, + const uint8_t hf_version, + const std::string& source_asset, + const std::string& dest_asset, + const boost::optional& change_addr, + const std::vector &extra, + transaction& tx, + uint64_t unlock_time, + const crypto::secret_key &tx_key, + const std::vector &additional_tx_keys, + bool rct, + const rct::RCTConfig &rct_config, + bool shuffle_outs, + bool use_view_tags + ) { hw::device &hwdev = sender_account_keys.get_device(); @@ -381,6 +402,12 @@ namespace cryptonote tx.vin.push_back(input_to_key); } + transaction_type tx_type; + if (!get_tx_type(source_asset, dest_asset, tx_type)) { + LOG_ERROR("invalid tx type"); + return false; + } + if (shuffle_outs) { std::shuffle(destinations.begin(), destinations.end(), crypto::random_device{}); @@ -448,6 +475,14 @@ namespace cryptonote tx.vout.push_back(out); output_index++; summary_outs_money += dst_entr.amount; + if (tx_type == cryptonote::transaction_type::BURN || tx_type == cryptonote::transaction_type::CONVERT) { + if (dst_entr.asset_type == dest_asset) { + tx.amount_burnt += dst_entr.amount; + } + if (tx_type == cryptonote::transaction_type::CONVERT) { + tx.amount_minted += dst_entr.amount; + } + } } CHECK_AND_ASSERT_MES(additional_tx_public_keys.size() == additional_tx_keys.size(), false, "Internal error creating additional public keys"); @@ -554,6 +589,7 @@ namespace cryptonote rct::ctkeyM mixRing(use_simple_rct ? sources.size() : n_total_outs); rct::keyV destinations; std::vector inamounts, outamounts; + std::vector destination_asset_types; std::vector index; for (size_t i = 0; i < sources.size(); ++i) { @@ -572,8 +608,19 @@ namespace cryptonote for (size_t i = 0; i < tx.vout.size(); ++i) { crypto::public_key output_public_key; - get_output_public_key(tx.vout[i], output_public_key); + bool ok = get_output_public_key(tx.vout[i], output_public_key); + if (!ok) { + LOG_ERROR("failed to get output public key for tx.vout[" << i << "]"); + return false; + } + std::string output_asset_type; + ok = cryptonote::get_output_asset_type(tx.vout[i], output_asset_type); + if (!ok) { + LOG_ERROR("failed to get output asset type for tx.vout[" << i << "]"); + return false; + } destinations.push_back(rct::pk2rct(output_public_key)); + destination_asset_types.push_back(output_asset_type); outamounts.push_back(tx.vout[i].amount); amount_out += tx.vout[i].amount; } @@ -603,8 +650,11 @@ namespace cryptonote } // fee + uint64_t fee = 0; if (!use_simple_rct && amount_in > amount_out) outamounts.push_back(amount_in - amount_out); + else + fee = summary_inputs_money - summary_outs_money; // zero out all amounts to mask rct outputs, real amounts are now encrypted for (size_t i = 0; i < tx.vin.size(); ++i) @@ -619,7 +669,23 @@ namespace cryptonote get_transaction_prefix_hash(tx, tx_prefix_hash, hwdev); rct::ctkeyV outSk; if (use_simple_rct) - tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, index, outSk, rct_config, hwdev); + tx.rct_signatures = rct::genRctSimple( + rct::hash2rct(tx_prefix_hash), + inSk, + destinations, + tx_type, + source_asset, + destination_asset_types, + inamounts, + outamounts, + fee, + mixRing, + amount_keys, + index, + outSk, + rct_config, + hwdev + ); else tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, sources[0].real_output, outSk, rct_config, hwdev); // same index assumption memwipe(inSk.data(), inSk.size() * sizeof(rct::ctkey)); @@ -634,7 +700,7 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const uint8_t hf_version, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool use_view_tags) + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const uint8_t hf_version, const std::string& source_asset, const std::string& dest_asset, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool use_view_tags) { hw::device &hwdev = sender_account_keys.get_device(); hwdev.open_tx(tx_key); @@ -655,7 +721,7 @@ namespace cryptonote } bool shuffle_outs = true; - bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, hf_version, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, shuffle_outs, use_view_tags); + bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, hf_version, source_asset, dest_asset, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, shuffle_outs, use_view_tags); hwdev.close_tx(); return r; } catch(...) { @@ -664,14 +730,14 @@ namespace cryptonote } } //--------------------------------------------------------------- - bool construct_tx(const account_keys& sender_account_keys, std::vector& sources, const std::vector& destinations, const uint8_t hf_version, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time) + bool construct_tx(const account_keys& sender_account_keys, std::vector& sources, const std::vector& destinations, const uint8_t hf_version, const std::string& source_asset, const std::string& dest_asset, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time) { std::unordered_map subaddresses; subaddresses[sender_account_keys.m_account_address.m_spend_public_key] = {0,0}; crypto::secret_key tx_key; std::vector additional_tx_keys; std::vector destinations_copy = destinations; - return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, hf_version, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0}); + return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, hf_version, source_asset, dest_asset, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0}); } //--------------------------------------------------------------- bool generate_genesis_block( diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h index d6b8526..65cc895 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.h +++ b/src/cryptonote_core/cryptonote_tx_utils.h @@ -125,9 +125,9 @@ namespace cryptonote //--------------------------------------------------------------- crypto::public_key get_destination_view_key_pub(const std::vector &destinations, const boost::optional& change_addr); - bool construct_tx(const account_keys& sender_account_keys, std::vector &sources, const std::vector& destinations, const uint8_t hf_version, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time); - bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const uint8_t hf_version, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool shuffle_outs = true, bool use_view_tags = false); - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const uint8_t hf_version, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool use_view_tags = false); + bool construct_tx(const account_keys& sender_account_keys, std::vector &sources, const std::vector& destinations, const uint8_t hf_version, const std::string& source_asset, const std::string& dest_asset, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time); + bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const uint8_t hf_version, const std::string& source_asset, const std::string& dest_asset, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool shuffle_outs = true, bool use_view_tags = false); + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const uint8_t hf_version, const std::string& source_asset, const std::string& dest_asset, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool use_view_tags = false); bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key, const cryptonote::tx_destination_entry &dst_entr, const boost::optional &change_addr, const size_t output_index, const bool &need_additional_txkeys, const std::vector &additional_tx_keys, diff --git a/src/cryptonote_core/tx_verification_utils.cpp b/src/cryptonote_core/tx_verification_utils.cpp index a93ef2f..ffa2c51 100644 --- a/src/cryptonote_core/tx_verification_utils.cpp +++ b/src/cryptonote_core/tx_verification_utils.cpp @@ -38,7 +38,7 @@ using namespace cryptonote; // Do RCT expansion, then do post-expansion sanity checks, then do full non-semantics verification. -static bool expand_tx_and_ver_rct_non_sem(transaction& tx, const rct::ctkeyM& mix_ring) +static bool expand_tx_and_ver_rct_non_sem(transaction& tx, const rct::ctkeyM& mix_ring, uint8_t hf_version) { // Pruned transactions can not be expanded and verified because they are missing RCT data VER_ASSERT(!tx.pruned, "Pruned transaction will not pass verRctNonSemanticsSimple"); @@ -47,7 +47,7 @@ static bool expand_tx_and_ver_rct_non_sem(transaction& tx, const rct::ctkeyM& mi const crypto::hash tx_prefix_hash = get_transaction_prefix_hash(tx); // Expand mixring, tx inputs, tx key images, prefix hash message, etc into the RCT sig - const bool exp_res = Blockchain::expand_transaction_2(tx, tx_prefix_hash, mix_ring); + const bool exp_res = Blockchain::expand_transaction_2(tx, tx_prefix_hash, mix_ring, hf_version); VER_ASSERT(exp_res, "Failed to expand rct signatures!"); const rct::rctSig& rv = tx.rct_signatures; @@ -115,7 +115,8 @@ bool ver_rct_non_semantics_simple_cached transaction& tx, const rct::ctkeyM& mix_ring, rct_ver_cache_t& cache, - const std::uint8_t rct_type_to_cache + const std::uint8_t rct_type_to_cache, + uint8_t hf_version ) { // Hello future Monero dev! If you got this assert, read the following carefully: @@ -138,7 +139,7 @@ bool ver_rct_non_semantics_simple_cached if (tx.rct_signatures.type != rct_type_to_cache) { MDEBUG("RCT cache: tx " << get_transaction_hash(tx) << " skipped"); - return expand_tx_and_ver_rct_non_sem(tx, mix_ring); + return expand_tx_and_ver_rct_non_sem(tx, mix_ring, hf_version); } // Generate unique hash for tx+mix_ring pair @@ -153,7 +154,7 @@ bool ver_rct_non_semantics_simple_cached // We had a cache miss, so now we must expand the mix ring and do full verification MDEBUG("RCT cache: tx " << get_transaction_hash(tx) << " missed"); - if (!expand_tx_and_ver_rct_non_sem(tx, mix_ring)) + if (!expand_tx_and_ver_rct_non_sem(tx, mix_ring, hf_version)) { return false; } diff --git a/src/cryptonote_core/tx_verification_utils.h b/src/cryptonote_core/tx_verification_utils.h index ccd401d..54ba3fe 100644 --- a/src/cryptonote_core/tx_verification_utils.h +++ b/src/cryptonote_core/tx_verification_utils.h @@ -72,7 +72,8 @@ bool ver_rct_non_semantics_simple_cached transaction& tx, const rct::ctkeyM& mix_ring, rct_ver_cache_t& cache, - std::uint8_t rct_type_to_cache + std::uint8_t rct_type_to_cache, + uint8_t hf_version ); } // namespace cryptonote diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index fc5f1b3..6a9b0ec 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -412,7 +412,7 @@ bool t_command_server::apropos(const std::vector& args) std::string t_command_server::get_commands_str() { std::stringstream ss; - ss << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << std::endl; + ss << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << std::endl; ss << "Commands: " << std::endl; std::string usage = m_command_lookup.get_usage(); boost::replace_all(usage, "\n", "\n "); diff --git a/src/daemon/executor.cpp b/src/daemon/executor.cpp index d67bd61..1b88cff 100644 --- a/src/daemon/executor.cpp +++ b/src/daemon/executor.cpp @@ -40,7 +40,7 @@ namespace daemonize { - std::string const t_executor::NAME = "Monero Daemon"; + std::string const t_executor::NAME = "Fulmo Daemon"; void t_executor::init_options( boost::program_options::options_description & configurable_options @@ -58,7 +58,7 @@ namespace daemonize boost::program_options::variables_map const & vm ) { - LOG_PRINT_L0("Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ") Daemonised"); + LOG_PRINT_L0("Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ") Daemonised"); return t_daemon{vm, public_rpc_port}; } diff --git a/src/daemonizer/windows_daemonizer.inl b/src/daemonizer/windows_daemonizer.inl index a008640..f7fbf16 100644 --- a/src/daemonizer/windows_daemonizer.inl +++ b/src/daemonizer/windows_daemonizer.inl @@ -181,7 +181,7 @@ namespace daemonizer } else // interactive { - //LOG_PRINT_L0("Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL); + //LOG_PRINT_L0("Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL); if (command_line::has_arg(vm, arg_non_interactive)) return executor.run_non_interactive(vm); else diff --git a/src/debug_utilities/cn_deserialize.cpp b/src/debug_utilities/cn_deserialize.cpp index 41c397b..6d64926 100644 --- a/src/debug_utilities/cn_deserialize.cpp +++ b/src/debug_utilities/cn_deserialize.cpp @@ -103,7 +103,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } diff --git a/src/debug_utilities/dns_checks.cpp b/src/debug_utilities/dns_checks.cpp index caa0421..f7a21f3 100644 --- a/src/debug_utilities/dns_checks.cpp +++ b/src/debug_utilities/dns_checks.cpp @@ -121,7 +121,7 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 1; } diff --git a/src/gen_ssl_cert/gen_ssl_cert.cpp b/src/gen_ssl_cert/gen_ssl_cert.cpp index cd810ed..1d97edd 100644 --- a/src/gen_ssl_cert/gen_ssl_cert.cpp +++ b/src/gen_ssl_cert/gen_ssl_cert.cpp @@ -121,13 +121,13 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; std::cout << desc_options << std::endl; return 0; } if (command_line::get_arg(vm, command_line::arg_version)) { - std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL; + std::cout << "Fulmo '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL; return 0; } diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index 9b6f58c..3433252 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -1102,7 +1102,23 @@ namespace rct { //RCT simple //for post-rct only - rctSig genRctSimple(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector &inamounts, const vector &outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector & index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev) { + rctSig genRctSimple( + const key &message, + const ctkeyV & inSk, + const keyV & destinations, + const cryptonote::transaction_type tx_type, + const std::string& in_asset_type, + const std::vector & destination_asset_types, + const vector &inamounts, + const vector &outamounts, + xmr_amount txnFee, + const ctkeyM & mixRing, + const keyV &amount_keys, + const std::vector & index, + ctkeyV &outSk, + const RCTConfig &rct_config, + hw::device &hwdev + ) { const bool bulletproof_or_plus = rct_config.range_proof_type > RangeProofBorromean; CHECK_AND_ASSERT_THROW_MES(inamounts.size() > 0, "Empty inamounts"); CHECK_AND_ASSERT_THROW_MES(inamounts.size() == inSk.size(), "Different number of inamounts/inSk"); @@ -1283,7 +1299,22 @@ namespace rct { return rv; } - rctSig genRctSimple(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector &inamounts, const vector &outamounts, const keyV &amount_keys, xmr_amount txnFee, unsigned int mixin, const RCTConfig &rct_config, hw::device &hwdev) { + rctSig genRctSimple( + const key &message, + const ctkeyV & inSk, + const ctkeyV & inPk, + const keyV & destinations, + const cryptonote::transaction_type tx_type, + const std::string& in_asset_type, + const std::vector & destination_asset_types, + const vector &inamounts, + const vector &outamounts, + const keyV &amount_keys, + xmr_amount txnFee, + unsigned int mixin, + const RCTConfig &rct_config, + hw::device &hwdev + ) { std::vector index; index.resize(inPk.size()); ctkeyM mixRing; @@ -1293,7 +1324,7 @@ namespace rct { mixRing[i].resize(mixin+1); index[i] = populateFromBlockchainSimple(mixRing[i], inPk[i], mixin); } - return genRctSimple(message, inSk, destinations, inamounts, outamounts, txnFee, mixRing, amount_keys, index, outSk, rct_config, hwdev); + return genRctSimple(message, inSk, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, txnFee, mixRing, amount_keys, index, outSk, rct_config, hwdev); } //RingCT protocol diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h index 17cfd77..40a0e18 100644 --- a/src/ringct/rctSigs.h +++ b/src/ringct/rctSigs.h @@ -47,6 +47,8 @@ extern "C" { } #include "crypto/crypto.h" +#include "cryptonote_basic/cryptonote_basic.h" +#include "cryptonote_protocol/enums.h" #include "rctTypes.h" #include "rctOps.h" @@ -125,8 +127,39 @@ namespace rct { // must know the destination private key to find the correct amount, else will return a random number rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const std::vector & amounts, const ctkeyM &mixRing, const keyV &amount_keys, unsigned int index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev); rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector & amounts, const keyV &amount_keys, const int mixin, const RCTConfig &rct_config, hw::device &hwdev); - rctSig genRctSimple(const key & message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector & inamounts, const std::vector & outamounts, const keyV &amount_keys, xmr_amount txnFee, unsigned int mixin, const RCTConfig &rct_config, hw::device &hwdev); - rctSig genRctSimple(const key & message, const ctkeyV & inSk, const keyV & destinations, const std::vector & inamounts, const std::vector & outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector & index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev); + rctSig genRctSimple( + const key & message, + const ctkeyV & inSk, + const ctkeyV & inPk, + const keyV & destinations, + const cryptonote::transaction_type tx_type, + const std::string& in_asset_type, + const std::vector & destination_asset_types, + const std::vector & inamounts, + const std::vector & outamounts, + const keyV &amount_keys, + xmr_amount txnFee, + unsigned int mixin, + const RCTConfig &rct_config, + hw::device &hwdev + ); + rctSig genRctSimple( + const key & message, + const ctkeyV & inSk, + const keyV & destinations, + const cryptonote::transaction_type tx_type, + const std::string& in_asset_type, + const std::vector & destination_asset_types, + const std::vector & inamounts, + const std::vector & outamounts, + xmr_amount txnFee, + const ctkeyM & mixRing, + const keyV &amount_keys, + const std::vector & index, + ctkeyV &outSk, + const RCTConfig &rct_config, + hw::device &hwdev + ); bool verRct(const rctSig & rv, bool semantics); static inline bool verRct(const rctSig & rv) { return verRct(rv, true) && verRct(rv, false); } bool verRctSemanticsSimple(const rctSig & rv); diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 9637442..7c0ee62 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1,3 +1,4 @@ +// Copyright (c) 2023, The Fulmo Project // Copyright (c) 2014-2022, The Monero Project // // All rights reserved. @@ -158,6 +159,8 @@ typedef cryptonote::simple_wallet sw; enum TransferType { Transfer, TransferLocked, + Convert, + Burn, }; static std::string get_human_readable_timespan(std::chrono::seconds seconds); @@ -183,7 +186,7 @@ namespace const command_line::arg_descriptor arg_non_deterministic = {"non-deterministic", sw::tr("Generate non-deterministic view and spend keys"), false}; const command_line::arg_descriptor arg_restore_height = {"restore-height", sw::tr("Restore from specific blockchain height"), 0}; const command_line::arg_descriptor arg_restore_date = {"restore-date", sw::tr("Restore from estimated blockchain height on specified date"), ""}; - const command_line::arg_descriptor arg_do_not_relay = {"do-not-relay", sw::tr("The newly created transaction will not be relayed to the monero network"), false}; + const command_line::arg_descriptor arg_do_not_relay = {"do-not-relay", sw::tr("The newly created transaction will not be relayed to the Fulmo network"), false}; const command_line::arg_descriptor arg_create_address_file = {"create-address-file", sw::tr("Create an address file for new wallets"), false}; const command_line::arg_descriptor arg_subaddress_lookahead = {"subaddress-lookahead", tools::wallet2::tr("Set subaddress lookahead sizes to :"), ""}; const command_line::arg_descriptor arg_use_english_language_names = {"use-english-language-names", sw::tr("Display English language names"), false}; @@ -196,14 +199,14 @@ namespace const char* USAGE_INCOMING_TRANSFERS("incoming_transfers [available|unavailable] [verbose] [uses] [index=[,[,...]]]"); const char* USAGE_PAYMENTS("payments [ ... ]"); const char* USAGE_PAYMENT_ID("payment_id"); - const char* USAGE_TRANSFER("transfer [index=[,,...]] [] [] ( |
) []"); + const char* USAGE_TRANSFER("transfer [index=[,,...]] [] [] ( |
[]) []"); const char* USAGE_LOCKED_TRANSFER("locked_transfer [index=[,,...]] [] [] ( | ) []"); const char* USAGE_LOCKED_SWEEP_ALL("locked_sweep_all [index=[,,...] | index=all] [] []
[]"); const char* USAGE_SWEEP_ALL("sweep_all [index=[,,...] | index=all] [] [] [outputs=]
[]"); const char* USAGE_SWEEP_ACCOUNT("sweep_account [index=[,,...] | index=all] [] [] [outputs=]
[]"); const char* USAGE_SWEEP_BELOW("sweep_below [index=[,,...]] [] []
[]"); const char* USAGE_SWEEP_SINGLE("sweep_single [] [] [outputs=]
[]"); - const char* USAGE_BURN("burn [index=[,,...]] "); + const char* USAGE_BURN("burn "); const char* USAGE_CONVERT("convert [index=[,,...]] [] [] ( |
) []"); const char* USAGE_PRICE_INFO("price_info"); const char* USAGE_SUPPLY_INFO("supply_info"); @@ -257,7 +260,7 @@ namespace const char* USAGE_MMS("mms [ []]"); const char* USAGE_MMS_INIT("mms init / "); const char* USAGE_MMS_INFO("mms info"); - const char* USAGE_MMS_SIGNER("mms signer [