This will be a parent issue for smaller ones.
When it's finished, it should look something like that:
// ping-pong/query.rs
const SERVICE_ID: u16 = 1;
// Query
#[derive(Clone, Serialize, Deserialize)]
struct Ping {
some_useful_data: i64
}
// Reply
#[derive(Clone, Serialize, Deserialize)]
struct Pong {
satisfied: bool
}
impl Replyable for Pong {
// Verifies raw query to change local peer score. Defaults to `None`
fn verify(&self, _: &Query) -> VerificationMethod {
VerificationMethod::None
}
}
impl Queryable for Ping {
// These constants allows communication between peers even if one of them doesn't know all queries that knows another peer.
const SERVICE_ID: u16 = SERVICE_ID;
const METHOD_ID: u16 = 1;
// Reply type
type Reply = Pong;
// To whom is this query addressed
fn peer_selection(&self) -> PeerSelection {
PeerSelection::Random(5)
}
// To prevent abuse, what kind of PoW (Proof-of-Work) challenge should a node return. Defaults to `None`
fn pow_config(&self) -> PowConfig {
PowConfig::Low
}
}
// ping-pong/service.rs
struct PingPongService {
network_rx: mpsc::Receiver<Query>, // Receive queries
network_handle: NetworkHandle, // and answer to them
}
#[actor]
impl PingPongService {
pub fn new(network_rx: mpsc::Receiver<Query>, network_handle: NetworkHandle) -> Self {
Self { network_rx, network_handle }
}
#[listen(self.network_rx.recv())]
async fn query(&mut self, q: Query) {
match q.method_id {
Ping::METHOD_ID => {
let ping: Ping = q.into(); // Deserializes from bytes
let pong = Pong { satisfied: ping.some_useful_data > 0 };
// query_id links this reply to the ping query
pong.reply_to(q.query_id, &self.network_handle).await;
}
_ => {} // unknown
}
}
// node/main.rs
fn main() {
let (pingpong_net_tx, pingpong_net_rx) = Channel::new(1024);
let network_handle = NetworkActor::new()
.register(ping_pong::SERVICE_ID, pingpong_net_tx)
.spawn();
PingPong::new(pingpong_net_rx, network_handle).spawn();
}
// client/main.rs
fn main() {
let network = NetworkActor::new().spawn();
let Pong { satisfied } = Ping { some_useful_data: -1 }.query(&network).await.expect("something went wrong");
assert!(!satisfied);
}
The API design isn't final yet, so if you have any ideas, I'd love to hear them!
This will be a parent issue for smaller ones.
When it's finished, it should look something like that:
The API design isn't final yet, so if you have any ideas, I'd love to hear them!