diff options
author | W. J. van der Laan <laanwj@protonmail.com> | 2021-05-26 09:41:49 +0200 |
---|---|---|
committer | W. J. van der Laan <laanwj@protonmail.com> | 2021-05-26 10:16:41 +0200 |
commit | 707ba8692b0013f4824dc3c2ea6554ccad5d20c2 (patch) | |
tree | 345a8c04ba50a587f49f6c20c02a395e57ed0227 /src/test/fuzz | |
parent | 7aa41fc58196843bc021ab06a7d3f37189b4a871 (diff) | |
parent | 66545da2008cd9e806e41b74522ded259cd64f86 (diff) | |
download | bitcoin-707ba8692b0013f4824dc3c2ea6554ccad5d20c2.tar.xz |
Merge bitcoin/bitcoin#21966: Remove double serialization; use software encoder for fee estimation
66545da2008cd9e806e41b74522ded259cd64f86 Remove support for double serialization (Pieter Wuille)
fff1cae43af959a601cf2558cb3c77f3c2b1aa80 Convert uses of double-serialization to {En,De}codeDouble (Pieter Wuille)
afd964d70b6f7583ecf89c380f80db07f5b66a60 Convert existing float encoding tests (Pieter Wuille)
bda33f98e2f32f2411fb0a8f5fb4f0a32abdf7d4 Add unit tests for serfloat module (Pieter Wuille)
2be4cd94f4c7d92a4287971233a20d68db81c9c9 Add platform-independent float encoder/decoder (Pieter Wuille)
e40224d0c77674348bf0a518365208bc118f39a4 Remove unused float serialization (MarcoFalke)
Pull request description:
Based on #21981.
This adds a software-based platform-independent float/double encoder/decoder (platform independent in the sense that it only uses arithmetic and library calls, but never inspects the binary representation). This should strengthen our guarantee that encoded float/double values are portable across platforms. It then removes the functionality to serialize doubles from serialize.h, and replaces its only (non-test) use for fee estimation data serialization with the software encoder.
At least on x86/ARM, the only difference should be how certain NaN values are encoded/decoded (but not *whether* they are NaN or not).
It comes with tests that verify on is_iec559 platforms (which are the only ones we support, at least for now) that the serialized bytes exactly match the binary representation of floats in memory (for non-NaN).
ACKs for top commit:
laanwj:
Code review re-ACK 66545da2008cd9e806e41b74522ded259cd64f86
practicalswift:
cr re-ACK 66545da2008cd9e806e41b74522ded259cd64f86
Tree-SHA512: 62ad9adc26e28707b2eb12a919feefd4fd10cf9032652dbb1ca1cc97638ac21de89e240858e80d293d5112685c623e58affa3d316a9783ff0e6d291977a141f5
Diffstat (limited to 'src/test/fuzz')
-rw-r--r-- | src/test/fuzz/float.cpp | 35 | ||||
-rw-r--r-- | src/test/fuzz/util.h | 4 |
2 files changed, 14 insertions, 25 deletions
diff --git a/src/test/fuzz/float.cpp b/src/test/fuzz/float.cpp index d18a87d177..adef66a3ee 100644 --- a/src/test/fuzz/float.cpp +++ b/src/test/fuzz/float.cpp @@ -3,14 +3,14 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <memusage.h> -#include <serialize.h> -#include <streams.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> +#include <util/serfloat.h> #include <version.h> #include <cassert> -#include <cstdint> +#include <cmath> +#include <limits> FUZZ_TARGET(float) { @@ -19,24 +19,17 @@ FUZZ_TARGET(float) { const double d = fuzzed_data_provider.ConsumeFloatingPoint<double>(); (void)memusage::DynamicUsage(d); - assert(ser_uint64_to_double(ser_double_to_uint64(d)) == d); - CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION); - stream << d; - double d_deserialized; - stream >> d_deserialized; - assert(d == d_deserialized); - } - - { - const float f = fuzzed_data_provider.ConsumeFloatingPoint<float>(); - (void)memusage::DynamicUsage(f); - assert(ser_uint32_to_float(ser_float_to_uint32(f)) == f); - - CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION); - stream << f; - float f_deserialized; - stream >> f_deserialized; - assert(f == f_deserialized); + uint64_t encoded = EncodeDouble(d); + if constexpr (std::numeric_limits<double>::is_iec559) { + if (!std::isnan(d)) { + uint64_t encoded_in_memory; + std::copy((const unsigned char*)&d, (const unsigned char*)(&d + 1), (unsigned char*)&encoded_in_memory); + assert(encoded_in_memory == encoded); + } + } + double d_deserialized = DecodeDouble(encoded); + assert(std::isnan(d) == std::isnan(d_deserialized)); + assert(std::isnan(d) || d == d_deserialized); } } diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 86b203c6b5..36b1d5035c 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -513,8 +513,6 @@ void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noe WRITE_TO_STREAM_CASE(uint32_t, fuzzed_data_provider.ConsumeIntegral<uint32_t>()), WRITE_TO_STREAM_CASE(int64_t, fuzzed_data_provider.ConsumeIntegral<int64_t>()), WRITE_TO_STREAM_CASE(uint64_t, fuzzed_data_provider.ConsumeIntegral<uint64_t>()), - WRITE_TO_STREAM_CASE(float, fuzzed_data_provider.ConsumeFloatingPoint<float>()), - WRITE_TO_STREAM_CASE(double, fuzzed_data_provider.ConsumeFloatingPoint<double>()), WRITE_TO_STREAM_CASE(std::string, fuzzed_data_provider.ConsumeRandomLengthString(32)), WRITE_TO_STREAM_CASE(std::vector<char>, ConsumeRandomLengthIntegralVector<char>(fuzzed_data_provider))); } catch (const std::ios_base::failure&) { @@ -545,8 +543,6 @@ void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) no READ_FROM_STREAM_CASE(uint32_t), READ_FROM_STREAM_CASE(int64_t), READ_FROM_STREAM_CASE(uint64_t), - READ_FROM_STREAM_CASE(float), - READ_FROM_STREAM_CASE(double), READ_FROM_STREAM_CASE(std::string), READ_FROM_STREAM_CASE(std::vector<char>)); } catch (const std::ios_base::failure&) { |