diff --git a/package.json b/package.json index df0abf0..33443f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cryptoforknote-util", - "version": "12.0.0", + "version": "13.0.0", "main": "cryptoforknote-util", "author": { "name": "LucasJones", diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index aff6d2f..ba73830 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -2,13 +2,16 @@ #define CURRENT_TRANSACTION_VERSION 1 #define POU_TRANSACTION_VERSION 6 +#define COLLATERAL_TRANSACTION_VERSION 7 #define OFFSHORE_TRANSACTION_VERSION 3 #define HF_VERSION_XASSET_FEES_V2 17 #define HF_VERSION_HAVEN2 18 +#define HF_VERSION_USE_COLLATERAL 20 // UNLOCK TIMES #define TX_V6_OFFSHORE_UNLOCK_BLOCKS 21*720 // 21 day unlock time #define TX_V6_ONSHORE_UNLOCK_BLOCKS 360 // 12 hour unlock time +#define TX_V7_ONSHORE_UNLOCK_BLOCKS 21*720 // 21 day unlock time #define TX_V6_XASSET_UNLOCK_BLOCKS 1440 // 2 day unlock time #define TX_V6_OFFSHORE_UNLOCK_BLOCKS_TESTNET 60 // 2 hour unlock time - FOR TESTING ONLY #define TX_V6_ONSHORE_UNLOCK_BLOCKS_TESTNET 30 // 1 hour unlock time - FOR TESTING ONLY diff --git a/src/cryptonote_core/cryptonote_basic.h b/src/cryptonote_core/cryptonote_basic.h index c3b9277..056e57c 100644 --- a/src/cryptonote_core/cryptonote_basic.h +++ b/src/cryptonote_core/cryptonote_basic.h @@ -257,11 +257,12 @@ namespace cryptonote std::vector offshore_data; uint64_t amount_burnt; uint64_t amount_minted; + std::vector output_unlock_times; + size_t collateral_index; // index to the outputs vector that denotes the collateral output. // // NOTE: Loki specific // - std::vector output_unlock_times; enum loki_type_t { loki_type_standard, @@ -312,6 +313,11 @@ namespace cryptonote if (version >= POU_TRANSACTION_VERSION && vout_xhv.size() != output_unlock_times.size()) return false; VARINT_FIELD(amount_burnt) VARINT_FIELD(amount_minted) + if (version >= COLLATERAL_TRANSACTION_VERSION) { + VARINT_FIELD(collateral_index) + if (collateral_index >= vout.size()) + return false; + } } END_SERIALIZE() @@ -426,6 +432,7 @@ namespace cryptonote amount_burnt = 0; amount_minted = 0; output_unlock_times.clear(); + collateral_index = 0; } inline @@ -658,6 +665,13 @@ namespace cryptonote { crypto::public_key pub; crypto::secret_key sec; + + static inline keypair generate() + { + keypair k; + generate_keys(k.pub, k.sec); + return k; + } }; //--------------------------------------------------------------- diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 641cd56..bdde60d 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -257,6 +257,7 @@ namespace rct { RCTTypeCLSAG = 5, RCTTypeCLSAGN = 6, RCTTypeHaven2 = 7, // Add public mask sum terms, remove extraneous fields (txnFee_usd,txnFee_xasset,txnOffshoreFee_usd,txnOffshoreFee_xasset) + RCTTypeHaven3 = 8, // Add public mask sum term for collateral }; enum RangeProofType { RangeProofBorromean, RangeProofBulletproof, RangeProofMultiOutputBulletproof, RangeProofPaddedBulletproof }; struct RCTConfig { @@ -279,7 +280,7 @@ namespace rct { xmr_amount txnOffshoreFee = 0; xmr_amount txnOffshoreFee_usd = 0; xmr_amount txnOffshoreFee_xasset = 0; - keyV maskSums; // contains 2 elements. 1. is the sum of masks of inputs. 2. is the sum of masks of changes. + 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. template class Archive> bool serialize_rctsig_base(Archive &ar, size_t inputs, size_t outputs) @@ -287,10 +288,10 @@ namespace rct { FIELD(type) if (type == RCTTypeNull) return ar.stream().good(); - if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeCLSAGN && type != RCTTypeHaven2) + if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeCLSAGN && type != RCTTypeHaven2 && type != RCTTypeHaven3) return false; VARINT_FIELD(txnFee) - if (type == RCTTypeHaven2) { + if (type == RCTTypeHaven2 || type == RCTTypeHaven3) { // serialize offshore fee VARINT_FIELD(txnOffshoreFee) } else if (type == RCTTypeCLSAG || type == RCTTypeCLSAGN) { @@ -338,7 +339,7 @@ namespace rct { return false; for (size_t i = 0; i < outputs; ++i) { - if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2) + if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3) { ar.begin_object(); if (!typename Archive::is_saving()) @@ -369,7 +370,22 @@ namespace rct { } ar.end_array(); - if (type == RCTTypeHaven2) { + // if txnOffshoreFee is not 0, it is a conversion tx + if (type == RCTTypeHaven3 && txnOffshoreFee) { + + ar.tag("maskSums"); + ar.begin_array(); + PREPARE_CUSTOM_VECTOR_SERIALIZATION(3, maskSums); + if (maskSums.size() != 3) + return false; + FIELDS(maskSums[0]) + ar.delimit_array(); + FIELDS(maskSums[1]) + ar.delimit_array(); + FIELDS(maskSums[2]) + ar.end_array(); + + } else if (type == RCTTypeHaven2) { ar.tag("maskSums"); ar.begin_array(); @@ -430,12 +446,12 @@ namespace rct { { if (type == RCTTypeNull) return ar.stream().good(); - if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeCLSAGN && type != RCTTypeHaven2) + if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeCLSAGN && type != RCTTypeHaven2 && type != RCTTypeHaven3) return false; - if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2) + if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3) { uint32_t nbp = bulletproofs.size(); - if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2) + if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3) VARINT_FIELD(nbp) else FIELD(nbp) @@ -470,7 +486,7 @@ namespace rct { ar.end_array(); } - if ((type == RCTTypeCLSAG) || (type == RCTTypeCLSAGN) || (type == RCTTypeHaven2)) + if ((type == RCTTypeCLSAG) || (type == RCTTypeCLSAGN) || (type == RCTTypeHaven2) || (type == RCTTypeHaven3)) { ar.tag("CLSAGs"); ar.begin_array(); @@ -561,7 +577,7 @@ namespace rct { } ar.end_array(); } - if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2) + if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3) { ar.tag("pseudoOuts"); ar.begin_array(); @@ -585,12 +601,12 @@ namespace rct { keyV& get_pseudo_outs() { - return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 ? p.pseudoOuts : pseudoOuts; + return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3 ? p.pseudoOuts : pseudoOuts; } keyV const& get_pseudo_outs() const { - return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 ? p.pseudoOuts : pseudoOuts; + return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3 ? p.pseudoOuts : pseudoOuts; } };