Deal with negative integer encodings

Change the blink quorum checksum value on the wire to a positive
uint64_t rather than the 2s complement int64_t encoded value that
bt_value produces by default.  Also updates the bt_dict_consumer code
to handle the needed int64_t -> uint64_t conversion if a negative
int64_t (from a previous lokid version) arrives on the wire.
This commit is contained in:
Jason Rhinelander 2020-04-30 14:55:23 -03:00
parent fb6e4659fd
commit 62c77fe4c7
3 changed files with 12 additions and 4 deletions

View file

@ -40,7 +40,7 @@ find_package(PkgConfig REQUIRED)
if(NOT STATIC)
pkg_check_modules(MINIUPNPC miniupnpc>=2.1)
pkg_check_modules(UNBOUND libunbound)
pkg_check_modules(LOKIMQ liblokimq>=1.1.3)
pkg_check_modules(LOKIMQ liblokimq>=1.1.4)
endif()
if(MINIUPNPC_FOUND)

2
external/loki-mq vendored

@ -1 +1 @@
Subproject commit 3a0508fdce910bd7e424ec25c7f28607db00f611
Subproject commit 719a9b0b58b7520931b83aa3c5ce110172e4c279

View file

@ -1154,7 +1154,15 @@ void handle_blink_signature(Message& m, SNNWrapper& snw) {
// q - quorum membership checksum
if (!data.skip_until("q")) throw std::invalid_argument("Invalid blink signature data: missing required field 'q'");
uint64_t checksum = data.consume_integer<uint64_t>();
// Before 7.1.8 we get a int64_t on the wire, using 2s-complement representation when the value
// is a uint64_t that exceeds the max of an int64_t so, if negative, pull it off and static cast
// it back (the static_cast assumes a 2s-complement architecture which isn't technically
// guaranteed until C++20, but is pretty much universal).
static_assert(sizeof(int64_t) == sizeof(uint64_t) && static_cast<uint64_t>(int64_t{-1}) == ~uint64_t{0},
"Non 2s-complement architecture not supported"); // Just in case
uint64_t checksum = data.is_negative_integer()
? static_cast<uint64_t>(data.consume_integer<int64_t>())
: data.consume_integer<uint64_t>(); // If not negative, read as uint64_t (so that we allow large positive uint64_t's on the wire)
// r - list of 1/0 results (1 = approved, 0 = rejected)
extract_signature_values(data, "r", signatures, [](bt_list_consumer& l) { return l.consume_integer<bool>(); });
@ -1332,7 +1340,7 @@ std::future<std::pair<cryptonote::blink_result, std::string>> send_blink(void *o
{"!", blink_tag},
{"#", get_data_as_string(tx_hash)},
{"h", height},
{"q", checksum},
{"q", bt_u64{checksum}},
{"t", tx_blob}
});