From 66854eb683d75c207186031bc0306eb589e551f1 Mon Sep 17 00:00:00 2001 From: Some Random Crypto Guy Date: Tue, 9 Jul 2024 12:42:12 +0100 Subject: [PATCH] initial update to add Salvium support --- src/cryptonote_config.h | 1 + src/cryptonote_core/cryptonote_basic.h | 127 +++++++++++++++++- .../cryptonote_format_utils.cpp | 8 +- src/ringct/rctTypes.h | 3 + 4 files changed, 134 insertions(+), 5 deletions(-) diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 0dcb228..5a88aa5 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -36,4 +36,5 @@ enum BLOB_TYPE { BLOB_TYPE_CRYPTONOTE_XTA = 12, // ITALO BLOB_TYPE_CRYPTONOTE_ZEPHYR = 13, // ZEPHYR BLOB_TYPE_CRYPTONOTE_XLA = 14, // XLA + BLOB_TYPE_CRYPTONOTE_SALVIUM= 15, // Salvium }; diff --git a/src/cryptonote_core/cryptonote_basic.h b/src/cryptonote_core/cryptonote_basic.h index 307a45c..082ec06 100644 --- a/src/cryptonote_core/cryptonote_basic.h +++ b/src/cryptonote_core/cryptonote_basic.h @@ -48,7 +48,19 @@ namespace cryptonote typedef std::vector ring_signature; - + enum salvium_transaction_type + { + UNSET = 0, + MINER = 1, + PROTOCOL = 2, + TRANSFER = 3, + CONVERT = 4, + BURN = 5, + STAKE = 6, + RETURN = 7, + MAX = 7 + }; + /* outputs */ struct txout_to_script @@ -167,6 +179,41 @@ namespace cryptonote END_SERIALIZE() }; + // SALVIUM + struct txout_salvium_key + { + txout_salvium_key() { } + txout_salvium_key(const crypto::public_key &_key, const std::string &_asset_type, const uint64_t &_unlock_time) : + key(_key), asset_type(_asset_type), unlock_time(_unlock_time) { } + crypto::public_key key; + std::string asset_type; + uint64_t unlock_time; + + BEGIN_SERIALIZE_OBJECT() + FIELD(key) + FIELD(asset_type) + VARINT_FIELD(unlock_time) + END_SERIALIZE() + }; + + struct txout_salvium_tagged_key + { + txout_salvium_tagged_key() { } + txout_salvium_tagged_key(const crypto::public_key &_key, const std::string &_asset_type, const uint64_t &_unlock_time, const crypto::view_tag &_view_tag) : + key(_key), asset_type(_asset_type), unlock_time(_unlock_time), view_tag(_view_tag) { } + crypto::public_key key; + std::string asset_type; + uint64_t unlock_time; + crypto::view_tag view_tag; // optimization to reduce scanning time + + BEGIN_SERIALIZE_OBJECT() + FIELD(key) + FIELD(asset_type) + VARINT_FIELD(unlock_time) + FIELD(view_tag) + END_SERIALIZE() + }; + /* inputs */ struct txin_gen @@ -290,11 +337,28 @@ namespace cryptonote END_SERIALIZE() }; + struct txin_salvium_key + { + uint64_t amount; + std::string asset_type; + std::vector key_offsets; + crypto::key_image k_image; // double spending protection + + BEGIN_SERIALIZE_OBJECT() + VARINT_FIELD(amount) + FIELD(asset_type) + FIELD(key_offsets) + FIELD(k_image) + END_SERIALIZE() + }; + typedef boost::variant txin_v; typedef boost::variant txin_zephyr_v; + typedef boost::variant txin_salvium_v; typedef boost::variant txout_target_v; typedef boost::variant txout_xhv_target_v; + typedef boost::variant txout_salvium_target_v; typedef boost::variant txout_stablero_target_v; @@ -331,6 +395,17 @@ namespace cryptonote END_SERIALIZE() }; + struct tx_out_salvium + { + uint64_t amount; + txout_salvium_target_v target; + + BEGIN_SERIALIZE_OBJECT() + VARINT_FIELD(amount) + FIELD(target) + END_SERIALIZE() + }; + enum loki_version { @@ -352,9 +427,11 @@ namespace cryptonote std::vector vin; std::vector vin_zephyr; + std::vector vin_salvium; std::vector vout; std::vector vout_xhv; std::vector vout_zephyr; + std::vector vout_salvium; //extra std::vector extra; // Block height to use PR from @@ -366,6 +443,23 @@ namespace cryptonote std::vector output_unlock_times; std::vector collateral_indices; + // SALVIUM-SPECIFIC FIELDS + // TX type + cryptonote::salvium_transaction_type type; + // Return address + crypto::public_key return_address; + // Return TX public key + crypto::public_key return_pubkey; + // Source asset type + std::string source_asset_type; + // Destination asset type (this is only necessary for CONVERT transactions) + std::string destination_asset_type; + // Circulating supply information - already provided by Haven + //uint64_t amount_burnt; + // Slippage limit + uint64_t amount_slippage_limit; + + // // NOTE: Loki specific // @@ -629,7 +723,27 @@ namespace cryptonote VARINT_FIELD(pricing_record_height) VARINT_FIELD(amount_burnt) VARINT_FIELD(amount_minted) - + + } else if (blob_type == BLOB_TYPE_CRYPTONOTE_SALVIUM) { + + VARINT_FIELD(version) + if(version == 0 || CURRENT_TRANSACTION_VERSION < version) return false; + VARINT_FIELD(unlock_time) + FIELD(vin) + FIELD(vout) + FIELD(extra) + VARINT_FIELD(type) + if (type != cryptonote::transaction_type::PROTOCOL) { + VARINT_FIELD(amount_burnt) + if (type != cryptonote::transaction_type::MINER) { + FIELD(return_address) + FIELD(return_pubkey) + FIELD(source_asset_type) + FIELD(destination_asset_type) + VARINT_FIELD(amount_slippage_limit) + } + } + } else { VARINT_FIELD(version) @@ -1001,10 +1115,11 @@ namespace cryptonote bytecoin_block parent_block; transaction miner_tx; + transaction protocol_tx; std::vector tx_hashes; mutable crypto::hash uncle = cryptonote::null_hash; - void set_blob_type(enum BLOB_TYPE bt) { miner_tx.blob_type = blob_type = bt; } + void set_blob_type(enum BLOB_TYPE bt) { miner_tx.blob_type = protocol_tx.blob_type = blob_type = bt; } BEGIN_SERIALIZE_OBJECT() FIELDS(*static_cast(this)) @@ -1014,6 +1129,10 @@ namespace cryptonote FIELD_N("parent_block", sbb); } FIELD(miner_tx) + if (blob_type == BLOB_TYPE_SALVIUM) + { + FIELD(protocol_tx) + } FIELD(tx_hashes) if (blob_type == BLOB_TYPE_CRYPTONOTE3) { @@ -1081,8 +1200,10 @@ VARIANT_TAG(binary_archive, cryptonote::txin_haven_key, 0x6); VARIANT_TAG(binary_archive, cryptonote::txout_to_script, 0x0); VARIANT_TAG(binary_archive, cryptonote::txout_to_scripthash, 0x1); VARIANT_TAG(binary_archive, cryptonote::txout_to_key, 0x2); +VARIANT_TAG(binary_archive, cryptonote::txout_salvium_key, 0x2); VARIANT_TAG(binary_archive, cryptonote::txout_zephyr_tagged_key, 0x2); VARIANT_TAG(binary_archive, cryptonote::txout_to_tagged_key, 0x3); +VARIANT_TAG(binary_archive, cryptonote::txout_salvium_tagged_key, 0x3); VARIANT_TAG(binary_archive, cryptonote::txout_offshore, 0x3); VARIANT_TAG(binary_archive, cryptonote::txout_xasset, 0x5); VARIANT_TAG(binary_archive, cryptonote::txout_haven_key, 0x6); diff --git a/src/cryptonote_core/cryptonote_format_utils.cpp b/src/cryptonote_core/cryptonote_format_utils.cpp index 14c8932..885c7a3 100644 --- a/src/cryptonote_core/cryptonote_format_utils.cpp +++ b/src/cryptonote_core/cryptonote_format_utils.cpp @@ -237,7 +237,7 @@ namespace cryptonote std::stringstream ss; binary_archive ba(ss); const size_t inputs = t.blob_type == BLOB_TYPE_CRYPTONOTE_ZEPHYR ? t.vin_zephyr.size() : t.vin.size(); - const size_t outputs = t.blob_type == BLOB_TYPE_CRYPTONOTE_ZEPHYR ? t.vout_zephyr.size() : t.blob_type != BLOB_TYPE_CRYPTONOTE_XHV ? t.vout.size() : t.vout_xhv.size(); + const size_t outputs = t.blob_type == BLOB_TYPE_CRYPTONOTE_SALVIUM ? t.vout_salvium.size() : t.blob_type == BLOB_TYPE_CRYPTONOTE_ZEPHYR ? t.vout_zephyr.size() : t.blob_type != BLOB_TYPE_CRYPTONOTE_XHV ? t.vout.size() : t.vout_xhv.size(); size_t mixin; if (t.blob_type == BLOB_TYPE_CRYPTONOTE_ZEPHYR) { mixin = t.vin_zephyr.empty() ? 0 : t.vin_zephyr[0].type() == typeid(txin_zephyr_key) ? boost::get(t.vin_zephyr[0]).key_offsets.size() - 1 : 0; @@ -285,7 +285,11 @@ namespace cryptonote } crypto::hash tree_root_hash = get_tx_tree_hash(b); blob.append(reinterpret_cast(&tree_root_hash), sizeof(tree_root_hash)); - blob.append(tools::get_varint_data(b.tx_hashes.size()+1)); + if (b.blob_type == BLOB_TYPE_CRYPTONOTE_SALVIUM) { + blob.append(tools::get_varint_data(b.tx_hashes.size()+2)); + } else { + blob.append(tools::get_varint_data(b.tx_hashes.size()+1)); + } if (b.blob_type == BLOB_TYPE_CRYPTONOTE3) { blob.append(reinterpret_cast(&b.uncle), sizeof(b.uncle)); } diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 2ce91e5..7fa8c8f 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -325,6 +325,7 @@ namespace rct { xmr_amount txnOffshoreFee_usd = 0; xmr_amount txnOffshoreFee_xasset = 0; keyV maskSums; // contains 2 or 3 elements. 1. is the sum of masks of inputs. 2. is the sum of masks of change outputs. 3. mask of the col output. + key p_r; template class Archive> bool serialize_rctsig_base(Archive &ar, size_t inputs, size_t outputs) @@ -384,6 +385,8 @@ namespace rct { FIELDS(maskSums[2]) ar.end_array(); } + if (p_r != crypto::null_pkey) + FIELD(p_r) return ar.stream().good(); }