Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions based/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 16 additions & 11 deletions based/bin/gateway_registry/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
time::Duration,
};

use alloy_primitives::{Address, B256, U256};
use alloy_primitives::{Address, U256};
use alloy_provider::{Provider, RootProvider};
use bop_common::{
api::RegistryApiServer,
Expand Down Expand Up @@ -108,19 +108,19 @@ enum RegistryError {
}
type Result<T> = std::result::Result<T, RegistryError>;

fn refresh_gateway_clients(path: impl AsRef<Path>) -> Result<Vec<(Url, Address, B256)>> {
fn refresh_gateway_clients(path: impl AsRef<Path>) -> Result<Vec<(Url, Address)>> {
Ok(serde_json::from_reader(std::fs::File::open(path.as_ref())?)?)
}

fn write_gateway_clients(path: Arc<PathBuf>, clients: &[(Url, Address, B256)]) {
fn write_gateway_clients(path: Arc<PathBuf>, clients: &[(Url, Address)]) {
let _ = std::fs::write(Arc::unwrap_or_clone(path), serde_json::to_string(clients).unwrap());
}

#[derive(Clone)]
pub struct RegistryServer {
eth_client: RootProvider,
// url, address, jwt secret
gateway_clients: Arc<RwLock<Vec<(Url, Address, B256)>>>,
// url, address
gateway_clients: Arc<RwLock<Vec<(Url, Address)>>>,
gateway_update_blocks: u64,
registry_path: Arc<PathBuf>,

Expand Down Expand Up @@ -190,7 +190,7 @@ impl RegistryServer {
#[async_trait]
impl RegistryApiServer for RegistryServer {
#[tracing::instrument(skip_all, err, ret(level = Level::DEBUG))]
async fn get_future_gateway(&self, n_blocks_into_the_future: u64) -> RpcResult<(u64, Url, Address, B256)> {
async fn get_future_gateway(&self, n_blocks_into_the_future: u64) -> RpcResult<(u64, Url, Address)> {
// let curblock = self.eth_client.block_number().await?;
let curblock = if !self.use_mock_blocknumber {
self.eth_client
Expand All @@ -210,26 +210,31 @@ impl RegistryApiServer for RegistryServer {
n_blocks_into_the_future;

let id = (target_block / self.gateway_update_blocks) as usize;
let (url, address, jwt_in_b256) = gateways[id % n_gateways].clone();
let (url, address) = gateways[id % n_gateways].clone();
tracing::debug!("serving future gateway for block {target_block}: url={url}, address={address}",);
Ok((target_block, url, address, jwt_in_b256))
Ok((target_block, url, address))
}

#[tracing::instrument(skip_all, err, ret(level = Level::DEBUG))]
async fn registered_gateways(&self) -> RpcResult<Vec<(Url, Address, B256)>> {
async fn registered_gateways(&self) -> RpcResult<Vec<(Url, Address)>> {
Ok(self.gateway_clients.read().clone())
}

#[tracing::instrument(skip_all, err, ret(level = Level::DEBUG))]
async fn register_gateway(&self, gateway: (Url, Address, B256)) -> RpcResult<()> {
async fn register_gateway(&self, gateway: (Url, Address)) -> RpcResult<()> {
let mut gateways = self.gateway_clients.read().clone();
if !gateways.iter().any(|g| g.0.host() == gateway.0.host() || g.2 == gateway.2) {
if !gateways.iter().any(|g| g.0.host() == gateway.0.host() || g.1 == gateway.1) {
gateways.push(gateway);
write_gateway_clients(self.registry_path.clone(), &gateways);
*self.gateway_clients.write() = gateways;
}
Ok(())
}

#[tracing::instrument(skip_all, ret(level = Level::DEBUG))]
async fn gateway_update_blocks(&self) -> RpcResult<u64> {
Ok(self.gateway_update_blocks)
}
}

#[tokio::main]
Expand Down
2 changes: 1 addition & 1 deletion based/bin/overseer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl OverseerConnections {
}

pub fn current_gateway(&self) -> Result<(Url, Address), ClientError> {
self.runtime.block_on(self.client_portal.current_gateway()).map(|(_, url, address, _)| (url, address))
self.runtime.block_on(self.client_portal.current_gateway()).map(|(_, url, address)| (url, address))
}

pub fn peers_based_op_node(&self) -> Result<Vec<OpPeerInfo>, ClientError> {
Expand Down
27 changes: 25 additions & 2 deletions based/bin/portal/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::path::PathBuf;
use std::{fs, path::PathBuf};

use bop_common::config::{LoggingConfig, LoggingFlags};
use bop_common::{
config::{LoggingConfig, LoggingFlags},
signing::ECDSASigner,
};
use clap::Parser;
use reqwest::Url;
use reth_rpc_layer::JwtSecret;
Expand Down Expand Up @@ -40,6 +43,9 @@ pub struct PortalArgs {
/// Timeout for gateway requests in milliseconds
#[arg(long = "gateway.timeout_ms", default_value_t = 100)]
pub gateway_timeout_ms: u64,
/// Signing key used to authenticate with gateways (hex string or path to file containing hex)
#[arg(long = "gateway.signing-key")]
pub gateway_signing_key: String,

/// Enable debug logging
#[arg(long)]
Expand Down Expand Up @@ -88,6 +94,10 @@ impl PortalArgs {
.or_else(|_| JwtSecret::from_file(std::path::Path::new(&self.config_dir.join("jwt"))))
.expect("Please set the --fallback.jwt flag manually, or generate and place a jwt file in the config dir")
}

pub fn gateway_signer(&self) -> eyre::Result<ECDSASigner> {
parse_signing_key(&self.gateway_signing_key)
}
}

impl From<&PortalArgs> for LoggingConfig {
Expand All @@ -106,3 +116,16 @@ impl From<&PortalArgs> for LoggingConfig {
}
}
}

fn parse_signing_key(input: &str) -> eyre::Result<ECDSASigner> {
let trimmed = input.trim();
let normalized = trimmed.trim_start_matches("0x");
match ECDSASigner::try_from_hex(normalized) {
Ok(signer) => Ok(signer),
Err(_) => {
let contents = fs::read_to_string(trimmed)?;
let key = contents.trim().trim_start_matches("0x");
ECDSASigner::try_from_hex(key).map_err(|err| eyre::eyre!("failed to parse gateway signing key: {err}"))
}
}
}
Loading
Loading