eth/eth_handshake_guard.cpp¶
Namespaces¶
| Name |
|---|
| eth |
Functions¶
| Name | |
|---|---|
| std::optional< uint8_t > | NormalizeEthWireMessageId(uint8_t wire_message_id, uint8_t negotiated_eth_offset) Return the ETH-local message id for a wire-level message. |
| uint64_t | ExtractLatestBlockNumber(const StatusMessage & status) Return the latest block number from a validated ETH Status message. |
| rlp::outcome::result< StatusMessage, StatusValidationError, rlp::outcome::policy::all_narrow > | DecodeValidatedStatusMessage(const rlpx::protocol::Message & message, uint8_t negotiated_eth_offset, uint8_t negotiated_eth_version, uint64_t network_id, const Hash256 & genesis_hash, const std::vector< EthMessageSchema > & eth_message_schemas ={}) Decode and validate an inbound ETH Status message. |
| HandshakeMessageDisposition | HandleEthHandshakeMessage(const rlpx::protocol::Message & message, uint8_t negotiated_eth_offset, uint8_t negotiated_eth_version, uint64_t network_id, const Hash256 & genesis_hash, bool & status_received) Process one inbound ETH handshake-phase message. |
Functions Documentation¶
function NormalizeEthWireMessageId¶
std::optional< uint8_t > NormalizeEthWireMessageId(
uint8_t wire_message_id,
uint8_t negotiated_eth_offset
)
Return the ETH-local message id for a wire-level message.
Parameters:
- wire_message_id Wire-level RLPx message id.
- negotiated_eth_offset Negotiated ETH wire offset.
Return: ETH-local message id if the wire id belongs to ETH; std::nullopt otherwise.
function ExtractLatestBlockNumber¶
Return the latest block number from a validated ETH Status message.
Parameters:
- status Decoded ETH Status message.
Return: Latest block number for ETH/69, or 0 for earlier layouts.
function DecodeValidatedStatusMessage¶
rlp::outcome::result< StatusMessage, StatusValidationError, rlp::outcome::policy::all_narrow > DecodeValidatedStatusMessage(
const rlpx::protocol::Message & message,
uint8_t negotiated_eth_offset,
uint8_t negotiated_eth_version,
uint64_t network_id,
const Hash256 & genesis_hash,
const std::vector< EthMessageSchema > & eth_message_schemas ={}
)
Decode and validate an inbound ETH Status message.
Parameters:
- message Inbound wire-level RLPx message.
- negotiated_eth_offset Negotiated ETH wire offset.
- negotiated_eth_version Negotiated ETH version.
- network_id Expected local network identifier.
- genesis_hash Expected local genesis hash.
Return: Decoded valid ETH Status message, or a validation/decode error.
function HandleEthHandshakeMessage¶
HandshakeMessageDisposition HandleEthHandshakeMessage(
const rlpx::protocol::Message & message,
uint8_t negotiated_eth_offset,
uint8_t negotiated_eth_version,
uint64_t network_id,
const Hash256 & genesis_hash,
bool & status_received
)
Process one inbound ETH handshake-phase message.
Parameters:
- message Inbound wire-level RLPx message.
- negotiated_eth_offset Negotiated ETH wire offset.
- negotiated_eth_version Negotiated ETH version.
- network_id Expected local network identifier.
- genesis_hash Expected local genesis hash.
- status_received Whether a valid remote ETH Status was already accepted.
Return: Disposition indicating whether the message was ignored, accepted, or rejected.
Source code¶
// Copyright 2026 Genius Ventures, Inc.
// SPDX-License-Identifier: MIT
#include <eth/eth_handshake_guard.hpp>
#include <eth/messages.hpp>
namespace eth {
std::optional<uint8_t> NormalizeEthWireMessageId(
uint8_t wire_message_id,
uint8_t negotiated_eth_offset) noexcept
{
if (wire_message_id < negotiated_eth_offset)
{
return std::nullopt;
}
return static_cast<uint8_t>(wire_message_id - negotiated_eth_offset);
}
uint64_t ExtractLatestBlockNumber(const StatusMessage& status) noexcept
{
return std::visit([](const auto& message) -> uint64_t
{
if constexpr (std::is_same_v<std::decay_t<decltype(message)>, StatusMessage69>)
{
return message.latest_block;
}
return 0;
}, status);
}
rlp::outcome::result<StatusMessage, StatusValidationError, rlp::outcome::policy::all_narrow>
DecodeValidatedStatusMessage(
const rlpx::protocol::Message& message,
uint8_t negotiated_eth_offset,
uint8_t negotiated_eth_version,
uint64_t network_id,
const Hash256& genesis_hash,
const std::vector<EthMessageSchema>& eth_message_schemas) noexcept
{
const auto eth_id = NormalizeEthWireMessageId(message.id, negotiated_eth_offset);
if (!eth_id.has_value() || *eth_id != protocol::kStatusMessageId)
{
return rlp::outcome::failure(StatusValidationError::kProtocolVersionMismatch);
}
const rlp::ByteView payload(message.payload.data(), message.payload.size());
const auto decoded = eth_message_schemas.empty()
? protocol::decode_status(payload)
: protocol::decode_status(payload, eth_message_schemas);
if (!decoded)
{
return rlp::outcome::failure(StatusValidationError::kProtocolVersionMismatch);
}
const auto valid = ValidateRemoteStatusMessage(
decoded.value(),
negotiated_eth_version,
network_id,
genesis_hash);
if (!valid)
{
return rlp::outcome::failure(valid.error());
}
return decoded.value();
}
HandshakeMessageDisposition HandleEthHandshakeMessage(
const rlpx::protocol::Message& message,
uint8_t negotiated_eth_offset,
uint8_t negotiated_eth_version,
uint64_t network_id,
const Hash256& genesis_hash,
bool& status_received) noexcept
{
const auto eth_id = NormalizeEthWireMessageId(message.id, negotiated_eth_offset);
if (!eth_id.has_value())
{
return HandshakeMessageDisposition::kIgnored;
}
if (*eth_id != protocol::kStatusMessageId)
{
if (!status_received)
{
return HandshakeMessageDisposition::kRejected;
}
return HandshakeMessageDisposition::kIgnored;
}
const auto decoded = DecodeValidatedStatusMessage(
message,
negotiated_eth_offset,
negotiated_eth_version,
network_id,
genesis_hash);
if (!decoded)
{
return HandshakeMessageDisposition::kRejected;
}
status_received = true;
return HandshakeMessageDisposition::kAcceptedStatus;
}
} // namespace eth
Updated on 2026-06-05 at 17:22:19 -0700