bb_ops/syscalls/peers/
lookup.rs1use bb_ir::proto::onnx::NodeProto;
11use bb_runtime::atomic::DispatchResult;
12use bb_runtime::bus::{OpError, OpErrorKind};
13use bb_runtime::ids::PeerId;
14use bb_runtime::runtime::RuntimeResourceRef;
15use bb_runtime::slot_value::SlotValue;
16use bb_runtime::syscall::values::{AddressVecValue, PeerIdValue};
17
18pub const DOMAIN: &str = "ai.bytesandbrains.address_book";
20pub const OP_TYPE: &str = "Lookup";
22pub const PORT_ADDRESSES: &str = "addresses";
24
25pub fn invoke(
30 _node: &NodeProto,
31 inputs: &[(&str, &dyn SlotValue)],
32 ctx: &mut RuntimeResourceRef<'_>,
33) -> Result<DispatchResult, OpError> {
34 let peer = downcast_peer(inputs)?;
35 let addrs = ctx
36 .peers
37 .addresses
38 .lookup(peer)
39 .map(|s| s.to_vec())
40 .ok_or_else(|| OpError {
41 kind: OpErrorKind::ExecutionFailed,
42 reason: "address_book_lookup_miss",
43 detail: format!("AddressBook::Lookup: peer {peer} not in address book"),
44 })?;
45 Ok(DispatchResult::Immediate(vec![(
46 PORT_ADDRESSES.to_string(),
47 Box::new(AddressVecValue(addrs)) as Box<dyn SlotValue>,
48 )]))
49}
50
51fn downcast_peer(inputs: &[(&str, &dyn SlotValue)]) -> Result<PeerId, OpError> {
52 let (_, value) = inputs
53 .iter()
54 .find(|(n, _)| *n == "peer")
55 .ok_or_else(|| OpError {
56 kind: OpErrorKind::MissingSlot,
57 reason: "missing_peer",
58 detail: "AddressBook::Lookup: required input `peer` is absent".into(),
59 })?;
60 value
61 .as_any()
62 .downcast_ref::<PeerIdValue>()
63 .map(|p| p.0)
64 .ok_or_else(|| OpError {
65 kind: OpErrorKind::TypeMismatch,
66 reason: "expected_peer_id",
67 detail: "AddressBook::Lookup: input `peer` is not a PeerId".into(),
68 })
69}
70
71
72bb_derive::register_op! {
73 domain: "ai.bytesandbrains.address_book",
74 op_type: "Lookup",
75 invoke: invoke,
76}