Fixed a number of issues with serialization of pricing_record entries.

This commit is contained in:
Some Random Crypto Guy
2024-01-17 12:43:10 +00:00
parent 8657823a72
commit 3a032c58a4
11 changed files with 141 additions and 111 deletions
+2
View File
@@ -389,12 +389,14 @@ typedef struct circ_supply_tally {
} circ_supply_tally;
typedef struct yield_tx_data {
uint64_t block_height;
crypto::hash tx_hash;
crypto::public_key return_address;
uint64_t amount;
} yield_tx_data;
typedef struct yield_block_data {
uint64_t block_height;
uint64_t slippage_total;
uint64_t locked_coins_total;
uint8_t network_health_percentage;
-63
View File
@@ -491,69 +491,6 @@ namespace cryptonote
return boost::apply_visitor(txin_signature_size_visitor(), tx_in);
}
/************************************************************************/
/* */
/************************************************************************/
/*
struct asset_data {
std::string asset_type;
uint64_t spot_price;
uint64_t ma_price;
public:
BEGIN_SERIALIZE_OBJECT()
FIELD(asset_type)
VARINT_FIELD(spot_price)
VARINT_FIELD(ma_price)
END_SERIALIZE()
};
inline bool operator==(const asset_data& a, const asset_data& b) noexcept
{
return (a.asset_type == b.asset_type &&
a.spot_price == b.spot_price &&
a.ma_price == b.ma_price);
}
struct pricing_record
{
uint64_t pr_version;
std::vector<asset_data> assets;
uint64_t timestamp;
std::string signature;
public:
//! Load from epee p2p format
bool _load(epee::serialization::portable_storage& src, epee::serialization::section* hparent);
//! Store in epee p2p format
bool store(epee::serialization::portable_storage& dest, epee::serialization::section* hparent) const;
inline uint64_t operator[](const std::string& asset_type) const
{
return 0;
}
inline bool operator==(const pricing_record& other) noexcept
{
return ((pr_version == other.pr_version) &&
(assets == other.assets) &&
(timestamp == other.timestamp) &&
(signature == other.signature));
}
BEGIN_SERIALIZE_OBJECT()
VARINT_FIELD(pr_version)
FIELD(assets)
VARINT_FIELD(timestamp)
FIELD(signature)
END_SERIALIZE()
};
*/
/************************************************************************/
/* */
/************************************************************************/
@@ -200,6 +200,13 @@ namespace boost
}
}
template <class Archive>
inline void serialize(Archive &a, oracle::supply_data &sd, const boost::serialization::version_type ver)
{
a & sd.fulm;
a & sd.fusd;
}
template <class Archive>
inline void serialize(Archive &a, oracle::asset_data &ad, const boost::serialization::version_type ver)
{
@@ -212,6 +219,8 @@ namespace boost
inline void serialize(Archive &a, oracle::pricing_record &pr, const boost::serialization::version_type ver)
{
a & pr.pr_version;
a & pr.height;
a & pr.supply;
a & pr.assets;
a & pr.timestamp;
a & pr.signature;
+1 -5
View File
@@ -260,11 +260,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 = "023c01ff000180c09e90acbb1402ba4fcfcff0d4a91441c87615e514be3938e173179ac34a7fc98c0286e7320fdc0446554c4d3c0000000000000021019e809607ceda9ae7ae6755e05bcdc9c555acc8e95dcaede402eca1166a032e1a0100000000000000000000000000000000000000000000000000000000000000000000000000";
//M2
//std::string const GENESIS_TX = "023c01ff000180c09e90acbb1402ae6cfc932cab508d92455942efbb2ec5a8632e33ff6bcac04a8e31be271efb8c0446554c4d3c0000000000000021015a71ac0441d4ee3f321df5ffd4bd3d0f04755152e7e6485a3b6c965356cb92ed0100000000000000000000000000000000000000000000000000000000000000000000000000";
//M3
std::string const GENESIS_TX = "020001ff000180c09e90acbb1402fd5c232c394e6ea4e99672cae46d28b0dc56e1883637fc9445018b1e282901000446554c4d3c0000000000000021017c46e0a3f65ec0de58a78350f6dceddd77a9a1bebf94685009a7c7e5e2cdc8ce0100000000000000000000000000000000000000000000000000000000000000000000000000";
std::string const GENESIS_TX = "020001ff000180c09e90acbb1402e8ee31433aa5ef7eb19af9740660381fe858b541d8c87e5ed38044d061c7072c0446554c4d3c0000000000000021019d1150e5f49422643dfeab470b89c6266f2b1b4469ab969f3bfba0bed74bcd1f0100000000000000000000000000000000000000000000000000000000000000000000000000";
uint32_t const GENESIS_NONCE = 10000;
+5 -5
View File
@@ -2706,19 +2706,19 @@ bool Blockchain::get_pricing_record(oracle::pricing_record &pr, std::map<std::st
res.pr = oracle::pricing_record();
}
// Copy the PR
pr = res.pr;
// Verify the signature
if (pr.verifySignature(get_config(m_nettype).ORACLE_PUBLIC_KEY)) {
if (res.pr.verifySignature(get_config(m_nettype).ORACLE_PUBLIC_KEY)) {
// Copy the PR
pr = res.pr;
} else {
LOG_PRINT_L0("Failed to verify signature of pricing record from Oracle - returning empty PR");
pr = oracle::pricing_record();
}
std::string sig_hex;
for (size_t i = 0; i < 64; i++) {
for (size_t i = 0; i < pr.signature.size(); i++) {
std::stringstream ss;
ss << std::hex << std::setw(2) << std::setfill('0') << (0xff & pr.signature[i]);
ss << std::hex << std::setw(2) << std::setfill('0') << (0xff & pr.signature.at(i));
sig_hex += ss.str();
}
LOG_PRINT_L1("Received pricing record - signature = " << sig_hex);
@@ -483,8 +483,6 @@ namespace cryptonote
buf.height = height;
crypto::hash_to_scalar(&buf, sizeof(buf), uniqueness);
LOG_ERROR("*** DOMAIN = " << buf.domain_separator << ", HEIGHT = " << height);
} else if (type == cryptonote::transaction_type::PROTOCOL) {
// Sanity checks
+14 -5
View File
@@ -85,12 +85,19 @@ namespace oracle
pricing_record::pricing_record() noexcept
: pr_version(0)
, height(0)
, supply()
, assets()
, timestamp(0)
, signature()
{
}
pricing_record::~pricing_record() noexcept
{
pr_version = 99;
}
bool supply_data::_load(epee::serialization::portable_storage& src, epee::serialization::section* hparent)
{
supply_data_serialized in{};
@@ -145,10 +152,12 @@ namespace oracle
timestamp = in.timestamp;
// Signature arrives in HEX format, but needs to be used in BINARY format - convert it here
signature.resize(in.signature.length() >> 1);
for (unsigned int i = 0; i < in.signature.length(); i += 2) {
signature.resize(0);
assert(in.signature.size()%2 == 0);
signature.reserve(in.signature.size() >> 1);
for (unsigned int i = 0; i < in.signature.size(); i += 2) {
std::string byteString = in.signature.substr(i, 2);
signature[i>>1] = (char) strtol(byteString.c_str(), NULL, 16);
signature.emplace_back((uint8_t)strtol(byteString.c_str(), NULL, 16));
}
return true;
}
@@ -160,9 +169,9 @@ namespace oracle
bool pricing_record::store(epee::serialization::portable_storage& dest, epee::serialization::section* hparent) const
{
std::string sig_hex;
for (unsigned int i=0; i<64; i++) {
for (size_t i=0; i<signature.size(); ++i) {
std::stringstream ss;
ss << std::hex << std::setw(2) << std::setfill('0') << (0xff & signature[i]);
ss << std::hex << std::setw(2) << std::setfill('0') << (0xff & signature.at(i));
sig_hex += ss.str();
}
const pr_serialized out{pr_version, height, supply, assets, timestamp, sig_hex};
+22 -5
View File
@@ -74,6 +74,11 @@ namespace oracle
bool _load(epee::serialization::portable_storage& src, epee::serialization::section* hparent);
//! Store in epee p2p format
bool store(epee::serialization::portable_storage& dest, epee::serialization::section* hparent) const;
BEGIN_SERIALIZE_OBJECT()
VARINT_FIELD(fulm)
VARINT_FIELD(fusd)
END_SERIALIZE()
};
inline bool operator==(const supply_data& a, const supply_data& b) noexcept
@@ -91,6 +96,12 @@ namespace oracle
bool _load(epee::serialization::portable_storage& src, epee::serialization::section* hparent);
//! Store in epee p2p format
bool store(epee::serialization::portable_storage& dest, epee::serialization::section* hparent) const;
BEGIN_SERIALIZE_OBJECT()
FIELD(asset_type)
VARINT_FIELD(spot_price)
VARINT_FIELD(ma_price)
END_SERIALIZE()
};
inline bool operator==(const asset_data& a, const asset_data& b) noexcept
@@ -100,11 +111,8 @@ namespace oracle
a.ma_price == b.ma_price);
}
class pricing_record
struct pricing_record
{
public:
// Fields
uint64_t pr_version;
uint64_t height;
@@ -120,7 +128,7 @@ namespace oracle
//! Store in epee p2p format
bool store(epee::serialization::portable_storage& dest, epee::serialization::section* hparent) const;
pricing_record(const pricing_record& orig) noexcept;
~pricing_record() = default;
~pricing_record() noexcept;
bool equal(const pricing_record& other) const noexcept;
bool empty() const noexcept;
bool verifySignature(const std::string& public_key) const;
@@ -128,6 +136,15 @@ namespace oracle
pricing_record& operator=(const pricing_record& orig) noexcept;
uint64_t operator[](const std::string& asset_type) const;
BEGIN_SERIALIZE_OBJECT()
VARINT_FIELD(pr_version)
VARINT_FIELD(height)
FIELD(supply)
FIELD(assets)
VARINT_FIELD(timestamp)
FIELD(signature)
END_SERIALIZE()
};
inline bool operator==(const pricing_record& a, const pricing_record& b) noexcept
+5
View File
@@ -1177,6 +1177,8 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const oracle::prici
dest.StartObject();
INSERT_INTO_JSON_OBJECT(dest, pr_version, pricing_record.pr_version);
INSERT_INTO_JSON_OBJECT(dest, height, pricing_record.height);
INSERT_INTO_JSON_OBJECT(dest, supply, pricing_record.supply);
INSERT_INTO_JSON_OBJECT(dest, assets, pricing_record.assets);
INSERT_INTO_JSON_OBJECT(dest, timestamp, pricing_record.timestamp);
INSERT_INTO_JSON_OBJECT(dest, signature, pricing_record.signature);
@@ -1186,12 +1188,15 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const oracle::prici
void fromJsonValue(const rapidjson::Value& val, oracle::pricing_record& pricing_record)
{
LOG_ERROR("Oracle::" << __func__ << ":" << __LINE__);
if (!val.IsObject())
{
throw WRONG_TYPE("json object");
}
GET_FROM_JSON_OBJECT(val, pricing_record.pr_version, pr_version);
GET_FROM_JSON_OBJECT(val, pricing_record.height, height);
GET_FROM_JSON_OBJECT(val, pricing_record.supply, supply);
GET_FROM_JSON_OBJECT(val, pricing_record.assets, assets);
GET_FROM_JSON_OBJECT(val, pricing_record.timestamp, timestamp);
std::string sig_hex;
-2
View File
@@ -197,8 +197,6 @@ void fromJsonValue(const rapidjson::Value& val, long& i);
// end integers
//void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const std::pair<std::string, std::pair<uint64_t, uint64_t>>& entry);
//void fromJsonValue(const rapidjson::Value& val, std::pair<std::string, std::pair<uint64_t, uint64_t>>& entry);
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const oracle::supply_data& supply_data);
void fromJsonValue(const rapidjson::Value& val, oracle::supply_data& supply_data);
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const oracle::asset_data& asset_data);
+83 -24
View File
@@ -39,21 +39,27 @@
// read
template <template <bool> class Archive>
bool do_serialize(Archive<false> &ar, oracle::supply_data &ad, uint8_t version)
bool do_serialize(Archive<false> &ar, oracle::supply_data &sd, uint8_t version)
{
assert(false);
return false;
ar.serialize_varint(sd.fulm);
if (!ar.good())
return false;
ar.serialize_varint(sd.fusd);
if (!ar.good())
return false;
return true;
}
// write
template <template <bool> class Archive>
bool do_serialize(Archive<true> &ar, oracle::supply_data &sd, uint8_t version)
{
ar.begin_string();
ar.serialize_blob(&sd, sizeof(oracle::supply_data), "");
if (!ar.good())
return false;
ar.end_string();
ar.serialize_varint(sd.fulm);
ar.serialize_varint(sd.fusd);
if (!ar.good())
return false;
return true;
}
@@ -61,19 +67,33 @@ bool do_serialize(Archive<true> &ar, oracle::supply_data &sd, uint8_t version)
template <template <bool> class Archive>
bool do_serialize(Archive<false> &ar, oracle::asset_data &ad, uint8_t version)
{
assert(false);
return false;
ar.serialize_string(ad.asset_type);
if (!ar.good())
return false;
ar.serialize_varint(ad.spot_price);
if (!ar.good())
return false;
ar.serialize_varint(ad.ma_price);
if (!ar.good())
return false;
return true;
}
// write
template <template <bool> class Archive>
bool do_serialize(Archive<true> &ar, oracle::asset_data &ad, uint8_t version)
{
ar.begin_string();
ar.serialize_blob(&ad, sizeof(oracle::asset_data), "");
if (!ar.good())
return false;
ar.end_string();
ar.serialize_string(ad.asset_type);
if (!ar.good())
return false;
ar.serialize_varint(ad.spot_price);
if (!ar.good())
return false;
ar.serialize_varint(ad.ma_price);
if (!ar.good())
return false;
return true;
}
@@ -81,15 +101,40 @@ bool do_serialize(Archive<true> &ar, oracle::asset_data &ad, uint8_t version)
template <template <bool> class Archive>
bool do_serialize(Archive<false> &ar, oracle::pricing_record &pr, uint8_t version)
{
// very basic sanity check
if (ar.remaining_bytes() < sizeof(oracle::pricing_record)) {
return false;
}
ar.serialize_blob(&pr, sizeof(oracle::pricing_record), "");
// very basic sanity checks
if (!ar.good())
return false;
ar.serialize_varint(pr.pr_version);
if (!ar.good())
return false;
ar.serialize_varint(pr.height);
if (!ar.good())
return false;
if (!do_serialize(ar, pr.supply, version))
return false;
/*
// The next line should never do anything, but better safe than sorry
pr.asset_data.empty();
size_t asset_count;
ar.begin_array(asset_count);
if (!ar.good())
return false;
for (size_t idx=0; idx<asset_count; idx++) {
if (idx > 0) ar.delimit_array();
asset_data ad;
if (!do_serialize(ar, ad, version))
return false;
pr.asset_data.emplace_back(ad);
}
ar.end_array();
*/
if (!do_serialize_container(ar, pr.assets))
return false;
ar.serialize_varint(pr.timestamp);
if (!ar.good())
return false;
if (!do_serialize_container(ar, pr.signature))
return false;
return true;
}
@@ -97,14 +142,28 @@ bool do_serialize(Archive<false> &ar, oracle::pricing_record &pr, uint8_t versio
template <template <bool> class Archive>
bool do_serialize(Archive<true> &ar, oracle::pricing_record &pr, uint8_t version)
{
ar.begin_string();
ar.serialize_blob(&pr, sizeof(oracle::pricing_record), "");
// very basic sanity checks
if (!ar.good())
return false;
ar.end_string();
ar.serialize_varint(pr.pr_version);
if (!ar.good())
return false;
ar.serialize_varint(pr.height);
if (!ar.good())
return false;
if (!do_serialize(ar, pr.supply, version))
return false;
if (!do_serialize_container(ar, pr.assets))
return false;
ar.serialize_varint(pr.timestamp);
if (!ar.good())
return false;
pr.signature.empty();
if (!do_serialize_container(ar, pr.signature))
return false;
return true;
}
BLOB_SERIALIZER(oracle::supply_data);
BLOB_SERIALIZER(oracle::asset_data);
BLOB_SERIALIZER(oracle::pricing_record);
//BLOB_SERIALIZER(oracle::supply_data);
//BLOB_SERIALIZER(oracle::asset_data);
//BLOB_SERIALIZER(oracle::pricing_record);