diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2018-07-23 12:42:40 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2018-07-23 12:52:53 +0200 |
commit | c0a47da7250586dd2a6b7ba368a876ba8c6a15f2 (patch) | |
tree | a9a4b3a8d624e96d3212177e3b9e6092554e9308 | |
parent | d2186b3db61a9d4dc2d4a6211573790d9e34bf58 (diff) | |
parent | 84547fa6d408bdda1685f6d5972232bb19d97a7d (diff) |
Merge #13719: Avoid creating a temporary vector for size-prefixed elements
84547fa6d408bdda1685f6d5972232bb19d97a7d Avoid creating a temporary vector for size-prefixed elements (Pieter Wuille)
Pull request description:
This is a simple improvement to the PSBT serialization code, avoiding the need for temporary vectors everywhere.
Tree-SHA512: 9f7243b7169ec8ba00ffad31af03c016ab84e4f76ebac810167f91f5e8008f3827ad59fbcee0cb2bd2334fc26466eb222404af24e7fb6ec040fd78229ebe0fd1
-rw-r--r-- | src/script/sign.h | 18 | ||||
-rw-r--r-- | src/serialize.h | 8 |
2 files changed, 16 insertions, 10 deletions
diff --git a/src/script/sign.h b/src/script/sign.h index e3a6196b28..250b637035 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -116,26 +116,24 @@ static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02; // as a 0 length key which indicates that this is the separator. The separator has no value. static constexpr uint8_t PSBT_SEPARATOR = 0x00; -// Takes a stream and multiple arguments and serializes them into a vector and then into the stream +// Takes a stream and multiple arguments and serializes them as if first serialized into a vector and then into the stream // The resulting output into the stream has the total serialized length of all of the objects followed by all objects concatenated with each other. template<typename Stream, typename... X> void SerializeToVector(Stream& s, const X&... args) { - std::vector<unsigned char> ret; - CVectorWriter ss(SER_NETWORK, PROTOCOL_VERSION, ret, 0); - SerializeMany(ss, args...); - s << ret; + WriteCompactSize(s, GetSerializeSizeMany(s, args...)); + SerializeMany(s, args...); } // Takes a stream and multiple arguments and unserializes them first as a vector then each object individually in the order provided in the arguments template<typename Stream, typename... X> void UnserializeFromVector(Stream& s, X&... args) { - std::vector<unsigned char> data; - s >> data; - CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION); - UnserializeMany(ss, args...); - if (!ss.eof()) { + size_t expected_size = ReadCompactSize(s); + size_t remaining_before = s.size(); + UnserializeMany(s, args...); + size_t remaining_after = s.size(); + if (remaining_after + expected_size != remaining_before) { throw std::ios_base::failure("Size of value was not the stated size"); } } diff --git a/src/serialize.h b/src/serialize.h index df3b47ba87..627225b6ef 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -991,4 +991,12 @@ size_t GetSerializeSize(const S& s, const T& t) return (CSizeComputer(s.GetType(), s.GetVersion()) << t).size(); } +template <typename S, typename... T> +size_t GetSerializeSizeMany(const S& s, const T&... t) +{ + CSizeComputer sc(s.GetType(), s.GetVersion()); + SerializeMany(sc, t...); + return sc.size(); +} + #endif // BITCOIN_SERIALIZE_H |