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.
251ss >> s;252BOOST_CHECK_EQUAL(sv, s);253}255BOOST_AUTO_TEST_CASE(limited_vector)256{257const std::vector<int> v = {1,2,3,4,-5,-6,-7,-8,-9,-10,10000,20000,-30000};259auto check = [&]<size_t N>() {260DataStream ss;261ss << v;262try {263std::vector<int> r;264ss >> LIMITED_VECTOR(r, N);265BOOST_CHECK_LE(r.size(), N);266BOOST_CHECK(std::ranges::equal(r, v));267} catch (const std::ios_base::failure&) {268BOOST_CHECK_GT(v.size(), N);269}270};271check.operator()<0>();272check.operator()<10>();273check.operator()<12>();274check.operator()<13>();275check.operator()<14>();276check.operator()<100>();277}279BOOST_AUTO_TEST_CASE(class_methods)280{281int intval(100);282bool boolval(true);283std::string stringval("testing");284const uint8_t charstrval[16]{"testing charstr"};285CMutableTransaction txval;286CTransactionRef tx_ref{MakeTransactionRef(txval)};287CSerializeMethodsTestSingle methodtest1(intval, boolval, stringval, charstrval, tx_ref);288CSerializeMethodsTestMany methodtest2(intval, boolval, stringval, charstrval, tx_ref);289CSerializeMethodsTestSingle methodtest3;290CSerializeMethodsTestMany methodtest4;291DataStream ss;292BOOST_CHECK(methodtest1 == methodtest2);293ss << methodtest1;294ss >> methodtest4;295ss << methodtest2;296ss >> methodtest3;297BOOST_CHECK(methodtest1 == methodtest2);298BOOST_CHECK(methodtest2 == methodtest3);299BOOST_CHECK(methodtest3 == methodtest4);301DataStream ss2;302ss2 << intval << boolval << stringval << charstrval << TX_WITH_WITNESS(txval);303ss2 >> methodtest3;304BOOST_CHECK(methodtest3 == methodtest4);305{306DataStream ds;307const std::string in{"ab"};308ds << std::span{in} << std::byte{'c'};309std::array<std::byte, 2> out;310std::byte out_3;311ds >> std::span{out} >> out_3;312BOOST_CHECK_EQUAL(out.at(0), std::byte{'a'});313BOOST_CHECK_EQUAL(out.at(1), std::byte{'b'});314BOOST_CHECK_EQUAL(out_3, std::byte{'c'});315}316}318struct BaseFormat {319const enum {320RAW,321HEX,322} m_base_format;323SER_PARAMS_OPFUNC324};325constexpr BaseFormat RAW{BaseFormat::RAW};326constexpr BaseFormat HEX{BaseFormat::HEX};328/// (Un)serialize a number as raw byte or 2 hexadecimal chars.329class Base330{331public:332uint8_t m_base_data;334Base() : m_base_data(17) {}335explicit Base(uint8_t data) : m_base_data(data) {}337template <typename Stream>338void Serialize(Stream& s) const339{340if (s.template GetParams<BaseFormat>().m_base_format == BaseFormat::RAW) {341s << m_base_data;342} else {343s << std::span<const char>{HexStr(std::span{&m_base_data, 1})};344}345}347template <typename Stream>348void Unserialize(Stream& s)349{350if (s.template GetParams<BaseFormat>().m_base_format == BaseFormat::RAW) {351s >> m_base_data;352} else {353std::string hex{"aa"};354s >> std::span{hex}.first(hex.size());355m_base_data = TryParseHex<uint8_t>(hex).value().at(0);356}357}358};360class DerivedAndBaseFormat361{362public:363BaseFormat m_base_format;365enum class DerivedFormat {366LOWER,367UPPER,368} m_derived_format;370SER_PARAMS_OPFUNC371};373class Derived : public Base374{375public:376std::string m_derived_data;378SERIALIZE_METHODS(Derived, obj)379{380auto& fmt = SER_PARAMS(DerivedAndBaseFormat);381READWRITE(fmt.m_base_format(AsBase<Base>(obj)));383if (ser_action.ForRead()) {384std::string str;385s >> str;386SER_READ(obj, obj.m_derived_data = str);387} else {388s << (fmt.m_derived_format == DerivedAndBaseFormat::DerivedFormat::LOWER ?389ToLower(obj.m_derived_data) :390ToUpper(obj.m_derived_data));391}392}393};395struct OtherParam {396uint8_t param;397SER_PARAMS_OPFUNC398};400//! Checker for value of OtherParam. When being serialized, serializes the401//! param to the stream. When being unserialized, verifies the value in the402//! stream matches the param.403class OtherParamChecker404{405public:406template <typename Stream>407void Serialize(Stream& s) const408{409const uint8_t param = s.template GetParams<OtherParam>().param;410s << param;411}413template <typename Stream>414void Unserialize(Stream& s) const415{416const uint8_t param = s.template GetParams<OtherParam>().param;417uint8_t value;418s >> value;419BOOST_CHECK_EQUAL(value, param);420}421};423//! Test creating a stream with multiple parameters and making sure424//! serialization code requiring different parameters can retrieve them. Also425//! test that earlier parameters take precedence if the same parameter type is426//! specified twice. (Choice of whether earlier or later values take precedence427//! or multiple values of the same type are allowed was arbitrary, and just428//! decided based on what would require smallest amount of ugly C++ template429//! code. Intent of the test is to just ensure there is no unexpected behavior.)430BOOST_AUTO_TEST_CASE(with_params_multi)431{432const OtherParam other_param_used{.param = 0x10};433const OtherParam other_param_ignored{.param = 0x11};434const OtherParam other_param_override{.param = 0x12};435const OtherParamChecker check;436DataStream stream;437ParamsStream pstream{stream, RAW, other_param_used, other_param_ignored};439Base base1{0x20};440pstream << base1 << check << other_param_override(check);441BOOST_CHECK_EQUAL(stream.str(), "\x20\x10\x12");443Base base2;444pstream >> base2 >> check >> other_param_override(check);445BOOST_CHECK_EQUAL(base2.m_base_data, 0x20);446}448//! Test creating a ParamsStream that moves from a stream argument.449BOOST_AUTO_TEST_CASE(with_params_move)450{451UncopyableStream stream{MakeByteSpan(std::string_view{"abc"})};452ParamsStream pstream{std::move(stream), RAW, HEX, RAW};453BOOST_CHECK_EQUAL(pstream.GetStream().str(), "abc");454pstream.GetStream().clear();456Base base1{0x20};457pstream << base1;458BOOST_CHECK_EQUAL(pstream.GetStream().str(), "\x20");460Base base2;461pstream >> base2;462BOOST_CHECK_EQUAL(base2.m_base_data, 0x20);463}465BOOST_AUTO_TEST_CASE(with_params_base)466{467Base b{0x0F};469DataStream stream;471stream << RAW(b);472BOOST_CHECK_EQUAL(stream.str(), "\x0F");474b.m_base_data = 0;475stream >> RAW(b);476BOOST_CHECK_EQUAL(b.m_base_data, 0x0F);478stream.clear();480stream << HEX(b);481BOOST_CHECK_EQUAL(stream.str(), "0f");483b.m_base_data = 0;484stream >> HEX(b);485BOOST_CHECK_EQUAL(b.m_base_data, 0x0F);486}488BOOST_AUTO_TEST_CASE(with_params_vector_of_base)489{490std::vector<Base> v{Base{0x0F}, Base{0xFF}};492DataStream stream;494stream << RAW(v);495BOOST_CHECK_EQUAL(stream.str(), "\x02\x0F\xFF");497v[0].m_base_data = 0;498v[1].m_base_data = 0;499stream >> RAW(v);500BOOST_CHECK_EQUAL(v[0].m_base_data, 0x0F);
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.