bb_ops/syscalls/peers/
insert.rs1use bb_ir::proto::onnx::NodeProto;
12use bb_runtime::atomic::DispatchResult;
13use bb_runtime::bus::{OpError, OpErrorKind};
14use bb_runtime::framework::Address;
15use bb_runtime::ids::PeerId;
16use bb_runtime::runtime::RuntimeResourceRef;
17use bb_runtime::slot_value::SlotValue;
18use bb_runtime::syscall::values::{AddressValue, PeerIdValue};
19
20pub const DOMAIN: &str = "ai.bytesandbrains.address_book";
22pub const OP_TYPE: &str = "Insert";
24
25pub fn invoke(
33 _node: &NodeProto,
34 inputs: &[(&str, &dyn SlotValue)],
35 ctx: &mut RuntimeResourceRef<'_>,
36) -> Result<DispatchResult, OpError> {
37 let peer = downcast_peer(inputs)?;
38 let addr = downcast_addr(inputs)?;
39 let result = if ctx.peers.addresses.lookup(peer).is_some() {
40 ctx.peers.addresses.register_address(peer, addr)
41 } else {
42 ctx.peers.addresses.add_peer(peer, vec![addr])
43 };
44 match result {
45 Ok(()) => Ok(DispatchResult::Immediate(Vec::new())),
46 Err(e) => Err(OpError {
47 kind: OpErrorKind::ExecutionFailed,
48 reason: "address_book_insert_failed",
49 detail: format!("AddressBook::Insert: {e}"),
50 }),
51 }
52}
53
54fn downcast_peer(inputs: &[(&str, &dyn SlotValue)]) -> Result<PeerId, OpError> {
55 let (_, value) = inputs
56 .iter()
57 .find(|(n, _)| *n == "peer")
58 .ok_or_else(|| OpError {
59 kind: OpErrorKind::MissingSlot,
60 reason: "missing_peer",
61 detail: "AddressBook::Insert: required input `peer` is absent".into(),
62 })?;
63 value
64 .as_any()
65 .downcast_ref::<PeerIdValue>()
66 .map(|p| p.0)
67 .ok_or_else(|| OpError {
68 kind: OpErrorKind::TypeMismatch,
69 reason: "expected_peer_id",
70 detail: "AddressBook::Insert: input `peer` is not a PeerId".into(),
71 })
72}
73
74fn downcast_addr(inputs: &[(&str, &dyn SlotValue)]) -> Result<Address, OpError> {
75 let (_, value) = inputs
76 .iter()
77 .find(|(n, _)| *n == "addr")
78 .ok_or_else(|| OpError {
79 kind: OpErrorKind::MissingSlot,
80 reason: "missing_addr",
81 detail: "AddressBook::Insert: required input `addr` is absent".into(),
82 })?;
83 value
84 .as_any()
85 .downcast_ref::<AddressValue>()
86 .map(|a| a.0.clone())
87 .ok_or_else(|| OpError {
88 kind: OpErrorKind::TypeMismatch,
89 reason: "expected_multiaddress",
90 detail: "AddressBook::Insert: input `addr` is not a Multiaddress".into(),
91 })
92}
93
94
95bb_derive::register_op! {
96 domain: "ai.bytesandbrains.address_book",
97 op_type: "Insert",
98 invoke: invoke,
99}