From 23c3520d13385333cde578386627d7c8746c750d Mon Sep 17 00:00:00 2001 From: MoneroOcean Date: Sat, 24 Jun 2023 21:42:23 +0000 Subject: [PATCH] ZEPH support --- binding.gyp | 1 + src/cryptonote_config.h | 1 + src/cryptonote_core/cryptonote_basic.h | 92 +++++++++++++++++-- .../cryptonote_format_utils.cpp | 23 +++-- 4 files changed, 99 insertions(+), 18 deletions(-) diff --git a/binding.gyp b/binding.gyp index 10da871..8795957 100644 --- a/binding.gyp +++ b/binding.gyp @@ -6,6 +6,7 @@ "src/main.cc", "src/cryptonote_core/cryptonote_format_utils.cpp", "src/offshore/pricing_record.cpp", + "src/oracle/pricing_record.cpp", "src/crypto/tree-hash.c", "src/crypto/crypto.cpp", "src/crypto/crypto-ops.c", diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index ba73830..57bea85 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -33,4 +33,5 @@ enum BLOB_TYPE { BLOB_TYPE_CRYPTONOTE_TUBE = 10, // TUBE BLOB_TYPE_CRYPTONOTE_XHV = 11, // Haven BLOB_TYPE_CRYPTONOTE_XTA = 12, // ITALO + BLOB_TYPE_CRYPTONOTE_ZEPH = 13, // ZEPH }; diff --git a/src/cryptonote_core/cryptonote_basic.h b/src/cryptonote_core/cryptonote_basic.h index d1ca1e2..9dcccb3 100644 --- a/src/cryptonote_core/cryptonote_basic.h +++ b/src/cryptonote_core/cryptonote_basic.h @@ -16,6 +16,7 @@ #include "serialization/binary_archive.h" #include "serialization/crypto.h" #include "serialization/pricing_record.h" +#include "serialization/pricing_record_zeph.h" #include "serialization/keyvalue_serialization.h" // eepe named serialization #include "string_tools.h" #include "cryptonote_config.h" @@ -26,6 +27,7 @@ #include "ringct/rctTypes.h" #include "cryptonote_protocol/blobdatatype.h" #include "offshore/pricing_record.h" +#include "oracle/pricing_record.h" namespace cryptonote @@ -199,9 +201,42 @@ namespace cryptonote FIELD(k_image) END_SERIALIZE() }; + + struct txin_zephyr_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() + }; + + struct txout_zephyr_tagged_key + { + txout_zephyr_tagged_key() { } + txout_zephyr_tagged_key(const crypto::public_key &_key, const std::string &_asset_type, const crypto::view_tag &_view_tag) : key(_key), asset_type(_asset_type), view_tag(_view_tag) { } + crypto::public_key key; + std::string asset_type; + crypto::view_tag view_tag; // optimization to reduce scanning time + + BEGIN_SERIALIZE_OBJECT() + FIELD(key) + FIELD(asset_type) + FIELD(view_tag) + END_SERIALIZE() + }; typedef boost::variant txin_v; + typedef boost::variant txin_zeph_v; + typedef boost::variant txout_zeph_target_v; + typedef boost::variant txout_target_v; typedef boost::variant txout_xhv_target_v; @@ -227,6 +262,17 @@ namespace cryptonote END_SERIALIZE() }; + struct tx_out_zeph + { + uint64_t amount; + txout_zeph_target_v target; + + BEGIN_SERIALIZE_OBJECT() + VARINT_FIELD(amount) + FIELD(target) + END_SERIALIZE() + }; + enum loki_version { @@ -247,8 +293,10 @@ namespace cryptonote uint64_t unlock_time; //number of block (or time), used as a limitation like: spend this tx not early then block/time std::vector vin; + std::vector vin_zeph; std::vector vout; std::vector vout_xhv; + std::vector vout_zeph; //extra std::vector extra; // Block height to use PR from @@ -287,11 +335,17 @@ namespace cryptonote } if (blob_type != BLOB_TYPE_CRYPTONOTE_XHV || version < POU_TRANSACTION_VERSION) VARINT_FIELD(unlock_time) - FIELD(vin) - if (blob_type != BLOB_TYPE_CRYPTONOTE_XHV) - FIELD(vout) + if (blob_type == BLOB_TYPE_CRYPTONOTE_ZEPH) + FIELD(vin_zeph) else + FIELD(vin) + if (blob_type == BLOB_TYPE_CRYPTONOTE_XHV) FIELD(vout_xhv) + else if (blob_type == BLOB_TYPE_CRYPTONOTE_ZEPH) + FIELD(vout_zeph) + else + FIELD(vout) + if (blob_type == BLOB_TYPE_CRYPTONOTE_LOKI || blob_type == BLOB_TYPE_CRYPTONOTE_XTNC) { if (version >= loki_version_3_per_output_unlock_times && vout.size() != output_unlock_times.size()) return false; @@ -323,6 +377,10 @@ namespace cryptonote return false; } } + } else if (blob_type == BLOB_TYPE_CRYPTONOTE_ZEPH) { + VARINT_FIELD(pricing_record_height) + VARINT_FIELD(amount_burnt) + VARINT_FIELD(amount_minted) } END_SERIALIZE() @@ -381,23 +439,32 @@ namespace cryptonote if (!vin.empty()) { ar.begin_object(); - bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), blob_type != BLOB_TYPE_CRYPTONOTE_XHV ? vout.size() : vout_xhv.size()); + bool r; + if (blob_type == BLOB_TYPE_CRYPTONOTE_XHV) + r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout_xhv.size()); + else if (blob_type == BLOB_TYPE_CRYPTONOTE_XHV) + r = rct_signatures.serialize_rctsig_base(ar, vin_zeph.size(), vout_zeph.size()); + else + r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size()); if (!r || !ar.stream().good()) return false; ar.end_object(); if (rct_signatures.type != rct::RCTTypeNull) { ar.tag("rctsig_prunable"); ar.begin_object(); - if (blob_type != BLOB_TYPE_CRYPTONOTE_XHV) { - r = rct_signatures.p.serialize_rctsig_prunable(ar, rct_signatures.type, vin.size(), vout.size(), - vin[0].type() == typeid(txin_to_key) ? boost::get(vin[0]).key_offsets.size() - 1 : 0); - } else { + if (blob_type == BLOB_TYPE_CRYPTONOTE_XHV) { r = rct_signatures.p.serialize_rctsig_prunable(ar, rct_signatures.type, vin.size(), vout_xhv.size(), vin.size() > 0 && vin[0].type() == typeid(txin_to_key) ? boost::get(vin[0]).key_offsets.size() - 1 : vin.size() > 0 && vin[0].type() == typeid(txin_offshore) ? boost::get(vin[0]).key_offsets.size() - 1 : vin.size() > 0 && vin[0].type() == typeid(txin_onshore) ? boost::get(vin[0]).key_offsets.size() - 1 : vin.size() > 0 && vin[0].type() == typeid(txin_xasset) ? boost::get(vin[0]).key_offsets.size() - 1 : 0); + } else if (blob_type == BLOB_TYPE_CRYPTONOTE_ZEPH) { + r = rct_signatures.p.serialize_rctsig_prunable(ar, rct_signatures.type, vin_zeph.size(), vout_zeph.size(), + vin_zeph.size() > 0 && vin_zeph[0].type() == typeid(txin_zephyr_key) ? boost::get(vin_zeph[0]).key_offsets.size() - 1 : 0); + } else { + r = rct_signatures.p.serialize_rctsig_prunable(ar, rct_signatures.type, vin.size(), vout.size(), + vin[0].type() == typeid(txin_to_key) ? boost::get(vin[0]).key_offsets.size() - 1 : 0); } if (!r || !ar.stream().good()) return false; ar.end_object(); @@ -428,8 +495,10 @@ namespace cryptonote version = 0; unlock_time = 0; vin.clear(); + vin_zeph.clear(); vout.clear(); vout_xhv.clear(); + vout_zeph.clear(); extra.clear(); signatures.clear(); pricing_record_height = 0; @@ -452,6 +521,7 @@ namespace cryptonote size_t operator()(const txin_offshore& txin) const {return txin.key_offsets.size();} size_t operator()(const txin_onshore& txin) const {return txin.key_offsets.size();} size_t operator()(const txin_xasset& txin) const {return txin.key_offsets.size();} + size_t operator()(const txin_zephyr_key& txin) const {return txin.key_offsets.size();} }; return boost::apply_visitor(txin_signature_size_visitor(), tx_in); @@ -572,6 +642,7 @@ namespace cryptonote uint64_t nonce; uint64_t nonce8; offshore::pricing_record pricing_record; + oracle::pricing_record pricing_record_zeph; crypto::cycle cycle; crypto::cycle40 cycle40; crypto::cycle48 cycle48; @@ -583,7 +654,7 @@ namespace cryptonote FIELD(prev_id) if (blob_type == BLOB_TYPE_CRYPTONOTE_CUCKOO || blob_type == BLOB_TYPE_CRYPTONOTE_TUBE || blob_type == BLOB_TYPE_CRYPTONOTE_XTA) FIELD(nonce8) if (blob_type != BLOB_TYPE_FORKNOTE2) { - if (blob_type == BLOB_TYPE_AEON) { + if (blob_type == BLOB_TYPE_AEON || blob_type == BLOB_TYPE_CRYPTONOTE_ZEPH) { FIELD(nonce) } else { uint32_t nonce32; @@ -596,6 +667,7 @@ namespace cryptonote if (blob_type == BLOB_TYPE_CRYPTONOTE_TUBE) FIELD(cycle40) if (blob_type == BLOB_TYPE_CRYPTONOTE_XTA) FIELD(cycle48) if (blob_type == BLOB_TYPE_CRYPTONOTE_XHV) FIELD(pricing_record) + if (blob_type == BLOB_TYPE_CRYPTONOTE_ZEPH) FIELD(pricing_record_zeph) END_SERIALIZE() }; @@ -683,12 +755,14 @@ VARIANT_TAG(binary_archive, cryptonote::txin_gen, 0xff); VARIANT_TAG(binary_archive, cryptonote::txin_to_script, 0x0); VARIANT_TAG(binary_archive, cryptonote::txin_to_scripthash, 0x1); VARIANT_TAG(binary_archive, cryptonote::txin_to_key, 0x2); +VARIANT_TAG(binary_archive, cryptonote::txin_zephyr_key, 0x2); VARIANT_TAG(binary_archive, cryptonote::txin_offshore, 0x3); VARIANT_TAG(binary_archive, cryptonote::txin_onshore, 0x4); VARIANT_TAG(binary_archive, cryptonote::txin_xasset, 0x5); 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_zephyr_tagged_key, 0x2); VARIANT_TAG(binary_archive, cryptonote::txout_to_tagged_key, 0x3); VARIANT_TAG(binary_archive, cryptonote::txout_offshore, 0x3); VARIANT_TAG(binary_archive, cryptonote::txout_xasset, 0x5); diff --git a/src/cryptonote_core/cryptonote_format_utils.cpp b/src/cryptonote_core/cryptonote_format_utils.cpp index 44dfa62..998f6cf 100644 --- a/src/cryptonote_core/cryptonote_format_utils.cpp +++ b/src/cryptonote_core/cryptonote_format_utils.cpp @@ -185,18 +185,21 @@ namespace cryptonote { BOOST_FOREACH(const auto& in, tx.vin) { - if (tx.blob_type != BLOB_TYPE_CRYPTONOTE_XHV) { - CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key), false, "wrong variant type: " - << in.type().name() << ", expected " << typeid(txin_to_key).name() - << ", in transaction id=" << get_transaction_hash(tx)); - } else { + if (tx.blob_type == BLOB_TYPE_CRYPTONOTE_XHV) { CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key) || in.type() == typeid(txin_offshore) || in.type() == typeid(txin_onshore) || in.type() == typeid(txin_xasset), false, "wrong variant type: " << in.type().name() << ", expected " << typeid(txin_to_key).name() << "or " << typeid(txin_offshore).name() << "or " << typeid(txin_onshore).name() << "or " << typeid(txin_xasset).name() << ", in transaction id=" << get_transaction_hash(tx)); - } + } else if (tx.blob_type == BLOB_TYPE_CRYPTONOTE_ZEPH) { + CHECK_AND_ASSERT_MES(in.type() == typeid(txin_zephyr_key), false, "wrong variant type: " + << in.type().name() << ", expected " << typeid(txin_zephyr_key).name() + << ", in transaction id=" << get_transaction_hash(tx)); + } else { + CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key), false, "wrong variant type: " + << in.type().name() << ", expected " << typeid(txin_to_key).name() + << ", in transaction id=" << get_transaction_hash(tx)); } return true; } @@ -277,15 +280,17 @@ namespace cryptonote const size_t inputs = t.vin.size(); const size_t outputs = t.blob_type != BLOB_TYPE_CRYPTONOTE_XHV ? t.vout.size() : t.vout_xhv.size(); size_t mixin; - if (t.blob_type != BLOB_TYPE_CRYPTONOTE_XHV) { - mixin = t.vin.empty() ? 0 : t.vin[0].type() == typeid(txin_to_key) ? boost::get(t.vin[0]).key_offsets.size() - 1 : 0; - } else { + if (t.blob_type == BLOB_TYPE_CRYPTONOTE_XHV) { mixin = t.vin.empty() ? 0 : t.vin[0].type() == typeid(txin_to_key) ? boost::get(t.vin[0]).key_offsets.size() - 1 : t.vin[0].type() == typeid(txin_offshore) ? boost::get(t.vin[0]).key_offsets.size() - 1 : t.vin[0].type() == typeid(txin_onshore) ? boost::get(t.vin[0]).key_offsets.size() - 1 : t.vin[0].type() == typeid(txin_xasset) ? boost::get(t.vin[0]).key_offsets.size() - 1 : 0; + } else if (t.blob_type == BLOB_TYPE_CRYPTONOTE_ZEPH) { + mixin = t.vin_zeph.empty() ? 0 : t.vin_zeph[0].type() == typeid(txin_to_key) ? boost::get(t.vin_zeph[0]).key_offsets.size() - 1 : 0; + } else { + mixin = t.vin.empty() ? 0 : t.vin[0].type() == typeid(txin_to_key) ? boost::get(t.vin[0]).key_offsets.size() - 1 : 0; } bool r = tt.rct_signatures.p.serialize_rctsig_prunable(ba, t.rct_signatures.type, inputs, outputs, mixin); CHECK_AND_ASSERT_MES(r, false, "Failed to serialize rct signatures prunable");