From d1a0cf9439673f4e2635b6c4d9b5017e7f4085b8 Mon Sep 17 00:00:00 2001 From: Neil Coggins Date: Tue, 20 Jul 2021 21:07:54 +0100 Subject: [PATCH] updated pricing record to support timestamps --- src/cryptonote_config.h | 3 +- src/offshore/asset_types.h | 107 +++++++++++++++++++++++++++++ src/offshore/pricing_record.cpp | 27 +++++--- src/offshore/pricing_record.h | 75 +++++++++++++++++++- src/serialization/pricing_record.h | 56 +++++++++++---- 5 files changed, 245 insertions(+), 23 deletions(-) diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 88425b9..72998ff 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -1,7 +1,8 @@ #pragma once -#define CURRENT_TRANSACTION_VERSION 1 +#define CURRENT_TRANSACTION_VERSION 4 #define OFFSHORE_TRANSACTION_VERSION 3 +#define HF_VERSION_XASSET_FEES_V2 17 enum BLOB_TYPE { BLOB_TYPE_CRYPTONOTE = 0, diff --git a/src/offshore/asset_types.h b/src/offshore/asset_types.h index 565dbd0..e179d54 100644 --- a/src/offshore/asset_types.h +++ b/src/offshore/asset_types.h @@ -33,4 +33,111 @@ namespace offshore { const std::vector ASSET_TYPES = {"XHV", "XAG", "XAU", "XAUD", "XBTC", "XCAD", "XCHF", "XCNY", "XEUR", "XGBP", "XJPY", "XNOK", "XNZD", "XUSD"}; + class asset_type_counts + { + + public: + + // Fields + uint64_t XHV; + uint64_t XAG; + uint64_t XAU; + uint64_t XAUD; + uint64_t XBTC; + uint64_t XCAD; + uint64_t XCHF; + uint64_t XCNY; + uint64_t XEUR; + uint64_t XGBP; + uint64_t XJPY; + uint64_t XNOK; + uint64_t XNZD; + uint64_t XUSD; + + asset_type_counts() noexcept + : XHV(0) + , XAG(0) + , XAU(0) + , XAUD(0) + , XBTC(0) + , XCAD(0) + , XCHF(0) + , XCNY(0) + , XEUR(0) + , XGBP(0) + , XJPY(0) + , XNOK(0) + , XNZD(0) + , XUSD(0) + { + } + + uint64_t operator[](const std::string asset_type) const noexcept + { + if (asset_type == "XHV") { + return XHV; + } else if (asset_type == "XUSD") { + return XUSD; + } else if (asset_type == "XAG") { + return XAG; + } else if (asset_type == "XAU") { + return XAU; + } else if (asset_type == "XAUD") { + return XAUD; + } else if (asset_type == "XBTC") { + return XBTC; + } else if (asset_type == "XCAD") { + return XCAD; + } else if (asset_type == "XCHF") { + return XCHF; + } else if (asset_type == "XCNY") { + return XCNY; + } else if (asset_type == "XEUR") { + return XEUR; + } else if (asset_type == "XGBP") { + return XGBP; + } else if (asset_type == "XJPY") { + return XJPY; + } else if (asset_type == "XNOK") { + return XNOK; + } else if (asset_type == "XNZD") { + return XNZD; + } + + return 0; + } + + void add(const std::string asset_type, const uint64_t val) + { + if (asset_type == "XHV") { + XHV += val; + } else if (asset_type == "XUSD") { + XUSD += val; + } else if (asset_type == "XAG") { + XAG += val; + } else if (asset_type == "XAU") { + XAU += val; + } else if (asset_type == "XAUD") { + XAUD += val; + } else if (asset_type == "XBTC") { + XBTC += val; + } else if (asset_type == "XCAD") { + XCAD += val; + } else if (asset_type == "XCHF") { + XCHF += val; + } else if (asset_type == "XCNY") { + XCNY += val; + } else if (asset_type == "XEUR") { + XEUR += val; + } else if (asset_type == "XGBP") { + XGBP += val; + } else if (asset_type == "XJPY") { + XJPY += val; + } else if (asset_type == "XNOK") { + XNOK += val; + } else if (asset_type == "XNZD") { + XNZD += val; + } + } + }; } diff --git a/src/offshore/pricing_record.cpp b/src/offshore/pricing_record.cpp index 256b601..6cf1606 100644 --- a/src/offshore/pricing_record.cpp +++ b/src/offshore/pricing_record.cpp @@ -55,6 +55,7 @@ namespace offshore uint64_t unused1; uint64_t unused2; uint64_t unused3; + uint64_t timestamp; std::string signature; BEGIN_KV_SERIALIZE_MAP() @@ -74,6 +75,7 @@ namespace offshore KV_SERIALIZE(unused1) KV_SERIALIZE(unused2) KV_SERIALIZE(unused3) + KV_SERIALIZE(timestamp) KV_SERIALIZE(signature) END_KV_SERIALIZE_MAP() }; @@ -96,6 +98,7 @@ namespace offshore , unused1(0) , unused2(0) , unused3(0) + , timestamp(0) { std::memset(signature, 0, sizeof(signature)); } @@ -122,6 +125,7 @@ namespace offshore unused1 = in.unused1; unused2 = in.unused2; unused3 = in.unused3; + timestamp = in.timestamp; for (unsigned int i = 0; i < in.signature.length(); i += 2) { std::string byteString = in.signature.substr(i, 2); signature[i>>1] = (char) strtol(byteString.c_str(), NULL, 16); @@ -141,7 +145,7 @@ namespace offshore ss << std::hex << std::setw(2) << std::setfill('0') << (0xff & signature[i]); sig_hex += ss.str(); } - const pr_serialized out{xAG,xAU,xAUD,xBTC,xCAD,xCHF,xCNY,xEUR,xGBP,xJPY,xNOK,xNZD,xUSD,unused1,unused2,unused3,sig_hex}; + const pr_serialized out{xAG,xAU,xAUD,xBTC,xCAD,xCHF,xCNY,xEUR,xGBP,xJPY,xNOK,xNZD,xUSD,unused1,unused2,unused3,timestamp,sig_hex}; return out.store(dest, hparent); } @@ -162,6 +166,7 @@ namespace offshore , unused1(orig.unused1) , unused2(orig.unused2) , unused3(orig.unused3) + , timestamp(orig.timestamp) { std::memcpy(signature, orig.signature, sizeof(signature)); } @@ -184,11 +189,12 @@ namespace offshore unused1 = orig.unused1; unused2 = orig.unused2; unused3 = orig.unused3; + timestamp = orig.timestamp; ::memcpy(signature, orig.signature, sizeof(signature)); return *this; } - uint64_t pricing_record::operator[](const std::string asset_type) const noexcept + uint64_t pricing_record::operator[](const std::string asset_type) const { if (asset_type == "XHV") { return 1000000000000; @@ -219,7 +225,7 @@ namespace offshore } else if (asset_type == "XNZD") { return xNZD; } else { - return 1000000000000; + CHECK_AND_ASSERT_THROW_MES(false, "Asset type doesn't exist in pricing record!"); } } @@ -241,19 +247,22 @@ namespace offshore (unused1 == other.unused1) && (unused2 == other.unused2) && (unused3 == other.unused3) && + (timestamp == other.timestamp) && !::memcmp(signature, other.signature, sizeof(signature))); } + bool pricing_record::is_empty() const noexcept + { + const pricing_record empty_pr = offshore::pricing_record(); + return (*this).equal(empty_pr); + } bool pricing_record::verifySignature(EVP_PKEY* public_key) const noexcept { // Sanity check - accept empty pricing records - unsigned char test_sig[64]; - std::memset(test_sig, 0, sizeof(test_sig)); - if (std::memcmp(test_sig, signature, sizeof(signature)) == 0) { + if ((*this).is_empty()) return true; - } - + // Convert our internal 64-byte binary representation into 128-byte hex string std::string sig_hex; for (unsigned int i=0; i<64; i++) { @@ -308,6 +317,8 @@ namespace offshore oss << ",\"unused1\":" << unused1; oss << ",\"unused2\":" << unused2; oss << ",\"unused3\":" << unused3; + if (timestamp > 0) + oss << ",\"timestamp\":" << timestamp; oss << "}"; std::string message = oss.str(); diff --git a/src/offshore/pricing_record.h b/src/offshore/pricing_record.h index 7115417..06a3b18 100644 --- a/src/offshore/pricing_record.h +++ b/src/offshore/pricing_record.h @@ -41,6 +41,7 @@ #include #include +#include namespace epee { @@ -98,6 +99,7 @@ namespace offshore uint64_t unused1; uint64_t unused2; uint64_t unused3; + uint64_t timestamp; unsigned char signature[64]; // Default c'tor @@ -112,10 +114,12 @@ namespace offshore ~pricing_record() = default; pricing_record& operator=(const pricing_record& orig) noexcept; - uint64_t operator[](const std::string asset_type) const noexcept; + uint64_t operator[](const std::string asset_type) const; bool equal(const pricing_record& other) const noexcept; + bool is_empty() const noexcept; + bool verifySignature(EVP_PKEY* public_key = NULL) const noexcept; }; @@ -129,4 +133,73 @@ namespace offshore return !a.equal(b); } + // did not have a timestamp + class pricing_record_v1 + { + + public: + uint64_t xAG; + uint64_t xAU; + uint64_t xAUD; + uint64_t xBTC; + uint64_t xCAD; + uint64_t xCHF; + uint64_t xCNY; + uint64_t xEUR; + uint64_t xGBP; + uint64_t xJPY; + uint64_t xNOK; + uint64_t xNZD; + uint64_t xUSD; + uint64_t unused1; + uint64_t unused2; + uint64_t unused3; + unsigned char signature[64]; + + bool write_to_pr(offshore::pricing_record &pr) + { + pr.xAG = xAG; + pr.xAU = xAU; + pr.xAUD = xAUD; + pr.xBTC = xBTC; + pr.xCAD = xCAD; + pr.xCHF = xCHF; + pr.xCNY = xCNY; + pr.xEUR = xEUR; + pr.xGBP = xGBP; + pr.xJPY = xJPY; + pr.xNOK = xNOK; + pr.xNZD = xNZD; + pr.xUSD = xUSD; + pr.unused1 = unused1; + pr.unused2 = unused2; + pr.unused3 = unused3; + pr.timestamp = 0; + ::memcpy(pr.signature, signature, sizeof(pr.signature)); + return true; + }; + + bool read_from_pr(offshore::pricing_record &pr) + { + xAG = pr.xAG; + xAU = pr.xAU; + xAUD = pr.xAUD; + xBTC = pr.xBTC; + xCAD = pr.xCAD; + xCHF = pr.xCHF; + xCNY = pr.xCNY; + xEUR = pr.xEUR; + xGBP = pr.xGBP; + xJPY = pr.xJPY; + xNOK = pr.xNOK; + xNZD = pr.xNZD; + xUSD = pr.xUSD; + unused1 = pr.unused1; + unused2 = pr.unused2; + unused3 = pr.unused3; + ::memcpy(signature, pr.signature, sizeof(signature)); + return true; + }; + }; + } // offshore diff --git a/src/serialization/pricing_record.h b/src/serialization/pricing_record.h index 73d2fb9..2b01f04 100644 --- a/src/serialization/pricing_record.h +++ b/src/serialization/pricing_record.h @@ -35,33 +35,63 @@ #include "serialization.h" #include "debug_archive.h" #include "offshore/pricing_record.h" +#include "cryptonote_config.h" -/* // read template