|
8 | 8 | #include <net.h>
|
9 | 9 | #include <netaddress.h>
|
10 | 10 | #include <netbase.h>
|
| 11 | +#include <netmessagemaker.h> |
11 | 12 | #include <serialize.h>
|
12 | 13 | #include <span.h>
|
13 | 14 | #include <streams.h>
|
@@ -728,4 +729,85 @@ BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle)
|
728 | 729 | BOOST_CHECK(!IsLocal(addr));
|
729 | 730 | }
|
730 | 731 |
|
| 732 | +void message_serialize_deserialize_test(bool v2, const std::vector<CSerializedNetMsg>& test_msgs) |
| 733 | +{ |
| 734 | + // use 32 byte keys with all zeros |
| 735 | + CPrivKey k1(32, 0); |
| 736 | + CPrivKey k2(32, 0); |
| 737 | + |
| 738 | + // construct the serializers |
| 739 | + std::unique_ptr<TransportSerializer> serializer; |
| 740 | + std::unique_ptr<TransportDeserializer> deserializer; |
| 741 | + |
| 742 | + if (v2) { |
| 743 | + serializer = std::make_unique<V2TransportSerializer>(V2TransportSerializer(k1, k2)); |
| 744 | + deserializer = std::make_unique<V2TransportDeserializer>(V2TransportDeserializer((NodeId)0, k1, k2)); |
| 745 | + } else { |
| 746 | + serializer = std::make_unique<V1TransportSerializer>(V1TransportSerializer()); |
| 747 | + deserializer = std::make_unique<V1TransportDeserializer>(V1TransportDeserializer(Params(), (NodeId)0, SER_NETWORK, INIT_PROTO_VERSION)); |
| 748 | + } |
| 749 | + // run a couple of times through all messages with the same AEAD instance |
| 750 | + for (unsigned int i = 0; i < 100; i++) { |
| 751 | + for (const CSerializedNetMsg& msg_orig : test_msgs) { |
| 752 | + // bypass the copy protection |
| 753 | + CSerializedNetMsg msg; |
| 754 | + msg.data = msg_orig.data; |
| 755 | + msg.m_type = msg_orig.m_type; |
| 756 | + size_t raw_msg_size{msg.data.size()}; |
| 757 | + |
| 758 | + std::vector<unsigned char> serialized_header; |
| 759 | + serializer->prepareForTransport(msg, serialized_header); |
| 760 | + |
| 761 | + // read two times |
| 762 | + // first: read header |
| 763 | + size_t read_bytes{0}; |
| 764 | + Span<const uint8_t> span_header(serialized_header.data(), serialized_header.size()); |
| 765 | + if (serialized_header.size() > 0) read_bytes += deserializer->Read(span_header); |
| 766 | + // second: read the encrypted payload (if required) |
| 767 | + Span<const uint8_t> span_msg(msg.data.data(), msg.data.size()); |
| 768 | + if (msg.data.size() > 0) read_bytes += deserializer->Read(span_msg); |
| 769 | + if (msg.data.size() > read_bytes) { |
| 770 | + Span<const uint8_t> span_msg(msg.data.data() + read_bytes, msg.data.size() - read_bytes); |
| 771 | + read_bytes += deserializer->Read(span_msg); |
| 772 | + } |
| 773 | + BOOST_CHECK(deserializer->Complete()); |
| 774 | + BOOST_CHECK_EQUAL(read_bytes, msg.data.size() + serialized_header.size()); |
| 775 | + // message must be complete |
| 776 | + bool reject_message{true}; |
| 777 | + bool disconnect{true}; |
| 778 | + CNetMessage result{deserializer->GetMessage(GetTime<std::chrono::microseconds>(), reject_message, disconnect)}; |
| 779 | + BOOST_CHECK(!reject_message); |
| 780 | + BOOST_CHECK(!disconnect); |
| 781 | + BOOST_CHECK_EQUAL(result.m_type, msg.m_type); |
| 782 | + BOOST_CHECK_EQUAL(raw_msg_size, result.m_message_size); |
| 783 | + } |
| 784 | + } |
| 785 | +} |
| 786 | + |
| 787 | +BOOST_AUTO_TEST_CASE(net_v2) |
| 788 | +{ |
| 789 | + // create some messages where we perform serialization and deserialization |
| 790 | + std::vector<CSerializedNetMsg> test_msgs; |
| 791 | + test_msgs.push_back(CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK)); |
| 792 | + test_msgs.push_back(CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERSION, PROTOCOL_VERSION, (int)NODE_NETWORK, 123, CAddress(CService(), NODE_NONE), CAddress(CService(), NODE_NONE), 123, "foobar", 500000, true)); |
| 793 | + test_msgs.push_back(CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::PING, 123456)); |
| 794 | + CDataStream stream(ParseHex("020000000001013107ca31e1950a9b44b75ce3e8f30127e4d823ed8add1263a1cc8adcc8e49164000000001716001487835ecf51ea0351ef266d216a7e7a3e74b84b4efeffffff02082268590000000017a9144a94391b99e672b03f56d3f60800ef28bc304c4f8700ca9a3b0000000017a9146d5df9e79f752e3c53fc468db89cafda4f7d00cb87024730440220677de5b11a5617d541ba06a1fa5921ab6b4509f8028b23f18ab8c01c5eb1fcfb02202fe382e6e87653f60ff157aeb3a18fc888736720f27ced546b0b77431edabdb0012102608c772598e9645933a86bcd662a3b939e02fb3e77966c9713db5648d5ba8a0006010000"), SER_NETWORK, PROTOCOL_VERSION); |
| 795 | + test_msgs.push_back(CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::TX, CTransaction(deserialize, stream))); |
| 796 | + std::vector<CInv> vInv; |
| 797 | + for (unsigned int i = 0; i < 1000; i++) { |
| 798 | + vInv.push_back(CInv(MSG_BLOCK, Params().GenesisBlock().GetHash())); |
| 799 | + } |
| 800 | + test_msgs.push_back(CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::INV, vInv)); |
| 801 | + |
| 802 | + // add a dummy message |
| 803 | + std::string dummy; |
| 804 | + for (unsigned int i = 0; i < 100; i++) { |
| 805 | + dummy += "020000000001013107ca31e1950a9b44b75ce3e8f30127e4d823ed8add1263a1cc8adcc8e49164000000001716001487835ecf51ea0351ef266d216a7e7a3e74b84b4efeffffff02082268590000000017a9144a94391b99e672b03f56d3f60800ef28bc304c4f8700ca9a3b0000000017a9146d5df9e79f752e3c53fc468db89cafda4f7d00cb87024730440220677de5b11a5617d541ba06a1fa5921ab6b4509f8028b23f18ab8c01c5eb1fcfb02202fe382e6e87653f60ff157aeb3a18fc888736720f27ced546b0b77431edabdb0012102608c772598e9645933a86bcd662a3b939e02fb3e77966c9713db5648d5ba8a0006010000"; |
| 806 | + } |
| 807 | + test_msgs.push_back(CNetMsgMaker(INIT_PROTO_VERSION).Make("foobar", dummy)); |
| 808 | + |
| 809 | + message_serialize_deserialize_test(true, test_msgs); |
| 810 | + message_serialize_deserialize_test(false, test_msgs); |
| 811 | +} |
| 812 | + |
731 | 813 | BOOST_AUTO_TEST_SUITE_END()
|
0 commit comments