Fixed a number of issues with serialization of pricing_record entries.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user