2022-12-24 23:49:50 +00:00
|
|
|
// Copyright (c) 2020-2022 The Bitcoin Core developers
|
2020-04-04 07:30:51 +08:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
|
#include <test/util/net.h>
|
|
|
|
|
|
|
|
#include <chainparams.h>
|
2022-05-26 16:07:04 +02:00
|
|
|
#include <node/eviction.h>
|
2020-04-04 07:30:51 +08:00
|
|
|
#include <net.h>
|
2022-07-11 18:14:36 +02:00
|
|
|
#include <net_processing.h>
|
|
|
|
#include <netmessagemaker.h>
|
2021-07-01 12:48:51 +02:00
|
|
|
#include <span.h>
|
|
|
|
|
|
|
|
#include <vector>
|
2020-04-04 07:30:51 +08:00
|
|
|
|
2022-07-11 18:14:36 +02:00
|
|
|
void ConnmanTestMsg::Handshake(CNode& node,
|
|
|
|
bool successfully_connected,
|
|
|
|
ServiceFlags remote_services,
|
2020-07-20 20:28:37 +01:00
|
|
|
ServiceFlags local_services,
|
2022-07-11 18:14:36 +02:00
|
|
|
int32_t version,
|
|
|
|
bool relay_txs)
|
|
|
|
{
|
|
|
|
auto& peerman{static_cast<PeerManager&>(*m_msgproc)};
|
|
|
|
auto& connman{*this};
|
|
|
|
const CNetMsgMaker mm{0};
|
|
|
|
|
2020-07-20 20:28:37 +01:00
|
|
|
peerman.InitializeNode(node, local_services);
|
net: move message conversion to wire bytes from PushMessage to SocketSendData
This furthers transport abstraction by removing the assumption that a message
can always immediately be converted to wire bytes. This assumption does not hold
for the v2 transport proposed by BIP324, as no messages can be sent before the
handshake completes.
This is done by only keeping (complete) CSerializedNetMsg objects in vSendMsg,
rather than the resulting bytes (for header and payload) that need to be sent.
In SocketSendData, these objects are handed to the transport as permitted by it,
and sending out the bytes the transport tells us to send. This also removes the
nSendOffset member variable in CNode, as keeping track of how much has been sent
is now a responsability of the transport.
This is not a pure refactor, and has the following effects even for the current
v1 transport:
* Checksum calculation now happens in SocketSendData rather than PushMessage.
For non-optimistic-send messages, that means this computation now happens in
the network thread rather than the message handler thread (generally a good
thing, as the message handler thread is more of a computational bottleneck).
* Checksum calculation now happens while holding the cs_vSend lock. This is
technically unnecessary for the v1 transport, as messages are encoded
independent from one another, but is untenable for the v2 transport anyway.
* Statistics updates about per-message sent bytes now happen when those bytes
are actually handed to the OS, rather than at PushMessage time.
2023-08-16 13:31:50 -04:00
|
|
|
FlushSendBuffer(node); // Drop the version message added by InitializeNode.
|
2022-07-11 18:07:53 +02:00
|
|
|
|
2022-07-11 18:14:36 +02:00
|
|
|
CSerializedNetMsg msg_version{
|
|
|
|
mm.Make(NetMsgType::VERSION,
|
|
|
|
version, //
|
|
|
|
Using<CustomUintFormatter<8>>(remote_services), //
|
|
|
|
int64_t{}, // dummy time
|
|
|
|
int64_t{}, // ignored service bits
|
2023-01-31 18:04:44 +01:00
|
|
|
WithParams(CNetAddr::V1, CService{}), // dummy
|
2022-07-11 18:14:36 +02:00
|
|
|
int64_t{}, // ignored service bits
|
2023-01-31 18:04:44 +01:00
|
|
|
WithParams(CNetAddr::V1, CService{}), // ignored
|
2022-07-11 18:14:36 +02:00
|
|
|
uint64_t{1}, // dummy nonce
|
|
|
|
std::string{}, // dummy subver
|
|
|
|
int32_t{}, // dummy starting_height
|
|
|
|
relay_txs),
|
|
|
|
};
|
|
|
|
|
2023-07-21 16:31:59 -04:00
|
|
|
(void)connman.ReceiveMsgFrom(node, std::move(msg_version));
|
2022-07-11 18:14:36 +02:00
|
|
|
node.fPauseSend = false;
|
|
|
|
connman.ProcessMessagesOnce(node);
|
2022-09-13 12:22:18 +10:00
|
|
|
peerman.SendMessages(&node);
|
net: move message conversion to wire bytes from PushMessage to SocketSendData
This furthers transport abstraction by removing the assumption that a message
can always immediately be converted to wire bytes. This assumption does not hold
for the v2 transport proposed by BIP324, as no messages can be sent before the
handshake completes.
This is done by only keeping (complete) CSerializedNetMsg objects in vSendMsg,
rather than the resulting bytes (for header and payload) that need to be sent.
In SocketSendData, these objects are handed to the transport as permitted by it,
and sending out the bytes the transport tells us to send. This also removes the
nSendOffset member variable in CNode, as keeping track of how much has been sent
is now a responsability of the transport.
This is not a pure refactor, and has the following effects even for the current
v1 transport:
* Checksum calculation now happens in SocketSendData rather than PushMessage.
For non-optimistic-send messages, that means this computation now happens in
the network thread rather than the message handler thread (generally a good
thing, as the message handler thread is more of a computational bottleneck).
* Checksum calculation now happens while holding the cs_vSend lock. This is
technically unnecessary for the v1 transport, as messages are encoded
independent from one another, but is untenable for the v2 transport anyway.
* Statistics updates about per-message sent bytes now happen when those bytes
are actually handed to the OS, rather than at PushMessage time.
2023-08-16 13:31:50 -04:00
|
|
|
FlushSendBuffer(node); // Drop the verack message added by SendMessages.
|
2022-07-11 18:14:36 +02:00
|
|
|
if (node.fDisconnect) return;
|
|
|
|
assert(node.nVersion == version);
|
|
|
|
assert(node.GetCommonVersion() == std::min(version, PROTOCOL_VERSION));
|
|
|
|
CNodeStateStats statestats;
|
|
|
|
assert(peerman.GetNodeStateStats(node.GetId(), statestats));
|
|
|
|
assert(statestats.m_relay_txs == (relay_txs && !node.IsBlockOnlyConn()));
|
2020-07-20 18:46:13 +01:00
|
|
|
assert(statestats.their_services == remote_services);
|
2022-07-11 18:14:36 +02:00
|
|
|
if (successfully_connected) {
|
|
|
|
CSerializedNetMsg msg_verack{mm.Make(NetMsgType::VERACK)};
|
2023-07-21 16:31:59 -04:00
|
|
|
(void)connman.ReceiveMsgFrom(node, std::move(msg_verack));
|
2022-07-11 18:14:36 +02:00
|
|
|
node.fPauseSend = false;
|
|
|
|
connman.ProcessMessagesOnce(node);
|
2022-09-13 12:22:18 +10:00
|
|
|
peerman.SendMessages(&node);
|
2022-07-11 18:14:36 +02:00
|
|
|
assert(node.fSuccessfullyConnected == true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-20 10:16:10 +01:00
|
|
|
void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_bytes, bool& complete) const
|
2020-04-04 07:30:51 +08:00
|
|
|
{
|
2020-09-30 17:08:26 +02:00
|
|
|
assert(node.ReceiveMsgBytes(msg_bytes, complete));
|
2020-04-04 07:30:51 +08:00
|
|
|
if (complete) {
|
2023-03-24 15:45:50 +01:00
|
|
|
node.MarkReceivedMsgsForProcessing();
|
2020-04-04 07:30:51 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
net: move message conversion to wire bytes from PushMessage to SocketSendData
This furthers transport abstraction by removing the assumption that a message
can always immediately be converted to wire bytes. This assumption does not hold
for the v2 transport proposed by BIP324, as no messages can be sent before the
handshake completes.
This is done by only keeping (complete) CSerializedNetMsg objects in vSendMsg,
rather than the resulting bytes (for header and payload) that need to be sent.
In SocketSendData, these objects are handed to the transport as permitted by it,
and sending out the bytes the transport tells us to send. This also removes the
nSendOffset member variable in CNode, as keeping track of how much has been sent
is now a responsability of the transport.
This is not a pure refactor, and has the following effects even for the current
v1 transport:
* Checksum calculation now happens in SocketSendData rather than PushMessage.
For non-optimistic-send messages, that means this computation now happens in
the network thread rather than the message handler thread (generally a good
thing, as the message handler thread is more of a computational bottleneck).
* Checksum calculation now happens while holding the cs_vSend lock. This is
technically unnecessary for the v1 transport, as messages are encoded
independent from one another, but is untenable for the v2 transport anyway.
* Statistics updates about per-message sent bytes now happen when those bytes
are actually handed to the OS, rather than at PushMessage time.
2023-08-16 13:31:50 -04:00
|
|
|
void ConnmanTestMsg::FlushSendBuffer(CNode& node) const
|
|
|
|
{
|
|
|
|
LOCK(node.cs_vSend);
|
|
|
|
node.vSendMsg.clear();
|
|
|
|
node.m_send_memusage = 0;
|
|
|
|
while (true) {
|
|
|
|
const auto& [to_send, _more, _msg_type] = node.m_transport->GetBytesToSend();
|
|
|
|
if (to_send.empty()) break;
|
|
|
|
node.m_transport->MarkBytesSent(to_send.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-21 16:31:59 -04:00
|
|
|
bool ConnmanTestMsg::ReceiveMsgFrom(CNode& node, CSerializedNetMsg&& ser_msg) const
|
2020-04-04 07:30:51 +08:00
|
|
|
{
|
2023-07-21 16:31:59 -04:00
|
|
|
bool queued = node.m_transport->SetMessageToSend(ser_msg);
|
|
|
|
assert(queued);
|
|
|
|
bool complete{false};
|
|
|
|
while (true) {
|
|
|
|
const auto& [to_send, _more, _msg_type] = node.m_transport->GetBytesToSend();
|
|
|
|
if (to_send.empty()) break;
|
|
|
|
NodeReceiveMsgBytes(node, to_send, complete);
|
|
|
|
node.m_transport->MarkBytesSent(to_send.size());
|
|
|
|
}
|
2020-04-04 07:30:51 +08:00
|
|
|
return complete;
|
|
|
|
}
|
2021-07-01 12:48:51 +02:00
|
|
|
|
|
|
|
std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context)
|
|
|
|
{
|
|
|
|
std::vector<NodeEvictionCandidate> candidates;
|
2023-03-26 20:17:55 +01:00
|
|
|
candidates.reserve(n_candidates);
|
2021-07-01 12:48:51 +02:00
|
|
|
for (int id = 0; id < n_candidates; ++id) {
|
|
|
|
candidates.push_back({
|
2021-09-14 16:56:34 +02:00
|
|
|
/*id=*/id,
|
2021-12-13 12:32:28 +01:00
|
|
|
/*m_connected=*/std::chrono::seconds{random_context.randrange(100)},
|
2021-09-14 16:56:34 +02:00
|
|
|
/*m_min_ping_time=*/std::chrono::microseconds{random_context.randrange(100)},
|
2021-12-13 12:32:28 +01:00
|
|
|
/*m_last_block_time=*/std::chrono::seconds{random_context.randrange(100)},
|
|
|
|
/*m_last_tx_time=*/std::chrono::seconds{random_context.randrange(100)},
|
2021-09-14 16:56:34 +02:00
|
|
|
/*fRelevantServices=*/random_context.randbool(),
|
2020-06-16 16:27:34 -04:00
|
|
|
/*m_relay_txs=*/random_context.randbool(),
|
2021-09-14 16:56:34 +02:00
|
|
|
/*fBloomFilter=*/random_context.randbool(),
|
|
|
|
/*nKeyedNetGroup=*/random_context.randrange(100),
|
|
|
|
/*prefer_evict=*/random_context.randbool(),
|
|
|
|
/*m_is_local=*/random_context.randbool(),
|
|
|
|
/*m_network=*/ALL_NETWORKS[random_context.randrange(ALL_NETWORKS.size())],
|
2022-05-26 15:40:21 +02:00
|
|
|
/*m_noban=*/false,
|
2022-05-26 15:49:10 +02:00
|
|
|
/*m_conn_type=*/ConnectionType::INBOUND,
|
2021-07-01 12:48:51 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return candidates;
|
|
|
|
}
|