litep2p/protocol/libp2p/bitswap/handle.rs
1// Copyright 2023 litep2p developers
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21//! Bitswap handle for communicating with the bitswap protocol implementation.
22
23use crate::{
24 protocol::libp2p::bitswap::{BlockPresenceType, WantType},
25 PeerId,
26};
27
28use cid::Cid;
29use tokio::sync::mpsc::{Receiver, Sender};
30
31use std::{
32 pin::Pin,
33 task::{Context, Poll},
34};
35
36/// Events emitted by the bitswap protocol.
37#[derive(Debug)]
38pub enum BitswapEvent {
39 /// Bitswap request.
40 Request {
41 /// Peer ID.
42 peer: PeerId,
43
44 /// Requested CIDs.
45 cids: Vec<(Cid, WantType)>,
46 },
47}
48
49/// Response type for received bitswap request.
50#[derive(Debug)]
51#[cfg_attr(feature = "fuzz", derive(serde::Serialize, serde::Deserialize))]
52pub enum ResponseType {
53 /// Block.
54 Block {
55 /// CID.
56 cid: Cid,
57
58 /// Found block.
59 block: Vec<u8>,
60 },
61
62 /// Presense.
63 Presence {
64 /// CID.
65 cid: Cid,
66
67 /// Whether the requested block exists or not.
68 presence: BlockPresenceType,
69 },
70}
71
72/// Commands sent from the user to `Bitswap`.
73#[derive(Debug)]
74#[cfg_attr(feature = "fuzz", derive(serde::Serialize, serde::Deserialize))]
75pub enum BitswapCommand {
76 /// Send bitswap response.
77 SendResponse {
78 /// Peer ID.
79 peer: PeerId,
80
81 /// CIDs.
82 responses: Vec<ResponseType>,
83 },
84}
85
86/// Handle for communicating with the bitswap protocol.
87pub struct BitswapHandle {
88 /// RX channel for receiving bitswap events.
89 event_rx: Receiver<BitswapEvent>,
90
91 /// TX channel for sending commads to `Bitswap`.
92 cmd_tx: Sender<BitswapCommand>,
93}
94
95impl BitswapHandle {
96 /// Create new [`BitswapHandle`].
97 pub(super) fn new(event_rx: Receiver<BitswapEvent>, cmd_tx: Sender<BitswapCommand>) -> Self {
98 Self { event_rx, cmd_tx }
99 }
100
101 /// Send `request` to `peer`.
102 ///
103 /// Not supported by the current implementation.
104 pub async fn send_request(&self, _peer: PeerId, _request: Vec<u8>) {
105 unimplemented!("bitswap requests are not supported");
106 }
107
108 /// Send `response` to `peer`.
109 pub async fn send_response(&self, peer: PeerId, responses: Vec<ResponseType>) {
110 let _ = self.cmd_tx.send(BitswapCommand::SendResponse { peer, responses }).await;
111 }
112
113 #[cfg(feature = "fuzz")]
114 /// Expose functionality for fuzzing
115 pub async fn fuzz_send_message(&mut self, command: BitswapCommand) -> crate::Result<()> {
116 let _ = self.cmd_tx.try_send(command);
117 Ok(())
118 }
119}
120
121impl futures::Stream for BitswapHandle {
122 type Item = BitswapEvent;
123
124 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
125 Pin::new(&mut self.event_rx).poll_recv(cx)
126 }
127}