Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1001{1002K key;1003Unserialize(is, key);1004it = m.insert(it, key);1005}1006}1010/**1011* unique_ptr1012*/1013template<typename Stream, typename T> void1014Serialize(Stream& os, const std::unique_ptr<const T>& p)1015{1016Serialize(os, *p);1017}1019template<typename Stream, typename T>1020void Unserialize(Stream& is, std::unique_ptr<const T>& p)1021{1022p.reset(new T(deserialize, is));1023}1027/**1028* shared_ptr1029*/1030template<typename Stream, typename T> void1031Serialize(Stream& os, const std::shared_ptr<const T>& p)1032{1033Serialize(os, *p);1034}1036template<typename Stream, typename T>1037void Unserialize(Stream& is, std::shared_ptr<const T>& p)1038{1039p = std::make_shared<const T>(deserialize, is);1040}1042/**1043* Support for (un)serializing many things at once1044*/1046template <typename Stream, typename... Args>1047void SerializeMany(Stream& s, const Args&... args)1048{1049(::Serialize(s, args), ...);1050}1052template <typename Stream, typename... Args>1053inline void UnserializeMany(Stream& s, Args&&... args)1054{1055(::Unserialize(s, args), ...);1056}1058/**1059* Support for all macros providing or using the ser_action parameter of the SerializationOps method.1060*/1061struct ActionSerialize {1062static constexpr bool ForRead() { return false; }1064template<typename Stream, typename... Args>1065static void SerReadWriteMany(Stream& s, const Args&... args)1066{1067::SerializeMany(s, args...);1068}1070template<typename Stream, typename Type, typename Fn>1071static void SerRead(Stream& s, Type&&, Fn&&)1072{1073}1075template<typename Stream, typename Type, typename Fn>1076static void SerWrite(Stream& s, Type&& obj, Fn&& fn)1077{1078fn(s, std::forward<Type>(obj));1079}1080};1081struct ActionUnserialize {1082static constexpr bool ForRead() { return true; }1084template<typename Stream, typename... Args>1085static void SerReadWriteMany(Stream& s, Args&&... args)1086{1087::UnserializeMany(s, args...);1088}1090template<typename Stream, typename Type, typename Fn>1091static void SerRead(Stream& s, Type&& obj, Fn&& fn)1092{1093fn(s, std::forward<Type>(obj));1094}1096template<typename Stream, typename Type, typename Fn>1097static void SerWrite(Stream& s, Type&&, Fn&&)1098{1099}1100};1102/* ::GetSerializeSize implementations1103*1104* Computing the serialized size of objects is done through a special stream1105* object of type SizeComputer, which only records the number of bytes written1106* to it.1107*1108* If your Serialize or SerializationOp method has non-trivial overhead for1109* serialization, it may be worthwhile to implement a specialized version for1110* SizeComputer, which uses the s.seek() method to record bytes that would1111* be written instead.1112*/1113class SizeComputer1114{1115protected:1116uint64_t m_size{0};1118public:1119SizeComputer() = default;1121void write(std::span<const std::byte> src)1122{1123m_size += src.size();1124}1126/** Pretend this many bytes are written, without specifying them. */1127void seek(uint64_t num)1128{1129m_size += num;1130}1132template <typename T>1133SizeComputer& operator<<(const T& obj)1134{1135::Serialize(*this, obj);1136return *this;1137}1139uint64_t size() const1140{1141return m_size;1142}1143};1145template<typename I>1146inline void WriteVarInt(SizeComputer &s, I n)1147{1148s.seek(GetSizeOfVarInt<I>(n));1149}1151inline void WriteCompactSize(SizeComputer &s, uint64_t nSize)1152{1153s.seek(GetSizeOfCompactSize(nSize));1154}1156template <typename T>1157uint64_t GetSerializeSize(const T& t)1158{1159return (SizeComputer() << t).size();1160}1162//! Check if type contains a stream by seeing if has a GetStream() method.1163template<typename T>1164concept ContainsStream = requires(T t) { t.GetStream(); };1166/** Wrapper that overrides the GetParams() function of a stream. */1167template <typename SubStream, typename Params>1168class ParamsStream1169{1170const Params& m_params;1171// If ParamsStream constructor is passed an lvalue argument, Substream will1172// be a reference type, and m_substream will reference that argument.1173// Otherwise m_substream will be a substream instance and move from the1174// argument. Letting ParamsStream contain a substream instance instead of1175// just a reference is useful to make the ParamsStream object self contained1176// and let it do cleanup when destroyed, for example by closing files if1177// SubStream is a file stream.1178SubStream m_substream;1180public:1181ParamsStream(SubStream&& substream, const Params& params LIFETIMEBOUND) : m_params{params}, m_substream{std::forward<SubStream>(substream)} {}1183template <typename NestedSubstream, typename Params1, typename Params2, typename... NestedParams>1184ParamsStream(NestedSubstream&& s, const Params1& params1 LIFETIMEBOUND, const Params2& params2 LIFETIMEBOUND, const NestedParams&... params LIFETIMEBOUND)1185: ParamsStream{::ParamsStream{std::forward<NestedSubstream>(s), params2, params...}, params1} {}1187template <typename U> ParamsStream& operator<<(const U& obj) { ::Serialize(*this, obj); return *this; }1188template <typename U> ParamsStream& operator>>(U&& obj) { ::Unserialize(*this, obj); return *this; }1189void write(std::span<const std::byte> src) { GetStream().write(src); }1190void read(std::span<std::byte> dst) { GetStream().read(dst); }1191void ignore(size_t num) { GetStream().ignore(num); }1192bool empty() const { return GetStream().empty(); }1193size_t size() const { return GetStream().size(); }1195//! Get reference to stream parameters.1196template <typename P>1197const auto& GetParams() const1198{1199if constexpr (std::is_convertible_v<Params, P>) {1200return m_params;1201} else {1202return m_substream.template GetParams<P>();1203}1204}1206//! Get reference to underlying stream.1207auto& GetStream()1208{1209if constexpr (ContainsStream<SubStream>) {1210return m_substream.GetStream();1211} else {1212return m_substream;1213}1214}1215const auto& GetStream() const1216{1217if constexpr (ContainsStream<SubStream>) {1218return m_substream.GetStream();1219} else {1220return m_substream;1221}1222}1223};1225/**1226* Explicit template deduction guide is required for single-parameter1227* constructor so Substream&& is treated as a forwarding reference, and1228* SubStream is deduced as reference type for lvalue arguments.1229*/1230template <typename Substream, typename Params>1231ParamsStream(Substream&&, const Params&) -> ParamsStream<Substream, Params>;1233/**1234* Template deduction guide for multiple params arguments that creates a nested1235* ParamsStream.1236*/1237template <typename Substream, typename Params1, typename Params2, typename... Params>1238ParamsStream(Substream&& s, const Params1& params1, const Params2& params2, const Params&... params) ->1239ParamsStream<decltype(ParamsStream{std::forward<Substream>(s), params2, params...}), Params1>;1241/** Wrapper that serializes objects with the specified parameters. */1242template <typename Params, typename T>1243class ParamsWrapper1244{1245const Params& m_params;1246T& m_object;1248public:1249explicit ParamsWrapper(const Params& params, T& obj) : m_params{params}, m_object{obj} {}