eth/rpc_config_audit.cpp
Namespaces
Functions
|
Name |
| AuditSummary |
audit_rpc_config(const RpcManagerConfig & config, const FinalityPolicy & finality_policy) |
Functions Documentation
function audit_rpc_config
AuditSummary audit_rpc_config(
const RpcManagerConfig & config,
const FinalityPolicy & finality_policy
)
Source code
// Copyright 2026 Genius Ventures, Inc.
// SPDX-License-Identifier: MIT
#include <eth/rpc_config_audit.hpp>
#include <base/rlp-logger.hpp>
#include <algorithm>
#include <map>
#include <set>
namespace eth::rpc {
namespace {
AuditFinding make_finding(AuditSeverity severity,
std::string chain_name,
uint64_t chain_id,
std::string message)
{
return {severity, std::move(chain_name), chain_id, std::move(message)};
}
} // namespace
AuditSummary audit_rpc_config(
const RpcManagerConfig& config,
const FinalityPolicy& finality_policy)
{
AuditSummary summary;
summary.passed = true;
if (config.endpoints.empty())
{
summary.findings.push_back(
make_finding(AuditSeverity::kError, "", 0,
"No RPC endpoints configured — at least one endpoint per chain is required"));
summary.passed = false;
return summary;
}
if (finality_policy.confirmation_depth == 0
&& !finality_policy.prefer_finalized
&& !finality_policy.prefer_safe)
{
summary.findings.push_back(
make_finding(AuditSeverity::kError, "", 0,
"Confirmation depth is zero and neither 'prefer_finalized' nor 'prefer_safe' is set — "
"no finality guarantee"));
summary.passed = false;
}
std::map<uint64_t, size_t> endpoint_count_by_chain;
std::set<std::string> seen_endpoints;
for (const auto& ep : config.endpoints)
{
if (ep.chain_name.empty())
{
summary.findings.push_back(
make_finding(AuditSeverity::kError, "", ep.chain_id,
"Endpoint has empty chain_name"));
summary.passed = false;
}
if (ep.chain_id == 0)
{
summary.findings.push_back(
make_finding(AuditSeverity::kError, ep.chain_name, 0,
"Endpoint has zero chain_id"));
summary.passed = false;
}
if (ep.url_template.empty())
{
summary.findings.push_back(
make_finding(AuditSeverity::kError, ep.chain_name, ep.chain_id,
"Endpoint has empty url_template"));
summary.passed = false;
}
const auto dedup_key = std::to_string(ep.chain_id) + "|" + ep.url_template;
if (seen_endpoints.find(dedup_key) != seen_endpoints.end())
{
summary.findings.push_back(
make_finding(AuditSeverity::kWarning, ep.chain_name, ep.chain_id,
"Duplicate endpoint: " + ep.url_template));
}
seen_endpoints.insert(dedup_key);
++endpoint_count_by_chain[ep.chain_id];
}
for (const auto& [chain_id, count] : endpoint_count_by_chain)
{
if (count == 0)
{
std::string chain_label = chain_id != 0
? "chain_id=" + std::to_string(chain_id)
: std::string("(unknown chain)");
summary.findings.push_back(
make_finding(AuditSeverity::kError, "", chain_id,
"No usable endpoints for " + chain_label));
summary.passed = false;
}
}
return summary;
}
} // namespace eth::rpc
Updated on 2026-06-05 at 17:22:19 -0700