Skip to content

Commit

Permalink
feat: add relay and utxo data adapters with mock implementations (#10)
Browse files Browse the repository at this point in the history
* feat: add relay and utxo data providers with mock implementations

* refactor: rename UtxoDataProvider to UtxoDataAdapter and update related implementations
  • Loading branch information
Mercurial authored Feb 4, 2025
1 parent 8a9e9fb commit 5f7a7dd
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/ledger/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod relay;
pub mod utxo;
41 changes: 41 additions & 0 deletions src/ledger/relay/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use async_trait::async_trait;

/// A simple trait for returning a list of relay addresses in the format "hostname:port".
#[async_trait]
pub trait RelayDataProvider {
async fn get_relays(&self) -> Vec<String>;
}

/// A mock provider that returns a pre-defined list of string addresses, e.g., ["relay1:3001", "relay2:3002"].
pub struct MockRelayDataProvider {
pub mock_relays: Vec<String>,
}

#[async_trait]
impl RelayDataProvider for MockRelayDataProvider {
async fn get_relays(&self) -> Vec<String> {
self.mock_relays.clone()
}
}

#[cfg(test)]
mod tests {
use super::*;
use tokio::test;

#[test]
async fn it_returns_mock_relays() {
let provider = MockRelayDataProvider {
mock_relays: vec![
"relay1:3001".to_string(),
"relay2:3002".to_string(),
],
};

let relays = provider.get_relays().await;

assert_eq!(relays.len(), 2);
assert_eq!(relays[0], "relay1:3001");
assert_eq!(relays[1], "relay2:3002");
}
}
75 changes: 75 additions & 0 deletions src/ledger/utxo/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use async_trait::async_trait;
use std::collections::HashMap;
use thiserror::Error;

/// Errors related to querying UTxOs.
#[derive(Debug, Error)]
pub enum UtxoQueryError {
#[error("network error")]
Network(#[from] std::io::Error),
#[error("unknown error: {0}")]
Unknown(String),
}

#[async_trait]
pub trait UtxoDataAdapter {
async fn fetch_utxos(
&self,
utxo_refs: &[String],
) -> Result<HashMap<String, Vec<u8>>, UtxoQueryError>;
}

pub struct MockUtxoDataAdapter {
pub known_utxos: HashMap<String, Vec<u8>>,
}

#[async_trait]
impl UtxoDataAdapter for MockUtxoDataAdapter {
async fn fetch_utxos(
&self,
utxo_refs: &[String],
) -> Result<HashMap<String, Vec<u8>>, UtxoQueryError> {
let mut result = HashMap::new();

// Check each requested reference; if known, clone the data into the result
for reference in utxo_refs {
if let Some(cbor_data) = self.known_utxos.get(reference) {
result.insert(reference.clone(), cbor_data.clone());
}
}

Ok(result)
}
}

#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;

#[tokio::test]
async fn it_returns_found_utxos_only() {
// Arrange: a mock with two known references
let mut known = HashMap::new();
known.insert("abc123#0".to_string(), vec![0x82, 0xa0]); // example CBOR
known.insert("abc123#1".to_string(), vec![0x83, 0x04]);

let provider = MockUtxoDataAdapter { known_utxos: known };

// We'll request three references, one of which doesn't exist
let requested = vec![
"abc123#0".to_string(),
"abc123#1".to_string(),
"missing#2".to_string(),
];

// Act
let results = provider.fetch_utxos(&requested).await.unwrap();

// Assert
assert_eq!(results.len(), 2, "Should only contain two known references");
assert!(results.contains_key("abc123#0"));
assert!(results.contains_key("abc123#1"));
assert!(!results.contains_key("missing#2"));
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, Env
mod pipeline;
mod server;
mod storage;
mod ledger;

#[tokio::main]
async fn main() -> Result<()> {
Expand Down
4 changes: 1 addition & 3 deletions src/pipeline/fanout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ impl gasket::framework::Worker<Stage> for Worker {
let mut transaction = unit.clone();
info!("fanout {}", transaction.id);

// extract cbor from unit and pass it to tx_submit_peer_manager
// comment out for now until we have a proper tx to submit
self.tx_submit_peer_manager
.add_tx(transaction.raw.clone())
.await;
Expand Down Expand Up @@ -101,7 +99,7 @@ mod fanout_tests {
use super::*;

#[tokio::test]
async fn test_fanout_stage() {
async fn it_should_fanout_stage() {
let _ = tracing_subscriber::fmt().with_env_filter("info").try_init();

let peer_server = Arc::new(MockOuroborosTxSubmitPeerServer::new(
Expand Down
3 changes: 2 additions & 1 deletion src/server/utxorpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ impl submit_service_server::SubmitService for SubmitServiceImpl {
}
}

info!(?hashes, "submitting txs");
let hashes_str: Vec<String> = hashes.iter().map(|x| hex::encode(x)).collect();
info!(?hashes_str, "submitting txs");

self.tx_storage.create(&txs).await.map_err(|error| {
error!(?error);
Expand Down

0 comments on commit 5f7a7dd

Please sign in to comment.