Skip to content

Commit

Permalink
init dandelion integration
Browse files Browse the repository at this point in the history
  • Loading branch information
Boog900 committed Oct 10, 2024
1 parent 8be3698 commit adf592e
Show file tree
Hide file tree
Showing 16 changed files with 504 additions and 3 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ rayon = { version = "1.10.0", default-features = false }
serde_bytes = { version = "0.11.15", default-features = false }
serde_json = { version = "1.0.128", default-features = false }
serde = { version = "1.0.210", default-features = false }
sha3 = { version = "0.10.8", default-features = false }
thiserror = { version = "1.0.63", default-features = false }
thread_local = { version = "1.1.8", default-features = false }
tokio-util = { version = "0.7.12", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions binaries/cuprated/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ rayon = { workspace = true }
serde_bytes = { workspace = true }
serde_json = { workspace = true }
serde = { workspace = true }
sha3 = { workspace = true, features = ["std"] }
thiserror = { workspace = true }
thread_local = { workspace = true }
tokio-util = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion binaries/cuprated/src/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod manager;
mod syncer;
mod types;

use types::{
pub use types::{
ConcreteBlockVerifierService, ConcreteTxVerifierService, ConsensusBlockchainReadHandle,
};

Expand Down
5 changes: 5 additions & 0 deletions binaries/cuprated/src/txpool.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//! Transaction Pool
//!
//! Will handle initiating the tx-pool, providing the preprocessor required for the dandelion pool.

mod dandelion;
mod incoming_tx;
mod manager;
mod txs_being_handled;
38 changes: 38 additions & 0 deletions binaries/cuprated/src/txpool/dandelion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use bytes::Bytes;
use cuprate_dandelion_tower::{DandelionConfig, DandelionRouter};
use cuprate_p2p::NetworkInterface;
use cuprate_p2p_core::ClearNet;
use cuprate_wire::NetworkAddress;

mod diffuse_service;
mod stem_service;
mod tx_store;

struct DandelionTx(Bytes);

type TxId = [u8; 32];

pub fn start_dandelion_router(
clear_net: NetworkInterface<ClearNet>,
) -> DandelionRouter<
stem_service::OutboundPeerStream,
diffuse_service::DiffuseService,
NetworkAddress,
stem_service::StemPeerService<ClearNet>,
DandelionTx,
> {
DandelionRouter::new(
diffuse_service::DiffuseService {
clear_net_broadcast_service: clear_net.broadcast_svc(),
},
stem_service::OutboundPeerStream {
clear_net: clear_net.clone(),
},
DandelionConfig {
time_between_hop: Default::default(),
epoch_duration: Default::default(),
fluff_probability: 0.0,
graph: Default::default(),
},
)
}
32 changes: 32 additions & 0 deletions binaries/cuprated/src/txpool/dandelion/diffuse_service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::task::{Context, Poll};
use tower::Service;

use crate::txpool::dandelion::DandelionTx;
use cuprate_dandelion_tower::traits::DiffuseRequest;
use cuprate_p2p::{BroadcastRequest, BroadcastSvc, NetworkInterface};
use cuprate_p2p_core::ClearNet;

pub struct DiffuseService {
pub clear_net_broadcast_service: BroadcastSvc<ClearNet>,
}

impl Service<DiffuseRequest<DandelionTx>> for DiffuseService {
type Response = BroadcastSvc::Response;
type Error = tower::BoxError;
type Future = BroadcastSvc::Future;

fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.clear_net_broadcast_service
.poll_ready(cx)
.map_err(Into::into)
}

fn call(&mut self, req: DiffuseRequest<DandelionTx>) -> Self::Future {
self.clear_net_broadcast_service
.call(BroadcastRequest::Transaction {
tx_bytes: req.0 .0,
direction: None,
received_from: None,
})
}
}
54 changes: 54 additions & 0 deletions binaries/cuprated/src/txpool/dandelion/stem_service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use super::DandelionTx;
use bytes::Bytes;
use cuprate_dandelion_tower::traits::StemRequest;
use cuprate_dandelion_tower::OutboundPeer;
use cuprate_p2p::NetworkInterface;
use cuprate_p2p_core::client::Client;
use cuprate_p2p_core::{ClearNet, NetworkZone, PeerRequest, ProtocolRequest};
use cuprate_wire::protocol::NewTransactions;
use cuprate_wire::NetworkAddress;
use futures::Stream;
use std::pin::Pin;
use std::task::{Context, Poll};
use tower::Service;

pub struct OutboundPeerStream {
pub clear_net: NetworkInterface<ClearNet>,
}

impl Stream for OutboundPeerStream {
type Item = Result<OutboundPeer<NetworkAddress, StemPeerService<ClearNet>>, tower::BoxError>;

fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Poll::Ready(Some(Ok(self
.clear_net
.client_pool()
.outbound_client()
.map_or(OutboundPeer::Exhausted, |client| {
OutboundPeer::Peer(client.info.id.into(), StemPeerService(client))
}))))
}
}

pub struct StemPeerService<N>(Client<N>);

impl<N: NetworkZone> Service<StemRequest<DandelionTx>> for StemPeerService<N> {
type Response = ();
type Error = tower::BoxError;
type Future = Client::Future;

fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.0.poll_ready(cx)
}

fn call(&mut self, req: StemRequest<DandelionTx>) -> Self::Future {
self.0
.call(PeerRequest::Protocol(ProtocolRequest::NewTransactions(
NewTransactions {
txs: vec![req.0 .0],
dandelionpp_fluff: false,
padding: Bytes::new(),
},
)))
}
}
47 changes: 47 additions & 0 deletions binaries/cuprated/src/txpool/dandelion/tx_store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::txpool::dandelion::{DandelionTx, TxId};
use bytes::Bytes;
use cuprate_dandelion_tower::traits::{TxStoreRequest, TxStoreResponse};
use cuprate_database::RuntimeError;
use cuprate_txpool::service::interface::{TxpoolReadRequest, TxpoolReadResponse};
use cuprate_txpool::service::{TxpoolReadHandle, TxpoolWriteHandle};
use futures::future::BoxFuture;
use futures::{FutureExt, StreamExt, TryFutureExt};
use std::task::{Context, Poll};
use tower::util::Oneshot;
use tower::{Service, ServiceExt};

pub struct TxStoreService {
txpool_read_handle: TxpoolReadHandle,
txpool_write_handle: TxpoolWriteHandle,
}

impl Service<TxStoreRequest<TxId>> for TxStoreService {
type Response = TxStoreResponse<DandelionTx>;
type Error = tower::BoxError;
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;

fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}

fn call(&mut self, req: TxStoreRequest<TxId>) -> Self::Future {
match req {
TxStoreRequest::Get(tx_id) => self
.txpool_read_handle
.clone()
.oneshot(TxpoolReadRequest::TxBlob(tx_id))
.map(|res| match res {
Ok(TxpoolReadResponse::TxBlob(blob)) => Ok(TxStoreResponse::Transaction(Some(
(DandelionTx(Bytes::from(blob)), todo!()),
))),
Err(RuntimeError::KeyNotFound) => Ok(TxStoreResponse::Transaction(None)),
Err(e) => Err(e.into()),
Ok(_) => unreachable!(),
})
.boxed(),
TxStoreRequest::Promote(tx_id) => {
todo!()
}
}
}
}
Loading

0 comments on commit adf592e

Please sign in to comment.