eth/rpc_manager.hpp¶
Namespaces¶
| Name |
|---|
| eth |
| eth::rpc |
Classes¶
| Name | |
|---|---|
| struct | eth::rpc::RpcEndpointError |
| struct | eth::rpc::RpcEndpoint |
| struct | eth::rpc::RpcEndpointGroup |
| class | eth::rpc::RpcEndpointPool |
| class | eth::rpc::RpcManager |
| struct | eth::rpc::RpcReceiptSourceHandle |
Types¶
| Name | |
|---|---|
| enum class | RpcEndpointState |
| enum class | RpcEndpointErrorCode |
| template <typename T > using outcome::result< T, RpcEndpointError, outcome::policy::all_narrow > |
RpcResult |
| using std::function< std::optional< std::string >(std::string_view)> | RpcEnvLookup |
Functions¶
| Name | |
|---|---|
| const char * | to_string(RpcEndpointErrorCode code) |
| const char * | to_string(RpcEndpointState state) |
| RpcResult< std::string > | render_rpc_endpoint_url(const RpcEndpointConfig & config, RpcEnvLookup env_lookup ={}) Resolve a URL template into a concrete endpoint URL. |
| RpcResult< RpcEndpoint > | build_rpc_endpoint(const RpcEndpointConfig & config, RpcEnvLookup env_lookup) Materialize a runtime endpoint from configuration. |
| std::vector< RpcEndpointGroup > | group_rpc_endpoints(const RpcManagerConfig & config, RpcEnvLookup env_lookup) Group endpoints by chain name and chain id with deterministic ordering. |
| std::optional< RpcReceiptSourceHandle > | make_receipt_source(RpcManager & manager, std::string chain_name, uint64_t chain_id, FinalityPolicy finality_policy) |
Types Documentation¶
enum RpcEndpointState¶
| Enumerator | Value | Description |
|---|---|---|
| kAvailable | ||
| kTemporarilyFailed | ||
| kDisabled |
enum RpcEndpointErrorCode¶
| Enumerator | Value | Description |
|---|---|---|
| kMissingApiKey | ||
| kInvalidTemplate |
using RpcResult¶
template <typename T >
using eth::rpc::RpcResult = outcome::result<T, RpcEndpointError, outcome::policy::all_narrow>;
using RpcEnvLookup¶
Functions Documentation¶
function to_string¶
function to_string¶
function render_rpc_endpoint_url¶
RpcResult< std::string > render_rpc_endpoint_url(
const RpcEndpointConfig & config,
RpcEnvLookup env_lookup ={}
)
Resolve a URL template into a concrete endpoint URL.
The only supported placeholder is {key}.
function build_rpc_endpoint¶
RpcResult< RpcEndpoint > build_rpc_endpoint(
const RpcEndpointConfig & config,
RpcEnvLookup env_lookup
)
Materialize a runtime endpoint from configuration.
function group_rpc_endpoints¶
std::vector< RpcEndpointGroup > group_rpc_endpoints(
const RpcManagerConfig & config,
RpcEnvLookup env_lookup
)
Group endpoints by chain name and chain id with deterministic ordering.
function make_receipt_source¶
std::optional< RpcReceiptSourceHandle > make_receipt_source(
RpcManager & manager,
std::string chain_name,
uint64_t chain_id,
FinalityPolicy finality_policy
)
Source code¶
// Copyright 2026 Genius Ventures, Inc.
// SPDX-License-Identifier: MIT
#ifndef EVMRELAY_INCLUDE_ETH_RPC_MANAGER_HPP
#define EVMRELAY_INCLUDE_ETH_RPC_MANAGER_HPP
#include <eth/finality_policy.hpp>
#include <eth/rpc_manager_config.hpp>
#include <eth/rpc_receipt_source.hpp>
#include <eth/rpc_http_transport.hpp>
#include <boost/outcome/result.hpp>
#include <chrono>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
namespace eth::rpc {
namespace outcome = BOOST_OUTCOME_V2_NAMESPACE;
enum class RpcEndpointState
{
kAvailable,
kTemporarilyFailed,
kDisabled
};
enum class RpcEndpointErrorCode
{
kMissingApiKey,
kInvalidTemplate
};
struct RpcEndpointError
{
RpcEndpointErrorCode code = RpcEndpointErrorCode::kInvalidTemplate;
std::string detail;
};
template <typename T>
using RpcResult = outcome::result<T, RpcEndpointError, outcome::policy::all_narrow>;
struct RpcEndpoint
{
std::string chain_name;
uint64_t chain_id = 0;
std::string url;
uint32_t priority = 0;
uint32_t weight = 0;
uint32_t rate_limit_per_second = 0;
bool is_paid = false;
bool is_public = true;
bool verified = false;
RpcEndpointState state = RpcEndpointState::kAvailable;
std::chrono::steady_clock::time_point last_failure_time{};
uint32_t failure_count = 0;
std::chrono::steady_clock::time_point backoff_until{};
};
struct RpcEndpointGroup
{
std::string chain_name;
uint64_t chain_id = 0;
std::vector<RpcEndpoint> endpoints;
};
using RpcEnvLookup = std::function<std::optional<std::string>(std::string_view)>;
[[nodiscard]] const char* to_string(RpcEndpointErrorCode code) noexcept;
[[nodiscard]] const char* to_string(RpcEndpointState state) noexcept;
[[nodiscard]] RpcResult<std::string> render_rpc_endpoint_url(
const RpcEndpointConfig& config,
RpcEnvLookup env_lookup = {});
[[nodiscard]] RpcResult<RpcEndpoint> build_rpc_endpoint(
const RpcEndpointConfig& config,
RpcEnvLookup env_lookup = {});
[[nodiscard]] std::vector<RpcEndpointGroup> group_rpc_endpoints(
const RpcManagerConfig& config,
RpcEnvLookup env_lookup = {});
class RpcEndpointPool
{
public:
static constexpr auto kMaxBackoff = std::chrono::seconds(60);
static constexpr auto kBaseBackoff = std::chrono::seconds(1);
static constexpr auto kEscalationWindow = std::chrono::minutes(5);
static constexpr uint32_t kEscalationThreshold = 3;
RpcEndpointPool() = default;
explicit RpcEndpointPool(std::vector<RpcEndpoint> endpoints);
[[nodiscard]] const std::vector<RpcEndpoint>& endpoints() const noexcept
{
return endpoints_;
}
[[nodiscard]] std::vector<RpcEndpoint>& endpoints() noexcept
{
return endpoints_;
}
[[nodiscard]] std::optional<std::reference_wrapper<RpcEndpoint>> next_endpoint();
[[nodiscard]] std::optional<std::reference_wrapper<const RpcEndpoint>> next_endpoint() const;
void mark_temporary_failure(std::string_view url);
void disable(std::string_view url);
void reset_temporary_failures();
private:
[[nodiscard]] static bool is_usable(const RpcEndpoint& endpoint) noexcept;
std::vector<RpcEndpoint> endpoints_;
};
class RpcManager
{
public:
explicit RpcManager(
RpcManagerConfig config,
RpcEnvLookup env_lookup = {});
[[nodiscard]] const std::vector<RpcEndpointGroup>& endpoint_groups() const noexcept
{
return groups_;
}
[[nodiscard]] std::optional<std::reference_wrapper<RpcEndpointPool>> pool(
std::string_view chain_name,
uint64_t chain_id);
[[nodiscard]] std::optional<std::reference_wrapper<const RpcEndpointPool>> pool(
std::string_view chain_name,
uint64_t chain_id) const;
private:
struct PoolEntry
{
RpcEndpointGroup group;
RpcEndpointPool pool;
};
[[nodiscard]] static std::string make_chain_key(std::string_view chain_name, uint64_t chain_id);
std::vector<RpcEndpointGroup> groups_;
std::vector<PoolEntry> pools_;
};
struct RpcReceiptSourceHandle
{
std::unique_ptr<RpcHttpTransport> transport;
std::unique_ptr<RpcReceiptSource> source;
};
[[nodiscard]] std::optional<RpcReceiptSourceHandle> make_receipt_source(
RpcManager& manager,
std::string chain_name,
uint64_t chain_id,
FinalityPolicy finality_policy = {});
} // namespace eth::rpc
#endif // EVMRELAY_INCLUDE_ETH_RPC_MANAGER_HPP
Updated on 2026-06-05 at 17:22:19 -0700